Page 1 of 1
CanvasGadget/OpenGLGadget - Mouse events
Posted: Fri Jun 28, 2019 8:32 am
by wombats
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: Select all
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: Select all
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.
Re: CanvasGadget/OpenGLGadget - Mouse events
Posted: Fri Jun 28, 2019 9:24 am
by #NULL
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.
Re: CanvasGadget/OpenGLGadget - Mouse events
Posted: Fri Jun 28, 2019 11:32 am
by srod
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.
Re: CanvasGadget/OpenGLGadget - Mouse events
Posted: Fri Jun 28, 2019 2:17 pm
by RASHAD
For Windows the rest for Shardik
Code: Select all
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: Select all
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
Re: CanvasGadget/OpenGLGadget - Mouse events
Posted: Fri Jun 28, 2019 4:07 pm
by srod
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: Select all
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
Re: CanvasGadget/OpenGLGadget - Mouse events
Posted: Sun Jun 30, 2019 2:48 pm
by wombats
Thank you all. I mainly use macOS, but I will try your code when I am on Windows.