[aseprite] 249/308: Add touch magnify event to support OS X trackpad gesture

Tobias Hansen thansen at moszumanska.debian.org
Tue Mar 8 02:45:16 UTC 2016


This is an automated email from the git hooks/post-receive script.

thansen pushed a commit to branch master
in repository aseprite.

commit 15e10ad9f601e2dd9147ba10f7cbd1495d246d0f
Author: David Capello <davidcapello at gmail.com>
Date:   Thu Feb 18 13:58:45 2016 -0300

    Add touch magnify event to support OS X trackpad gesture
---
 src/app/ui/editor/editor.cpp                    | 17 +++++++-
 src/app/ui/editor/editor_state.h                |  8 +++-
 src/app/ui/editor/state_with_wheel_behavior.cpp | 54 +++++++++++++++++--------
 src/app/ui/editor/state_with_wheel_behavior.h   |  9 ++++-
 src/render/zoom.cpp                             | 15 ++++++-
 src/render/zoom.h                               | 16 +++++---
 src/she/event.h                                 |  6 ++-
 src/she/osx/view.mm                             | 13 +++++-
 src/ui/manager.cpp                              | 29 +++++++++++++
 src/ui/manager.h                                |  3 ++
 src/ui/message.h                                | 21 +++++++++-
 src/ui/message_type.h                           |  5 ++-
 12 files changed, 164 insertions(+), 32 deletions(-)

diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp
index 17e51dc..7a6eab8 100644
--- a/src/app/ui/editor/editor.cpp
+++ b/src/app/ui/editor/editor.cpp
@@ -361,6 +361,12 @@ void Editor::setZoom(const render::Zoom& zoom)
     m_zoom = zoom;
     notifyZoomChanged();
   }
+  else {
+    // Just copy the zoom as the internal "Zoom::m_internalScale"
+    // value might be different and we want to keep this value updated
+    // for better zooming experience in StateWithWheelBehavior.
+    m_zoom = zoom;
+  }
 }
 
 void Editor::setDefaultScroll()
@@ -1273,6 +1279,13 @@ bool Editor::onProcessMessage(Message* msg)
       }
       break;
 
+    case kTouchMagnifyMessage:
+      if (m_sprite) {
+        EditorStatePtr holdState(m_state);
+        return m_state->onTouchMagnify(this, static_cast<TouchMessage*>(msg));
+      }
+      break;
+
     case kKeyDownMessage:
       if (m_sprite) {
         EditorStatePtr holdState(m_state);
@@ -1488,9 +1501,9 @@ void Editor::setZoomAndCenterInMouse(const Zoom& zoom,
     padding.x - (screenPos.x-vp.x) + zoom.apply(spritePos.x+zoom.remove(1)/2) + int(zoom.apply(subpixelPos.x)),
     padding.y - (screenPos.y-vp.y) + zoom.apply(spritePos.y+zoom.remove(1)/2) + int(zoom.apply(subpixelPos.y)));
 
-  if ((m_zoom != zoom) || (screenPos != view->viewScroll())) {
-    setZoom(zoom);
+  setZoom(zoom);
 
+  if ((m_zoom != zoom) || (screenPos != view->viewScroll())) {
     updateEditor();
     setEditorScroll(scrollPos);
   }
diff --git a/src/app/ui/editor/editor_state.h b/src/app/ui/editor/editor_state.h
index 18a5d47..a3d99ef 100644
--- a/src/app/ui/editor/editor_state.h
+++ b/src/app/ui/editor/editor_state.h
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -18,8 +18,9 @@ namespace gfx {
 }
 
 namespace ui {
-  class MouseMessage;
   class KeyMessage;
+  class MouseMessage;
+  class TouchMessage;
 }
 
 namespace app {
@@ -85,6 +86,9 @@ namespace app {
     // Called when the user moves the mouse wheel over the editor.
     virtual bool onMouseWheel(Editor* editor, ui::MouseMessage* msg) { return false; }
 
+    // Called when the user wants to zoom in/out using a pinch gesture in the trackpad.
+    virtual bool onTouchMagnify(Editor* editor, ui::TouchMessage* msg) { return false; }
+
     // Called each time the mouse changes its position so we can set an
     // appropiated cursor depending on the new coordinates of the mouse
     // pointer.
diff --git a/src/app/ui/editor/state_with_wheel_behavior.cpp b/src/app/ui/editor/state_with_wheel_behavior.cpp
index 50b83fc..42b8c3e 100644
--- a/src/app/ui/editor/state_with_wheel_behavior.cpp
+++ b/src/app/ui/editor/state_with_wheel_behavior.cpp
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -36,7 +36,7 @@ enum WHEEL_ACTION { WHEEL_NONE,
 
 bool StateWithWheelBehavior::onMouseWheel(Editor* editor, MouseMessage* msg)
 {
-  int dz = msg->wheelDelta().x + msg->wheelDelta().y;
+  double dz = msg->wheelDelta().x + msg->wheelDelta().y;
   WHEEL_ACTION wheelAction = WHEEL_NONE;
   bool scrollBigSteps = false;
 
@@ -79,7 +79,7 @@ bool StateWithWheelBehavior::onMouseWheel(Editor* editor, MouseMessage* msg)
         if (ColorBar::instance()->getFgColor().getType() == app::Color::IndexType) {
           int lastIndex = get_current_palette()->size()-1;
 
-          newIndex = ColorBar::instance()->getFgColor().getIndex() + dz;
+          newIndex = ColorBar::instance()->getFgColor().getIndex() + int(dz);
           newIndex = MID(0, newIndex, lastIndex);
         }
         ColorBar::instance()->setFgColor(app::Color::fromIndex(newIndex));
@@ -92,7 +92,7 @@ bool StateWithWheelBehavior::onMouseWheel(Editor* editor, MouseMessage* msg)
         if (ColorBar::instance()->getBgColor().getType() == app::Color::IndexType) {
           int lastIndex = get_current_palette()->size()-1;
 
-          newIndex = ColorBar::instance()->getBgColor().getIndex() + dz;
+          newIndex = ColorBar::instance()->getBgColor().getIndex() + int(dz);
           newIndex = MID(0, newIndex, lastIndex);
         }
         ColorBar::instance()->setBgColor(app::Color::fromIndex(newIndex));
@@ -102,27 +102,25 @@ bool StateWithWheelBehavior::onMouseWheel(Editor* editor, MouseMessage* msg)
     case WHEEL_FRAME:
       {
         Command* command = CommandsModule::instance()->getCommandByName
-          ((dz < 0) ? CommandId::GotoNextFrame:
-                      CommandId::GotoPreviousFrame);
+          ((dz < 0.0) ? CommandId::GotoNextFrame:
+                        CommandId::GotoPreviousFrame);
         if (command)
           UIContext::instance()->executeCommand(command);
       }
       break;
 
     case WHEEL_ZOOM: {
-      MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
       render::Zoom zoom = editor->zoom();
 
-      zoom = render::Zoom::fromLinearScale(zoom.linearScale() - dz);
+      if (msg->preciseWheel()) {
+        dz /= 1.5;
+        if (dz < -1.0) dz = -1.0;
+        else if (dz > 1.0) dz = 1.0;
+      }
 
-      if (editor->zoom() != zoom) {
-        bool center = Preferences::instance().editor.zoomFromCenterWithWheel();
+      zoom = render::Zoom::fromLinearScale(zoom.linearScale() - int(dz));
 
-        editor->setZoomAndCenterInMouse(
-          zoom, mouseMsg->position(),
-          (center ? Editor::ZoomBehavior::CENTER:
-                    Editor::ZoomBehavior::MOUSE));
-      }
+      setZoom(editor, zoom, msg->position());
       break;
     }
 
@@ -139,10 +137,10 @@ bool StateWithWheelBehavior::onMouseWheel(Editor* editor, MouseMessage* msg)
         gfx::Rect vp = view->viewportBounds();
 
         if (wheelAction == WHEEL_HSCROLL) {
-          delta.x = dz * vp.w;
+          delta.x = int(dz * vp.w);
         }
         else {
-          delta.y = dz * vp.h;
+          delta.y = int(dz * vp.h);
         }
 
         if (scrollBigSteps) {
@@ -162,4 +160,26 @@ bool StateWithWheelBehavior::onMouseWheel(Editor* editor, MouseMessage* msg)
   return true;
 }
 
+bool StateWithWheelBehavior::onTouchMagnify(Editor* editor, ui::TouchMessage* msg)
+{
+  render::Zoom zoom = editor->zoom();
+  zoom = render::Zoom::fromScale(
+    zoom.internalScale() + zoom.internalScale() * msg->magnification());
+
+  setZoom(editor, zoom, msg->position());
+  return true;
+}
+
+void StateWithWheelBehavior::setZoom(Editor* editor,
+                                     const render::Zoom& zoom,
+                                     const gfx::Point& mousePos)
+{
+  bool center = Preferences::instance().editor.zoomFromCenterWithWheel();
+
+  editor->setZoomAndCenterInMouse(
+    zoom, mousePos,
+    (center ? Editor::ZoomBehavior::CENTER:
+              Editor::ZoomBehavior::MOUSE));
+}
+
 } // namespace app
diff --git a/src/app/ui/editor/state_with_wheel_behavior.h b/src/app/ui/editor/state_with_wheel_behavior.h
index c1b7523..67b5a78 100644
--- a/src/app/ui/editor/state_with_wheel_behavior.h
+++ b/src/app/ui/editor/state_with_wheel_behavior.h
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -11,11 +11,18 @@
 
 #include "app/ui/editor/editor_state.h"
 
+namespace render {
+  class Zoom;
+}
+
 namespace app {
 
   class StateWithWheelBehavior : public EditorState {
   public:
     virtual bool onMouseWheel(Editor* editor, ui::MouseMessage* msg) override;
+    virtual bool onTouchMagnify(Editor* editor, ui::TouchMessage* msg) override;
+  private:
+    void setZoom(Editor* editor, const render::Zoom& zoom, const gfx::Point& mousePos);
   };
 
 } // namespace app
diff --git a/src/render/zoom.cpp b/src/render/zoom.cpp
index bd1e3ff..27d60cf 100644
--- a/src/render/zoom.cpp
+++ b/src/render/zoom.cpp
@@ -34,6 +34,15 @@ static int scales[][2] = {
 
 static int scales_size = sizeof(scales) / sizeof(scales[0]);
 
+Zoom::Zoom(int num, int den)
+  : m_num(num)
+  , m_den(den)
+{
+  ASSERT(m_num > 0);
+  ASSERT(m_den > 0);
+  m_internalScale = scale();
+}
+
 void Zoom::in()
 {
   int i = linearScale();
@@ -41,6 +50,7 @@ void Zoom::in()
     ++i;
     m_num = scales[i][0];
     m_den = scales[i][1];
+    m_internalScale = scale();
   }
 }
 
@@ -51,6 +61,7 @@ void Zoom::out()
     --i;
     m_num = scales[i][0];
     m_den = scales[i][1];
+    m_internalScale = scale();
   }
 }
 
@@ -69,7 +80,9 @@ int Zoom::linearScale() const
 // static
 Zoom Zoom::fromScale(double scale)
 {
-  return fromLinearScale(findClosestLinearScale(scale));
+  Zoom zoom = fromLinearScale(findClosestLinearScale(scale));
+  zoom.m_internalScale = scale;
+  return zoom;
 }
 
 // static
diff --git a/src/render/zoom.h b/src/render/zoom.h
index f767555..a56b9f9 100644
--- a/src/render/zoom.h
+++ b/src/render/zoom.h
@@ -14,13 +14,16 @@ namespace render {
 
   class Zoom {
   public:
-    Zoom(int num, int den)
-      : m_num(num), m_den(den) {
-      ASSERT(m_num > 0);
-      ASSERT(m_den > 0);
+    Zoom(int num, int den);
+
+    double scale() const {
+      return static_cast<double>(m_num) / static_cast<double>(m_den);
     }
 
-    double scale() const { return static_cast<double>(m_num) / static_cast<double>(m_den); }
+    // This value isn't used in operator==() or operator!=()
+    double internalScale() const {
+      return m_internalScale;
+    }
 
     template<typename T>
     T apply(T x) const {
@@ -72,6 +75,9 @@ namespace render {
 
     int m_num;
     int m_den;
+
+    // Internal scale value used for precise zooming purposes.
+    double m_internalScale;
   };
 
 } // namespace render
diff --git a/src/she/event.h b/src/she/event.h
index 9009cf0..1b50bb3 100644
--- a/src/she/event.h
+++ b/src/she/event.h
@@ -1,5 +1,5 @@
 // SHE library
-// Copyright (C) 2012-2015  David Capello
+// Copyright (C) 2012-2016  David Capello
 //
 // This source file is ditributed under a BSD-like license, please
 // read LICENSE.txt for more information.
@@ -35,6 +35,7 @@ namespace she {
       MouseDoubleClick,
       KeyDown,
       KeyUp,
+      TouchMagnify,
     };
 
     enum MouseButton {
@@ -67,6 +68,7 @@ namespace she {
     gfx::Point wheelDelta() const { return m_wheelDelta; }
     bool preciseWheel() const { return m_preciseWheel; }
     MouseButton button() const { return m_button; }
+    double magnification() const { return m_magnification; }
 
     void setType(Type type) { m_type = type; }
     void setDisplay(Display* display) { m_display = display; }
@@ -80,6 +82,7 @@ namespace she {
     void setWheelDelta(const gfx::Point& delta) { m_wheelDelta = delta; }
     void setPreciseWheel(bool precise) { m_preciseWheel = precise; }
     void setButton(MouseButton button) { m_button = button; }
+    void setMagnification(double magnification) { m_magnification = magnification; }
 
   private:
     Type m_type;
@@ -93,6 +96,7 @@ namespace she {
     gfx::Point m_wheelDelta;
     bool m_preciseWheel;
     MouseButton m_button;
+    double m_magnification;
   };
 
 } // namespace she
diff --git a/src/she/osx/view.mm b/src/she/osx/view.mm
index 896f114..06ae186 100644
--- a/src/she/osx/view.mm
+++ b/src/she/osx/view.mm
@@ -1,5 +1,5 @@
 // SHE library
-// Copyright (C) 2015  David Capello
+// Copyright (C) 2015-2016  David Capello
 //
 // This file is released under the terms of the MIT license.
 // Read LICENSE.txt for more information.
@@ -370,6 +370,17 @@ bool is_key_pressed(KeyScancode scancode)
   queue_event(ev);
 }
 
+- (void)magnifyWithEvent:(NSEvent*)event
+{
+  Event ev;
+  ev.setType(Event::TouchMagnify);
+  ev.setMagnification(event.magnification);
+  ev.setPosition(get_local_mouse_pos(self, event));
+  ev.setModifiers(get_modifiers_from_nsevent(event));
+
+  queue_event(ev);
+}
+
 - (void)cursorUpdate:(NSEvent*)event
 {
   [self updateCurrentCursor];
diff --git a/src/ui/manager.cpp b/src/ui/manager.cpp
index f7a1ba1..1d585c5 100644
--- a/src/ui/manager.cpp
+++ b/src/ui/manager.cpp
@@ -380,6 +380,16 @@ void Manager::generateMessagesFromSheEvents()
                          sheEvent.preciseWheel());
         break;
       }
+
+      case she::Event::TouchMagnify: {
+        _internal_set_mouse_position(sheEvent.position());
+
+        handleTouchMagnify(sheEvent.position(),
+                           sheEvent.modifiers(),
+                           sheEvent.magnification());
+        break;
+      }
+
     }
   }
 
@@ -479,6 +489,24 @@ void Manager::handleMouseWheel(const gfx::Point& mousePos,
       wheelDelta, preciseWheel));
 }
 
+void Manager::handleTouchMagnify(const gfx::Point& mousePos,
+                                 const KeyModifiers modifiers,
+                                 const double magnification)
+{
+  Widget* widget = (capture_widget ? capture_widget: mouse_widget);
+  if (widget) {
+    Message* msg = new TouchMessage(
+      kTouchMagnifyMessage,
+      modifiers,
+      mousePos,
+      magnification);
+
+    msg->addRecipient(widget);
+
+    enqueueMessage(msg);
+  }
+}
+
 // Handles Z order: Send the window to top (only when you click in a
 // window that aren't the desktop).
 void Manager::handleWindowZOrder()
@@ -1222,6 +1250,7 @@ void Manager::pumpQueue()
           "kMouseMoveMessage",
           "kSetCursorMessage",
           "kMouseWheelMessage",
+          "kTouchMagnifyMessage",
         };
         const char* string =
           (msg->type() >= kOpenMessage &&
diff --git a/src/ui/manager.h b/src/ui/manager.h
index 14f26c1..0b83646 100644
--- a/src/ui/manager.h
+++ b/src/ui/manager.h
@@ -123,6 +123,9 @@ namespace ui {
     void handleMouseDoubleClick(const gfx::Point& mousePos, MouseButtons mouseButtons, KeyModifiers modifiers);
     void handleMouseWheel(const gfx::Point& mousePos, MouseButtons mouseButtons, KeyModifiers modifiers,
                           const gfx::Point& wheelDelta, bool preciseWheel);
+    void handleTouchMagnify(const gfx::Point& mousePos,
+                            const KeyModifiers modifiers,
+                            const double magnification);
     void handleWindowZOrder();
 
     void pumpQueue();
diff --git a/src/ui/message.h b/src/ui/message.h
index db27fa5..6529154 100644
--- a/src/ui/message.h
+++ b/src/ui/message.h
@@ -1,5 +1,5 @@
 // Aseprite UI Library
-// Copyright (C) 2001-2013, 2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This file is released under the terms of the MIT license.
 // Read LICENSE.txt for more information.
@@ -129,6 +129,25 @@ namespace ui {
     bool m_preciseWheel;
   };
 
+  class TouchMessage : public Message {
+  public:
+    TouchMessage(MessageType type,
+                 KeyModifiers modifiers,
+                 const gfx::Point& pos,
+                 double magnification)
+      : Message(type, modifiers),
+        m_pos(pos),
+        m_magnification(magnification) {
+    }
+
+    const gfx::Point& position() const { return m_pos; }
+    double magnification() const { return m_magnification; }
+
+  private:
+    gfx::Point m_pos;           // Mouse position
+    double m_magnification;
+  };
+
   class TimerMessage : public Message {
   public:
     TimerMessage(int count, Timer* timer)
diff --git a/src/ui/message_type.h b/src/ui/message_type.h
index b4b25e4..12f7e3f 100644
--- a/src/ui/message_type.h
+++ b/src/ui/message_type.h
@@ -1,5 +1,5 @@
 // Aseprite UI Library
-// Copyright (C) 2001-2013, 2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This file is released under the terms of the MIT license.
 // Read LICENSE.txt for more information.
@@ -38,6 +38,9 @@ namespace ui {
     kSetCursorMessage,      // A widget needs to setup the mouse cursor.
     kMouseWheelMessage,     // User moves the wheel.
 
+    // Touch related messages.
+    kTouchMagnifyMessage,
+
     // TODO Drag'n'drop messages...
     // k...DndMessage
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git



More information about the Pkg-games-commits mailing list