[gnome-calendar] gcal-day-view: added #GtkContainer:add implementation



commit 32cd17c8e8140b32bccf54636fba395af627e634
Author: Erick Pérez Castellanos <erick red gmail com>
Date:   Wed Jun 12 12:39:37 2013 -0400

    gcal-day-view: added #GtkContainer:add implementation
    
    gcal-days-grid: added #GtkWidget:size-allocate implementation
    
    These implementations are initial approaches, there's a lot
    fo FIXME around the code with some fixes still needed.

 src/gcal-day-view.c  |   71 ++++++++++++++---
 src/gcal-days-grid.c |  219 +++++++++++++++++++++++++++++++++++++++-----------
 src/gcal-days-grid.h |    3 +-
 3 files changed, 235 insertions(+), 58 deletions(-)
---
diff --git a/src/gcal-day-view.c b/src/gcal-day-view.c
index 3f82bac..745fdb6 100644
--- a/src/gcal-day-view.c
+++ b/src/gcal-day-view.c
@@ -19,12 +19,12 @@
  */
 
 #include "gcal-day-view.h"
-#include "gcal-view.h"
 #include "gcal-all-day-grid.h"
 #include "gcal-days-grid.h"
 #include "gcal-viewport.h"
 #include "gcal-utils.h"
 #include "gcal-view.h"
+#include "gcal-event-widget.h"
 
 #include <glib/gi18n.h>
 
@@ -64,6 +64,9 @@ static void           gcal_day_view_get_property          (GObject        *objec
                                                            GValue         *value,
                                                            GParamSpec     *pspec);
 
+static void           gcal_day_view_add                   (GtkContainer   *container,
+                                                           GtkWidget      *widget);
+
 static void           gcal_day_view_set_date              (GcalDayView    *view,
                                                            icaltimetype   *date);
 
