I also found out how to get the gadget id in a notification callback.
Update v1.02.0
- Fix automated PlaceHolderList
- Add SetWindowNotification
OSX_GadgetCallback.pb
Code: Select all
;-TOP
; Comment : MacOS SetGadgetCallback and SetGadgetNotification (Base by Shardik)
; Author : mk-soft
; Version : v1.02.0
; Create : 28.02.2021
; Update : 06.03.2021
; Link Base of Shardik: https://www.purebasic.fr/english/viewtopic.php?f=19&t=65891&p=492568#p492568s
EnableExplicit
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
ImportC ""
sel_registerName(str.p-utf8)
class_addMethod(class, selector, imp, types.p-utf8)
class_getInstanceMethod(class, selector)
EndImport
; *** Required variables ***
Global notificationCenter = CocoaMessage(0, 0, "NSNotificationCenter defaultCenter")
Global appDelegate = CocoaMessage(0, CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
Global delegateClass = CocoaMessage(0, appDelegate, "class")
Structure udtGadgetCallback
Window.i
Gadget.i
refCount.i
EndStructure
Structure udtWindowNotification
Window.i
refCount.i
EndStructure
Structure udtGadgetNotification
Window.i
Gadget.i
refCount.i
EndStructure
Global NewMap mapGadgetCallback.udtGadgetCallback()
Global NewMap mapWindowNotification.udtWindowNotification()
Global NewMap mapGadgetNotification.udtGadgetNotification()
; *** Callback ***
Procedure SetGadgetCallback(Window, Gadget, *Callback, Method.s, PlaceholderList.s = "")
Protected key.s, selector
; Add gadget to map gadget callback
key = Str(GadgetID(Gadget))
If Not FindMapElement(mapGadgetCallback(), key)
AddMapElement(mapGadgetCallback(), key)
mapGadgetCallback()\Window = Window
mapGadgetCallback()\Gadget = Gadget
EndIf
mapGadgetCallback()\refCount + 1
; Add method to delegateClass
If Not Bool(PlaceholderList)
PlaceholderList = "v@:" + LSet("@", CountString(Method, ":"), "@")
EndIf
selector = sel_registerName_(Method)
If Not class_getInstanceMethod(delegateClass, selector)
class_addMethod_(delegateClass, selector, *Callback, PlaceholderList)
EndIf
; Add gadget to appDelegate
CocoaMessage(0, GadgetID(Gadget), "setDelegate:", appDelegate)
EndProcedure
; *** Notification ***
Procedure SetWindowNotification(Window, *Callback, Notification.s)
Protected selector, key.s
; Add Window to map Window notification
key = Str(WindowID(Window))
If Not FindMapElement(mapWindowNotification(), key)
AddMapElement(mapWindowNotification(), key)
mapWindowNotification()\Window = Window
mapWindowNotification()\Window = Window
EndIf
mapWindowNotification()\refCount + 1
; Add new callback method to delegateClass
selector = sel_registerName("windowNotificationCB_" + Str(*Callback))
If Not class_getInstanceMethod(delegateClass, selector)
class_addMethod(delegateClass, selector, *Callback, "v@:@")
EndIf
; Add Window to notification center
CocoaMessage(0, notificationCenter,
"addObserver:", appDelegate,
"selector:", selector,
"name:$", @Notification,
"object:", WindowID(Window))
EndProcedure
; ----
Procedure RemoveWindowNotification(Window, *Callback, Notification.s)
If FindMapElement(mapWindowNotification(), Str(WindowID(Window)))
CocoaMessage(0, notificationCenter,
"removeObserver:", appDelegate,
"name:$", @Notification,
"object:", WindowID(Window))
mapWindowNotification()\refCount - 1
If mapWindowNotification()\refCount <= 0
DeleteMapElement(mapWindowNotification())
EndIf
EndIf
EndProcedure
; ----
Procedure SetGadgetNotification(Window, Gadget, *Callback, Notification.s)
Protected selector, key.s
; Add gadget to map gadget notification
key = Str(GadgetID(Gadget))
If Not FindMapElement(mapGadgetNotification(), key)
AddMapElement(mapGadgetNotification(), key)
mapGadgetNotification()\Window = Window
mapGadgetNotification()\Gadget = Gadget
EndIf
mapGadgetNotification()\refCount + 1
; Add new callback method to delegateClass
selector = sel_registerName("gadgetNotificationCB_" + Str(*Callback))
If Not class_getInstanceMethod(delegateClass, selector)
class_addMethod(delegateClass, selector, *Callback, "v@:@")
EndIf
; Add gadget to notification center
CocoaMessage(0, notificationCenter,
"addObserver:", appDelegate,
"selector:", selector,
"name:$", @Notification,
"object:", GadgetID(Gadget))
EndProcedure
; ----
Procedure RemoveGadgetNotification(Window, Gadget, *Callback, Notification.s)
If FindMapElement(mapGadgetNotification(), Str(GadgetID(Gadget)))
CocoaMessage(0, notificationCenter,
"removeObserver:", appDelegate,
"name:$", @Notification,
"object:", GadgetID(Gadget))
mapGadgetNotification()\refCount - 1
If mapGadgetNotification()\refCount <= 0
DeleteMapElement(mapGadgetNotification())
EndIf
EndIf
EndProcedure
; *** Cocoa String Helper ***
Macro CocoaString(NSString)
PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8)
EndMacro
CompilerEndIf
; ********