[gnome-calendar/ui-rewrite] gcal-days-grid: added marks related code



commit fed9b847e2662c3df56fb9fc2e9b455c3ba2effe
Author: Erick Pérez Castellanos <erick red gmail com>
Date:   Sat Jul 6 18:08:29 2013 -0400

    gcal-days-grid: added marks related code
    
    GcalDaysGrid emit signal when marked in order to communicate with
    GcalDayView container.

 src/gcal-days-grid.c |  248 +++++++++++++++++++++++++++++++++++++++++++++++++-
 src/gcal-days-grid.h |   14 +++
 2 files changed, 258 insertions(+), 4 deletions(-)
---
diff --git a/src/gcal-days-grid.c b/src/gcal-days-grid.c
index 3e07ec5..811f11a 100644
--- a/src/gcal-days-grid.c
+++ b/src/gcal-days-grid.c
@@ -73,8 +73,22 @@ typedef struct
   GList          *children;
 
   GdkWindow      *event_window;
+
+  /* button_down/up flags */
+  gint            clicked_cell;
+  gint            start_mark_cell;
+  gint            end_mark_cell;
+
 } GcalDaysGridPrivate;
 
+enum
+{
+  MARKED,
+  NUM_SIGNALS
+};
+
+static guint signals[NUM_SIGNALS] = { 0, };
+
 /* Helpers and private */
 static gint           compare_child_info                   (gconstpointer   a,
                                                             gconstpointer   b);
@@ -116,6 +130,9 @@ static gboolean       gcal_days_grid_draw                  (GtkWidget      *widg
 static gboolean       gcal_days_grid_button_press_event    (GtkWidget      *widget,
                                                             GdkEventButton *event);
 
+static gboolean       gcal_days_grid_motion_notify_event   (GtkWidget      *widget,
+                                                            GdkEventMotion *event);
+
 static gboolean       gcal_days_grid_button_release_event  (GtkWidget      *widget,
                                                             GdkEventButton *event);
 
@@ -172,6 +189,7 @@ gcal_days_grid_class_init (GcalDaysGridClass *klass)
   widget_class->size_allocate = gcal_days_grid_size_allocate;
   widget_class->draw = gcal_days_grid_draw;
   widget_class->button_press_event = gcal_days_grid_button_press_event;
+  widget_class->motion_notify_event = gcal_days_grid_motion_notify_event;
   widget_class->button_release_event = gcal_days_grid_button_release_event;
 
   container_class = GTK_CONTAINER_CLASS (klass);
@@ -201,6 +219,18 @@ gcal_days_grid_class_init (GcalDaysGridClass *klass)
                             FALSE,
                             G_PARAM_CONSTRUCT |
                             G_PARAM_READWRITE));
+
+  /* to comunicate to it's parent view the marking */
+  signals[MARKED] = g_signal_new ("marked",
+                                  GCAL_TYPE_DAYS_GRID,
+                                  G_SIGNAL_RUN_LAST,
+                                  G_STRUCT_OFFSET (GcalDaysGridClass,
+                                                   marked),
+                                  NULL, NULL, NULL,
+                                  G_TYPE_NONE,
+                                  2,
+                                  G_TYPE_UINT,
+                                  G_TYPE_UINT);
 }
 
 
@@ -217,6 +247,11 @@ gcal_days_grid_init (GcalDaysGrid *self)
   priv->req_cell_height = 0;
 
   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");
