[gnome-calendar] date-selector: make it GtkMenuButton descendant



commit 5395dca4f2f7f4dca6933b72bb34c3239c29be74
Author: Erick Pérez Castellanos <erick red gmail com>
Date:   Thu Dec 25 13:03:15 2014 -0500

    date-selector: make it GtkMenuButton descendant
    
    Added GtkBuilder's UI file definition

 data/ui/date-selector.ui |  168 +++++++++++++++++++++++++++++++---------------
 src/gcal-date-selector.c |  129 ++++++++++++-----------------------
 src/gcal-date-selector.h |    4 +-
 3 files changed, 160 insertions(+), 141 deletions(-)
---
diff --git a/data/ui/date-selector.ui b/data/ui/date-selector.ui
index e5a990b..fa81038 100644
--- a/data/ui/date-selector.ui
+++ b/data/ui/date-selector.ui
@@ -2,90 +2,148 @@
 <!-- Generated with glade 3.18.3 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
-  <object class="GtkGrid" id="grid">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="border_width">12</property>
-    <property name="row_spacing">6</property>
+  <template class="GcalDateSelector" parent="GtkMenuButton">
+    <property name="use_popover">True</property>
+    <property name="popover">date_selector_popover</property>
     <child>
-      <object class="GtkCalendar" id="calendar">
+      <object class="GtkLabel" id="date_label">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="year">2014</property>
-        <property name="month">11</property>
-        <property name="day">18</property>
-        <property name="show_week_numbers">True</property>
       </object>
-      <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">2</property>
-        <property name="width">3</property>
-      </packing>
     </child>
+  </template>
+  <object class="GtkPopover" id="date_selector_popover">
+    <property name="visible">False</property>
+    <property name="position">bottom</property>
     <child>
-      <object class="GtkBox" id="box">
+      <object class="GtkGrid" id="grid">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
-        <property name="hexpand">True</property>
-        <property name="homogeneous">True</property>
+        <property name="border_width">12</property>
+        <property name="row_spacing">6</property>
         <child>
-          <object class="GtkEntry" id="entry0">
+          <object class="GtkLabel">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="width_chars">4</property>
-            <property name="max_width_chars">4</property>
-            <property name="xalign">0.5</property>
-            <property name="input_purpose">number</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
           </object>
           <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
           </packing>
         </child>
         <child>
-          <object class="GtkEntry" id="entry1">
+          <object class="GtkLabel">
+            <property name="visible">True</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="width_chars">4</property>
-            <property name="max_width_chars">4</property>
-            <property name="xalign">0.5</property>
-            <property name="input_purpose">number</property>
             <style>
-              <class name="middle-entry"/>
+              <class name="dim-label"/>
             </style>
           </object>
           <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
+            <property name="left_attach">2</property>
+            <property name="top_attach">0</property>
           </packing>
         </child>
         <child>
-          <object class="GtkEntry" id="entry2">
+          <object class="GtkCalendar" id="calendar">
             <property name="visible">True</property>
             <property name="can_focus">True</property>
-            <property name="max_length">4</property>
-            <property name="width_chars">4</property>
-            <property name="max_width_chars">4</property>
-            <property name="xalign">0.5</property>
-            <property name="input_purpose">number</property>
+            <property name="show_week_numbers">True</property>
+            <signal name="day-selected" handler="calendar_day_selected" object="GcalDateSelector" 
swapped="no"/>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">2</property>
+            <property name="width">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="hexpand">True</property>
+            <property name="homogeneous">True</property>
+            <child>
+              <object class="GtkEntry">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="width_chars">4</property>
+                <property name="max_width_chars">4</property>
+                <property name="xalign">0.5</property>
+                <property name="input_purpose">number</property>
+                <signal name="insert-text" handler="text_inserted" object="GcalDateSelector" swapped="no"/>
+                <signal name="focus-out-event" handler="date_entry_focus_out" object="GcalDateSelector" 
swapped="no"/>
+                <signal name="activate" handler="entry_activated" object="GcalDateSelector" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="width_chars">4</property>
+                <property name="max_width_chars">4</property>
+                <property name="xalign">0.5</property>
+                <property name="input_purpose">number</property>
+                <signal name="insert-text" handler="text_inserted" object="GcalDateSelector" swapped="no"/>
+                <signal name="focus-out-event" handler="date_entry_focus_out" object="GcalDateSelector" 
swapped="no"/>
+                <signal name="activate" handler="entry_activated" object="GcalDateSelector" swapped="no"/>
+                <style>
+                  <class name="middle-entry"/>
+                </style>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkEntry">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="max_length">4</property>
+                <property name="width_chars">4</property>
+                <property name="max_width_chars">4</property>
+                <property name="xalign">0.5</property>
+                <property name="input_purpose">number</property>
+                <signal name="insert-text" handler="text_inserted" object="GcalDateSelector" swapped="no"/>
+                <signal name="focus-out-event" handler="date_entry_focus_out" object="GcalDateSelector" 
swapped="no"/>
+                <signal name="activate" handler="entry_activated" object="GcalDateSelector" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <style>
+              <class name="linked"/>
+            </style>
           </object>
           <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+            <property name="width">3</property>
           </packing>
         </child>
