[gnome-calendar/wip/pandusonu/week-view] week-grid: implement event creation



commit 343283e37ad75e561b3704a5a5da5bae49d17878
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Fri Dec 9 14:46:40 2016 -0200

    week-grid: implement event creation

 data/theme/gtk-styles.css  |    4 +
 data/ui/window.ui          |    1 +
 src/views/gcal-week-grid.c |  192 ++++++++++++++++++++++++++++++++++++++++++++
 src/views/gcal-week-grid.h |    2 +
 src/views/gcal-week-view.c |   11 ++-
 5 files changed, 208 insertions(+), 2 deletions(-)
---
diff --git a/data/theme/gtk-styles.css b/data/theme/gtk-styles.css
index 1cee172..c33ed85 100644
--- a/data/theme/gtk-styles.css
+++ b/data/theme/gtk-styles.css
@@ -421,3 +421,7 @@ weekgrid.now-strip {
     margin: 0 0 0 1px;
     min-height: 2px;
 }
+
+weekgrid:selected {
+    background-color: alpha(@theme_selected_bg_color, 0.4);
+}
diff --git a/data/ui/window.ui b/data/ui/window.ui
index b6a89dd..085c84d 100644
--- a/data/ui/window.ui
+++ b/data/ui/window.ui
@@ -56,6 +56,7 @@
                   <object class="GcalWeekView" id="week_view">
                     <property name="visible">True</property>
                     <property name="active-date" bind-source="GcalWindow" bind-property="active-date" 
bind-flags="bidirectional"/>
+                    <signal name="create-event" handler="show_new_event_widget" object="GcalWindow" 
swapped="no"/>
                     <signal name="event-activated" handler="event_activated" object="GcalWindow" 
swapped="no"/>
                   </object>
                   <packing>
diff --git a/src/views/gcal-week-grid.c b/src/views/gcal-week-grid.c
index c2ff945..7c7358f 100644
--- a/src/views/gcal-week-grid.c
+++ b/src/views/gcal-week-grid.c
@@ -60,6 +60,13 @@ struct _GcalWeekGrid
   gboolean            children_changed;
   gint                redraw_timeout_id;
 
+  /*
+   * These fields are "cells" rather than minutes. Each cell
+   * correspond to 30 minutes.
+   */
+  gint                selection_start;
+  gint                selection_end;
+
   GcalManager        *manager;
 };
 