@@ -577,6 +612,7 @@ gcal_days_grid_draw (GtkWidget *widget,
   gint width;
 
   GdkRGBA ligther_color;
+  GdkRGBA background_selected_color;
   GdkRGBA font_color;
 
   PangoLayout *layout;
@@ -604,6 +640,11 @@ gcal_days_grid_draw (GtkWidget *widget,
       gtk_widget_get_state_flags (widget) | GTK_STATE_FLAG_INSENSITIVE,
       &ligther_color);
 
+  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);
+
   gtk_style_context_get (
       gtk_widget_get_style_context (widget),
       gtk_widget_get_state_flags (widget),
@@ -641,6 +682,51 @@ gcal_days_grid_draw (GtkWidget *widget,
       g_free (hours);
     }
 
+  /* drawing new-event mark */
+  if (priv->start_mark_cell != -1 &&
+      priv->end_mark_cell != -1)
+    {
+      gint first_cell;
+      gint last_cell;
+      gint columns;
+
+      cairo_save (cr);
+      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_set_source_rgba (cr,
+                             background_selected_color.red,
+                             background_selected_color.green,
+                             background_selected_color.blue,
+                             background_selected_color.alpha);
+
+      for (columns = 0; columns < last_cell / 48 - first_cell / 48 + 1; columns++)
+        {
+          gint first_point;
+          gint last_point;
+
+          first_point = (columns == 0) ? first_cell : ((first_cell / 48) + columns) * 48;
+          last_point = (columns == (last_cell / 48 - first_cell / 48)) ? last_cell : ((first_cell / 48) + 
columns) * 48 + 47;
+
+          cairo_rectangle (cr,
+                           priv->scale_width + (width / priv->columns_nr) * (first_point / 48),
+                           (first_point % 48) * (alloc.height / 48),
+                           (width / priv->columns_nr),
+                           (last_point - first_point + 1) * (alloc.height / 48));
+          cairo_fill (cr);
+
+        }
+      cairo_restore (cr);
+    }
+
   /* drawing lines */
   cairo_set_source_rgb (cr,
                         ligther_color.red,
@@ -692,16 +778,113 @@ static gboolean
 gcal_days_grid_button_press_event (GtkWidget      *widget,
                                    GdkEventButton *event)
 {
-  g_debug ("Button pressed on days-grid area");
-  return FALSE;
+  GcalDaysGridPrivate *priv;
+
+  GtkBorder padding;
+  GtkAllocation alloc;
+  gint width_block;
+  gint height_block;
+  gint left_pad;
+
+  priv = gcal_days_grid_get_instance_private (GCAL_DAYS_GRID (widget));
+
+  gtk_style_context_get_padding (
+      gtk_widget_get_style_context (widget),
+      gtk_widget_get_state_flags (widget),
+      &padding);
+  left_pad = padding.left + padding.right + priv->scale_width;
+
+  /* XXX: an improvement will be to scroll to that position on click */
+  if (event->x < left_pad)
+    return FALSE;
+
+  gtk_widget_get_allocation (widget, &alloc);
+  width_block = (alloc.width - left_pad) / priv->columns_nr;
+  height_block = (alloc.height - (padding.top + padding.bottom)) / 48;
+
+  priv->clicked_cell = 48 * (((gint) event->x - left_pad) / width_block) + event->y / height_block;
+  priv->start_mark_cell = priv->clicked_cell;
+
+  return TRUE;
+}
+
+static gboolean
+gcal_days_grid_motion_notify_event (GtkWidget      *widget,
+                                    GdkEventMotion *event)
+{
+  GcalDaysGridPrivate *priv;
+
+  GtkBorder padding;
+  GtkAllocation alloc;
+  gint width_block;
+  gint height_block;
+  gint left_pad;
+
+  priv = gcal_days_grid_get_instance_private (GCAL_DAYS_GRID (widget));
+
+  if (priv->clicked_cell == -1)
+    return FALSE;
+
+  gtk_style_context_get_padding (
+      gtk_widget_get_style_context (widget),
+      gtk_widget_get_state_flags (widget),
+      &padding);
+  left_pad = padding.left + padding.right + priv->scale_width;
+
+  gtk_widget_get_allocation (widget, &alloc);
+  width_block = (alloc.width - left_pad) / priv->columns_nr;
+  height_block = (alloc.height - (padding.top + padding.bottom)) / 48;
+
+
+  priv->end_mark_cell = 48 * (((gint) event->x - left_pad) / width_block) + event->y / height_block;
+
+  gtk_widget_queue_draw (widget);
+  return TRUE;
 }
 
 static gboolean
 gcal_days_grid_button_release_event (GtkWidget      *widget,
                                      GdkEventButton *event)
 {
-  g_debug ("Button released on days-grid area");
-  return FALSE;
+  GcalDaysGridPrivate *priv;
+
+  GtkBorder padding;
+  GtkAllocation alloc;
+  gint width_block;
+  gint height_block;
+  gint left_pad;
+
+  priv = gcal_days_grid_get_instance_private (GCAL_DAYS_GRID (widget));
+
+  if (priv->clicked_cell == -1)
+    return FALSE;
+
+  gtk_style_context_get_padding (
+      gtk_widget_get_style_context (widget),
+      gtk_widget_get_state_flags (widget),
+      &padding);
+  left_pad = padding.left + padding.right + priv->scale_width;
+  if (event->x < left_pad)
+    {
+      priv->start_mark_cell = -1;
+      priv->end_mark_cell = -1;
+      return FALSE;
+    }
+
+  gtk_widget_get_allocation (widget, &alloc);
+  width_block = (alloc.width - left_pad) / priv->columns_nr;
+  height_block = (alloc.height - (padding.top + padding.bottom)) / 48;
+
+  priv->end_mark_cell = 48 * (((gint) event->x - left_pad) / width_block) + event->y / height_block;
+
+  gtk_widget_queue_draw (widget);
+
+  g_signal_emit (GCAL_DAYS_GRID (widget),
+                 signals[MARKED], 0,
+                 priv->start_mark_cell, priv->end_mark_cell);
+
+  priv->clicked_cell = -1;
+  return TRUE;
 }
 
 /* GtkContainer API */
@@ -939,3 +1122,60 @@ gcal_days_grid_get_by_uuid (GcalDaysGrid *days_grid,
 
   return NULL;
 }
+
+void
+gcal_days_grid_clear_marks (GcalDaysGrid *days_grid)
+{
+  GcalDaysGridPrivate *priv;
+
+  priv = gcal_days_grid_get_instance_private (days_grid);
+
+  priv->start_mark_cell = -1;
+  priv->end_mark_cell = -1;
+  gtk_widget_queue_draw (GTK_WIDGET (days_grid));
+}
+
+void
+gcal_days_grid_mark_cell (GcalDaysGrid *days_grid,
+                          guint         cell)
+{
+  GcalDaysGridPrivate *priv;
+
+  priv = gcal_days_grid_get_instance_private (days_grid);
+
+  priv->start_mark_cell = cell;
+  priv->end_mark_cell = cell;
+  gtk_widget_queue_draw (GTK_WIDGET (days_grid));
+}
+
+void
+gcal_days_grid_get_cell_position (GcalDaysGrid *days_grid,
+                                  guint         cell,
+                                  gint         *x,
+                                  gint         *y)
+{
+  GcalDaysGridPrivate *priv;
+
+  GtkWidget *widget;
+  GtkBorder padding;
+  GtkAllocation alloc;
+  gint width;
+  gint height;
+  gint left_pad;
+
+  priv = gcal_days_grid_get_instance_private (days_grid);
+  widget = GTK_WIDGET (days_grid);
+
+  gtk_style_context_get_padding (
+      gtk_widget_get_style_context (widget),
+      gtk_widget_get_state_flags (widget),
+      &padding);
+  left_pad = padding.left + padding.right + priv->scale_width;
+
+  gtk_widget_get_allocation (widget, &alloc);
+  width = alloc.width - left_pad;
+  height = alloc.height - (padding.top + padding.bottom);
+
+  *x = (gint) left_pad + (width / priv->columns_nr) * (cell / 48 + 0.5);
+  *y = (gint) (height / 48) * ((cell % 48) + 0.5);
+}
diff --git a/src/gcal-days-grid.h b/src/gcal-days-grid.h
index 712d8ea..bd3b256 100644
--- a/src/gcal-days-grid.h
+++ b/src/gcal-days-grid.h
@@ -42,6 +42,9 @@ struct _GcalDaysGrid
 struct _GcalDaysGridClass
 {
   GtkContainerClass parent_class;
+
+  /* signals */
+  void (*marked) (guint start_cell, guint end_cell);
 };
 
 GType          gcal_days_grid_get_type                  (void);
@@ -59,9 +62,20 @@ void           gcal_days_grid_place                     (GcalDaysGrid   *days_gr
                                                         guint           start_cell,
                                                         guint           end_cell);
 
+/* GcalView API helpers */
 GtkWidget*     gcal_days_grid_get_by_uuid               (GcalDaysGrid   *days_grid,
                                                         const gchar    *uuid);
 
+void           gcal_days_grid_clear_marks               (GcalDaysGrid   *days_grid);
+
+void           gcal_days_grid_mark_cell                 (GcalDaysGrid   *days_grid,
+                                                        guint           cell);
+
+void           gcal_days_grid_get_cell_position         (GcalDaysGrid   *days_grid,
+                                                        guint           cell,
+                                                        gint           *x,
+                                                        gint           *y);
+
 G_END_DECLS
 
 #endif /* __GCAL_DAYS_GRID_H__ */


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