It is currently Fri Dec 13, 2019 12:07 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: CanvasGadget/OpenGLGadget - Mouse events
PostPosted: Fri Jun 28, 2019 8:32 am 
Offline
Enthusiast
Enthusiast

Joined: Thu Dec 29, 2011 5:03 pm
Posts: 509
Hi,

The CanvasGadget and OpenGLGadget don't fire the #PB_EventType_MouseEnter and #PB_EventType_MouseLeave events while a mouse button is pressed. Is this a bug? If not, is there a way to do this across all three platforms (Windows, macOS and Linux/Qt)?

I need this because I am changing the cursor depending on the user's action in the gadget. However, if they move the cursor outside of the gadget while holding down a mouse button, the cursor changes to the default (as expected), but my code doesn't have the opportunity to change it back when they reenter the gadget because #PB_EventType_MouseEnter isn't fired.

Code:
Procedure CanvasEvents()
  Select EventType()
    Case #PB_EventType_MouseEnter : Debug "Mouse enter"
    Case #PB_EventType_MouseLeave : Debug "Mouse leave"
  EndSelect
EndProcedure

OpenWindow(0, 0, 0, 320, 240, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 320, 240)
BindGadgetEvent(0, @CanvasEvents())

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

Code:
Procedure CanvasEvents()
  Select EventType()
    Case #PB_EventType_MouseEnter : Debug "Mouse enter"
    Case #PB_EventType_MouseLeave : Debug "Mouse leave"
  EndSelect
EndProcedure

