[gnome-calendar] event-widget: lazily relayout main grid



commit e04b7f0fd38f77b0a3efa79a474f191c2238b682
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Sun Oct 29 19:00:42 2017 -0200

    event-widget: lazily relayout main grid

 data/ui/event-widget.ui |   42 +++++++++++++++++++++++++++
 src/gcal-event-widget.c |   71 +++++++++++++++++++++++++++++++++++------------
 2 files changed, 95 insertions(+), 18 deletions(-)
---
diff --git a/data/ui/event-widget.ui b/data/ui/event-widget.ui
index 96be2dd..58f0142 100644
--- a/data/ui/event-widget.ui
+++ b/data/ui/event-widget.ui
@@ -41,4 +41,46 @@
       </object>
     </child>
   </template>
+
+  <!-- HACK!!!
+       We need this ghost GtkGrid because we can't change the position of the
+       labels in size-allocate. This grid will simulate the main grid with the
+       labels vertically positioned, so we don't need to chage the main grid's
+       label position in size-allocate -->
+  <object class="GtkGrid" id="ghost_grid">
+    <property name="visible">True</property>
+    <property name="column_spacing">4</property>
+    <property name="margin-top">1</property>
+    <property name="margin-bottom">1</property>
+    <property name="margin-start">6</property>
+    <property name="margin-end">4</property>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="label" bind-source="hour_label" bind-property="label" bind-flags="default" />
+        <property name="can_focus">False</property>
+        <property name="xalign">0.0</property>
+        <attributes>
+          <attribute name="weight" value="semibold"/>
+        </attributes>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="label" bind-source="summary_label" bind-property="label" bind-flags="default" />
+        <property name="hexpand">True</property>
+        <property name="xalign">0</property>
+        <property name="ellipsize">end</property>
+      </object>
+      <packing>
+        <property name="top_attach">1</property>
+      </packing>
+    </child>
+  </object>
 </interface>
diff --git a/src/gcal-event-widget.c b/src/gcal-event-widget.c
index 96e9961..f403674 100644
--- a/src/gcal-event-widget.c
+++ b/src/gcal-event-widget.c
@@ -38,6 +38,7 @@ struct _GcalEventWidget
   GDateTime          *dt_end;
 
   /* widgets */
+  GtkWidget          *ghost_grid;
   GtkWidget          *hour_label;
   GtkWidget          *main_grid;
   GtkWidget          *summary_label;
@@ -53,6 +54,7 @@ struct _GcalEventWidget
 
   GtkOrientation      orientation;
 
+  guint               toggle_description_id;
   gboolean            button_pressed;
 };
 
@@ -90,6 +92,40 @@ G_DEFINE_TYPE_WITH_CODE (GcalEventWidget, gcal_event_widget, GTK_TYPE_BIN,
  * Auxiliary methods
  */
 
+static gboolean
+toggle_description_position_cb (GcalEventWidget *self)
+{
+  gint current_top;
+
+  gtk_container_child_get (GTK_CONTAINER (self->main_grid),
+                           self->summary_label,
+                           "top-attach", &current_top,
+                           NULL);
+
+  gtk_label_set_line_wrap (GTK_LABEL (self->summary_label),
+                           !gtk_label_get_line_wrap (GTK_LABEL (self->summary_label)));
+
+  gtk_container_child_set (GTK_CONTAINER (self->main_grid),
+                           self->summary_label,
+                           "left-attach", current_top == 1 ? 1 : 0,
+                           "top-attach", current_top == 1 ? 0 : 1,
+                           "width", current_top == 1 ? 1 : 2,
+                           NULL);
+
+  self->toggle_description_id = 0;
+
+  return G_SOURCE_REMOVE;
+}
+
+static void
+queue_toggle_description_position (GcalEventWidget *self)
+{
+  if (self->toggle_description_id > 0)
+    g_source_remove (self->toggle_description_id);
+
+  self->toggle_description_id = g_idle_add ((GSourceFunc) toggle_description_position_cb, self);
+}
+
 static void
 set_drag_source_enabled (GcalEventWidget *self,
                          gboolean         enabled)
@@ -526,32 +562,23 @@ gcal_event_widget_size_allocate (GtkWidget     *widget,
   if (self->orientation == GTK_ORIENTATION_VERTICAL && !gcal_event_get_all_day (self->event))
     {
       gint minimum_grid_height;
+      gint current_top;
 
-      gtk_label_set_line_wrap (GTK_LABEL (self->summary_label), TRUE);
+      gtk_widget_get_preferred_height (self->ghost_grid, &minimum_grid_height, NULL);
 
-      gtk_container_child_set (GTK_CONTAINER (self->main_grid),
+      gtk_container_child_get (GTK_CONTAINER (self->main_grid),
                                self->summary_label,
-                               "left-attach", 0,
-                               "top-attach", 1,
-                               "width", 2,
+                               "top-attach", &current_top,
                                NULL);
 
-      gtk_widget_get_preferred_height (self->main_grid, &minimum_grid_height, NULL);
-
       /*
-       * There is no vertical space to put the summary label below the hour label.
-       * Thus, reset the label's original attributes.
+       * Since we can't change the position of the events inside size-allocate,
+       * queue it for future iterations of the mainloop.
        */
-      if (allocation->height < minimum_grid_height)
+      if ((allocation->height < minimum_grid_height && current_top == 1) ||
+          (allocation->height >= minimum_grid_height && current_top == 0))
         {
-          gtk_container_child_set (GTK_CONTAINER (self->main_grid),
-                                   self->summary_label,
-                                   "left-attach", 1,
-                                   "top-attach", 0,
-                                   "width", 1,
-                                   NULL);
-
-          gtk_label_set_line_wrap (GTK_LABEL (self->summary_label), FALSE);
+          queue_toggle_description_position (self);
         }
     }
 
@@ -777,6 +804,13 @@ gcal_event_widget_finalize (GObject *object)
   g_clear_pointer (&self->css_class, g_free);
   g_clear_object (&self->event);
 
+  /* withdraw mainloop sources */
+  if (self->toggle_description_id > 0)
+    {
+      g_source_remove (self->toggle_description_id);
+      self->toggle_description_id = 0;
+    }
+
   G_OBJECT_CLASS (gcal_event_widget_parent_class)->finalize (object);
 }
 
@@ -866,6 +900,7 @@ gcal_event_widget_class_init (GcalEventWidgetClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/calendar/event-widget.ui");
 
+  gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, ghost_grid);
   gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, hour_label);
   gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, main_grid);
   gtk_widget_class_bind_template_child (widget_class, GcalEventWidget, summary_label);


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