@@ -461,6 +468,45 @@ gcal_week_grid_draw (GtkWidget *widget,
 
   cairo_set_line_width (cr, 0.65);
 
+  /* First, draw the selection */
+  if (self->selection_start != -1 && self->selection_end != -1)
+    {
+      gdouble minutes_height;
+      gint selection_height;
+      gint column;
+      gint start;
+      gint end;
+
+      start = self->selection_start;
+      end = self->selection_end;
+
+      /* Swap cells if needed */
+      if (start > end)
+        {
+          start = start + end;
+          end = start - end;
+          start = start - end;
+        }
+
+      minutes_height = (gdouble) height / MINUTES_PER_DAY;
+      column = start * 30 / MINUTES_PER_DAY;
+      selection_height = (end - start + 1) * 30 * minutes_height;
+
+      x = column * column_width;
+
+      gtk_style_context_save (context);
+      gtk_style_context_set_state (context, state | GTK_STATE_FLAG_SELECTED);
+
+      gtk_render_background (context,
+                             cr,
+                             ALIGNED (x),
+                             round ((start * 30 % MINUTES_PER_DAY) * minutes_height),
+                             column_width,
+                             selection_height);
+
+      gtk_style_context_restore (context);
+    }
+
   /* Today column */
   today_column = get_today_column (GCAL_WEEK_GRID (widget));
 
@@ -720,6 +766,135 @@ gcal_week_grid_get_preferred_height (GtkWidget *widget,
     *natural_height = height;
 }
 
+static gboolean
+gcal_week_grid_button_press (GtkWidget      *widget,
+                             GdkEventButton *event_button)
+{
+  GcalWeekGrid *self;
+  GtkAllocation alloc;
+  gboolean ltr;
+  gdouble minute_height;
+  gint column_width;
+  gint column;
+  gint minute;
+
+  self = GCAL_WEEK_GRID (widget);
+  ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;
+
+  gtk_widget_get_allocation (widget, &alloc);
+  minute_height = (gdouble) alloc.height / MINUTES_PER_DAY;
+  column_width = floor (alloc.width / 7);
+  column = (gint) event_button->x / column_width;
+  minute = event_button->y / minute_height;
+  minute = minute - (minute % 30);
+
+  self->selection_start = (column * MINUTES_PER_DAY + minute) / 30;
+  self->selection_end = self->selection_start;
+
+  gtk_widget_queue_draw (widget);
+
+  return GDK_EVENT_STOP;
+}
+
+static gboolean
+gcal_week_grid_motion_notify_event (GtkWidget      *widget,
+                                    GdkEventMotion *event)
+{
+  GcalWeekGrid *self;
+  GtkAllocation alloc;
+  gboolean ltr;
+  gdouble minute_height;
+  gint column;
+  gint minute;
+
+  if (!(event->state & GDK_BUTTON_PRESS_MASK))
+    return GDK_EVENT_PROPAGATE;
+
+  self = GCAL_WEEK_GRID (widget);
+  ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;
+
+  gtk_widget_get_allocation (widget, &alloc);
+  minute_height = (gdouble) alloc.height / MINUTES_PER_DAY;
+  column = self->selection_start * 30 / MINUTES_PER_DAY;
+  minute = event->y / minute_height;
+  minute = minute - (minute % 30);
+
+  self->selection_end = (column * MINUTES_PER_DAY + minute) / 30;
+
+  gtk_widget_queue_draw (widget);
+
+  return GDK_EVENT_STOP;
+}
+
+static gboolean
+gcal_week_grid_button_release (GtkWidget      *widget,
+                               GdkEventButton *event)
+{
+  GcalWeekGrid *self;
+  GtkAllocation alloc;
+  GDateTime *week_start;
+  GDateTime *start, *end;
+  GtkWidget *weekview;
+  gboolean ltr;
+  gdouble minute_height;
+  gdouble x, y;
+  gint column;
+  gint minute;
+  gint out_x;
+  gint out_y;
+
+  self = GCAL_WEEK_GRID (widget);
+  ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;
+
+  gtk_widget_get_allocation (widget, &alloc);
+  minute_height = (gdouble) alloc.height / MINUTES_PER_DAY;
+  column = self->selection_start * 30 / MINUTES_PER_DAY;
+  minute = event->y / minute_height;
+  minute = minute - (minute % 30);
+
+  self->selection_end = (column * MINUTES_PER_DAY + minute) / 30;
+
+  gtk_widget_queue_draw (widget);
+
+  /* Fake the week view's event so we can control the X and Y values */
+  weekview = gtk_widget_get_ancestor (widget, GCAL_TYPE_WEEK_VIEW);
+  week_start = get_start_of_week (self->active_date);
+
+  if (ltr)
+    {
+      start = g_date_time_add_minutes (week_start, self->selection_start * 30);
+      end = g_date_time_add_minutes (week_start, (self->selection_end + 1) * 30);
+    }
+  else
+    {
+      start = g_date_time_add_minutes (week_start, MAX_MINUTES - column * MINUTES_PER_DAY + minute);
+      end = g_date_time_add_minutes (week_start, MAX_MINUTES - column * MINUTES_PER_DAY + 
(self->selection_end + 1) * 30);
+    }
+
+  x = round ((column + 0.5) * (alloc.width / 7.0));
+  y = (minute + 15) * minute_height;
+
+  gtk_widget_translate_coordinates (widget,
+                                    weekview,
+                                    x,
+                                    y,
+                                    &out_x,
+                                    &out_y);
+
+  g_signal_emit_by_name (weekview,
+                         "create-event",
+                         start,
+                         end,
+                         (gdouble) out_x,
+                         (gdouble) out_y);
+
+  gcal_clear_datetime (&week_start);
+  gcal_clear_datetime (&start);
+  gcal_clear_datetime (&end);
+
+  return GDK_EVENT_STOP;
+}
+
 static void
 gcal_week_grid_class_init (GcalWeekGridClass *klass)
 {
@@ -742,6 +917,9 @@ gcal_week_grid_class_init (GcalWeekGridClass *klass)
   widget_class->map = gcal_week_grid_map;
   widget_class->unmap = gcal_week_grid_unmap;
   widget_class->get_preferred_height = gcal_week_grid_get_preferred_height;
+  widget_class->button_press_event = gcal_week_grid_button_press;
+  widget_class->motion_notify_event = gcal_week_grid_motion_notify_event;
+  widget_class->button_release_event = gcal_week_grid_button_release;
 
   properties[PROP_ACTIVE_DATE] = g_param_spec_boxed ("active-date",
                                                      "Date",
@@ -768,6 +946,9 @@ gcal_week_grid_init (GcalWeekGrid *self)
 {
   gtk_widget_set_has_window (GTK_WIDGET (self), FALSE);
 
+  self->selection_start = -1;
+  self->selection_end = -1;
+
   self->events = gcal_range_tree_new ();
 }
 
@@ -903,3 +1084,14 @@ gcal_week_grid_get_children_by_uuid (GcalWeekGrid *self,
 
   return result;
 }
+
+void
+gcal_week_grid_clear_marks (GcalWeekGrid *self)
+{
+  g_return_if_fail (GCAL_IS_WEEK_GRID (self));
+
+  self->selection_start = -1;
+  self->selection_end = -1;
+
+  gtk_widget_queue_draw (GTK_WIDGET (self));
+}
diff --git a/src/views/gcal-week-grid.h b/src/views/gcal-week-grid.h
index 34eaa32..34d4881 100644
--- a/src/views/gcal-week-grid.h
+++ b/src/views/gcal-week-grid.h
@@ -52,6 +52,8 @@ void                 gcal_week_grid_remove_event                 (GcalWeekGrid
 GList*               gcal_week_grid_get_children_by_uuid         (GcalWeekGrid       *self,
                                                                   const gchar        *uid);
 
+void                 gcal_week_grid_clear_marks                  (GcalWeekGrid       *self);
+
 G_END_DECLS
 
 #endif /* GCAL_WEEK_GRID_H */
diff --git a/src/views/gcal-week-view.c b/src/views/gcal-week-view.c
index 85aff04..91108be 100644
--- a/src/views/gcal-week-view.c
+++ b/src/views/gcal-week-view.c
@@ -236,6 +236,14 @@ gcal_week_view_get_children_by_uuid (GcalView    *view,
 }
 
 static void
+gcal_week_view_clear_marks (GcalView *view)
+{
+  GcalWeekView *self = GCAL_WEEK_VIEW (view);
+
+  gcal_week_grid_clear_marks (GCAL_WEEK_GRID (self->week_grid));
+}
+
+static void
 update_hours_sidebar_size (GcalWeekView *self)
 {
   GtkStyleContext *context;
@@ -503,8 +511,7 @@ gcal_view_interface_init (GcalViewInterface *iface)
   iface->get_initial_date = gcal_week_view_get_initial_date;
   iface->get_final_date = gcal_week_view_get_final_date;
   iface->get_children_by_uuid = gcal_week_view_get_children_by_uuid;
-
-  /* iface->clear_marks = gcal_week_view_clear_marks; */
+  iface->clear_marks = gcal_week_view_clear_marks;
 }
 
 static void


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