Page 2 of 2

Re: EventHandler to detect key presses and mouse clicks

Posted: Thu Apr 24, 2014 9:25 am
by Niffo
In this last sample code, when you press a key, Cocoa triggers an audible error beep if no "keyboard gadget" has the focus.
Do you know how to avoid this ?
I have found an equivalent request on the web but how to implement the proposed solution in PB ?

http://stackoverflow.com/questions/1351 ... error-beep

Re: EventHandler to detect key presses and mouse clicks

Posted: Sat May 10, 2014 10:26 pm
by Shardik
Niffo wrote:In this last sample code, when you press a key, Cocoa triggers an audible error beep if no "keyboard gadget" has the focus.
Do you know how to avoid this ?
A solution to this problem is very easy: simply insert the following line behind the definition of the EditorGadget in wilbert's last code example:

Code: Select all

  CocoaMessage(0, WindowID(0), "makeFirstResponder:", GadgetID(0))

Re: EventHandler to detect key presses and mouse clicks

Posted: Fri May 23, 2014 1:58 pm
by Niffo
Thank you very much, it works like a charm when there is a gadget on the window !
But do you have a solution if there is no gadget on the window ?

Re: EventHandler to detect key presses and mouse clicks

Posted: Fri May 23, 2014 7:59 pm
by glomph
I really would like to know it too.

Re: EventHandler to detect key presses and mouse clicks

Posted: Wed May 01, 2024 8:07 pm
by Piero
I put together what I found on Forum (and added something…)

Code: Select all

EnableExplicit
; #NSLeftMouseUp ; #NSRightMouseUp ; #NSMouseMoved ; #NSScrollWheel ; …
Global keyTime, lastKeyTime = -99999 ; for doublecommand

Procedure.s modifierFlagsInfo(modifierFlags)
   Protected r1.s, flags
   flags = modifierFlags & $FFFF0000
   If modifierFlags & #NSCommandKeyMask
      r1 + "Command "
   EndIf
   If modifierFlags & #NSControlKeyMask
      r1 + "Control "
   EndIf
   If modifierFlags & #NSAlternateKeyMask
      r1 + "Alt "
   EndIf
   If modifierFlags & #NSShiftKeyMask
      r1 + "Shift "
   EndIf
   If modifierFlags & #NSAlphaShiftKeyMask
      r1 + "Caps Lock "
   EndIf
   If modifierFlags & #NSFunctionKeyMask
      if not modifierFlags & #NSNumericPadKeyMask ; for arrow keys…
         r1 + "fn "
      EndIf
   EndIf
   ProcedureReturn r1
EndProcedure

ImportC "" ;{
   sel_registerName(str.p-ascii)
   class_addMethod(class, selector, imp, types.p-ascii)
EndImport ;}

Macro Print(s)
   AddGadgetItem(0, -1, s)
   SetGadgetState(0, CountGadgetItems(0)-1)
   SetGadgetState(0, -1)
EndMacro

Procedure PrintKey(Ev.s, CurEv)
   Print(Ev + ": keyCode = " + CocoaMessage(0, CurEv, "keyCode"))
   Define Long = CocoaMessage(0, CurEv, "characters")
   CocoaMessage(@Long, Long, "UTF8String")
   Print(Ev + ": keyChar = " + Chr(Asc(PeekS(Long, -1, #PB_UTF8))))
   Protected modkeys.s = modifierFlagsInfo(CocoaMessage(0, CurEv, "modifierFlags"))
   if modkeys : Print("Modifiers: " + modkeys) : EndIf
   Print("")
EndProcedure

ProcedureC OS_CallBackEventsHandler(obj, sel, notification)
   Define sharedApplication = CocoaMessage(0, 0, "NSApplication sharedApplication")
   Define currentEvent = CocoaMessage(0, sharedApplication, "currentEvent")
   Static lastEvent
   If currentEvent = lastEvent : ProcedureReturn : EndIf
   lastEvent = currentEvent
   If currentEvent
      Select CocoaMessage(0, currentEvent, "type")
         Case #NSKeyDown
            PrintKey("Key Down", currentEvent)
         Case #NSKeyUp
            PrintKey("Key Up", currentEvent)
         Case #NSLeftMouseUp
            Debug "NSLeftMouseUp" ; whole window
         Case #NSFlagsChanged ; SHIFT, CMD, ALT, CTRL, CAPS, fn…
            If (CocoaMessage(0, currentEvent, "modifierFlags") & $FFFF0000) = #NSCommandKeyMask
               keyTime = ElapsedMilliseconds()
               If keyTime - lastKeyTime < DoubleClickTime()
                  Print("Double Command!") : Print("")
               EndIf
               lastKeyTime = keyTime
            EndIf
      EndSelect
   EndIf
EndProcedure

ProcedureC PerformKeyEquivalent(Sender, sel, event)
   ProcedureReturn #YES ; avoid beeps
EndProcedure

OpenWindow(0, 0, 0, 300, 300, "Keys Info")
ListViewGadget(0, 5, 5, 290, 290)

Define notificationCenter = CocoaMessage(0, 0, "NSNotificationCenter defaultCenter")
Define appDelegate = CocoaMessage(0, CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
Define delegateClass = CocoaMessage(0, appDelegate, "class")
Define selector = sel_registerName("EventsHandlerCallback:")
class_addMethod(delegateClass, selector, @OS_CallBackEventsHandler(), "v@:@")
CocoaMessage(0, notificationCenter, "addObserver:", appDelegate, "selector:", selector, "name:", #Null, "object:", WindowID(0))
; avoid beeps
Define class = CocoaMessage(0, WindowID(0), "class")
Define selector = sel_registerName("performKeyEquivalent:") 
class_addMethod(class, selector, @PerformKeyEquivalent(), "v@:@")

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow ; or EventMenu() = #PB_Menu_Quit