[gnome-calendar] month-view: allow changing months with scrolling



commit eb7ad4959b3f154a56b7bbebeda80d2d572023c2
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Sat Oct 1 18:55:23 2016 -0300

    month-view: allow changing months with scrolling
    
    It is very natural and intuitive to try and change the current date
    by scrolling. The current implementation of the Month view, however,
    blatantly ignores scroll events.
    
    Fix that by hearing to the scrolling events and changing the month
    when the scroll is enough.

 src/gcal-month-view.c |   33 +++++++++++++++++++++++++++++++--
 src/gcal-utils.c      |   36 ++++++++++++++++++++++++++++++++++++
 src/gcal-utils.h      |    3 +++
 3 files changed, 70 insertions(+), 2 deletions(-)
---
diff --git a/src/gcal-month-view.c b/src/gcal-month-view.c
index a09b0c6..6f21573 100644
--- a/src/gcal-month-view.c
+++ b/src/gcal-month-view.c
@@ -31,7 +31,7 @@
 
 #include <math.h>
 
-#define LINE_WIDTH 0.5
+#define LINE_WIDTH      0.5
 
 typedef struct
 {
@@ -83,6 +83,9 @@ typedef struct
   /* The cell hovered during Drag and Drop */
   gint            dnd_cell;
 
+  /* Storage for the accumulated scrolling */
+  gdouble         scroll_value;
+
   /* property */
   icaltimetype   *date;
   GcalManager    *manager;
@@ -967,6 +970,29 @@ cancel_dnd_from_overflow_popover (GtkWidget *popover)
   return FALSE;
 }
 
+static gboolean
+gcal_month_view_scroll_event (GtkWidget      *widget,
+                              GdkEventScroll *scroll_event)
+{
+  GcalMonthView *self = GCAL_MONTH_VIEW (widget);
+  GcalMonthViewPrivate *priv = gcal_month_view_get_instance_private (self);
+
+  /*
+   * If we accumulated enough scrolling, change the month. Otherwise, we'd scroll
+   * waaay too fast.
+   */
+  if (should_change_date_for_scroll (&priv->scroll_value, scroll_event))
+    {
+      priv->date->month += priv->scroll_value > 0 ? 1 : -1;
+      *priv->date = icaltime_normalize (*priv->date);
+      priv->scroll_value = 0;
+
+      g_object_notify (G_OBJECT (widget), "active-date");
+    }
+
+  return GDK_EVENT_STOP;
+}
+
 static void
 add_new_event_button_cb (GtkWidget *button,
                          gpointer   user_data)
@@ -1014,6 +1040,7 @@ gcal_month_view_class_init (GcalMonthViewClass *klass)
   widget_class->drag_motion = gcal_month_view_drag_motion;
   widget_class->drag_drop = gcal_month_view_drag_drop;
   widget_class->drag_leave = gcal_month_view_drag_leave;
+  widget_class->scroll_event = gcal_month_view_scroll_event;
 
   subscriber_view_class = GCAL_SUBSCRIBER_VIEW_CLASS (klass);
   subscriber_view_class->get_child_cell = gcal_month_view_get_child_cell;
@@ -1198,7 +1225,9 @@ gcal_month_view_realize (GtkWidget *widget)
                             GDK_POINTER_MOTION_HINT_MASK |
                             GDK_POINTER_MOTION_MASK |
                             GDK_ENTER_NOTIFY_MASK |
-                            GDK_LEAVE_NOTIFY_MASK);
+                            GDK_LEAVE_NOTIFY_MASK |
+                            GDK_SCROLL_MASK |
+                            GDK_SMOOTH_SCROLL_MASK);
   attributes_mask = GDK_WA_X | GDK_WA_Y;
 
   priv->event_window = gdk_window_new (parent_window,
diff --git a/src/gcal-utils.c b/src/gcal-utils.c
index b32705c..ec91ee3 100644
--- a/src/gcal-utils.c
+++ b/src/gcal-utils.c
@@ -63,6 +63,8 @@ month_item[12] =
   MON_12
 };
 
+#define SCROLL_HARDNESS 10.0
+
 G_DEFINE_BOXED_TYPE (icaltimetype, icaltime, gcal_dup_icaltime, g_free)
 
 gint
@@ -844,3 +846,37 @@ get_alarm_trigger_minutes (GcalEvent          *event,
 
   return diff;
 }
+
+gboolean
+should_change_date_for_scroll (gdouble        *scroll_value,
+                               GdkEventScroll *scroll_event)
+{
+  gdouble delta_y;
+
+  switch (scroll_event->direction)
+    {
+    case GDK_SCROLL_DOWN:
+      *scroll_value = SCROLL_HARDNESS;
+      break;
+
+    case GDK_SCROLL_UP:
+      *scroll_value = -SCROLL_HARDNESS;
+      break;
+
+    case GDK_SCROLL_SMOOTH:
+      gdk_event_get_scroll_deltas ((GdkEvent*) scroll_event, NULL, &delta_y);
+      *scroll_value += delta_y;
+      break;
+
+    /* Ignore horizontal scrolling for now */
+    case GDK_SCROLL_LEFT:
+    case GDK_SCROLL_RIGHT:
+    default:
+      break;
+    }
+
+  if (*scroll_value <= -SCROLL_HARDNESS || *scroll_value >= SCROLL_HARDNESS)
+    return TRUE;
+
+  return FALSE;
+}
diff --git a/src/gcal-utils.h b/src/gcal-utils.h
index b8be51b..90992a9 100644
--- a/src/gcal-utils.h
+++ b/src/gcal-utils.h
@@ -123,4 +123,7 @@ gchar*          format_utc_offset                               (gint64
 gint            get_alarm_trigger_minutes                       (GcalEvent             *event,
                                                                  ECalComponentAlarm    *alarm);
 
+gboolean        should_change_date_for_scroll                   (gdouble               *scroll_value,
+                                                                 GdkEventScroll        *scroll_event);
+
 #endif // __GCAL_UTILS_H__


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