[gnome-calendar] week-view: Allow zooming with Ctrl+Scroll



commit 6b39f7552b401a152209fb462085b65a0990a546
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Thu Jun 23 17:08:53 2022 +0200

    week-view: Allow zooming with Ctrl+Scroll
    
    So it's possible to zoom even if the device doesn't support pinching to
    do so.

 src/gui/views/gcal-week-view.c  | 76 +++++++++++++++++++++++++++++++++++++++++
 src/gui/views/gcal-week-view.ui | 20 +++++++++++
 2 files changed, 96 insertions(+)
---
diff --git a/src/gui/views/gcal-week-view.c b/src/gui/views/gcal-week-view.c
index 9958ed08..1d5fb19d 100644
--- a/src/gui/views/gcal-week-view.c
+++ b/src/gui/views/gcal-week-view.c
@@ -55,6 +55,10 @@ struct _GcalWeekView
 
   gdouble             gesture_zoom_center;
   gint                gesture_zoom_initial_height;
+
+  gboolean            pointer_position_valid;
+  gdouble             pointer_position_y;
+  gdouble             scroll_scale;
 };
 
 static void          schedule_position_scroll                    (GcalWeekView       *self);
@@ -127,6 +131,73 @@ apply_zoom (GcalWeekView *self,
   gtk_adjustment_set_value (vadjustment, (self->gesture_zoom_center * height) - view_center_y);
 }
 
+static void
+on_motion_controller_enter_cb (GcalWeekView             *self,
+                               gdouble                   x,
+                               gdouble                   y,
+                               GtkEventControllerMotion *controller)
+{
+  self->pointer_position_valid = TRUE;
+  self->pointer_position_y = y;
+}
+
+static void
+on_motion_controller_motion_cb (GcalWeekView             *self,
+                               gdouble                   x,
+                               gdouble                   y,
+                               GtkEventControllerMotion *controller)
+{
+  self->pointer_position_valid = TRUE;
+  self->pointer_position_y = y;
+}
+
+static void
+on_motion_controller_leave_cb (GcalWeekView             *self,
+                               GtkEventControllerMotion *controller)
+{
+  self->pointer_position_valid = FALSE;
+}
+
+static void
+on_scroll_controller_scroll_begin_cb (GcalWeekView             *self,
+                                      GtkEventControllerScroll *controller)
+{
+  gdouble view_center_y;
+
+  self->scroll_scale = 1.0;
+
+  if (self->pointer_position_valid)
+    view_center_y = self->pointer_position_y;
+  else
+    view_center_y = gtk_widget_get_allocated_height (self->scrolled_window) / 2.0;
+
+  begin_zoom (self, view_center_y);
+}
+
+static gboolean
+on_scroll_controller_scroll_cb (GcalWeekView             *self,
+                                gdouble                   dx,
+                                gdouble                   dy,
+                                GtkEventControllerScroll *controller)
+{
+  gdouble scale, view_center_y;
+
+  if (!(gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (controller)) & GDK_CONTROL_MASK))
+    return FALSE;
+
+  scale = dy / 100.0 + self->scroll_scale;
+
+  if (self->pointer_position_valid)
+    view_center_y = self->pointer_position_y;
+  else
+    view_center_y = gtk_widget_get_allocated_height (self->scrolled_window) / 2.0;
+
+  begin_zoom (self, view_center_y);
+  apply_zoom (self, view_center_y, scale);
+
+  return TRUE;
+}
+
 static void
 on_zoom_gesture_scale_changed_cb (GcalWeekView   *self,
                                   gdouble         scale,
@@ -501,6 +572,11 @@ gcal_week_view_class_init (GcalWeekViewClass *klass)
   gtk_widget_class_bind_template_child (widget_class, GcalWeekView, week_grid);
 
   gtk_widget_class_bind_template_callback (widget_class, on_event_activated);
+  gtk_widget_class_bind_template_callback (widget_class, on_motion_controller_enter_cb);
+  gtk_widget_class_bind_template_callback (widget_class, on_motion_controller_motion_cb);
+  gtk_widget_class_bind_template_callback (widget_class, on_motion_controller_leave_cb);
+  gtk_widget_class_bind_template_callback (widget_class, on_scroll_controller_scroll_begin_cb);
+  gtk_widget_class_bind_template_callback (widget_class, on_scroll_controller_scroll_cb);
   gtk_widget_class_bind_template_callback (widget_class, on_zoom_gesture_scale_changed_cb);
   gtk_widget_class_bind_template_callback (widget_class, on_zoom_gesture_begin_cb);
 
diff --git a/src/gui/views/gcal-week-view.ui b/src/gui/views/gcal-week-view.ui
index abd2bee6..e8268f9a 100644
--- a/src/gui/views/gcal-week-view.ui
+++ b/src/gui/views/gcal-week-view.ui
@@ -23,6 +23,26 @@
           </object>
         </child>
 
+        <!-- Scroll Event Controller -->
+        <child>
+          <object class="GtkEventControllerScroll">
+            <property name="propagation-phase">capture</property>
+            <property name="flags">vertical|kinetic</property>
+            <signal name="scroll" handler="on_scroll_controller_scroll_begin_cb" object="GcalWeekView" 
swapped="yes" />
+            <signal name="scroll" handler="on_scroll_controller_scroll_cb" object="GcalWeekView" 
swapped="yes" />
+          </object>
+        </child>
+
+        <!-- Motion Event Controller -->
+        <child>
+          <object class="GtkEventControllerMotion">
+            <property name="propagation-phase">capture</property>
+            <signal name="enter" handler="on_motion_controller_enter_cb" object="GcalWeekView" swapped="yes" 
/>
+            <signal name="motion" handler="on_motion_controller_motion_cb" object="GcalWeekView" 
swapped="yes" />
+            <signal name="leave" handler="on_motion_controller_leave_cb" object="GcalWeekView" swapped="yes" 
/>
+          </object>
+        </child>
+
         <child>
           <object class="GtkViewport">
             <child>


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