[gnome-calendar/ui-rewrite] gcal-all-day-grid: make it reactive



commit eed541b1f8ef93c9e5f668f763cbbbbf4422d078
Author: Erick Pérez Castellanos <erick red gmail com>
Date:   Sat Jul 27 19:05:17 2013 -0400

    gcal-all-day-grid: make it reactive
    
    Added button press/release/motion handlers.
    Added signaling mechanism to communicate to its
    parent about the marked cells

 src/gcal-all-day-grid.c |  159 +++++++++++++++++++++++++++++++++++++++++++++-
 src/gcal-all-day-grid.h |    6 ++
 2 files changed, 161 insertions(+), 4 deletions(-)
---
diff --git a/src/gcal-all-day-grid.c b/src/gcal-all-day-grid.c
index d63cc92..f11b6f1 100644
--- a/src/gcal-all-day-grid.c
+++ b/src/gcal-all-day-grid.c
@@ -47,8 +47,23 @@ typedef struct
   GList          *children;
 
   GdkWindow      *event_window;
+
+  /* button_down/up flags */
+  gint            clicked_cell;
+  gint            start_mark_cell;
+  gint            end_mark_cell;
+
 } GcalAllDayGridPrivate;
 
+enum
+{
+  MARKED,
+  NUM_SIGNALS
+};
+
+static guint signals[NUM_SIGNALS] = { 0, };
+
+/* Helpers and private */
 static void           gcal_all_day_grid_finalize              (GObject         *object);
 
 static void           gcal_all_day_grid_set_property          (GObject         *object,
@@ -86,6 +101,9 @@ static gboolean       gcal_all_day_grid_draw                  (GtkWidget       *
 static gboolean       gcal_all_day_grid_button_press_event    (GtkWidget       *widget,
                                                                GdkEventButton  *event);
 
+static gboolean       gcal_all_day_grid_motion_notify_event   (GtkWidget       *widget,
+                                                               GdkEventMotion  *event);
+
 static gboolean       gcal_all_day_grid_button_release_event  (GtkWidget       *widget,
                                                                GdkEventButton  *event);
 
@@ -124,6 +142,7 @@ gcal_all_day_grid_class_init (GcalAllDayGridClass *klass)
   widget_class->size_allocate = gcal_all_day_grid_size_allocate;
   widget_class->draw = gcal_all_day_grid_draw;
   widget_class->button_press_event = gcal_all_day_grid_button_press_event;
+  widget_class->motion_notify_event = gcal_all_day_grid_motion_notify_event;
   widget_class->button_release_event = gcal_all_day_grid_button_release_event;
 
   container_class = GTK_CONTAINER_CLASS (klass);
@@ -143,6 +162,18 @@ gcal_all_day_grid_class_init (GcalAllDayGridClass *klass)
                          0,
                          G_PARAM_CONSTRUCT_ONLY |
                          G_PARAM_READWRITE));
+
+  /* comunicate to its parent view the marking */
+  signals[MARKED] = g_signal_new ("marked",
+                                  GCAL_TYPE_ALL_DAY_GRID,
+                                  G_SIGNAL_RUN_LAST,
+                                  G_STRUCT_OFFSET (GcalAllDayGridClass,
+                                                   marked),
+                                  NULL, NULL, NULL,
+                                  G_TYPE_NONE,
+                                  2,
+                                  G_TYPE_UINT,
+                                  G_TYPE_UINT);
 }
 
 
@@ -158,6 +189,10 @@ gcal_all_day_grid_init (GcalAllDayGrid *self)
   priv->column_headers = NULL;
   priv->children = NULL;
 
+  priv->clicked_cell = -1;
+  priv->start_mark_cell = -1;
+  priv->end_mark_cell = -1;
+
   gtk_style_context_add_class (
       gtk_widget_get_style_context (GTK_WIDGET (self)),
       "calendar-view");
