How to get object under mouse

Mac OSX specific forum
User avatar
mk-soft
Always Here
Always Here
Posts: 5393
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

How to get object under mouse

Post by mk-soft »

the result is nil?

Code: Select all

rocedure GetObject()
  
  Protected obj, pt.nspoint
  
  pt\x = DesktopMouseX()
  pt\y = DesktopMouseY()
  
  obj = CocoaMessage(0,0,"objectUnderMousePoint:@", @pt)
  
  ProcedureReturn obj
  
EndProcedure


  OpenWindow(0,#PB_Ignore,#PB_Ignore,640,480,"",#PB_Window_SystemMenu)
 
  ButtonGadget(0,10,10,100,100,"Blub1")
  ButtonGadget(1,10,110,100,100,"Blub2")
 
  CreateStatusBar(0,WindowID(0))
  AddStatusBarField(#PB_Ignore)
 
  Repeat
    event = WaitWindowEvent() 
    If #PB_Event_Repaint
     
      Select GetObject()
        Case GadgetID(0)
          StatusBarText(0, 0, "Blub1")
        Case GadgetID(1)
          StatusBarText(0, 0, "Blub2")
        Default
          StatusBarText(0, 0, Str(x) + ":" + Str(y))
      EndSelect
     
    EndIf
   
  Until event = #PB_Event_CloseWindow

My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: How to get object under mouse

Post by wilbert »

Code: Select all

Global.i Window0_ID, Window0_CV

Procedure GetObject()
  
  Protected pt.NSPoint
  
  CocoaMessage(@pt, Window0_ID, "mouseLocationOutsideOfEventStream")
  ProcedureReturn CocoaMessage(0, Window0_CV, "hitTest:@", @pt)
  
EndProcedure



OpenWindow(0,#PB_Ignore,#PB_Ignore,640,480,"",#PB_Window_SystemMenu)
Window0_ID = WindowID(0)
Window0_CV = CocoaMessage(0, Window0_ID, "contentView")

ButtonGadget(0,10,10,100,100,"Blub1")
ButtonGadget(1,10,110,100,100,"Blub2")

CreateStatusBar(0,WindowID(0))
AddStatusBarField(#PB_Ignore)

Repeat
  event = WaitWindowEvent() 
  If #PB_Event_Repaint
    
    Select GetObject()
      Case GadgetID(0)
        StatusBarText(0, 0, "Blub1")
      Case GadgetID(1)
        StatusBarText(0, 0, "Blub2")
      Default
        StatusBarText(0, 0, "")
    EndSelect
    
  EndIf
  
Until event = #PB_Event_CloseWindow
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
mk-soft
Always Here
Always Here
Posts: 5393
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: How to get object under mouse

Post by mk-soft »

Thank´s :D
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Wolfram
Enthusiast
Enthusiast
Posts: 568
Joined: Thu May 30, 2013 4:39 pm

Re: How to get object under mouse

Post by Wolfram »

Very cool!
But isn't If #PB_Event_Repaint a typing error?
macOS Catalina 10.15.7
mestnyi
Addict
Addict
Posts: 1000
Joined: Mon Nov 25, 2013 6:41 am

Re: How to get object under mouse

Post by mestnyi »

But how can I get a window under the mouse?
User avatar
mk-soft
Always Here
Always Here
Posts: 5393
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: How to get object under mouse

Post by mk-soft »

Module System - GetParentWindowID

Link: viewtopic.php?f=12&t=72980
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
mestnyi
Addict
Addict
Posts: 1000
Joined: Mon Nov 25, 2013 6:41 am

Re: How to get object under mouse

Post by mestnyi »

I need to get a window under the mouse cursor.
there are three windows and when you hover over one of them get its handle.

Code: Select all

Procedure GetObject()
 
  Protected i,CV, w, id, pt.NSPoint
  
  Protected app =  CocoaMessage(0, 0, "NSApplication sharedApplication")
  Protected windows = CocoaMessage(0, app, "windows")
  Protected count = CocoaMessage(0, windows, "count") -1
  
  For i=count To 0 Step -1
    id = CocoaMessage(0, windows, "objectAtIndex:", i)
    CV = CocoaMessage(0, id, "contentView")
    CocoaMessage(@pt, id, "mouseLocationOutsideOfEventStream")
    
    If CocoaMessage(0, CV, "hitTest:@", @pt)
      Break
    EndIf
  Next
  
  ProcedureReturn id
EndProcedure

OpenWindow(0,100,100,300,300,"",#PB_Window_SystemMenu)
OpenWindow(1,200,200,300,300,"",#PB_Window_SystemMenu)
OpenWindow(2,300,300,300,300,"",#PB_Window_SystemMenu)

SetWindowTitle(0, Str(WindowID(0)))
SetWindowTitle(1, Str(WindowID(1)))
SetWindowTitle(2, Str(WindowID(2)))

Repeat
  event = WaitWindowEvent()
 
  If #PB_Event_Repaint
    Debug GetObject()
  EndIf
 
Until event = #PB_Event_CloseWindow
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: How to get object under mouse

Post by wilbert »

mestnyi wrote:I need to get a window under the mouse cursor.
there are three windows and when you hover over one of them get its handle.

Code: Select all

Procedure GetWindowUnderMouse()
  
  Protected.i NSApp, NSWindow, WindowNumber, Point.CGPoint
  
  CocoaMessage(@Point, 0, "NSEvent mouseLocation")
  WindowNumber = CocoaMessage(0, 0, "NSWindow windowNumberAtPoint:@", @Point, "belowWindowWithWindowNumber:", 0)
  NSApp = CocoaMessage(0, 0, "NSApplication sharedApplication")
  NSWindow = CocoaMessage(0, NSApp, "windowWithWindowNumber:", WindowNumber)
  ProcedureReturn NSWindow
  
EndProcedure

OpenWindow(0,100,100,300,300,"",#PB_Window_SystemMenu)
OpenWindow(1,200,200,300,300,"",#PB_Window_SystemMenu)
OpenWindow(2,300,300,300,300,"",#PB_Window_SystemMenu)

SetWindowTitle(0, Str(WindowID(0)))
SetWindowTitle(1, Str(WindowID(1)))
SetWindowTitle(2, Str(WindowID(2)))

Repeat
  event = WaitWindowEvent()
 
  If #PB_Event_Repaint
    Debug GetWindowUnderMouse()
  EndIf
 
Until event = #PB_Event_CloseWindow
or if you need to call it very often you can also compare against the window number.

Code: Select all

Procedure WindowNumberUnderMouse()
  Protected Point.CGPoint
  CocoaMessage(@Point, 0, "NSEvent mouseLocation")
  ProcedureReturn CocoaMessage(0, 0, "NSWindow windowNumberAtPoint:@", @Point, "belowWindowWithWindowNumber:", 0)
EndProcedure

Procedure WindowNumber(PBWindow)
  ProcedureReturn CocoaMessage(0, WindowID(PBWindow), "windowNumber")
EndProcedure


OpenWindow(0,100,100,300,300,"",#PB_Window_SystemMenu)
OpenWindow(1,200,200,300,300,"",#PB_Window_SystemMenu)
OpenWindow(2,300,300,300,300,"",#PB_Window_SystemMenu)

SetWindowTitle(0, Str(WindowNumber(0)))
SetWindowTitle(1, Str(WindowNumber(1)))
SetWindowTitle(2, Str(WindowNumber(2)))

Repeat
  event = WaitWindowEvent()
 
  If #PB_Event_Repaint
    Debug WindowNumberUnderMouse()
  EndIf
 
Until event = #PB_Event_CloseWindow
Windows (x64)
Raspberry Pi OS (Arm64)
mestnyi
Addict
Addict
Posts: 1000
Joined: Mon Nov 25, 2013 6:41 am

Re: How to get object under mouse

Post by mestnyi »

this is what you need thanks.
now it remains to get the gadget window.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: How to get object under mouse

Post by wilbert »

mestnyi wrote:now it remains to get the gadget window.
I'm not sure what you mean. :?
Do you need a combination of both things like this ? ...

Code: Select all

Procedure GetObjectUnderMouse()
  
  Protected.i ContentView, NSApp, NSWindow, WindowNumber, Point.CGPoint
  
  CocoaMessage(@Point, 0, "NSEvent mouseLocation")
  WindowNumber = CocoaMessage(0, 0, "NSWindow windowNumberAtPoint:@", @Point, "belowWindowWithWindowNumber:", 0)
  NSApp = CocoaMessage(0, 0, "NSApplication sharedApplication")
  NSWindow = CocoaMessage(0, NSApp, "windowWithWindowNumber:", WindowNumber)
  If NSWindow
    CocoaMessage(@Point, NSWindow, "mouseLocationOutsideOfEventStream")
    ContentView = CocoaMessage(0, NSWindow, "contentView")
    ProcedureReturn CocoaMessage(0, ContentView, "hitTest:@", @Point)
  Else
    ProcedureReturn 0
  EndIf
  
EndProcedure

OpenWindow(1,100,100,120,120,"Window1",#PB_Window_SystemMenu)
ButtonGadget(1,10,10,100,100,"Button1")
OpenWindow(2,200,200,120,120,"Window2",#PB_Window_SystemMenu)
ButtonGadget(2,10,10,100,100,"Button2")
OpenWindow(3,300,300,120,120,"Window3",#PB_Window_SystemMenu)
ButtonGadget(3,10,10,100,100,"Button3")

Repeat
  event = WaitWindowEvent()
 
  If #PB_Event_Repaint
    Select GetObjectUnderMouse()
      Case GadgetID(1):
        Debug "Button1"
      Case GadgetID(2):
        Debug "Button2"
      Case GadgetID(3):
        Debug "Button3"
    EndSelect        
  EndIf
 
Until event = #PB_Event_CloseWindow
Windows (x64)
Raspberry Pi OS (Arm64)
mestnyi
Addict
Addict
Posts: 1000
Joined: Mon Nov 25, 2013 6:41 am

Re: How to get object under mouse

Post by mestnyi »

I needed it too, but I did it like this.

Code: Select all

Procedure GetWindowUnderMouse()
    
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
      Protected.i NSApp, NSWindow, WindowNumber, Point.CGPoint
      
      CocoaMessage(@Point, 0, "NSEvent mouseLocation")
      WindowNumber = CocoaMessage(0, 0, "NSWindow windowNumberAtPoint:@", @Point, "belowWindowWithWindowNumber:", 0)
      NSApp = CocoaMessage(0, 0, "NSApplication sharedApplication")
      NSWindow = CocoaMessage(0, NSApp, "windowWithWindowNumber:", WindowNumber)
      
      ProcedureReturn NSWindow
    CompilerEndIf
    
  EndProcedure
  
  Procedure enterID()
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
      Protected.i NSWindow = GetWindowUnderMouse()
      Protected pt.NSPoint
      
      If NSWindow
        Protected CV = CocoaMessage(0, NSWindow, "contentView")
        CocoaMessage(@pt, NSWindow, "mouseLocationOutsideOfEventStream")
        Protected NsGadget = CocoaMessage(0, CV, "hitTest:@", @pt)
      EndIf
      
      If NsGadget <> CV And NsGadget
        If CV = CocoaMessage(0, NsGadget, "superview")
          ProcedureReturn GadgetPB(NsGadget)
        Else
          ProcedureReturn GadgetPB(CocoaMessage(0, NsGadget, "superview"))
        EndIf
      Else
        ProcedureReturn WindowPB(NSWindow)
      EndIf
      
    CompilerEndIf
  EndProcedure
  
Now I need to find its window back from the gadget

Code: Select all

  Procedure.i EventDrop(*this, eventtype.l)
    If *this =- 1
      *this = enterID()
      Debug "is gadget - "+IsGadget(*this)
      Debug "is window - "+IsWindow(*this)
      
      If _action_(*this)
        *Drag\widget = *this
        
        If IsGadget(*this)
          PostEvent(#PB_Event_GadgetDrop, get_gadget_window(*this), *this)
        Else
          PostEvent(#PB_Event_WindowDrop, *this, 0)
        EndIf
      EndIf
      
    Else
      
      Select eventtype
        Case #PB_EventType_MouseEnter
          If _action_(*this)
            If Not *Drop()\cursor
              *Drag\widget = *this
              *Drag\cursor = 0
              Cur(1)
            EndIf
          ElseIf *Drag
            If Not *Drag\cursor
              *Drop()\cursor = 0
              *Drag\widget = 0
              Cur(0)
            EndIf
          EndIf
          
        Case #PB_EventType_MouseLeave
          If *Drag And Not *Drag\cursor
            *Drop()\cursor = 0
            *Drag\widget = 0
            Cur(0)
          EndIf
          
        Case #PB_EventType_LeftButtonUp
          
          If *Drag And MapSize(*Drop())
            If *Drag\cursor Or *Drop()\cursor
              *Drag\cursor = 0
              *Drop()\cursor = 0
              ;Debug "set default cursor"
              SetGadgetAttribute(EventGadget(), #PB_Canvas_Cursor, #PB_Cursor_Default)
            EndIf
            
            ProcedureReturn _action_(*this)
          EndIf  
      EndSelect
      
    EndIf
    
  EndProcedure
Post Reply