OpenWindow(0, 0, 0, 320, 240, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenGLGadget(0, 0, 0, 320, 240)
BindGadgetEvent(0, @CanvasEvents())

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

I know that I can clip the cursor to the gadget on Windows with #PB_Canvas_ClipMouse, but I don't like that behaviour.


Top
 Profile  
Reply with quote  
 Post subject: Re: CanvasGadget/OpenGLGadget - Mouse events
PostPosted: Fri Jun 28, 2019 9:24 am 
Offline
Addict
Addict

Joined: Thu Aug 30, 2007 11:54 pm
Posts: 1160
Location: right here
On linux with gtk2 and gtk3 I get the enter and leave events while the button is pressed. The leave event is triggered twice, once when the mouse leaves and once when I release the button. With qt I don't get the events while the button is pressed, and I get the leave event only if I release the button.


Top
 Profile  
Reply with quote  
 Post subject: Re: CanvasGadget/OpenGLGadget - Mouse events
PostPosted: Fri Jun 28, 2019 11:32 am 
Offline
PureBasic Expert
PureBasic Expert

Joined: Wed Oct 29, 2003 4:35 pm
Posts: 10527
Location: Beyond the pale...
On Windows the canvas gadget is automatically capturing the mouse input after a left mouse button down event which is why you are not seeing the mouse-leave event until you release the mouse. This makes the canvas gadget easier to work with in many regards, but at the cost of a little flexibility since we may not always want to capture the mouse input after a left click etc.

While this is not a bug (as it is intentional) I would personally prefer for the canvas gadget not to automatically capture the mouse input and instead have the option to do it with a simple function call etc.

Your best option is to monitor the mouse move events and examine the mouse coordinates etc. Have to be careful with any embedded child gadgets mind and any overlapping windows could be problematic. On windows you also have the option of TrackMouseEvent_() which will send #WM_MOUSELEAVE messages if requested, though I am unsure how this rolls when the mouse has been captured - never tested that.

_________________
I may look like a mule, but I'm not a complete ass.


Top
 Profile  
Reply with quote  
 Post subject: Re: CanvasGadget/OpenGLGadget - Mouse events
PostPosted: Fri Jun 28, 2019 2:17 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Sun Apr 12, 2009 6:27 am
Posts: 3476
For Windows the rest for Shardik

Code:
Procedure IsMouseOver(hWnd)
    GetCursorPos_(p.POINT)
    GetWindowRect_(hWnd,r.RECT)
    If p\x >= r\left+4 And p\x < r\right-4 And p\y >= r\top+4 And p\y < r\bottom - 4
      ProcedureReturn 1
    Else
      ProcedureReturn 0
    EndIf
EndProcedure

Procedure CanvasEvents()
 If IsMouseOver(GadgetID(0)) <> 1
    ReleaseCapture_()
 EndIf
  Select EventType()
    Case #PB_EventType_MouseEnter : Debug "Mouse enter"
    Case #PB_EventType_MouseLeave : Debug "Mouse leave"
  EndSelect
EndProcedure

OpenWindow(0, 0, 0, 320, 240, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 320, 240)
BindGadgetEvent(0, @CanvasEvents())

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow


Should be cross platform
Code:
Procedure CanvasEvents()
  x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
  y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
  If x <= 0 Or x >= 320 Or y <= 0 Or y >= 240
    Debug "Mouse leave 2"
  Else
    Debug "Mouse enter 2"
  EndIf
  Select EventType()
    Case #PB_EventType_MouseEnter : Debug "Mouse enter"
    Case #PB_EventType_MouseLeave : Debug "Mouse leave"
  EndSelect
EndProcedure

OpenWindow(0, 0, 0, 320, 240, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 320, 240)
BindGadgetEvent(0, @CanvasEvents())
Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1     
   
  EndSelect
Until Quit = 1

_________________
Egypt my love


Top
 Profile  
Reply with quote  
 Post subject: Re: CanvasGadget/OpenGLGadget - Mouse events
PostPosted: Fri Jun 28, 2019 4:07 pm 
Offline
PureBasic Expert
PureBasic Expert

Joined: Wed Oct 29, 2003 4:35 pm
Posts: 10527
Location: Beyond the pale...
Windows only and without messing around with the mouse-capture. Move in and out of the canvas with the button down as many times as you see fit.

Code:
Procedure IsMouseOver(hWnd)
  GetCursorPos_(p.POINT)
  If WindowFromPoint_(p\y<<32+p\x) = hWnd
    ProcedureReturn 1
  Else
    ProcedureReturn 0
  EndIf
EndProcedure

Procedure ReportMouseEnter()
  Debug "Mouse enter"
EndProcedure

Procedure ReportMouseLeave()
  Debug "Mouse leave"
EndProcedure

Procedure CanvasEvents()
  Static st_MouseCaptured, st_blnCursorOverCanvas
  Protected blnCursorOverCanvas
  Select EventType()
    Case #PB_EventType_LeftButtonDown
      st_MouseCaptured = #True
      st_blnCursorOverCanvas = #True
    Case #PB_EventType_LeftButtonUp
      If st_blnCursorOverCanvas
        st_MouseCaptured = #False
      EndIf
    Case #PB_EventType_MouseMove
      If st_MouseCaptured
        blnCursorOverCanvas = IsMouseOver(GadgetID(0))
        If st_blnCursorOverCanvas <> blnCursorOverCanvas
          Select blnCursorOverCanvas
            Case 0
              ReportMouseLeave()
            Case 1
              ReportMouseEnter()
          EndSelect
        EndIf
        st_blnCursorOverCanvas = blnCursorOverCanvas
      EndIf
    Case #PB_EventType_MouseLeave
      If st_MouseCaptured = #False
        ReportMouseLeave()
      EndIf
      st_MouseCaptured = #False
   Case #PB_EventType_MouseEnter
      If st_MouseCaptured = #False
        ReportMouseEnter()
      EndIf
      st_MouseCaptured = #False
  EndSelect

EndProcedure

OpenWindow(0, 0, 0, 320, 240, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 320, 240)
BindGadgetEvent(0, @CanvasEvents())

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

_________________
I may look like a mule, but I'm not a complete ass.


Top
 Profile  
Reply with quote  
 Post subject: Re: CanvasGadget/OpenGLGadget - Mouse events
PostPosted: Sun Jun 30, 2019 2:48 pm 
Offline
Enthusiast
Enthusiast

Joined: Thu Dec 29, 2011 5:03 pm
Posts: 509
Thank you all. I mainly use macOS, but I will try your code when I am on Windows.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 10 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye