[vte] widget: Make scroll event its own class



commit 235f5ce5f89d9ec94a414514a6fb8bfbe2994fd1
Author: Christian Persch <chpe src gnome org>
Date:   Mon Nov 2 21:22:40 2020 +0100

    widget: Make scroll event its own class
    
    [gtk4 preparation]

 src/fwd.hh         |  1 +
 src/vte.cc         | 24 ++-------------
 src/vteinternal.hh |  2 +-
 src/widget.cc      | 34 +++++++++++++++++++++
 src/widget.hh      | 90 +++++++++++++++++++++++++++---------------------------
 5 files changed, 83 insertions(+), 68 deletions(-)
---
diff --git a/src/fwd.hh b/src/fwd.hh
index bf5906c8..7f9975ed 100644
--- a/src/fwd.hh
+++ b/src/fwd.hh
@@ -31,6 +31,7 @@ class Clipboard;
 class EventBase;
 class KeyEvent;
 class MouseEvent;
+class ScrollEvent;
 class Widget;
 
 } // namespace platform
diff --git a/src/vte.cc b/src/vte.cc
index e60eaf6f..43377cfa 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -9320,7 +9320,7 @@ vte_cairo_get_clip_region (cairo_t *cr)
 }
 
 bool
-Terminal::widget_mouse_scroll(vte::platform::MouseEvent const& event)
+Terminal::widget_mouse_scroll(vte::platform::ScrollEvent const& event)
 {
        gdouble v;
        gint cnt, i;
@@ -9332,27 +9332,7 @@ Terminal::widget_mouse_scroll(vte::platform::MouseEvent const& event)
         auto rowcol = confined_grid_coords_from_event(event);
 
         m_modifiers = event.modifiers();
-
-        switch (event.scroll_direction()) {
-        case vte::platform::MouseEvent::ScrollDirection::eUP:
-               m_mouse_smooth_scroll_delta -= 1.;
-               _vte_debug_print(VTE_DEBUG_EVENTS, "Scroll up\n");
-               break;
-        case vte::platform::MouseEvent::ScrollDirection::eDOWN:
-               m_mouse_smooth_scroll_delta += 1.;
-               _vte_debug_print(VTE_DEBUG_EVENTS, "Scroll down\n");
-               break;
-        case vte::platform::MouseEvent::ScrollDirection::eSMOOTH: {
-                auto const delta_y = event.scroll_delta_y();
-               m_mouse_smooth_scroll_delta += delta_y;
-               _vte_debug_print(VTE_DEBUG_EVENTS,
-                               "Smooth scroll by %f, delta now at %f\n",
-                               delta_y, m_mouse_smooth_scroll_delta);
-               break;
-        }
-       default:
-               break;
-       }
+        m_mouse_smooth_scroll_delta += event.dy();
 
        /* If we're running a mouse-aware application, map the scroll event
         * to a button press on buttons four and five. */
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index 57895de3..f9db1f2a 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -864,7 +864,7 @@ public:
         bool widget_mouse_release(vte::platform::MouseEvent const& event);
         void widget_mouse_enter(vte::platform::MouseEvent const& event);
         void widget_mouse_leave(vte::platform::MouseEvent const& event);
-        bool widget_mouse_scroll(vte::platform::MouseEvent const& event);
+        bool widget_mouse_scroll(vte::platform::ScrollEvent const& event);
         void widget_draw(cairo_t *cr);
         void widget_get_preferred_width(int *minimum_width,
                                         int *natural_width);
diff --git a/src/widget.cc b/src/widget.cc
index 3f5e0278..21cfff54 100644
--- a/src/widget.cc
+++ b/src/widget.cc
@@ -490,6 +490,40 @@ Widget::mouse_event_from_gdk(GdkEvent* event) const /* throws */
                 y};
 }
 
+ScrollEvent
+Widget::scroll_event_from_gdk(GdkEvent* event) const /* throws */
+{
+        auto button = unsigned{0};
+        (void)gdk_event_get_button(event, &button);
+
+        auto x = double{}, y = double{};
+        if (gdk_event_get_window(event) != m_event_window ||
+            !gdk_event_get_coords(event, &x, &y))
+                x = y = -1.; // FIXMEchpe or throw?
+
+        auto dx = double{}, dy = double{};
+        if (!gdk_event_get_scroll_deltas(event, &dx, &dy)) {
+                auto dir = GdkScrollDirection{};
+                if (!gdk_event_get_scroll_direction(event, &dir))
+                        __builtin_unreachable();
+
+                switch (dir) {
+                case GDK_SCROLL_UP:     dx =  0.; dy = -1.; break;
+                case GDK_SCROLL_DOWN:   dx =  0.; dy =  1.; break;
+                case GDK_SCROLL_LEFT:   dx = -1.; dy =  0.; break;
+                case GDK_SCROLL_RIGHT:  dx =  1.; dy =  0.; break;
+                case GDK_SCROLL_SMOOTH: break;
+                default: __builtin_unreachable();
+                }
+        }
+
+        return {event,
+                read_modifiers_from_gdk(event),
+                ScrollEvent::Button(button),
+                x, y,
+                dx, dy};
+}
+
 void
 Widget::map() noexcept
 {
diff --git a/src/widget.hh b/src/widget.hh
index 6924ade2..e0f5cd15 100644
--- a/src/widget.hh
+++ b/src/widget.hh
@@ -151,15 +151,6 @@ public:
                 eFIFTH  = 5,
         };
 
-        enum class ScrollDirection {
-                eUP,
-                eDOWN,
-                eLEFT,
-                eRIGHT,
-                eSMOOTH,
-                eNONE,
-        };
-
 protected:
 
         MouseEvent() noexcept = default;
@@ -201,41 +192,6 @@ public:
         constexpr auto is_mouse_motion()       const noexcept { return type() == Type::eMOUSE_MOTION;       }
         constexpr auto is_mouse_press()        const noexcept { return type() == Type::eMOUSE_PRESS;      }
         constexpr auto is_mouse_release()      const noexcept { return type() == Type::eMOUSE_RELEASE;      }
-        constexpr auto is_mouse_scroll()       const noexcept { return type() == Type::eMOUSE_SCROLL;       }
-
-        ScrollDirection scroll_direction() const noexcept
-        {
-                if (!is_mouse_scroll())
-                        return ScrollDirection::eNONE;
-                auto dir = GdkScrollDirection{};
-                if (gdk_event_get_scroll_deltas(platform_event(), nullptr, nullptr))
-                        dir = GDK_SCROLL_SMOOTH;
-                else if (!gdk_event_get_scroll_direction(platform_event(), &dir))
-                        return ScrollDirection::eNONE;
-
-                switch (dir) {
-                case GDK_SCROLL_UP:     return ScrollDirection::eUP;
-                case GDK_SCROLL_DOWN:   return ScrollDirection::eDOWN;
-                case GDK_SCROLL_LEFT:   return ScrollDirection::eLEFT;
-                case GDK_SCROLL_RIGHT:  return ScrollDirection::eRIGHT;
-                case GDK_SCROLL_SMOOTH: return ScrollDirection::eSMOOTH;
-                default: return ScrollDirection::eNONE;
-                }
-        }
-
-        auto scroll_delta_x() const noexcept
-        {
-                auto delta = double{0.};
-                gdk_event_get_scroll_deltas(platform_event(), &delta, nullptr);
-                return delta;
-        }
-
-        auto scroll_delta_y() const noexcept
-        {
-                auto delta = double{0.};
-                gdk_event_get_scroll_deltas(platform_event(), nullptr, &delta);
-                return delta;
-        }
 
 private:
         unsigned m_press_count;
@@ -245,6 +201,49 @@ private:
         double m_y;
 }; // class MouseEvent
 
+class ScrollEvent : public MouseEvent {
+        friend class vte::platform::Widget;
+        friend class Terminal;
+
+protected:
+
+        ScrollEvent() noexcept = default;
+
+        constexpr ScrollEvent(GdkEvent* gdk_event,
+                              unsigned modifiers,
+                              Button button,
+                              double x,
+                              double y,
+                              double dx,
+                              double dy) noexcept
+                : MouseEvent{gdk_event,
+                             EventBase::Type::eMOUSE_SCROLL,
+                             1, // press count
+                             modifiers,
+                             button,
+                             x,
+                             y},
+                  m_dx{dx},
+                  m_dy{dy}
+        {
+        }
+
+public:
+        ~ScrollEvent() noexcept = default;
+
+        ScrollEvent(ScrollEvent const&) = default;
+        ScrollEvent(ScrollEvent&&) = default;
+        ScrollEvent& operator=(ScrollEvent const&) = delete;
+        ScrollEvent& operator=(ScrollEvent&&) = delete;
+
+        constexpr auto dx()           const noexcept { return m_dx;               }
+        constexpr auto dy()           const noexcept { return m_dy;               }
+
+private:
+        double m_dx;
+        double m_dy;
+}; // class ScrollEvent
+
 class Widget : public std::enable_shared_from_this<Widget> {
 public:
         friend class vte::terminal::Terminal;
@@ -285,7 +284,7 @@ public:
         bool button_release(GdkEventButton *event) noexcept { return 
m_terminal->widget_mouse_release(mouse_event_from_gdk(reinterpret_cast<GdkEvent*>(event))); }
         void enter(GdkEventCrossing *event) noexcept { 
m_terminal->widget_mouse_enter(mouse_event_from_gdk(reinterpret_cast<GdkEvent*>(event))); }
         void leave(GdkEventCrossing *event) noexcept { 
m_terminal->widget_mouse_leave(mouse_event_from_gdk(reinterpret_cast<GdkEvent*>(event))); }
-        bool scroll(GdkEventScroll *event) noexcept { return 
m_terminal->widget_mouse_scroll(mouse_event_from_gdk(reinterpret_cast<GdkEvent*>(event))); }
+        bool scroll(GdkEventScroll *event) noexcept { return 
m_terminal->widget_mouse_scroll(scroll_event_from_gdk(reinterpret_cast<GdkEvent*>(event))); }
         bool motion_notify(GdkEventMotion *event) noexcept { return 
m_terminal->widget_mouse_motion(mouse_event_from_gdk(reinterpret_cast<GdkEvent*>(event))); }
 
         void grab_focus() noexcept { gtk_widget_grab_focus(gtk()); }
@@ -427,6 +426,7 @@ private:
         unsigned read_modifiers_from_gdk(GdkEvent* event) const noexcept;
         KeyEvent key_event_from_gdk(GdkEventKey* event) const;
         MouseEvent mouse_event_from_gdk(GdkEvent* event) const /* throws */;
+        ScrollEvent scroll_event_from_gdk(GdkEvent* event) const /* throws */;
 
         void clipboard_request_received_cb(Clipboard const& clipboard,
                                            std::string_view const& text);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]