[gnome-calendar] month-view: updated press/release/motions handlers



commit 268ef174840b52a8a79670164052a5f9d5d7166c
Author: Erick Pérez Castellanos <erick red gmail com>
Date:   Fri Dec 12 22:56:28 2014 -0500

    month-view: updated press/release/motions handlers
    
    Now internal values of button press, motion and releases are kept
    according the cell numbers alone, as explained in the comments.

 src/gcal-month-view.c |  235 ++++++++++++++++++++++++++----------------------
 1 files changed, 127 insertions(+), 108 deletions(-)
---
diff --git a/src/gcal-month-view.c b/src/gcal-month-view.c
index 2a3d394..ae64870 100644
--- a/src/gcal-month-view.c
+++ b/src/gcal-month-view.c
@@ -50,7 +50,11 @@ typedef struct
    * 0 for Sunday, 1 for Monday and so on */
   gint            first_weekday;
 
-  /* button_down/up flag */
+  /**
+   * button_down/up flag
+   * These keeps the cell index, meaning 0 for left top, 1 for the next in the row from left to right, etc.
+   * Note that this does not take into account the disabled row before the first active row.
+   */
   gint            clicked_cell;
   gint            start_mark_cell;
   gint            end_mark_cell;
@@ -70,6 +74,12 @@ enum
 static void           event_opened                          (GcalEventWidget *event_widget,
                                                              gpointer         user_data);
 
+static gint           get_cell_and_center_from_position     (GcalMonthView  *view,
+                                                             gdouble         x,
+                                                             gdouble         y,
+                                                             gdouble        *out_x,
+                                                             gdouble        *out_y);
+
 static void           gcal_view_interface_init              (GcalViewIface  *iface);
 
 static void           gcal_month_view_set_property          (GObject        *object,
@@ -154,6 +164,50 @@ event_opened (GcalEventWidget *event_widget,
                          event_widget);
 }
 
+static gint
+get_cell_and_center_from_position (GcalMonthView *view,
+                                   gdouble        x,
+                                   gdouble        y,
+                                   gdouble       *out_x,
+                                   gdouble       *out_y)
+{
+  GcalMonthViewPrivate *priv;
+  GtkWidget *widget;
+
+  gdouble start_grid_y;
+
+  gint shown_rows;
+  gdouble first_row_gap;
+
+  gdouble cell_width;
+  gdouble cell_height;
+
+  gint cell;
+
+  priv = gcal_month_view_get_instance_private (view);
+  widget = GTK_WIDGET (view);
+
+  start_grid_y = gcal_month_view_get_start_grid_y (widget);
+
+  shown_rows = ceil ((priv->days_delay + icaltime_days_in_month (priv->date->month, priv->date->year)) / 
7.0);
+  first_row_gap = (6 - shown_rows) * 0.5; /* invalid area before the actual rows */
+
+  cell_width = gtk_widget_get_allocated_width (widget) / 7.0;
+  cell_height = (gtk_widget_get_allocated_height (widget) - start_grid_y) / 6.0;
+
+  y = y - start_grid_y - first_row_gap * cell_height;
+
+  cell = 7 * (gint)(y / cell_height) + (gint)(x / cell_width);
+
+  if (out_x != NULL)
+    *out_x = cell_width * ((cell % 7) + 0.5);
+
+  if (out_y != NULL)
+    *out_y = cell_height * ((cell / 7) + 0.5 * (3.0 - (shown_rows % 2))) + start_grid_y;
+
+  return cell;
+}
+
 static void
 gcal_month_view_class_init (GcalMonthViewClass *klass)
 {
@@ -745,45 +799,37 @@ gcal_month_view_button_press (GtkWidget      *widget,
                               GdkEventButton *event)
 {
   GcalMonthViewPrivate *priv;
-  gdouble x, y;
-  gint width, height;
-  gdouble start_grid_y;
-
-  gdouble days;
-  gint shown_rows;
 
-  gdouble lines_gap;
-  gdouble lines_gap_for_5;
+  gint days;
 
-  gdouble v_block;
+  gint j;
+  gint sw, k;
 
   priv = gcal_month_view_get_instance_private (GCAL_MONTH_VIEW (widget));
 
-  x = event->x;
-  y = event->y;
-
-  width = gtk_widget_get_allocated_width (widget);
-  height = gtk_widget_get_allocated_height (widget);
-  start_grid_y = gcal_month_view_get_start_grid_y (widget);
-
-  y = y - start_grid_y;
-
   days = priv->days_delay + icaltime_days_in_month (priv->date->month, priv->date->year);
-  shown_rows = ceil (days / 7.0);
 
-  lines_gap = ((shown_rows + 1) / 2.0) + 0.5 - ceil (shown_rows / 2.0);
-  lines_gap_for_5 = shown_rows == 5 ? lines_gap : 0;
+  /* orientation factors */
+  if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR)
+    {
+      sw = 1;
+      k = 0;
+    }
+  else if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
+    {
+      sw = -1;
+      k = 1;
+    }
 
-  v_block = (height - start_grid_y) / 6.0;
+  priv->clicked_cell = get_cell_and_center_from_position (GCAL_MONTH_VIEW (widget), event->x, event->y, 
NULL, NULL);
 
-  priv->clicked_cell = 7 * (floor ((y - (lines_gap_for_5 * v_block))  / v_block)) + floor (x / (width / 7));
+  j = 7 * ((priv->clicked_cell + 7 * k) / 7) + sw * (priv->clicked_cell % 7) + (1 - k);
 
-  if (priv->clicked_cell < days)
-    {
-      priv->start_mark_cell = priv->clicked_cell;
-    }
+  if (j > priv->days_delay && j <= days)
+    priv->start_mark_cell = priv->clicked_cell;
 
-  g_debug ("pressed cell is: %d", priv->start_mark_cell);
+  g_debug ("clicked is: %d", priv->clicked_cell);
+  g_debug ("pressed is: %d", priv->start_mark_cell);
 
   return TRUE;
 }
