Hello!
I know I may sound annoying, but is there any workaround to detect one using the mouse wheel in a listicongadget with a vertical virtual scroll bar?
It must be cross-platform.
Thanks!
Kind regards,
>Marco A.G.Pinto
---------------
Using mousewheel in GUI (listicongadget)
- marcoagpinto
- Addict
- Posts: 1045
- Joined: Sun Mar 10, 2013 3:01 pm
- Location: Portugal
- Contact:
Re: Using mousewheel in GUI (listicongadget)
You may try the following cross-platform example which detects the movement of the mouse wheel in a ListIconGadget. In PB's ListIconGadget moving the mouse wheel scrolls the contents automatically on Linux, MacOS and Windows without the need to program any code. But when using a virtual scroll bar you need to be able to detect the mouse wheel movement in order to synchronize the contents of the ListIconGadget with your own custom scroll bar. I hope you are able to adapt the following code for your customized ListIconGadget with virtual scroll bar.
I have successfully tested the example with the following operating systems:
- MacOS X 10.6.8 (Snow Leopard) with PB 5.30 x86 and x64 in ASCII and Unicode mode
- Ubuntu 12.04 x64 with KDE and Unity with PB 5.30 x64 in ASCII and Unicode mode
- Windows 7 SP1 x64 with PB 5.30 x86 and x64 in ASCII and Unicode mode
You should be aware of a shortcoming of the current solution: each up and down doesn't necessarily mean an up or down of a complete row because this may be configurable by the user on some operating systems. These are my current settings of the tested operating systems for one up/down:
- MacOS X 10.6.8 (Snow Leopard): 1/10th of a row
- Ubuntu 12.04 x64 with KDE and Unity: 1 row
- Windows 7: 3 rows
I have successfully tested the example with the following operating systems:
- MacOS X 10.6.8 (Snow Leopard) with PB 5.30 x86 and x64 in ASCII and Unicode mode
- Ubuntu 12.04 x64 with KDE and Unity with PB 5.30 x64 in ASCII and Unicode mode
- Windows 7 SP1 x64 with PB 5.30 x86 and x64 in ASCII and Unicode mode
You should be aware of a shortcoming of the current solution: each up and down doesn't necessarily mean an up or down of a complete row because this may be configurable by the user on some operating systems. These are my current settings of the tested operating systems for one up/down:
- MacOS X 10.6.8 (Snow Leopard): 1/10th of a row
- Ubuntu 12.04 x64 with KDE and Unity: 1 row
- Windows 7: 3 rows
Code: Select all
EnableExplicit
#ListIcon = 0
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux ; --------------------------------------------------
ProcedureC MouseWheelEventHandler(*Event.GdkEventScroll, *UserData)
Protected *ListView.GtkWidget = GadgetID(#ListIcon)
If *ListView\window = gdk_window_get_parent_(*Event\window)
If *Event\type = #GDK_SCROLL
Select *Event\direction
Case #GDK_SCROLL_UP
Debug "Up"
Case #GDK_SCROLL_DOWN
Debug "Down"
EndSelect
EndIf
EndIf
gtk_main_do_event_(*Event)
EndProcedure
CompilerCase #PB_OS_MacOS ; --------------------------------------------------
#NSScrollWheel = 22
Procedure ScanVerticalMouseWheel()
Protected CurrentEvent.I
Protected DeltaY.F
Protected EventType.I
Protected SharedApplication.I = CocoaMessage(0, 0,
"NSApplication sharedApplication")
CurrentEvent = CocoaMessage(0, SharedApplication, "currentEvent")
If CurrentEvent
EventType = CocoaMessage(0, CurrentEvent, "type")
If EventType = #NSScrollWheel
If WindowMouseX(0) >= GadgetX(0) And
WindowMouseX(0) <= GadgetX(0) + GadgetWidth(0)
If WindowMouseY(0) >= GadgetY(0) And
WindowMouseY(0) <= GadgetY(0) + GadgetHeight(0)
CocoaMessage(@DeltaY, currentEvent, "deltaY")
If DeltaY < 0.0
Debug "Up"
Else
Debug "Down"
EndIf
EndIf
EndIf
EndIf
EndIf
EndProcedure
CompilerCase #PB_OS_Windows ; ------------------------------------------------
Define DefaultListIconCallback.I
Procedure CustomListIconCallback(WindowHandle.I, Msg.I, WParam.I, LParam.I)
Shared DefaultListIconCallback.I
If Msg = #WM_MOUSEWHEEL
If (WParam >> 16) & $8000
Debug "Down"
Else
Debug "Up"
EndIf
EndIf
ProcedureReturn CallWindowProc_(DefaultListIconCallback, WindowHandle,
Msg, WParam, LParam)
EndProcedure
CompilerEndSelect
Define i.I
OpenWindow(0, 200, 100, 300, 140, "Detect mouse wheel scrolling")
ListIconGadget(#ListIcon, 10, 10, 280, 120, "Column 1", 100)
For i = 1 To 20
AddGadgetItem(0, -1, "Line " + Str(i))
Next i
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
gdk_event_handler_set_(@MouseWheelEventHandler(), 0, 0)
CompilerCase #PB_OS_Windows
DefaultListIconCallback = GetWindowLongPtr_(GadgetID(#ListIcon), #GWL_WNDPROC)
SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC, @CustomListIconCallback())
CompilerEndSelect
SetActiveGadget(#ListIcon)
Repeat
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
ScanVerticalMouseWheel()
CompilerEndIf
Until WaitWindowEvent() = #PB_Event_CloseWindow
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
gdk_event_handler_set_(0, 0, 0)
CompilerEndIf
- marcoagpinto
- Addict
- Posts: 1045
- Joined: Sun Mar 10, 2013 3:01 pm
- Location: Portugal
- Contact:
Re: Using mousewheel in GUI (listicongadget)
Thanks!
The code is very complex for me to understand, but I will give a deeper look at it soon.
Kind regards,
>Marco A.G.Pinto
---------------
The code is very complex for me to understand, but I will give a deeper look at it soon.












Kind regards,
>Marco A.G.Pinto
---------------
- marcoagpinto
- Addict
- Posts: 1045
- Joined: Sun Mar 10, 2013 3:01 pm
- Location: Portugal
- Contact:
Re: Using mousewheel in GUI (listicongadget)
@Shardik
Not wanting to sound annoying, but is there a simple way of just detecting the the mouse wheel was scrolled, without binding it to gadgets?
Maybe the cross-platform code would become simpler and then I could associate it to the listicongadget the same way I am doing with other keys (CURS UP/DOWN and PG UP/DOWN).
Thanks, and sorry for bothering you.
Kind regards,
>Marco A.G.Pinto
----------------
Not wanting to sound annoying, but is there a simple way of just detecting the the mouse wheel was scrolled, without binding it to gadgets?
Maybe the cross-platform code would become simpler and then I could associate it to the listicongadget the same way I am doing with other keys (CURS UP/DOWN and PG UP/DOWN).
Thanks, and sorry for bothering you.
Kind regards,
>Marco A.G.Pinto
----------------
Re: Using mousewheel in GUI (listicongadget)
The simplest possibility already built-in in PureBasic is the EventType #PB_EventType_MouseWheel. But this EventType is only supported by the CanvasGadget and OpenGLGadget. And this EventType only detects that the mouse wheel has been moved but neither whether the wheel moved up or down nor the delta:
Code: Select all
OpenWindow(0, 200, 100, 300, 270, "Detect mouse wheel movement")
CanvasGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20, #PB_Canvas_Border)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
If EventGadget() = 0
If EventType() = #PB_EventType_MouseWheel
Debug "Mouse wheel was moved"
EndIf
EndIf
EndSelect
ForEver
Re: Using mousewheel in GUI (listicongadget)
I don't think that there is a simpler way. I would strongly advise to bind the mouse wheel event to the ListIconGadget because otherwise you would also react to wheel scrolling when the cursor is outside of your ListIconGadget. But please take a look into the modified example below: it should be at least simpler for you to implement because I have declared the two additional event typesmarcoagpinto wrote:Not wanting to sound annoying, but is there a simple way of just detecting the the mouse wheel was scrolled, without binding it to gadgets?
#PB_EventType_MouseWheel_Down
#PB_EventType_MouseWheel_Up
and all 3 callbacks now use PostEvent() to place these new event types in your standard event loop so that you may evaluate the mouse wheel events there:
Code: Select all
Case #PB_Event_Gadget
If EventGadget() = #ListIcon
Select EventType()
Case #PB_EventType_MouseWheel_Down
Debug "Mouse wheel moved down"
Case #PB_EventType_MouseWheel_Up
Debug "Mouse wheel moved up"
EndSelect
EndIf
Code: Select all
EnableExplicit
#ListIcon = 0
#Window = 0
Enumeration
#PB_EventType_MouseWheel_Down = #PB_EventType_FirstCustomValue
#PB_EventType_MouseWheel_Up
EndEnumeration
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux ; --------------------------------------------------
ProcedureC MouseWheelCallback(*Event.GdkEventScroll, *UserData)
Protected *ListView.GtkWidget = GadgetID(#ListIcon)
If *ListView\window = gdk_window_get_parent_(*Event\window)
If *Event\type = #GDK_SCROLL
Select *Event\direction
Case #GDK_SCROLL_UP
PostEvent(#PB_Event_Gadget, #Window, #ListIcon,
#PB_EventType_MouseWheel_Up)
Case #GDK_SCROLL_DOWN
PostEvent(#PB_Event_Gadget, #Window, #ListIcon,
#PB_EventType_MouseWheel_Down)
EndSelect
EndIf
EndIf
gtk_main_do_event_(*Event)
EndProcedure
CompilerCase #PB_OS_MacOS ; --------------------------------------------------
#kCGEventTapOptionListenOnly = 1
#kCGHeadInsertEventTap = 0
#NX_SCROLLWHEELMOVED = 22
#NX_SCROLLWHEELMOVEDMASK = 1 << #NX_SCROLLWHEELMOVED
ImportC ""
CGEventTapCreateForPSN(*ProcessSerialNumber, CGEventTapPlacement.I,
CGEventTapOptions.I, CGEventMask.Q, CGEventTapCallback.I, *UserData)
GetCurrentProcess(*ProcessSerialNumber)
EndImport
ProcedureC MouseWheelCallback(CGEventTapProxy.I, CGEventType.I, CGEvent.I,
*UserData)
Protected DeltaY.CGFloat
Protected NSEvent.I
Protected Point.NSPoint
NSEvent = CocoaMessage(0, 0, "NSEvent eventWithCGEvent:", CGEvent)
CocoaMessage(@Point, NSEvent, "locationInWindow")
If CocoaMessage(0, CocoaMessage(0, WindowID(#Window), "contentView"),
"hitTest:@", @Point) = GadgetID(#ListIcon)
CocoaMessage(@DeltaY, NSEvent, "deltaY")
If DeltaY < 0.0
PostEvent(#PB_Event_Gadget, #Window, #ListIcon,
#PB_EventType_MouseWheel_Down)
Else
PostEvent(#PB_Event_Gadget, #Window, #ListIcon,
#PB_EventType_MouseWheel_Up)
EndIf
EndIf
EndProcedure
CompilerCase #PB_OS_Windows ; ------------------------------------------------
Define DefaultListIconCallback.I
Procedure CustomListIconCallback(WindowHandle.I, Msg.I, WParam.I, LParam.I)
Shared DefaultListIconCallback.I
If Msg = #WM_MOUSEWHEEL
If (WParam >> 16) & $8000
PostEvent(#PB_Event_Gadget, #Window, #ListIcon,
#PB_EventType_MouseWheel_Down)
Else
PostEvent(#PB_Event_Gadget, #Window, #ListIcon,
#PB_EventType_MouseWheel_Up)
EndIf
EndIf
ProcedureReturn CallWindowProc_(DefaultListIconCallback, WindowHandle,
Msg, WParam, LParam)
EndProcedure
CompilerEndSelect
Define i.I
OpenWindow(0, 200, 100, 300, 140, "Detect mouse wheel scrolling")
ListIconGadget(#ListIcon, 10, 10, 280, 120, "Column 1", 100)
For i = 1 To 20
AddGadgetItem(0, -1, "Line " + Str(i))
Next i
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
gdk_event_handler_set_(@MouseWheelCallback(), 0, 0)
CompilerCase #PB_OS_MacOS
Define MachPort.I
Define ProcessSerialNumber.Q
GetCurrentProcess(@ProcessSerialNumber)
MachPort = CGEventTapCreateForPSN(@ProcessSerialNumber,
#kCGHeadInsertEventTap, #kCGEventTapOptionListenOnly,
#NX_SCROLLWHEELMOVEDMASK, @MouseWheelCallback(), 0)
If MachPort
CocoaMessage(0, CocoaMessage(0, 0, "NSRunLoop currentRunLoop"),
"addPort:", MachPort,
"forMode:$", @"kCFRunLoopCommonModes")
EndIf
CompilerCase #PB_OS_Windows
DefaultListIconCallback = GetWindowLongPtr_(GadgetID(#ListIcon),
#GWL_WNDPROC)
SetWindowLongPtr_(GadgetID(#ListIcon), #GWL_WNDPROC,
@CustomListIconCallback())
CompilerEndSelect
SetActiveGadget(#ListIcon)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
gdk_event_handler_set_(0, 0, 0)
CompilerCase #PB_OS_MacOS
CFRelease_(MachPort)
CompilerEndSelect
Break
Case #PB_Event_Gadget
If EventGadget() = #ListIcon
Select EventType()
Case #PB_EventType_MouseWheel_Down
Debug "Mouse wheel moved down"
Case #PB_EventType_MouseWheel_Up
Debug "Mouse wheel moved up"
EndSelect
EndIf
EndSelect
ForEver
- marcoagpinto
- Addict
- Posts: 1045
- Joined: Sun Mar 10, 2013 3:01 pm
- Location: Portugal
- Contact:
Re: Using mousewheel in GUI (listicongadget)
Thanks for all the help!!!!!