@@ -559,6 +594,7 @@ gcal_all_day_grid_draw (GtkWidget *widget,
   gint i;
 
   GdkRGBA ligther_color;
+  GdkRGBA background_selected_color;
 
   priv = gcal_all_day_grid_get_instance_private (GCAL_ALL_DAY_GRID (widget));
 
@@ -597,6 +633,43 @@ gcal_all_day_grid_draw (GtkWidget *widget,
       pango_cairo_show_layout (cr, layout);
     }
 
+  /* drawing marked cells */
+  if (priv->start_mark_cell != -1 &&
+      priv->end_mark_cell != -1)
+    {
+      gint first_cell;
+      gint last_cell;
+
+      gtk_style_context_get_background_color (
+          gtk_widget_get_style_context (widget),
+          gtk_widget_get_state_flags (widget) | GTK_STATE_FLAG_SELECTED,
+          &background_selected_color);
+
+      if (priv->start_mark_cell < priv->end_mark_cell)
+        {
+          first_cell = priv->start_mark_cell;
+          last_cell = priv->end_mark_cell;
+        }
+      else
+        {
+          first_cell = priv->end_mark_cell;
+          last_cell = priv->start_mark_cell;
+        }
+
+      cairo_save (cr);
+      cairo_set_source_rgba (cr,
+                             background_selected_color.red,
+                             background_selected_color.green,
+                             background_selected_color.blue,
+                             background_selected_color.alpha);
+
+      cairo_rectangle (cr,
+                       (alloc.width / priv->columns_nr) * first_cell, y_gap,
+                       (alloc.width / priv->columns_nr) * (last_cell + 1), alloc.height - y_gap);
+      cairo_fill (cr);
+      cairo_restore (cr);
+    }
+
   /* drawing lines */
   gtk_style_context_get_color (
       gtk_widget_get_style_context (widget),
@@ -634,16 +707,75 @@ static gboolean
 gcal_all_day_grid_button_press_event (GtkWidget      *widget,
                                       GdkEventButton *event)
 {
-  g_debug ("Button pressed on all-day area");
-  return FALSE;
+  GcalAllDayGridPrivate *priv;
+
+  gint width_block;
+
+  priv = gcal_all_day_grid_get_instance_private (GCAL_ALL_DAY_GRID (widget));
+
+  width_block = gtk_widget_get_allocated_width (widget) / priv->columns_nr;
+
+  priv->clicked_cell = event->x / width_block;
+  priv->start_mark_cell = priv->clicked_cell;
+
+  return TRUE;
+}
+
+static gboolean
+gcal_all_day_grid_motion_notify_event (GtkWidget      *widget,
+                                       GdkEventMotion *event)
+{
+  GcalAllDayGridPrivate *priv;
+
+  gint width_block;
+
+  priv = gcal_all_day_grid_get_instance_private (GCAL_ALL_DAY_GRID (widget));
+
+  if (priv->clicked_cell == -1)
+    return FALSE;
+
+  width_block = gtk_widget_get_allocated_width (widget) / priv->columns_nr;
+  priv->end_mark_cell = event->x / width_block;
+
+  gtk_widget_queue_draw (widget);
+  return TRUE;
 }
 
 static gboolean
 gcal_all_day_grid_button_release_event (GtkWidget      *widget,
                                         GdkEventButton *event)
 {
-  g_debug ("Button released on all-day area");
-  return FALSE;
+  GcalAllDayGridPrivate *priv;
+
+  gint width_block;
+
+  gint cell_temp;
+
+  priv = gcal_all_day_grid_get_instance_private (GCAL_ALL_DAY_GRID (widget));
+
+  if (priv->clicked_cell == -1)
+    return FALSE;
+
+  width_block = gtk_widget_get_allocated_width (widget) / priv->columns_nr;
+
+  priv->end_mark_cell = event->x / width_block;
+
+  gtk_widget_queue_draw (widget);
+
+  priv->clicked_cell = -1;
+
+  if (priv->start_mark_cell > priv->end_mark_cell)
+    {
+      cell_temp = priv->end_mark_cell;
+      priv->end_mark_cell = priv->start_mark_cell;
+      priv->start_mark_cell = cell_temp;
+    }
+
+  g_signal_emit (GCAL_ALL_DAY_GRID (widget),
+                 signals[MARKED], 0,
+                 priv->start_mark_cell, priv->end_mark_cell);
+
+  return TRUE;
 }
 
 /* GtkContainer API */
@@ -859,3 +991,22 @@ gcal_all_day_grid_get_by_uuid (GcalAllDayGrid *all_day,
 
   return NULL;
 }
+
+/**
+ * gcal_all_day_grid_clear_marks:
+ * @all_day: a #GcalAllDayGrid
+ *
+ * Clear the value of the markings and queue a draw to update
+ the widget looking
+ **/
+void
+gcal_all_day_grid_clear_marks (GcalAllDayGrid *all_day)
+{
+  GcalAllDayGridPrivate *priv;
+
+  priv = gcal_all_day_grid_get_instance_private (all_day);
+
+  priv->start_mark_cell = -1;
+  priv->end_mark_cell = -1;
+  gtk_widget_queue_draw (GTK_WIDGET (all_day));
+}
diff --git a/src/gcal-all-day-grid.h b/src/gcal-all-day-grid.h
index e5ae23c..99af796 100644
--- a/src/gcal-all-day-grid.h
+++ b/src/gcal-all-day-grid.h
@@ -42,6 +42,9 @@ struct _GcalAllDayGrid
 struct _GcalAllDayGridClass
 {
   GtkContainerClass parent_class;
+
+  /* signals */
+  void (*marked) (guint start_cell, guint end_cell);
 };
 
 GType          gcal_all_day_grid_get_type            (void);
@@ -58,6 +61,9 @@ void           gcal_all_day_grid_place               (GcalAllDayGrid *all_day,
 
 GtkWidget*     gcal_all_day_grid_get_by_uuid         (GcalAllDayGrid *all_day,
                                                       const gchar    *uuid);
+
+void           gcal_all_day_grid_clear_marks         (GcalAllDayGrid *all_day);
+
 G_END_DECLS
 
 #endif /* __GCAL_ALL_DAY_GRID_H__ */


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