-        <style>
-          <class name="linked"/>
-        </style>
       </object>
-      <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">1</property>
-        <property name="width">3</property>
-      </packing>
     </child>
   </object>
 </interface>
diff --git a/src/gcal-date-selector.c b/src/gcal-date-selector.c
index d119a26..fbf1657 100644
--- a/src/gcal-date-selector.c
+++ b/src/gcal-date-selector.c
@@ -36,9 +36,10 @@ struct _GcalDateSelectorPrivate
 {
   /* widgets */
   GtkWidget   *date_label;
-  GtkWidget   *popover;
-  GtkWidget   *entries[NUM_ENTRIES];
   GtkWidget   *calendar;
+  GtkWidget   *grid;
+
+  GtkWidget   *entries[NUM_ENTRIES];
 
   /* date */
   gint         day;
@@ -47,6 +48,8 @@ struct _GcalDateSelectorPrivate
 
   /* misc */
   gchar       *mask;
+
+  /* index in the mask starting by 0 */
   guint        day_pos;
   guint        month_pos;
   guint        year_pos;
@@ -80,7 +83,7 @@ static void     text_inserted                                     (GtkEditable
 
 static void     gcal_date_selector_constructed                    (GObject              *object);
 
-G_DEFINE_TYPE_WITH_PRIVATE (GcalDateSelector, gcal_date_selector, GTK_TYPE_TOGGLE_BUTTON);
+G_DEFINE_TYPE_WITH_PRIVATE (GcalDateSelector, gcal_date_selector, GTK_TYPE_MENU_BUTTON);
 
 static void
 calendar_day_selected (GtkCalendar *calendar,
@@ -201,6 +204,17 @@ gcal_date_selector_class_init (GcalDateSelectorClass *klass)
                                     G_STRUCT_OFFSET (GcalDateSelectorClass, modified),
                                     NULL, NULL, NULL,
                                     G_TYPE_NONE, 0);
+
+  gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), 
"/org/gnome/calendar/date-selector.ui");
+
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GcalDateSelector, date_label);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GcalDateSelector, calendar);
+  gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GcalDateSelector, grid);
+
+  gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), text_inserted);
+  gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), date_entry_focus_out);
+  gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), entry_activated);
+  gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass), calendar_day_selected);
 }
 
 static void
@@ -213,6 +227,8 @@ gcal_date_selector_init (GcalDateSelector *self)
 
   priv = gcal_date_selector_get_instance_private (GCAL_DATE_SELECTOR (self));;
 
+  gtk_widget_init_template (GTK_WIDGET (self));
+
   priv->day = 1;
   priv->month = 1;
   priv->year = 1970;