@@ -803,18 +849,11 @@ gcal_month_view_motion_notify_event (GtkWidget      *widget,
                                      GdkEventMotion *event)
 {
   GcalMonthViewPrivate *priv;
-  gint width, height;
-  gint y;
-  gdouble start_grid_y;
-
-  gdouble days;
-  gint shown_rows;
 
-  gdouble lines_gap;
-  gdouble lines_gap_for_5;
-
-  gdouble v_block;
+  gint days;
 
+  gint j;
+  gint sw, k;
   gint new_end_cell;
 
   priv = gcal_month_view_get_instance_private (GCAL_MONTH_VIEW (widget));
@@ -823,35 +862,32 @@ gcal_month_view_motion_notify_event (GtkWidget      *widget,
       priv->clicked_cell == -1)
     return FALSE;
 
-  width = gtk_widget_get_allocated_width (widget);
-  height = gtk_widget_get_allocated_height (widget);
-  start_grid_y = gcal_month_view_get_start_grid_y (widget);
-
-  y = event->y - start_grid_y;
-  if (y < 0)
-    return FALSE;
-
   days = priv->days_delay + icaltime_days_in_month (priv->date->month, priv->date->year);
-  shown_rows = ceil (days / 7.0);
-
-  lines_gap = ((shown_rows + 1) / 2.0) + 0.5 - ceil (shown_rows / 2.0);
-  lines_gap_for_5 = shown_rows == 5 ? lines_gap : 0;
 
-  v_block = (height - start_grid_y) / 6.0;
-
-  /* caching value */
-  new_end_cell = 7 * (floor ((y - (lines_gap_for_5 * v_block))  / v_block)) + floor (event->x / (width / 7));
-  if (priv->end_mark_cell != new_end_cell)
+  /* orientation factors */
+  if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR)
     {
-      gtk_widget_queue_draw (widget);
+      sw = 1;
+      k = 0;
+    }
+  else if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
+    {
+      sw = -1;
+      k = 1;
     }
 
-  priv->end_mark_cell = new_end_cell;
+  new_end_cell = get_cell_and_center_from_position (GCAL_MONTH_VIEW (widget), event->x, event->y, NULL, 
NULL);
+
+  j = 7 * ((new_end_cell + 7 * k) / 7) + sw * (new_end_cell % 7) + (1 - k);
 
-  g_debug ("move_notify: %d, %d, %d",
-           priv->start_mark_cell,
-           priv->end_mark_cell,
-           new_end_cell);
+  if (j > priv->days_delay && j <= days)
+    {
+      if (priv->end_mark_cell != new_end_cell)
+        gtk_widget_queue_draw (widget);
+
+      g_debug ("move_notify: %d, %d, %d", priv->start_mark_cell, priv->end_mark_cell, new_end_cell);
+      priv->end_mark_cell = new_end_cell;
+    }
 
   return TRUE;
 }
