I think the majority coding for OSX and iOS is using declares to squeeze the last bit out or even
to implement features which aren’t existing in the Xojo framework.
I honestly do it a lot to make the app more custom looking and support controls function which aren’t provided
by Xojo but sometimes I get stuck in the obj-c especially when it comes down to overriding function or subclassing things.
Is there a good tutorial (no MacOSLib) which explains how to work with subclassing/overriding stuff in obj-c and for
xojo controls ?
I am trying to change the TextField vertical alignment to center,top,bottom. As far as I know you need
to subclass NSCell and override a couple of methods. Sound like a lot of work for it…yes it is.
I kind of think this isn’t possible or or too much work. Anyway, I am stuck here and the methods doesn’t get called.
[code]Private Sub setUpCell(t as TextField)
dim cls as ptr = NSClassFromString(“XOJOCell”)
if cls=nil then
cls = objc_allocateClassPair( NSClassFromString(“NSCell”), “XOJOCell”,0)
if cls<>nil then
if class_addMethod( cls, NSSelectorFromString(“drawingRectForBounds:”), AddressOf drawingRect, “{NSRect=ffff}@:{NSRect=ffff}”) then
if class_addMethod( cls, NSSelectorFromString(“editWithFrame:inView:editor:delegate:event:”), AddressOf editWithFrame, “v@:{NSRect=ffff}@@@@”) then
if class_addMethod( cls, NSSelectorFromString(“selectWithFrame:inView:editor:delegate:start:length:”), AddressOf selectWithFrame, “v@:{NSRect=ffff}@@@ii”) then
objc_registerClassPair(cls)
end if
end if
end if
end if
end if
self.cellRef = init(alloc(cls))
declare sub setCell lib Cocoa selector “setCell:” (obj as ptr, cell as ptr)
setCell( ptr(t.Handle), self.cellRef)
You need to look at the Objective C Runtime. This is a library with a C API, not an Objective C one. You will have to look at:
objc_lookUpClass to test if a class is already registered in the Objective C Runtime
objc_allocateClassPair to allocate memory for a new class (and its meta class, hence “class pair”)
class_addMethod to register a method and thereby override one from the super class (use AddressOf to redirect to a Xojo method, this Xojo method must be either in a module or it must be a shared method of a class)
objc_registerClassPair to register the class and the meta class in the Objective C Runtime
objc_msgSendSuper and struct objc_super if you need to call the parent method in your Xojo method which overrides a method in the super class.
An example for implementing a protocol (NSTableViewDataSourceDelegate, subclassing NSObject):
If objc_lookUpClass("myDelegate") = Nil Then
Dim cls As Ptr = objc_allocateClassPair(NSClassFromString("NSObject"), "myDelegate", 0)
Call class_addMethod(cls, sel_registerName("numberOfRowsInTableView:"), _
AddressOf numberOfRowsInTableView_, "")
Call class_addMethod(cls, sel_registerName("tableView:objectValueForTableColumn:row:"), _
AddressOf tableView_objectValueForTableColumn_row_, "")
objc_registerClassPair(cls)
End
setDataSource(mTableView, alloc(NSClassFromString("myDelegate")))
You don’t need to add type encodings for methods you override or for methods from a protocol as the Objective C Runtime already knows them.
Make sure that the methods are shared methods (drawingRect, editWithFrame, selectWithFrame) on your class or put them in a module.
For a TextArea it would be (don’t know about TextField):
[code]#if TargetCocoa
Declare Sub setTextContainerInset Lib “AppKit” Selector “setTextContainerInset:” (NSTextView As Ptr,
inset As NSSize)
Declare Function documentView Lib “AppKit” Selector “documentView” (NSScrollView As Ptr) As Ptr
Dim size As NSSize
size.width = -2
size.height = 2
Dim scrollView As Ptr = Ptr(Handle)
Dim textView As Ptr = documentView(scrollView)
setTextContainerInset(textView, size)