From 2fe612fd006e2149801bbe85f16921ae03d0b017 Mon Sep 17 00:00:00 2001 From: David Capello Date: Wed, 14 Oct 2015 09:27:20 -0300 Subject: [PATCH] Add precise trackpad support on Skia/OSX port --- .../ui/editor/state_with_wheel_behavior.cpp | 30 +++++++++++-------- src/she/event.h | 12 +++++++- src/she/osx/view.h | 1 + src/she/osx/view.mm | 25 +++++++++++++++- src/ui/manager.cpp | 17 +++++++---- src/ui/manager.h | 9 ++++-- src/ui/message.h | 12 +++++--- 7 files changed, 79 insertions(+), 27 deletions(-) diff --git a/src/app/ui/editor/state_with_wheel_behavior.cpp b/src/app/ui/editor/state_with_wheel_behavior.cpp index c9966dba5..7fa682c40 100644 --- a/src/app/ui/editor/state_with_wheel_behavior.cpp +++ b/src/app/ui/editor/state_with_wheel_behavior.cpp @@ -134,24 +134,30 @@ bool StateWithWheelBehavior::onMouseWheel(Editor* editor, MouseMessage* msg) case WHEEL_HSCROLL: case WHEEL_VSCROLL: { View* view = View::getView(editor); - gfx::Rect vp = view->getViewportBounds(); + gfx::Point scroll = view->getViewScroll(); gfx::Point delta(0, 0); - if (wheelAction == WHEEL_HSCROLL) { - delta.x = dz * vp.w; + if (msg->preciseWheel()) { + delta = msg->wheelDelta(); } else { - delta.y = dz * vp.h; + gfx::Rect vp = view->getViewportBounds(); + + if (wheelAction == WHEEL_HSCROLL) { + delta.x = dz * vp.w; + } + else { + delta.y = dz * vp.h; + } + + if (scrollBigSteps) { + delta /= 2; + } + else { + delta /= 10; + } } - if (scrollBigSteps) { - delta /= 2; - } - else { - delta /= 10; - } - - gfx::Point scroll = view->getViewScroll(); editor->setEditorScroll(scroll+delta, true); break; } diff --git a/src/she/event.h b/src/she/event.h index d58730ed0..79d75589a 100644 --- a/src/she/event.h +++ b/src/she/event.h @@ -46,7 +46,14 @@ namespace she { typedef std::vector Files; - Event() : m_type(None) { } + Event() : m_type(None), + m_display(nullptr), + m_scancode(kKeyNil), + m_unicodeChar(0), + m_repeat(0), + m_preciseWheel(false), + m_button(NoneButton) { + } Type type() const { return m_type; } Display* display() const { return m_display; } @@ -56,6 +63,7 @@ namespace she { int repeat() const { return m_repeat; } gfx::Point position() const { return m_position; } gfx::Point wheelDelta() const { return m_wheelDelta; } + bool preciseWheel() const { return m_preciseWheel; } MouseButton button() const { return m_button; } void setType(Type type) { m_type = type; } @@ -67,6 +75,7 @@ namespace she { void setRepeat(int repeat) { m_repeat = repeat; } void setPosition(const gfx::Point& pos) { m_position = pos; } void setWheelDelta(const gfx::Point& delta) { m_wheelDelta = delta; } + void setPreciseWheel(bool precise) { m_preciseWheel = precise; } void setButton(MouseButton button) { m_button = button; } private: @@ -78,6 +87,7 @@ namespace she { int m_repeat; // repeat=0 means the first time the key is pressed gfx::Point m_position; gfx::Point m_wheelDelta; + bool m_preciseWheel; MouseButton m_button; }; diff --git a/src/she/osx/view.h b/src/she/osx/view.h index 454c21be0..d2952f2bf 100644 --- a/src/she/osx/view.h +++ b/src/she/osx/view.h @@ -38,6 +38,7 @@ - (void)handleMouseDown:(NSEvent*)event; - (void)handleMouseUp:(NSEvent*)event; - (void)handleMouseDragged:(NSEvent*)event; +- (void)scrollWheel:(NSEvent*)event; - (void)setFrameSize:(NSSize)newSize; - (void)createMouseTrackingArea; - (void)destroyMouseTrackingArea; diff --git a/src/she/osx/view.mm b/src/she/osx/view.mm index 8a0714a55..2127c05e0 100644 --- a/src/she/osx/view.mm +++ b/src/she/osx/view.mm @@ -25,7 +25,6 @@ inline gfx::Point get_local_mouse_pos(NSView* view, NSEvent* event) NSPoint point = [view convertPoint:[event locationInWindow] fromView:nil]; int scale = 1; - if ([view window]) scale = [(OSXWindow*)[view window] scale]; @@ -286,6 +285,30 @@ inline Event::MouseButton get_mouse_buttons(NSEvent* event) } } +- (void)scrollWheel:(NSEvent*)event +{ + Event ev; + ev.setType(Event::MouseWheel); + ev.setPosition(get_local_mouse_pos(self, event)); + ev.setButton(get_mouse_buttons(event)); + + int scale = 1; + if (self.window) + scale = [(OSXWindow*)self.window scale]; + + if (event.hasPreciseScrollingDeltas) { + ev.setWheelDelta(gfx::Point(-event.scrollingDeltaX / scale, + -event.scrollingDeltaY / scale)); + ev.setPreciseWheel(true); + } + else { + ev.setWheelDelta(gfx::Point(-event.scrollingDeltaX, + -event.scrollingDeltaY)); + } + + queue_event(ev); +} + - (void)createMouseTrackingArea { // Create a tracking area to receive mouseMoved events diff --git a/src/ui/manager.cpp b/src/ui/manager.cpp index c76a1c58d..f4d2bd3e4 100644 --- a/src/ui/manager.cpp +++ b/src/ui/manager.cpp @@ -367,7 +367,8 @@ void Manager::generateMessagesFromSheEvents() } case she::Event::MouseWheel: { - handleMouseWheel(sheEvent.position(), m_mouseButtons, sheEvent.wheelDelta()); + handleMouseWheel(sheEvent.position(), m_mouseButtons, + sheEvent.wheelDelta(), sheEvent.preciseWheel()); break; } } @@ -434,12 +435,13 @@ void Manager::handleMouseDoubleClick(const gfx::Point& mousePos, MouseButtons mo } } -void Manager::handleMouseWheel(const gfx::Point& mousePos, MouseButtons mouseButtons, const gfx::Point& wheelDelta) +void Manager::handleMouseWheel(const gfx::Point& mousePos, MouseButtons mouseButtons, + const gfx::Point& wheelDelta, bool preciseWheel) { enqueueMessage(newMouseMessage( kMouseWheelMessage, (capture_widget ? capture_widget: mouse_widget), - mousePos, mouseButtons, wheelDelta)); + mousePos, mouseButtons, wheelDelta, preciseWheel)); } // Handles Z order: Send the window to top (only when you click in a @@ -1336,11 +1338,14 @@ Widget* Manager::findMagneticWidget(Widget* widget) } // static -Message* Manager::newMouseMessage(MessageType type, +Message* Manager::newMouseMessage( + MessageType type, Widget* widget, const gfx::Point& mousePos, - MouseButtons buttons, const gfx::Point& wheelDelta) + MouseButtons buttons, + const gfx::Point& wheelDelta, bool preciseWheel) { - Message* msg = new MouseMessage(type, buttons, mousePos, wheelDelta); + Message* msg = new MouseMessage(type, buttons, mousePos, + wheelDelta, preciseWheel); if (widget != NULL) msg->addRecipient(widget); diff --git a/src/ui/manager.h b/src/ui/manager.h index dfce609ea..8c7eb08a9 100644 --- a/src/ui/manager.h +++ b/src/ui/manager.h @@ -106,16 +106,19 @@ namespace ui { void handleMouseDown(const gfx::Point& mousePos, MouseButtons mouseButtons); void handleMouseUp(const gfx::Point& mousePos, MouseButtons mouseButtons); void handleMouseDoubleClick(const gfx::Point& mousePos, MouseButtons mouseButtons); - void handleMouseWheel(const gfx::Point& mousePos, MouseButtons mouseButtons, const gfx::Point& wheelDelta); + void handleMouseWheel(const gfx::Point& mousePos, MouseButtons mouseButtons, + const gfx::Point& wheelDelta, bool preciseWheel); void handleWindowZOrder(); void pumpQueue(); static void removeWidgetFromRecipients(Widget* widget, Message* msg); static bool someParentIsFocusStop(Widget* widget); static Widget* findMagneticWidget(Widget* widget); - static Message* newMouseMessage(MessageType type, + static Message* newMouseMessage( + MessageType type, Widget* widget, const gfx::Point& mousePos, - MouseButtons buttons, const gfx::Point& wheelDelta = gfx::Point(0, 0)); + MouseButtons buttons, const gfx::Point& wheelDelta = gfx::Point(0, 0), + bool preciseWheel = false); void broadcastKeyMsg(Message* msg); static Manager* m_defaultManager; diff --git a/src/ui/message.h b/src/ui/message.h index 46c3b3238..df2dc2945 100644 --- a/src/ui/message.h +++ b/src/ui/message.h @@ -1,5 +1,5 @@ // Aseprite UI Library -// Copyright (C) 2001-2013 David Capello +// Copyright (C) 2001-2013, 2015 David Capello // // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. @@ -99,12 +99,14 @@ namespace ui { { public: MouseMessage(MessageType type, MouseButtons buttons, - const gfx::Point& pos, - const gfx::Point& wheelDelta = gfx::Point(0, 0)) + const gfx::Point& pos, + const gfx::Point& wheelDelta = gfx::Point(0, 0), + bool preciseWheel = false) : Message(type), m_buttons(buttons), m_pos(pos), - m_wheelDelta(wheelDelta) { + m_wheelDelta(wheelDelta), + m_preciseWheel(preciseWheel) { } MouseButtons buttons() const { return m_buttons; } @@ -112,6 +114,7 @@ namespace ui { bool right() const { return (m_buttons & kButtonRight) == kButtonRight; } bool middle() const { return (m_buttons & kButtonMiddle) == kButtonMiddle; } gfx::Point wheelDelta() const { return m_wheelDelta; } + bool preciseWheel() const { return m_preciseWheel; } const gfx::Point& position() const { return m_pos; } @@ -119,6 +122,7 @@ namespace ui { MouseButtons m_buttons; // Pressed buttons gfx::Point m_pos; // Mouse position gfx::Point m_wheelDelta; // Wheel axis variation + bool m_preciseWheel; }; class TimerMessage : public Message