Please take a look into the following advanced example which allows to subclass multiple StringGadgets on MacOS. It identifies the number of the StringGadget in the RightMouseDownCallback and displays the number of the right-clicked StringGadget. And it further demonstrates how to display a customized popup menu when right-clicking into the 2nd StringGadget.HarrysLad wrote:Your code does everything I need for one StringGadget but, on my particular application, I have 10 StringGadgets. Four of them require a popup-menu to be attached but all of them need the system popup to be suppressed.
Code: Select all
EnableExplicit
Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
"NSApplication sharedApplication"), "delegate")
Define i.I
Define SubclassedStringGadget.I
Dim StringGadgetID(2) ; Number of StringGadgets - 1
Procedure SubclassGadget(GadgetID.I, NewClassName.S)
Protected GadgetClass.I = CocoaMessage(0, GadgetID(GadgetID), "class")
Protected NewGadgetClass.I
NewGadgetClass = objc_allocateClassPair_(GadgetClass, NewClassName, 0)
objc_registerClassPair_(NewGadgetClass)
object_setClass_(GadgetID(GadgetID), NewGadgetClass)
ProcedureReturn NewGadgetClass
EndProcedure
ProcedureC ContextMenuCallback(Object.I, Selector.I, TextView.I, Menu.I,
Event.I, Index.I)
; ----- Suppress context menu
ProcedureReturn 0
EndProcedure
ProcedureC RightMouseDownCallback(Object.I, Selector.I, Event.I)
Shared StringGadgetID.I()
Protected i.I
For i = 0 To ArraySize(StringGadgetID())
If Object = StringGadgetID(i)
If i = 1
DisplayPopupMenu(0, WindowID(0))
Else
Debug "Right mouse button down on StringGadget " + Str(i + 1)
Break
EndIf
EndIf
Next i
EndProcedure
OpenWindow(0, 270, 100, 350, 130, "Detect right mouse button down")
; ----- Prepare popup menu for StringGadget 2
If CreatePopupMenu(0)
MenuItem(0, "Menu item 1")
MenuItem(1, "Menu item 2")
EndIf
For i = 0 To ArraySize(StringGadgetID())
StringGadgetID(i) = StringGadget(i, 80, 25 + i * 30, 170, 20, "")
SubclassedStringGadget = SubclassGadget(i, "SubclassedStringGadget" + Str(i))
class_addMethod_(SubclassedStringGadget,
sel_registerName_("rightMouseDown:"),
@RightMouseDownCallback(), "v@:@")
class_addMethod_(SubclassedStringGadget,
sel_registerName_("textView:menu:forEvent:atIndex:"),
@ContextMenuCallback(), "v@:@@@@")
Next i
CocoaMessage(0, StringGadgetID(0), "setDelegate:", AppDelegate)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Menu
Debug "Menu item " + Str(EventMenu() + 1) + " was selected"
EndSelect
ForEver
I have tested this cross-platform example successfully on these operating systems with PB 5.43:
- Linux Mint 18 x86 "Sarah" with Cinnamon (GTK 2 and GTK 3)
- MacOS X 10.9.5 (Mavericks)
- MacOS X 10.11.6 (El Capitan)
- Windows XP SP3
- Windows 8.1 x64
Unfortunately it currently doesn't work on MacOS X 10.6.8 (Snow Leopard)!
Code: Select all
EnableExplicit
#Event_StringGadget_RightClick = #PB_Event_FirstCustomValue
#StringGadget = 0
OpenWindow(0, 270, 100, 350, 75,
"Detect right click and suppress context menu")
StringGadget(0, 80, 25, 170, 25, "")
SetActiveGadget(0)
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux ; -------------------------------------------------
ProcedureC ButtonPressCallback(*Widget.GtkWidget,
*EventButton.GdkEventButton, UserData.I)
If *EventButton\button = 3
PostEvent(#Event_StringGadget_RightClick)
ProcedureReturn #True
EndIf
EndProcedure
g_signal_connect_(GadgetID(#StringGadget), "button-press-event",
@ButtonPressCallback(), 0)
CompilerCase #PB_OS_MacOS ; -------------------------------------------------
Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
"NSApplication sharedApplication"), "delegate")
Define SubclassedStringGadget.I
ProcedureC ContextMenuCallback(Object.I, Selector.I, TextView.I, Menu.I,
Event.I, Index.I)
ProcedureReturn 0
EndProcedure
ProcedureC RightMouseDownCallback(Object.I, Selector.I, Event.I)
PostEvent(#Event_StringGadget_RightClick)
EndProcedure
SubclassedStringGadget = objc_allocateClassPair_(CocoaMessage(0,
GadgetID(#StringGadget), "class"), "SubclassedStringGadget", 0)
objc_registerClassPair_(SubclassedStringGadget)
object_setClass_(GadgetID(#StringGadget), SubclassedStringGadget)
class_addMethod_(SubclassedStringGadget,
sel_registerName_("rightMouseDown:"),
@RightMouseDownCallback(), "v@:@")
class_addMethod_(SubclassedStringGadget,
sel_registerName_("textView:menu:forEvent:atIndex:"),
@ContextMenuCallback(), "v@:@@@@")
CocoaMessage(0, GadgetID(#StringGadget), "setDelegate:", AppDelegate)
CompilerCase #PB_OS_Windows ; -----------------------------------------------
Define DefaultStringGadgetCallback.I
Procedure CustomStringGadgetCallback(WindowHandle.I, Msg.I, WParam.I,
LParam.I)
Shared DefaultStringGadgetCallback.I
Protected Result.I
If Msg <> #WM_CONTEXTMENU
Result = CallWindowProc_(DefaultStringGadgetCallback, WindowHandle, Msg,
WParam, LParam)
Else
PostEvent(#Event_StringGadget_RightClick)
EndIf
ProcedureReturn Result
EndProcedure
DefaultStringGadgetCallback = SetWindowLongPtr_(GadgetID(#StringGadget),
#GWL_WNDPROC, @CustomStringGadgetCallback())
CompilerEndSelect ; -----------------------------------------------------------
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #Event_StringGadget_RightClick
Debug "Right click into StringGadget detected!"
EndSelect
ForEver