@@ -273,94 +289,39 @@ static void
 gcal_date_selector_constructed (GObject *object)
 {
   GcalDateSelectorPrivate *priv;
-  GtkWidget *grid;
-  GtkWidget *label;
-  GtkBuilder *builder;
 
-  gchar *entry_name;
+  GtkWidget *label, *box;
+  GList *l;
 
   priv = gcal_date_selector_get_instance_private (GCAL_DATE_SELECTOR (object));
 
   /* chaining up */
   G_OBJECT_CLASS (gcal_date_selector_parent_class)->constructed (object);
 
-  /* date label */
-  priv->date_label = gtk_label_new (NULL);
-  gtk_widget_show (priv->date_label);
-
-  gtk_container_add (GTK_CONTAINER (object), priv->date_label);
-
-  /* retrieve components from UI definition */
-  builder = gtk_builder_new ();
-  gtk_builder_add_from_resource (builder, "/org/gnome/calendar/date-selector.ui", NULL);
-
-  /* popover */
-  priv->popover = gtk_popover_new (GTK_WIDGET (object));
-  gtk_popover_set_position (GTK_POPOVER (priv->popover), GTK_POS_BOTTOM);
-
-  /* main grid */
-  grid = (GtkWidget*) gtk_builder_get_object (builder, "grid");
-
-  /* calendar */
-  priv->calendar = (GtkWidget*) gtk_builder_get_object (builder, "calendar");
-
-  /**
-   * Date entries
-   *
-   * day entry
-   */
-  entry_name = g_strdup_printf ("entry%d", priv->day_pos);
-
-  priv->entries[DAY] = (GtkWidget*) gtk_builder_get_object (builder, entry_name);
-  gtk_entry_set_max_length (GTK_ENTRY (priv->entries[DAY]), 2);
-  g_free (entry_name);
-
-  label = gtk_label_new (_("Day"));
-  gtk_widget_show (label);
-  gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
-  gtk_grid_attach (GTK_GRID (grid), label, priv->day_pos, 0, 1, 1);
-
-  /* month entry */
-  entry_name = g_strdup_printf ("entry%d", priv->month_pos);
-
-  priv->entries[MONTH] = (GtkWidget*) gtk_builder_get_object (builder, entry_name);
-  gtk_entry_set_max_length (GTK_ENTRY (priv->entries[MONTH]), 2);
-  g_free (entry_name);
-
-  label = gtk_label_new (_("Month"));
-  gtk_widget_show (label);
-  gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
-  gtk_grid_attach (GTK_GRID (grid), label, priv->month_pos, 0, 1, 1);
-
-  /* year entry */
-  entry_name = g_strdup_printf ("entry%d", priv->year_pos);
-
-  priv->entries[YEAR] = (GtkWidget*) gtk_builder_get_object (builder, entry_name);
-
-  g_free (entry_name);
-
-  label = gtk_label_new (_("Year"));
-  gtk_widget_show (label);
-  gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
-  gtk_grid_attach (GTK_GRID (grid), label, priv->year_pos, 0, 1, 1);
-
-  /* signals and properties */
-  gtk_container_add (GTK_CONTAINER (priv->popover), grid);
-  g_object_bind_property (priv->popover, "visible", object, "active", G_BINDING_BIDIRECTIONAL);
-
-  g_signal_connect (priv->entries[DAY], "insert-text", G_CALLBACK (text_inserted), object);
-  g_signal_connect (priv->entries[DAY], "focus-out-event", G_CALLBACK (date_entry_focus_out), object);
-  g_signal_connect (priv->entries[DAY], "activate", G_CALLBACK (entry_activated), object);
-  g_signal_connect (priv->entries[MONTH], "insert-text", G_CALLBACK (text_inserted), object);
-  g_signal_connect (priv->entries[MONTH], "focus-out-event", G_CALLBACK (date_entry_focus_out), object);
-  g_signal_connect (priv->entries[MONTH], "activate", G_CALLBACK (entry_activated), object);
-  g_signal_connect (priv->entries[YEAR], "insert-text", G_CALLBACK (text_inserted), object);
-  g_signal_connect (priv->entries[YEAR], "focus-out-event", G_CALLBACK (date_entry_focus_out), object);
-  g_signal_connect (priv->entries[YEAR], "activate", G_CALLBACK (entry_activated), object);
-
-  g_signal_connect (priv->calendar, "day-selected", G_CALLBACK (calendar_day_selected), object);
-
-  g_object_unref (builder);
+  /* set labels, on the first row */
+  label = gtk_grid_get_child_at (GTK_GRID (priv->grid), priv->day_pos, 0);
+  gtk_label_set_text (GTK_LABEL (label), _("Day"));
+  label = gtk_grid_get_child_at (GTK_GRID (priv->grid), priv->month_pos, 0);
+  gtk_label_set_text (GTK_LABEL (label), _("Month"));
+  label = gtk_grid_get_child_at (GTK_GRID (priv->grid), priv->year_pos, 0);
+  gtk_label_set_text (GTK_LABEL (label), _("Year"));
+
+  /* retrieve components from UI definition: entries */
+  box = gtk_grid_get_child_at (GTK_GRID (priv->grid), 0, 1);
+  for (l = gtk_container_get_children (GTK_CONTAINER (box)); l != NULL; l = g_list_next (l))
+    {
+      gint position;
+      gtk_container_child_get (GTK_CONTAINER (box), l->data, "position", &position, NULL);
+      if (position == priv->day_pos)
+        priv->entries[DAY] = l->data;
+      if (position == priv->month_pos)
+        priv->entries[MONTH] = l->data;
+      if (position == priv->year_pos)
+        priv->entries[YEAR] = l->data;
+
+      if (position == priv->day_pos || position == priv->month_pos)
+        gtk_entry_set_max_length (GTK_ENTRY (l->data), 2);
+    }
 }
 
 /* Public API */
diff --git a/src/gcal-date-selector.h b/src/gcal-date-selector.h
index 99762cd..15a6deb 100644
--- a/src/gcal-date-selector.h
+++ b/src/gcal-date-selector.h
@@ -39,12 +39,12 @@ typedef struct _GcalDateSelectorPrivate      GcalDateSelectorPrivate;
 
 struct _GcalDateSelector
 {
-  GtkToggleButton parent;
+  GtkMenuButton parent;
 };
 
 struct _GcalDateSelectorClass
 {
-  GtkToggleButtonClass parent_class;
+  GtkMenuButtonClass parent_class;
 
   /* signals */
   void (*modified)  (GcalDateSelector *selector);


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