@@ -861,19 +897,14 @@ gcal_month_view_button_release (GtkWidget      *widget,
                                 GdkEventButton *event)
 {
   GcalMonthViewPrivate *priv;
-  gdouble x, y;
-  gint width, height;
-  gdouble start_grid_y;
-  gint released;
 
-  gdouble days;
-  gint shown_rows;
+  gint days;
 
-  gdouble lines_gap;
-  gdouble lines_gap_for_5;
-  gint february_gap;
+  gint j;
+  gint sw, k;
+  gint released;
 
-  gdouble v_block;
+  gdouble x,y;
 
   icaltimetype *start_date;
   icaltimetype *end_date;
@@ -883,31 +914,25 @@ gcal_month_view_button_release (GtkWidget      *widget,
   if (priv->clicked_cell == -1)
     return FALSE;
 
-  x = event->x;
-  y = event->y;
-
-  width = gtk_widget_get_allocated_width (widget);
-  height = gtk_widget_get_allocated_height (widget);
-  start_grid_y = gcal_month_view_get_start_grid_y (widget);
-
-  y = y - start_grid_y;
-
-  days = priv->days_delay + icaltime_days_in_month (priv->date->month,
-                                                    priv->date->year);
-  shown_rows = ceil (days / 7.0);
+  days = priv->days_delay + icaltime_days_in_month (priv->date->month, priv->date->year);
 
-  lines_gap = ((shown_rows + 1) / 2.0) + 0.5 - ceil (shown_rows / 2.0);
-  lines_gap_for_5 = shown_rows == 5 ? lines_gap : 0;
-  february_gap = shown_rows == 4 ? 1 : 0;
+  /* orientation factors */
+  if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR)
+    {
+      sw = 1;
+      k = 0;
+    }
+  else if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
+    {
+      sw = -1;
+      k = 1;
+    }
 
-  v_block = (height - start_grid_y) / 6.0;
+  released = get_cell_and_center_from_position (GCAL_MONTH_VIEW (widget), event->x, event->y, &x, &y);
 
-  released = 7 * (floor ((y - (lines_gap_for_5 * v_block))  / v_block)) +
-             floor (event->x / (width / 7));
+  j = 7 * ((released + 7 * k) / 7) + sw * (released % 7) + (1 - k);
 
-  /* whether the event is out of the days of the month */
-  if (released < priv->days_delay + 7 * february_gap ||
-      released >= days)
+  if (j <= priv->days_delay || j > days)
     {
       priv->clicked_cell = -1;
       priv->start_mark_cell = -1;
@@ -922,34 +947,28 @@ gcal_month_view_button_release (GtkWidget      *widget,
 
   gtk_widget_queue_draw (widget);
 
-  x = (width / 7) * ((priv->end_mark_cell % 7) + 0.5);
-  y = start_grid_y + v_block * (lines_gap_for_5 + (priv->end_mark_cell / 7) + 0.5);
-
   start_date = gcal_dup_icaltime (priv->date);
-  start_date->day = priv->start_mark_cell - (priv->days_delay + 7 * february_gap) + 1;
+  start_date->day = 7 * ((priv->start_mark_cell + 7 * k) / 7) + sw * (priv->start_mark_cell % 7) + (1 - k);
+  start_date->day -= priv->days_delay;
   start_date->is_date = 1;
 
   end_date = NULL;
   if (priv->start_mark_cell != priv->end_mark_cell)
     {
       end_date = gcal_dup_icaltime (priv->date);
-      end_date->day = priv->end_mark_cell - (priv->days_delay + 7 * february_gap) + 1;
+      end_date->day = j - priv->days_delay;
       end_date->is_date = 1;
     }
 
-  if (priv->start_mark_cell > priv->end_mark_cell)
+  if (start_date->day > end_date->day)
     {
-      start_date->day = priv->end_mark_cell - (priv->days_delay + 7 * february_gap) + 1;
-      end_date->day = priv->start_mark_cell - (priv->days_delay + 7 * february_gap) + 1;
+      gint day;
+      day = start_date->day;
+      start_date->day = end_date->day;
+      end_date->day = day;
     }
 
-  g_debug ("[view] will emit signal on: %f, %f, with %s",
-           x, y, icaltime_as_ical_string (*start_date));
-
-  g_signal_emit_by_name (GCAL_VIEW (widget),
-                         "create-event",
-                         start_date, end_date,
-                         x, y);
+  g_signal_emit_by_name (GCAL_VIEW (widget), "create-event", start_date, end_date, x, y);
 
   g_free (start_date);
 


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