Thursday, December 1, 2022

#1 2022-11-19 09:57:56 am

David Brown
Member
Registered: 2021-04-24
Posts: 8

Is it possible to subclass without Xcode?

I would like a NSTextField whose text is vertically centered. All examples of doing so, which I have been able to find, are to subclass NSTextField. All examples of subclassing which I have found use Xcode. (I refer to subclassing anything, not only NSTextField.) However, I do not use Xcode. So...is it possible to subclass without using Xcode and, if so, how? I located a subclass solution by Daniel Jalkut of Red Sweater Software, which I have included in hope anyone with a solution can use it in their explanation.

Thank you in advance for any assistance.

The .m file:

Applescript:

//
// RSVerticallyCenteredTextField.m
// RSCommon
//
// Created by Daniel Jalkut on 6/17/06.
// Copyright 2006 Red Sweater Software. All rights reserved.
//

#import "RSVerticallyCenteredTextFieldCell.h"

@implementation RSVerticallyCenteredTextFieldCell

- (NSRect)drawingRectForBounds:(NSRect)theRect
{
// Get the parent's idea of where we should draw
NSRect newRect = [super drawingRectForBounds:theRect];

// When the text field is being
// edited or selected, we have to turn off the magic because it screws up
// the configuration of the field editor. We sneak around this by
// intercepting selectWithFrame and editWithFrame and sneaking a
// reduced, centered rect in at the last minute.
if (mIsEditingOrSelecting == NO)
{
// Get our ideal size for current text
NSSize textSize = [self cellSizeForBounds:theRect];

// Center that in the proposed rect
float heightDelta = newRect.size.height - textSize.height;
if (heightDelta > 0)
{
newRect.size.height -= heightDelta;
newRect.origin.y += (heightDelta / 2);
}
}

return newRect;
}