@@ -90,15 +93,8 @@ G_DEFINE_TYPE_WITH_CODE (GcalDayView,
 static void
 gcal_day_view_class_init (GcalDayViewClass *klass)
 {
-  /* FIXME: Uncomment stuff here */
-  /* GtkContainerClass *container_class; */
   GObjectClass *object_class;
-
-  /* container_class = GTK_CONTAINER_CLASS (klass); */
-  /* container_class->add   = gcal_day_view_add; */
-  /* container_class->remove = gcal_day_view_remove; */
-  /* container_class->forall = gcal_day_view_forall; */
-  /* gtk_container_class_handle_border_width (container_class); */
+  GtkContainerClass *container_class;
 
   object_class = G_OBJECT_CLASS (klass);
   object_class->constructed = gcal_day_view_constructed;
@@ -106,6 +102,13 @@ gcal_day_view_class_init (GcalDayViewClass *klass)
   object_class->set_property = gcal_day_view_set_property;
   object_class->get_property = gcal_day_view_get_property;
 
+  container_class = GTK_CONTAINER_CLASS (klass);
+  container_class->add = gcal_day_view_add;
+  /* FIXME: Uncomment stuff here */
+  /* container_class->remove = gcal_day_view_remove; */
+  /* container_class->forall = gcal_day_view_forall; */
+  /* gtk_container_class_handle_border_width (container_class); */
+
   g_object_class_override_property (object_class, PROP_DATE, "active-date");
 
   g_type_class_add_private ((gpointer)klass, sizeof (GcalDayViewPrivate));
@@ -143,9 +146,7 @@ gcal_day_view_constructed (GObject *object)
 {
   GcalDayViewPrivate *priv;
 
-  /* FIXME: debug code */
   GtkWidget *sw; /* involve overlay in it */
-  GdkRGBA color;
 
   g_return_if_fail (GCAL_IS_DAY_VIEW (object));
   priv = GCAL_DAY_VIEW (object)->priv;
@@ -249,6 +250,54 @@ gcal_day_view_get_property (GObject       *object,
     }
 }
 
+/* GtkContainer API */
+static void
+gcal_day_view_add (GtkContainer *container,
+                   GtkWidget    *widget)
+{
+  GcalDayViewPrivate *priv;
+  icaltimetype *dt_start;
+  icaltimetype *dt_end;
+  gchar* summ;
+
+  g_return_if_fail (GCAL_IS_EVENT_WIDGET (widget));
+  g_return_if_fail (gtk_widget_get_parent (widget) == NULL);
+  priv = GCAL_DAY_VIEW (container)->priv;
+
+  summ = gcal_event_widget_get_summary (GCAL_EVENT_WIDGET (widget));
+  dt_start = gcal_event_widget_get_date (GCAL_EVENT_WIDGET (widget));
+  dt_end = gcal_event_widget_get_end_date (GCAL_EVENT_WIDGET (widget));
+  /* FIXME: recheck conditions to add, what, where */
+  /* Maybe, should be good to add, inside days views only contained events */
+  if (gcal_event_widget_get_all_day (GCAL_EVENT_WIDGET (widget)))
+    {
+      g_debug ("[all-day-grid] %s from %s to %s",
+               summ,
+               icaltime_as_ical_string (*dt_start),
+               icaltime_as_ical_string (*dt_end));
+      gcal_all_day_grid_place (GCAL_ALL_DAY_GRID (priv->all_day_grid),
+                               widget,
+                               priv->date->day == dt_start->day ? 0 : 1);
+    }
+  else
+    {
+      g_debug ("[days-grid] %s from %s to %s",
+               summ,
+               icaltime_as_ical_string (*dt_start),
+               icaltime_as_ical_string (*dt_end));
+      gcal_days_grid_place (GCAL_DAYS_GRID (priv->day_grid),
+                            widget,
+                            priv->date->day == dt_start->day ? 0 : 1,
+                            dt_start->hour * 2 + (dt_start->minute / 30),
+                            dt_end->hour * 2 + (dt_end->minute / 30)); /* FIXME Include half hour and length 
*/
+    }
+
+  g_free (dt_start);
+  g_free (dt_end);
+  g_free (summ);
+}
+
+
 static void
 gcal_day_view_set_date (GcalDayView  *view,
                         icaltimetype *date)
diff --git a/src/gcal-days-grid.c b/src/gcal-days-grid.c
index bdd041b..6cb3934 100644
--- a/src/gcal-days-grid.c
+++ b/src/gcal-days-grid.c
@@ -24,6 +24,15 @@
 #include <glib/gi18n.h>
 
 #include <string.h>
+#include <math.h>
+
+/*
+ * Notes:
+ * 1. the widget's height is divided between 48 cells
+ *    representing each a half-hour of the day.
+ *    the preferred value of the cell is kept is req_cell_heigth
+ *    private field.
+ */
 
 static const double dashed [] =
 {
@@ -43,7 +52,10 @@ struct _ChildInfo
 {
   GtkWidget *widget;
 
-  guint      cell;
+  guint      start_cell;
+  guint      end_cell;
+  guint      sub_column;
+
   gboolean   hidden;
 };
 
@@ -64,6 +76,10 @@ struct _GcalDaysGridPrivate
   GdkWindow      *event_window;
 };
 
+/* Helpers and private */
+static gint           compare_child_info                   (gconstpointer   a,
+                                                            gconstpointer   b);
+
 static void           gcal_days_grid_finalize              (GObject        *object);
 
 static void           gcal_days_grid_set_property          (GObject        *object,
@@ -115,8 +131,26 @@ static void           gcal_days_grid_forall                (GtkContainer    *con
                                                             GtkCallback      callback,
                                                             gpointer         callback_data);
 
+
 G_DEFINE_TYPE (GcalDaysGrid,gcal_days_grid, GTK_TYPE_CONTAINER);
 
+/* Helpers and private */
+static gint
+compare_child_info (gconstpointer a,
+                    gconstpointer b)
+{
+  ChildInfo *ac = (ChildInfo*) a;
+  ChildInfo *bc = (ChildInfo*) b;
+
+  if (ac->start_cell < bc->start_cell)
+    return -1;
+  else if (ac->start_cell == bc->start_cell)
+    return 0;
+  else
+    return 1;
+}
+
+
 static void
 gcal_days_grid_class_init (GcalDaysGridClass *klass)
 {
@@ -449,13 +483,106 @@ static void
 gcal_days_grid_size_allocate (GtkWidget     *widget,
                               GtkAllocation *allocation)
 {
-  /* GcalDaysGridPrivate *priv; */
+  GcalDaysGridPrivate *priv;
+
+  GtkBorder padding;
+  gint width;
+  gint height;
+  gint width_block;
+  gint height_block;
 
-  /* priv = GCAL_DAYS_GRID (widget)->priv; */
+  GList *columns;
+  gint idx;
+
+  priv = GCAL_DAYS_GRID (widget)->priv;
   gtk_widget_set_allocation (widget, allocation);
 
-  /* FIXME: Todo, write later,
-   maybe write through delegation */
+  /* Placing the event_window */
+  if (gtk_widget_get_realized (widget))
+    {
+      gdk_window_move_resize (priv->event_window,
+                              allocation->x,
+                              allocation->y,
+                              allocation->width,
+                              allocation->height);
+    }
+
+  gtk_style_context_get_padding (gtk_widget_get_style_context (widget),
+                                 gtk_widget_get_state_flags (widget),
+                                 &padding);
+
+  width = allocation->width - (padding.left + padding.right) - priv->scale_width;
+  width_block = width / priv->columns_nr;
+  height = allocation->height - (padding.top + padding.bottom);
+  height_block = height / 48;
+
+  /* detecting columns and allocs */
+  for (columns = priv->children, idx = 0;
+       columns != NULL;
+       columns = g_list_next (columns), ++idx)
+    {
+      GtkAllocation child_allocation;
+      GArray *last_y;
+      GList* column = (GList*) columns->data;
+
+      /* last_y value for each column,
+         will keep the amount of columns as well */
+      last_y = g_array_new (FALSE, FALSE, sizeof (guint));
+
+      /* going through widgets */
+      for (;column != NULL; column = g_list_next (column))
+        {
+          ChildInfo *info;
+          gboolean new_column = TRUE;
+          gint i;
+
+          info = (ChildInfo*) column->data;
+
+          for (i = 0; i < last_y->len; ++i)
+            {
+              /* start before */
+              if (info->start_cell > g_array_index (last_y, guint, i))
+                {
+                  info->sub_column = i;
+                  new_column = FALSE;
+                  break;
+                }
+            }
+
+          if (new_column)
+            {
+              /* adding column to array */
+              g_array_append_val (last_y, info->end_cell);
+              info->sub_column = last_y->len - 1;
+            }
+          else
+            {
+              g_array_index (last_y, guint, info->sub_column) = info->end_cell;
+            }
+        }
+
+      /* allocating */
+      for (column = (GList*) columns->data;
+           column != NULL;
+           column = g_list_next (column))
+        {
+          ChildInfo *info;
+          guint sub_column_block;
+
+          info = (ChildInfo*) column->data;
+          sub_column_block = width_block / last_y->len;
+
+          child_allocation.x = allocation->x + priv->scale_width + padding.left +
+            idx * width_block + sub_column_block * info->sub_column;
+          child_allocation.y = info->start_cell * height_block;
+          child_allocation.width = sub_column_block;
+          child_allocation.height = (info->end_cell - info->start_cell) * height_block;
+
+          gtk_widget_size_allocate (info->widget, &child_allocation);
+        }
+
+      g_array_free (last_y, TRUE);
+    }
 }
 
 static gboolean
@@ -599,12 +726,15 @@ gcal_days_grid_button_release_event (GtkWidget      *widget,
 }
 
 /* GtkContainer API */
-/*
+/**
  * gcal_days_grid_add:
+ * @container:
+ * @widget:
  *
  * @gtk_container_add implementation. It assumes the widget will go
  * to the first column. If there's no column set, will set columns to 1
- */
+ *
+ **/
 static void
 gcal_days_grid_add (GtkContainer *container,
                     GtkWidget    *widget)
@@ -616,7 +746,7 @@ gcal_days_grid_add (GtkContainer *container,
 
   gcal_days_grid_place (GCAL_DAYS_GRID (container),
                         widget,
-                        0, 0);
+                        0, 0, 0);
 }
 
 static void
@@ -629,30 +759,27 @@ gcal_days_grid_remove (GtkContainer *container,
 
   priv = GCAL_DAYS_GRID (container)->priv;
 
-  if (priv->children != NULL)
+  for (columns = priv->children;
+       columns != NULL;
+       columns = g_list_next (columns))
     {
-      for (columns = priv->children;
-           columns != NULL;
-           columns = g_list_next (columns))
+      GList* column = (GList*) columns->data;
+      for (;column != NULL; column = g_list_next (column))
         {
-          GList* column = (GList*) columns->data;
-          for (;column != NULL; column = g_list_next (column))
+          ChildInfo *info = (ChildInfo*) column->data;
+          if (widget == info->widget)
             {
-              ChildInfo *info = (ChildInfo*) column->data;
-              if (widget == info->widget)
-                {
-                  GList* orig = (GList*) columns->data;
-                  orig = g_list_delete_link (orig, column);
+              GList* orig = (GList*) columns->data;
+              orig = g_list_delete_link (orig, column);
 
-                  g_free (info);
+              g_free (info);
 
-                  gtk_widget_unparent (widget);
+              gtk_widget_unparent (widget);
 
-                  columns->data = orig;
+              columns->data = orig;
 
-                  columns = NULL;
-                  break;
-                }
+              columns = NULL;
+              break;
             }
         }
     }
@@ -670,24 +797,20 @@ gcal_days_grid_forall (GtkContainer *container,
 
   priv = GCAL_DAYS_GRID (container)->priv;
 
-  if (priv->children != NULL)
+  columns = priv->children;
+  while (columns)
     {
-      columns = priv->children;
-
-      while (columns)
-        {
-          GList *column;
+      GList *column;
 
-          column = columns->data;
-          columns = columns->next;
+      column = columns->data;
+      columns = columns->next;
 
-          while (column)
-            {
-              ChildInfo *info = (ChildInfo*) column->data;
-              column  = column->next;
+      while (column)
+        {
+          ChildInfo *info = (ChildInfo*) column->data;
+          column  = column->next;
 
-              (* callback) (info->widget, callback_data);
-            }
+          (* callback) (info->widget, callback_data);
         }
     }
 }
@@ -753,10 +876,11 @@ gcal_days_grid_get_scale_width (GcalDaysGrid *days_grid)
 
 /**
  * gcal_days_grid_place:
- * @all_day: A #GcalDaysGrid widget
- * @widget: The child widget to add
- * @column_idx: The index of the column, starting with zero
- * @cell_idx: The cell, refering the month, starting with zero
+ * @all_day: a #GcalDaysGrid widget
+ * @widget: the child widget to add
+ * @column_idx: the index of the column, starting with zero
+ * @start_cell: the start-cell, refering the hour, starting with zero
+ * @end_cell: the end-cell, refering the hour, starting with zero
  *
  * Adding a widget to a specified column. If the column index
  * is bigger than the #GcalDaysGrid:columns property set,
@@ -766,7 +890,8 @@ void
 gcal_days_grid_place (GcalDaysGrid *all_day,
                       GtkWidget    *widget,
                       guint         column_idx,
-                      guint         cell_idx)
+                      guint         start_cell,
+                      guint         end_cell)
 {
   GcalDaysGridPrivate *priv;
   GList* children_link;
@@ -783,8 +908,10 @@ gcal_days_grid_place (GcalDaysGrid *all_day,
   info = g_new0 (ChildInfo, 1);
   info->widget = widget;
   info->hidden = FALSE;
-  info->cell = cell_idx;
-  children_link->data = g_list_append (column, info);
+  info->start_cell = start_cell;
+  info->end_cell = end_cell;
+  info->sub_column = 0;
+  children_link->data = g_list_insert_sorted (column, info, compare_child_info);
 
   gtk_widget_set_parent (widget, GTK_WIDGET (all_day));
 }
diff --git a/src/gcal-days-grid.h b/src/gcal-days-grid.h
index 78045c8..d7cb89e 100644
--- a/src/gcal-days-grid.h
+++ b/src/gcal-days-grid.h
@@ -60,7 +60,8 @@ guint          gcal_days_grid_get_scale_width           (GcalDaysGrid   *days_gr
 void           gcal_days_grid_place                     (GcalDaysGrid   *days_grid,
                                                         GtkWidget      *widget,
                                                         guint           column_idx,
-                                                        guint           cell_idx);
+                                                        guint           start_cell,
+                                                        guint           end_cell);
 
 GtkWidget*     gcal_days_grid_get_by_uuid               (GcalDaysGrid   *days_grid,
                                                         const gchar    *uuid);


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