diff options
-rw-r--r-- | pugl/detail/mac.m | 39 | ||||
-rw-r--r-- | pugl/detail/win.c | 6 | ||||
-rw-r--r-- | pugl/detail/x11.c | 20 | ||||
-rw-r--r-- | pugl/pugl.h | 37 | ||||
-rw-r--r-- | test/test_utils.h | 22 |
5 files changed, 96 insertions, 28 deletions
diff --git a/pugl/detail/mac.m b/pugl/detail/mac.m index 3e5a018..50c52c5 100644 --- a/pugl/detail/mac.m +++ b/pugl/detail/mac.m @@ -460,19 +460,32 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type) - (void) scrollWheel:(NSEvent*)event { - const NSPoint wloc = [self eventLocation:event]; - const NSPoint rloc = [NSEvent mouseLocation]; - const PuglEventScroll ev = { - PUGL_SCROLL, - 0, - [event timestamp], - wloc.x, - wloc.y, - rloc.x, - [[NSScreen mainScreen] frame].size.height - rloc.y, - getModifiers(event), - [event scrollingDeltaX], - [event scrollingDeltaY], + const NSPoint wloc = [self eventLocation:event]; + const NSPoint rloc = [NSEvent mouseLocation]; + const double dx = [event scrollingDeltaX]; + const double dy = [event scrollingDeltaY]; + const PuglScrollDirection dir = + ((dx == 0.0 && dy > 0.0) + ? PUGL_SCROLL_UP + : ((dx == 0.0 && dy < 0.0) + ? PUGL_SCROLL_DOWN + : ((dy == 0.0 && dx > 0.0) + ? PUGL_SCROLL_RIGHT + : ((dy == 0.0 && dx < 0.0) ? PUGL_SCROLL_LEFT + : PUGL_SCROLL_SMOOTH)))); + + const PuglEventScroll ev = { + PUGL_SCROLL, + 0, + [event timestamp], + wloc.x, + wloc.y, + rloc.x, + [[NSScreen mainScreen] frame].size.height - rloc.y, + getModifiers(event), + [event hasPreciseScrollingDeltas] ? PUGL_SCROLL_SMOOTH : dir, + dx, + dy, }; puglDispatchEvent(puglview, (const PuglEvent*)&ev); diff --git a/pugl/detail/win.c b/pugl/detail/win.c index 38f2615..ee690c4 100644 --- a/pugl/detail/win.c +++ b/pugl/detail/win.c @@ -668,10 +668,16 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) case WM_MOUSEWHEEL: initScrollEvent(&event, view, lParam); event.scroll.dy = GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; + event.scroll.direction = (event.scroll.dy > 0 + ? PUGL_SCROLL_UP + : PUGL_SCROLL_DOWN); break; case WM_MOUSEHWHEEL: initScrollEvent(&event, view, lParam); event.scroll.dx = GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; + event.scroll.direction = (event.scroll.dx > 0 + ? PUGL_SCROLL_RIGHT + : PUGL_SCROLL_LEFT); break; case WM_KEYDOWN: if (!ignoreKeyEvent(view, lParam)) { diff --git a/pugl/detail/x11.c b/pugl/detail/x11.c index 1cd76f7..b06f940 100644 --- a/pugl/detail/x11.c +++ b/pugl/detail/x11.c @@ -587,10 +587,22 @@ translateEvent(PuglView* view, XEvent xevent) event.scroll.dx = 0.0; event.scroll.dy = 0.0; switch (xevent.xbutton.button) { - case 4: event.scroll.dy = 1.0; break; - case 5: event.scroll.dy = -1.0; break; - case 6: event.scroll.dx = -1.0; break; - case 7: event.scroll.dx = 1.0; break; + case 4: + event.scroll.dy = 1.0; + event.scroll.direction = PUGL_SCROLL_UP; + break; + case 5: + event.scroll.dy = -1.0; + event.scroll.direction = PUGL_SCROLL_DOWN; + break; + case 6: + event.scroll.dx = -1.0; + event.scroll.direction = PUGL_SCROLL_LEFT; + break; + case 7: + event.scroll.dx = 1.0; + event.scroll.direction = PUGL_SCROLL_RIGHT; + break; } // fallthru } diff --git a/pugl/pugl.h b/pugl/pugl.h index 137e6d1..8c0bd6d 100644 --- a/pugl/pugl.h +++ b/pugl/pugl.h @@ -239,6 +239,22 @@ typedef enum { } PuglCrossingMode; /** + Scroll direction. + + Describes the direction of a #PuglEventScroll along with whether the scroll + is a "smooth" scroll. The discrete directions are for devices like mouse + wheels with constrained axes, while a smooth scroll is for those with + arbitrary scroll direction freedom, like some touchpads. +*/ +typedef enum { + PUGL_SCROLL_UP, ///< Scroll up + PUGL_SCROLL_DOWN, ///< Scroll down + PUGL_SCROLL_LEFT, ///< Scroll left + PUGL_SCROLL_RIGHT, ///< Scroll right + PUGL_SCROLL_SMOOTH ///< Smooth scroll in any direction +} PuglScrollDirection; + +/** Common header for all event structs. */ typedef struct { @@ -471,16 +487,17 @@ typedef struct { gracefully. */ typedef struct { - PuglEventType type; ///< #PUGL_SCROLL - PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values - double time; ///< Time in seconds - double x; ///< View-relative X coordinate - double y; ///< View-relative Y coordinate - double xRoot; ///< Root-relative X coordinate - double yRoot; ///< Root-relative Y coordinate - PuglMods state; ///< Bitwise OR of #PuglMod flags - double dx; ///< Scroll X distance in lines - double dy; ///< Scroll Y distance in lines + PuglEventType type; ///< #PUGL_SCROLL + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + double time; ///< Time in seconds + double x; ///< View-relative X coordinate + double y; ///< View-relative Y coordinate + double xRoot; ///< Root-relative X coordinate + double yRoot; ///< Root-relative Y coordinate + PuglMods state; ///< Bitwise OR of #PuglMod flags + PuglScrollDirection direction; ///< Scroll direction + double dx; ///< Scroll X distance in lines + double dy; ///< Scroll Y distance in lines } PuglEventScroll; /** diff --git a/test/test_utils.h b/test/test_utils.h index 8668e1d..977fba5 100644 --- a/test/test_utils.h +++ b/test/test_utils.h @@ -82,6 +82,25 @@ crossingModeString(const PuglCrossingMode mode) return "unknown"; } +static inline const char* +scrollDirectionString(const PuglScrollDirection direction) +{ + switch (direction) { + case PUGL_SCROLL_UP: + return "up"; + case PUGL_SCROLL_DOWN: + return "down"; + case PUGL_SCROLL_LEFT: + return "left"; + case PUGL_SCROLL_RIGHT: + return "right"; + case PUGL_SCROLL_SMOOTH: + return "smooth"; + } + + return "unknown"; +} + static inline int printEvent(const PuglEvent* event, const char* prefix, const bool verbose) { @@ -118,10 +137,11 @@ printEvent(const PuglEvent* event, const char* prefix, const bool verbose) event->button.y) + printModifiers(event->scroll.state)); case PUGL_SCROLL: - return (PRINT("%sScroll %5.1f %5.1f at " PFMT " ", + return (PRINT("%sScroll %5.1f %5.1f (%s) at " PFMT " ", prefix, event->scroll.dx, event->scroll.dy, + scrollDirectionString(event->scroll.direction), event->scroll.x, event->scroll.y) + printModifiers(event->scroll.state)); |