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 @@
+
+
+
+
+
+
+
+
+
+