Adding cmd-c, cmd-v, cmd-x functionality

Mac OSX specific forum
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3944
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Adding cmd-c, cmd-v, cmd-x functionality

Post by wilbert »

If your app doesn't use the PureBasic Menu commands and you don't want to add any menu items you can do it like this.
(I'm not sure if the app store approves this approach in case you want to submit your app there)

Code: Select all

ImportC ""
  class_replaceMethod(cls, name, imp, types.p-ascii)
  objc_msgSend(self, op)
  object_getClass(object)
  sel_registerName(str.p-ascii)
EndImport

PrototypeC SendEventProto(obj, sel, event)

Global.i SendEvent_.SendEventProto

Global.i NSApp = CocoaMessage(0, 0, "NSApplication sharedApplication")

Global.i SEL_charactersIgnoringModifiers = sel_registerName("charactersIgnoringModifiers")
Global.i SEL_modifierFlags = sel_registerName("modifierFlags")
Global.i SEL_type = sel_registerName("type")
Global.i SEL_UTF8String = sel_registerName("UTF8String")

ProcedureC SendEvent(obj, sel, event)
  If objc_msgSend(event, SEL_type) = 10; NSKeyDown
    If objc_msgSend(event, SEL_modifierFlags) & $ffff0000 = $100000; NSCommandKeyMask
      Select Asc(PeekS(objc_msgSend(objc_msgSend(event, SEL_charactersIgnoringModifiers), SEL_UTF8String), 1, #PB_UTF8))
        Case 'a'; cmd-a
          CocoaMessage(0, NSApp, "sendAction:", sel_registerName("selectAll:"), "to:", #nil, "from:", NSApp)
        Case 'c'; cmd-c
          CocoaMessage(0, NSApp, "sendAction:", sel_registerName("copy:"), "to:", #nil, "from:", NSApp)
        Case 'v'; cmd-v
          CocoaMessage(0, NSApp, "sendAction:", sel_registerName("paste:"), "to:", #nil, "from:", NSApp)
        Case 'x'; cmd-x
          CocoaMessage(0, NSApp, "sendAction:", sel_registerName("cut:"), "to:", #nil, "from:", NSApp)
        Case 'z'; cmd-z
          CocoaMessage(0, NSApp, "sendAction:", sel_registerName("undo:"), "to:", #nil, "from:", NSApp)
      EndSelect
    EndIf
  EndIf
  SendEvent_(obj, sel, event)
EndProcedure

SendEvent_ = class_replaceMethod(object_getClass(NSApp), sel_registerName("sendEvent:"), @SendEvent(), "v@:@")


; *** Test the code ***

Input$ = InputRequester("Title", "Please make your input:", "I'm the default input.")

Debug Input$
If your app doesn't use the PureBasic Menu commands but you don't mind adding menu items you can do it like this.

Code: Select all

ImportC ""
  sel_registerName(str.p-ascii)
EndImport

NSApp = CocoaMessage(0, 0, "NSApplication sharedApplication")
MainMenu = CocoaMessage(0, NSApp, "mainMenu")
EditMenu = CocoaMessage(0, CocoaMessage(0, CocoaMessage(0, 0, "NSMenu alloc"), "initWithTitle:$", @"Edit"), "autorelease")
CocoaMessage(0, EditMenu, "addItemWithTitle:$", @"Cut", "action:", sel_registerName("cut:"), "keyEquivalent:$", @"x")
CocoaMessage(0, EditMenu, "addItemWithTitle:$", @"Copy", "action:", sel_registerName("copy:"), "keyEquivalent:$", @"c")
CocoaMessage(0, EditMenu, "addItemWithTitle:$", @"Paste", "action:", sel_registerName("paste:"), "keyEquivalent:$", @"v")
CocoaMessage(0, EditMenu, "addItemWithTitle:$", @"Select All", "action:", sel_registerName("selectAll:"), "keyEquivalent:$", @"a")
CocoaMessage(0, CocoaMessage(0, MainMenu, "addItemWithTitle:$", @"Edit", "action:", #Null, "keyEquivalent:$", @""), "setSubmenu:", EditMenu)


; *** Test the code ***

OpenWindow(0, 100, 150, 195, 260, "PureBasic - Menu")
WaitWindowEvent()

Input$ = InputRequester("Title", "Please make your input:", "I'm the default input.")

Debug Input$
Windows (x64)
Raspberry Pi OS (Arm64)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3944
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Adding cmd-c, cmd-v, cmd-x functionality

Post by wilbert »

If your app uses a PureBasic menu you can add edit functionality like this

Code: Select all

ImportC ""
  sel_registerName(str.p-ascii)
EndImport


OpenWindow(0, 100, 150, 195, 260, "PureBasic - Menu")

If CreateMenu(0, WindowID(0))
  
  MenuTitle("File")
  MenuItem( 1, "&Load...")
  MenuItem( 2, "Save")
  MenuItem( 3, "Save As...")
  MenuTitle("Edit")
  
  ; Find menu title "Edit" and add functionality
  MenuArray = MenuID(0)
  Idx = CocoaMessage(0, MenuArray, "count") - 1
  While Idx >= 0
    TopMenu = CocoaMessage(0, MenuArray, "objectAtIndex:", Idx)
    If CocoaMessage(0, CocoaMessage(0, TopMenu, "title"), "isEqualToString:$", @"Edit")
      CocoaMessage(0, TopMenu, "addItemWithTitle:$", @"Undo", "action:", sel_registerName("undo:"), "keyEquivalent:$", @"z")
      CocoaMessage(0, TopMenu, "addItemWithTitle:$", @"Redo", "action:", sel_registerName("redo:"), "keyEquivalent:$", @"Z")
      CocoaMessage(0, TopMenu, "addItem:", CocoaMessage(0, 0, "NSMenuItem separatorItem"))
      CocoaMessage(0, TopMenu, "addItemWithTitle:$", @"Cut", "action:", sel_registerName("cut:"), "keyEquivalent:$", @"x")
      CocoaMessage(0, TopMenu, "addItemWithTitle:$", @"Copy", "action:", sel_registerName("copy:"), "keyEquivalent:$", @"c")
      CocoaMessage(0, TopMenu, "addItemWithTitle:$", @"Paste", "action:", sel_registerName("paste:"), "keyEquivalent:$", @"v")
      CocoaMessage(0, TopMenu, "addItemWithTitle:$", @"Select All", "action:", sel_registerName("selectAll:"), "keyEquivalent:$", @"a")
      While WindowEvent() : Wend
      Idx = CocoaMessage(0, TopMenu, "numberOfItems") - 1
      While Idx >= 7
        CocoaMessage(0, TopMenu, "removeItemAtIndex:", Idx)
        Idx - 1
      Wend
      Break
    EndIf
    Idx - 1
  Wend
  
EndIf


; *** Test ***

Input$ = InputRequester("Title", "Please make your input:", "I'm the default input.")

Debug Input$
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply