March 4th, 2007
Cocoa constants have to be used by value in Ambrai Smalltalk. For example, consider creating this simple attributed string in Cocoa:
NSDictionary *attributesDictionary = [NSDictionary
dictionaryWithObject:[NSFont fontWithName:@"Palatino-Roman" size:14.0]
forKey:NSFontAttributeName];
NSAttributedString *attributedString = [
[NSAttributedString alloc]
initWithString:@"Hello world!"
attributes:attributesDictionary];
The same attributed string has to be created using the NSFontAttributeName value, or ‘NSFont’, in Ambrai Smalltalk:
attributesDictionary := (ObjectiveCObject classNamed: 'NSDictionary')
dictionaryWithObject: (
(ObjectiveCObject classNamed: 'NSFont')
fontWithName: (ObjectiveCObject string: 'Palatino-Roman')
size: 14.0)
forKey: (ObjectiveCObject string: 'NSFont').
attributedString := (ObjectiveCObject classNamed: 'NSAttributedString') alloc
initWithString: (ObjectiveCObject string: 'Hello world!')
attributes: attributesDictionary.
Posted in Cocoa by Dorin Sandu | 1 Comment »
March 4th, 2007
Several people have asked how to implement custom Cocoa views in Ambrai Smalltalk. The normal way to do this is to first subclass NSView in the Interface Builder with say, MyView, then drag a CustomView from the palette to your window and set its class to MyView.
Once this is done, save the nib to:
Smalltalk.app/Contents/Resources/English.lproj/CustomView.nib
Next, start Ambrai Smalltalk and create a subclass MyView of class ObjectiveCSubObject. On the class side create two methods, the first simply returns the superclass of MyView, NSView in this case:
MyView class >> basicObjectiveCSuperclassName
^'NSView'
The second method flags the Smalltalk instance methods that need to be exported to the ObjC runtime. Since we plan to override drawRect: from NSView, we need to export its method definition:
MyView class >> basicObjectiveCInstanceMethodSignatures
^#(
drawRect: #'v@:@'
)
Next, create a new MyView instance method as follows:
MyView >> drawRect: aNSRect
| labelFont labelColor labelAttributes label |
labelFont := (ObjectiveCObject classNamed: 'NSFont')
fontWithName: (ObjectiveCObject string: 'Helvetica')
size: 14.0.
labelColor := (ObjectiveCObject classNamed: 'NSColor') blueColor.
labelAttributes := (ObjectiveCObject classNamed: 'NSMutableDictionary') alloc
initWithCapacity: 2.
labelAttributes
setValue: labelFont forKey: (ObjectiveCObject string: 'NSFont');
setValue: labelColor forKey: (ObjectiveCObject string: 'NSColor').
label := (ObjectiveCObject classNamed: 'NSAttributedString') alloc
initWithString: (ObjectiveCObject string: self printString)
attributes: labelAttributes.
label drawAtPoint: (Mac_NSPoint new x: 10.0; y: 10.0; yourself).
labelColor setStroke.
(ObjectiveCObject classNamed: 'NSBezierPath') strokeRect: self bounds)
This method simply draws a label and a border around the whole view using custom colors and fonts. The result is shown below:

Finally, to run the whole thing, evaluate:
Application current menu: (
(MacMenuBar owner: Application current)
addMenu: ((MacAppleMenu new)
addCommandItem: #onAbout text: 'About...';
yourself);
yourself).
MyView updateObjectiveCClass.
(ObjectiveCObject classNamed: 'NSBundle')
loadNibNamed: (ObjectiveCObject string: 'CustomView')
owner: (ObjectiveCObject classNamed: 'NSApplication') sharedApplication
Posted in Cocoa by Dorin Sandu | No Comments »