- (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(int)selStart length:(int)selLength
{
aRect = [self drawingRectForBounds:aRect];
mIsEditingOrSelecting = YES;
[super selectWithFrame:aRect inView:controlView editor:textObj delegate:anObject start:selStart length:selLength];
mIsEditingOrSelecting = NO;
}

- (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent
{
aRect = [self drawingRectForBounds:aRect];
mIsEditingOrSelecting = YES;
[super editWithFrame:aRect inView:controlView editor:textObj delegate:anObject event:theEvent];
mIsEditingOrSelecting = NO;
}

@end
[/AppleScript]

The .h file:

[applescript]//
// RSVerticallyCenteredTextFieldCell.h
// RSCommon
//
// Created by Daniel Jalkut on 6/17/06.
// Copyright 2006 Red Sweater Software. All rights reserved.
//

#import <Cocoa/Cocoa.h>


@interface RSVerticallyCenteredTextFieldCell : NSTextFieldCell
{
BOOL mIsEditingOrSelecting;
}

@end

Model: Mac Studio Ultra
Browser: Safari 605.1.15
Operating System: macOS 12

Offline

 

#2 2022-11-19 11:32:36 pm

technomorph
Member
Registered: 2017-12-14
Posts: 302

Re: Is it possible to subclass without Xcode?

Here's how to set up the SubClass, you'll have to translate the functions

Applescript:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use framework "AppKit"

script RSVerticallyCenteredTextFieldCell
   property parent : class "NSTextFieldCell"
   property mIsEditingOrSelecting : false
   
   -- translate the functions here
   
end script

Also do you know how you plan to "implement" the SubClass and use it?

Offline

 

#3 2022-11-25 01:17:30 pm

David Brown
Member
Registered: 2021-04-24
Posts: 8

Re: Is it possible to subclass without Xcode?

technomorph, thank you for your reply. After posting, I located a question about subclassing without Xcode on the forum of Late Night Software (https://forum.latenightsw.com/t/subclas … tobjc/2827). Shane gave a good explanation. In addition, I found a complete example on Takaaki Naganoya's AppleScript site (http://piyocast.com/as/archives/category/custom-class). I have now written a couple of simple subclasses, which work fine. However, I've been update to implement vertically centering text in a NSTextField. I have followed three basic approaches that I located online, without success. All used Xcode; solutions were expressed in .m and .h files. I did my best to write the appropriate AppleScriptObjC version, but without success. Also, it is necessary to subclass NSTextFieldCell, not NSTextField, but I believe I have correctly implemented that.

My subclass script is below, using the method of Daniel Jalkut (shown in my earlier post.) His method is to override drawingRectForBounds such that it returns the rectangle in which you would like the text placed, i.e. a rectangle just large enough to hold the text and centered in the text field's normal bounds. I started by seeing if I could implement that override; so my override simply returns the rectangle that applies to the textfield in my calling script. The result I get is what seems to be a normal NSTextField - no vertical centering.

You will notice two other overrides which I have commented out. Daniel's code uses these when the textfield is being edited, otherwise the text will be top-aligned during editing. When I enabled them, the text in my textfield can not be selected. At lease that confirms that my script is doing something.

Any insight and advice will be appreciated.

The subclass code:

Applescript:

use framework "Foundation"
use framework "AppKit"
use framework "AppleScriptObjC"
use scripting additions

script MYTextFieldCell
property parent : class "NSTextFieldCell"
property newRect : missing value

on drawingRectForBounds:aRect
set newRect to current application's NSMakeRect(250, 47, 200, 21)
return newRect
end drawingRectForBounds:

--on selectWithFrame:cFrame inView:cView editor:cEditor delegate:cDelegate start:cStart |length|:cLength
-- super's selectWithFrame:(current application's NSMakeRect(250, 20, 200, 75)) inView:cView editor:cEditor delegate:cDelegate start:cStart |length|:cLength
--end selectWithFrame:inView:editor:delegate:start:|length|:

--on editWithFrame:aFrame inView:aView editor:aEditor delegate:aDelegate |event|:aEvent
-- super's editWithFrame:(current application's NSMakeRect(250, 20, 200, 75)) inView:aView editor:aEditor delegate:aDelegate |event|:aEvent
--end editWithFrame:inView:editor:delegate:|event|:

end script
[/AppleScript]

The calling script:

[applescript]use framework "Foundation"
use framework "AppKit"
use framework "AppleScriptObjC"
use scripting additions

on run
set resourcePath to POSIX path of (path to me) & "Contents/Resources/Classes"
set theBundle to current application's NSBundle's bundleWithPath:resourcePath
theBundle's loadAppleScriptObjectiveCScripts()
my performSelectorOnMainThread:"prepareWindow:" withObject:(missing value) waitUntilDone:true
end run

on prepareWindow:sender
set theWindow to current application's NSWindow's alloc's initWithContentRect:(current application's NSMakeRect(1300, 900, 500, 300)) styleMask:7 backing:2 defer:false

current application's NSTextField's setCellClass:(current application's MYTextFieldCell)
set textField2 to current application's NSTextField's alloc()'s initWithFrame:{{250, 20}, {200, 75}}
textField2's setBordered:false
textField2's setAlignment:1
textField2's setFont:(current application's NSFont's fontWithName:"SFProRounded-Light" |size|:18)
textField2's setBackgroundColor:(current application's NSColor's systemRedColor)
textField2's setDrawsBackground:true
textField2's setStringValue:"Hello"
current application's NSTextField's setCellClass:(current application's NSTextFieldCell)
theWindow's contentView's addSubview:textField2
theWindow's makeKeyAndOrderFront:me
end prepareWindow:

Offline

 

#4 2022-11-26 09:10:35 pm

technomorph
Member
Registered: 2017-12-14
Posts: 302

Re: Is it possible to subclass without Xcode?

Your “init”ing a regular NSTextfield object.
You should be initiating your MYTextField class object.

Have a glance a Apples docs about subclasses.
Will give you a better understanding of how it all works together.


https://youtu.be/mLQBcB8wCa4

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)