[gnome-calendar] window: use GtkPopovers



commit 1e1052c65c3c6b58f49b76b714209301563f1b44
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Mon Sep 29 15:01:44 2014 -0300

    window: use GtkPopovers
    
    GNOME Calendar uses a custom GtkOverlay-based widget, witch is not necessary anymore. It should be 
replaced by GtkPopover.

 data/calendar.gresource.xml |    1 -
 data/theme/close-window.svg |  152 ----------------------------------------
 data/ui/new-event.ui        |  162 +++++++++++++++++++------------------------
 src/gcal-new-event-widget.c |   26 +------
 src/gcal-new-event-widget.h |    4 +-
 src/gcal-window.c           |  107 ++++++++++-------------------
 6 files changed, 113 insertions(+), 339 deletions(-)
---
diff --git a/data/calendar.gresource.xml b/data/calendar.gresource.xml
index a85f8ce..6c9a04e 100644
--- a/data/calendar.gresource.xml
+++ b/data/calendar.gresource.xml
@@ -4,7 +4,6 @@
     <file alias="nav_bar.ui" compressed="true" preprocess="xml-stripblanks">ui/nav_bar.ui</file>
     <file alias="viewport.ui" compressed="true" preprocess="xml-stripblanks">ui/viewport.ui</file>
     <file alias="new-event.ui" compressed="true" preprocess="xml-stripblanks">ui/new-event.ui</file>
-    <file alias="close.svg" compressed="true" preprocess="xml-stripblanks">theme/close-window.svg</file>
     <file alias="gtk-styles.css" compressed="true">theme/gtk-styles.css</file>
   </gresource>
 </gresources>
diff --git a/data/ui/new-event.ui b/data/ui/new-event.ui
index 466202a..0822583 100644
--- a/data/ui/new-event.ui
+++ b/data/ui/new-event.ui
@@ -1,139 +1,121 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.18.3 -->
 <interface>
-  <!-- interface-requires gtk+ 3.10 -->
-  <template class="GcalNewEventWidget" parent="GtkOverlay">
+  <requires lib="gtk+" version="3.10"/>
+  <template class="GcalNewEventWidget" parent="GtkGrid">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
-    <style>
-      <class name="new-event-widget"/>
-    </style>
-    <child type="overlay">
-      <object class="GtkButton" id="close_button">
+    <child>
+      <object class="GtkGrid" id="container">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-       <property name="halign">end</property>
-       <property name="valign">start</property>
-       <property name="focus_on_click">False</property>
-       <property name="relief">none</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">14</property>
         <child>
-          <object class="GtkImage" id="image1">
-           <property name="visible">True</property>
-           <property name="can_focus">False</property>
-           <property name="resource">/org/gnome/calendar/close.svg</property>
-         </object>
-        </child>
-      </object>
-    </child>
-    <child>
-      <object class="GcalArrowBin" id="container">
-       <property name="visible">True</property>
-       <property name="can_focus">False</property>
-       <property name="border_width">14</property>
-       <style>
-         <class name="arrow-bin"/>
-       </style>
-       <child>
-         <object class="GtkGrid" id="main_grid">
+          <object class="GtkGrid" id="main_grid">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-           <property name="row_spacing">18</property>
-           <property name="column_spacing">12</property>
+            <property name="row_spacing">18</property>
+            <property name="column_spacing">12</property>
             <property name="column_homogeneous">True</property>
-           <property name="margin">18</property>
-           <child>
+            <child>
               <object class="GtkLabel" id="title_label">
-               <property name="visible">True</property>
-               <property name="can_focus">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
               </object>
               <packing>
-               <property name="left_attach">0</property>
-               <property name="top_attach">0</property>
-               <property name="width">2</property>
-               <property name="height">1</property>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+                <property name="width">2</property>
               </packing>
             </child>
             <child>
               <object class="GtkButton" id="create_button">
-               <property name="label" translatable="yes">Create</property>
-               <property name="visible">True</property>
-               <property name="can_focus">True</property>
-               <property name="receives_default">True</property>
-               <style>
-                 <class name="suggested-action"/>
-               </style>
+                <property name="label" translatable="yes">Create</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <style>
+                  <class name="suggested-action"/>
+                </style>
               </object>
               <packing>
-               <property name="left_attach">0</property>
-               <property name="top_attach">2</property>
-               <property name="width">1</property>
-               <property name="height">1</property>
+                <property name="left_attach">0</property>
+                <property name="top_attach">2</property>
               </packing>
             </child>
             <child>
               <object class="GtkButton" id="details_button">
-               <property name="label" translatable="yes">More Details</property>
-               <property name="visible">True</property>
-               <property name="can_focus">True</property>
-               <property name="receives_default">True</property>
+                <property name="label" translatable="yes">More Details</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
               </object>
               <packing>
-               <property name="left_attach">1</property>
-               <property name="top_attach">2</property>
-               <property name="width">1</property>
-               <property name="height">1</property>
+                <property name="left_attach">1</property>
+                <property name="top_attach">2</property>
               </packing>
             </child>
             <child>
               <object class="GtkGrid" id="row_grid">
-               <property name="visible">True</property>
-               <property name="can_focus">False</property>
-               <property name="column_spacing">6</property>
-               <child>
-                 <object class="GtkEntry" id="what_entry">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="column_spacing">6</property>
+                <child>
+                  <object class="GtkEntry" id="what_entry">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="hexpand">True</property>
-                 </object>
-                 <packing>
+                  </object>
+                  <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                 </packing>
-               </child>
-               <child>
-                 <object class="GtkMenuButton" id="calendar_button">
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkMenuButton" id="calendar_button">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
-                   <property name="always_show_image">True</property>
+                    <property name="always_show_image">True</property>
                     <child>
                       <object class="GtkImage" id="image2">
-                       <property name="visible">True</property>
-                       <property name="can_focus">False</property>
-                       <property name="icon_name">x-office-calendar-symbolic</property>
-                       <property name="icon_size">1</property>
-                     </object>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">x-office-calendar-symbolic</property>
+                        <property name="icon_size">1</property>
+                      </object>
                     </child>
-                 </object>
-                 <packing>
+                  </object>
+                  <packing>
                     <property name="left_attach">1</property>
                     <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
-                 </packing>
-               </child>
+                  </packing>
+                </child>
               </object>
               <packing>
-               <property name="left_attach">0</property>
-               <property name="top_attach">1</property>
-               <property name="width">2</property>
-               <property name="height">1</property>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+                <property name="width">2</property>
               </packing>
             </child>
-         </object>
-       </child>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
       </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+        <property name="width">2</property>
+      </packing>
+    </child>
+    <child>
+      <placeholder/>
+    </child>
+    <child>
+      <placeholder/>
     </child>
   </template>
 </interface>
diff --git a/src/gcal-new-event-widget.c b/src/gcal-new-event-widget.c
index fa1c011..e360800 100644
--- a/src/gcal-new-event-widget.c
+++ b/src/gcal-new-event-widget.c
@@ -2,6 +2,7 @@
 /*
  * gcal-new-event-widget.c
  * Copyright (C) 2012 Erick Pérez Castellanos <erickpc gnome org>
+ * Copyright (C) 2014 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
  * gnome-calendar is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -18,7 +19,6 @@
  */
 
 #include "gcal-new-event-widget.h"
-#include "gcal-arrow-bin.h"
 #include "gcal-utils.h"
 
 typedef struct
@@ -26,17 +26,14 @@ typedef struct
   GtkWidget     *title_label;
   GtkWidget     *what_entry;
   GtkWidget     *calendar_button;
-
   GtkWidget     *create_button;
   GtkWidget     *details_button;
-
-  GtkWidget     *close_button;
 } GcalNewEventWidgetPrivate;
 
 static void      item_activated          (GtkWidget *item,
                                           gpointer   user_data);
 
-G_DEFINE_TYPE_WITH_PRIVATE (GcalNewEventWidget, gcal_new_event_widget, GTK_TYPE_OVERLAY)
+G_DEFINE_TYPE_WITH_PRIVATE (GcalNewEventWidget, gcal_new_event_widget, GTK_TYPE_GRID)
 
 static void
 item_activated (GtkWidget *item,
@@ -84,7 +81,7 @@ gcal_new_event_widget_class_init (GcalNewEventWidgetClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, GcalNewEventWidget, calendar_button);
   gtk_widget_class_bind_template_child_private (widget_class, GcalNewEventWidget, create_button);
   gtk_widget_class_bind_template_child_private (widget_class, GcalNewEventWidget, details_button);
-  gtk_widget_class_bind_template_child_private (widget_class, GcalNewEventWidget, close_button);
+
 }
 
 static void
@@ -265,23 +262,6 @@ gcal_new_event_widget_get_details_button (GcalNewEventWidget *widget)
 }
 
 /**
- * gcal_new_event_widget_get_close_button:
- * @widget: a #GcalNewEventWidget
- *
- * Get a pointer a to the close button in the widget.
- *
- * Returns: (transfer none) a #GtkWidget
- **/
-GtkWidget*
-gcal_new_event_widget_get_close_button (GcalNewEventWidget *widget)
-{
-  GcalNewEventWidgetPrivate *priv;
-
-  priv = gcal_new_event_widget_get_instance_private (widget);
-  return priv->close_button;
-}
-
-/**
  * gcal_new_event_widget_get_calendar_uid:
  * @widget: a #GcalNewEventWidget
  *
diff --git a/src/gcal-new-event-widget.h b/src/gcal-new-event-widget.h
index 3efeeb3..372ddec 100644
--- a/src/gcal-new-event-widget.h
+++ b/src/gcal-new-event-widget.h
@@ -47,12 +47,12 @@ typedef struct _GcalNewEventWidgetClass           GcalNewEventWidgetClass;
 
 struct _GcalNewEventWidget
 {
-  GtkOverlay parent;
+  GtkGrid parent;
 };
 
 struct _GcalNewEventWidgetClass
 {
-  GtkOverlayClass parent_class;
+  GtkGridClass parent_class;
 };
 
 
diff --git a/src/gcal-window.c b/src/gcal-window.c
index f76991e..859e9d7 100644
--- a/src/gcal-window.c
+++ b/src/gcal-window.c
@@ -2,6 +2,7 @@
 /*
  * gcal-window.c
  * Copyright (C) 2012 Erick Pérez Castellanos <erickpc gnome org>
+ * Copyright (C) 2014 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
  * gnome-calendar is free software: you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -64,8 +65,9 @@ typedef struct
   GtkWidget           *nav_bar;
   GtkWidget           *views_overlay;
   GtkWidget           *views_stack;
+  GtkWidget           *new_event_widget;
   GtkWidget           *noty; /* short-lived */
-  GtkWidget           *new_event_widget; /* short-lived */
+  GtkWidget           *popover; /* short-lived */
 
   /* header_bar widets */
   GtkWidget           *new_button;
@@ -130,10 +132,9 @@ static void           show_new_event_widget              (GcalView            *v
                                                           gdouble              y,
                                                           gpointer             user_data);
 
-static gboolean       place_new_event_widget             (GtkOverlay          *overlay,
-                                                          GtkWidget           *child,
-                                                          GdkRectangle        *allocation,
-                                                          gpointer             user_data);
+static gboolean       place_new_event_widget             (GtkWidget           *popover,
+                                                          gint                 x,
+                                                          gint                 y);
 
 static void           close_new_event_widget             (GtkButton           *button,
                                                           gpointer             user_data);
@@ -458,7 +459,6 @@ view_changed (GObject    *object,
               gpointer    user_data)
 {
   GcalWindowPrivate *priv;
-
   GEnumClass *eklass;
   GEnumValue *eval;
   GcalWindowViewType view_type;
@@ -489,7 +489,6 @@ static void
 set_new_event_mode (GcalWindow *window,
                     gboolean    enabled)
 {
-
   GcalWindowPrivate *priv;
 
   priv = gcal_window_get_instance_private (window);
@@ -501,10 +500,10 @@ set_new_event_mode (GcalWindow *window,
 
   /* XXX: here we could disable clicks from the views, yet */
   /* for now we relaunch the new-event widget */
-  if (priv->new_event_widget != NULL)
+  if (!enabled &&
+      gtk_widget_is_visible (priv->popover))
     {
-      gtk_widget_destroy (priv->new_event_widget);
-      priv->new_event_widget = NULL;
+      gtk_widget_set_visible (priv->popover, FALSE);
     }
 }
 
@@ -524,9 +523,6 @@ prepare_new_event_widget (GcalWindow *window)
   GtkWidget *widget;
 
   priv = gcal_window_get_instance_private (window);
-
-  /* FIXME: ensure destruction or singleton pattern */
-  priv->new_event_widget = gcal_new_event_widget_new ();
   new_widget = GCAL_NEW_EVENT_WIDGET (priv->new_event_widget);
 
   /* setting title */
@@ -546,9 +542,13 @@ prepare_new_event_widget (GcalWindow *window)
   gcal_new_event_widget_set_default_calendar (new_widget, uid);
   g_free (uid);
 
+  /* clear entry */
+  widget = gcal_new_event_widget_get_entry (new_widget);
+  gtk_entry_set_text (GTK_ENTRY (widget), "");
+
   /* FIXME: add signals handling */
-  widget = gcal_new_event_widget_get_close_button (new_widget);
-  g_signal_connect (widget, "clicked",
+  widget = GTK_WIDGET (priv->popover);
+  g_signal_connect (widget, "closed",
                     G_CALLBACK (close_new_event_widget), window);
   widget = gcal_new_event_widget_get_create_button (new_widget);
   g_signal_connect_swapped (widget, "clicked",
@@ -559,8 +559,7 @@ prepare_new_event_widget (GcalWindow *window)
   widget = gcal_new_event_widget_get_entry (new_widget);
   g_signal_connect_swapped (widget, "activate",
                             G_CALLBACK (create_event), window);
-
-  gtk_widget_show_all (priv->new_event_widget);
+  gtk_widget_show_all (priv->popover);
 }
 
 /* new-event interaction: second variant */
@@ -595,58 +594,26 @@ show_new_event_widget (GcalView *view,
     priv->event_creation_data->end_date = gcal_dup_icaltime (end_span);
   g_debug ("[show_new_event] position (%f, %f)", x, y);
 
+  /* Setup new event widget data */
   prepare_new_event_widget (GCAL_WINDOW (user_data));
 
-  gtk_overlay_add_overlay (GTK_OVERLAY (priv->views_overlay),
-                           priv->new_event_widget);
+  place_new_event_widget (priv->popover, x, y);
 }
 
 static gboolean
-place_new_event_widget (GtkOverlay   *overlay,
-                        GtkWidget    *child,
-                        GdkRectangle *allocation,
-                        gpointer      user_data)
+place_new_event_widget (GtkWidget    *popover,
+                        gint          x,
+                        gint          y)
 {
-  GcalWindowPrivate *priv;
-
-  gint nat_width;
-  gint nat_height;
-  gint nav_bar_height;
+  GdkRectangle rect;
 
-  priv = gcal_window_get_instance_private (GCAL_WINDOW (user_data));
+  /* Place popover over the given (x,y) position */
+  rect.x = x;
+  rect.y = y;
+  rect.width = 1;
+  rect.height = 1;
 
-  if (! priv->new_event_mode)
-    return FALSE;
-
-  gtk_widget_get_preferred_width (priv->new_event_widget,
-                                  NULL,
-                                  &nat_width);
-  gtk_widget_get_preferred_height_for_width (priv->new_event_widget,
-                                             nat_width,
-                                             NULL,
-                                             &nat_height);
-  nav_bar_height = gtk_widget_get_allocated_height (priv->nav_bar);
-
-  g_debug ("[allocate-child] incoming value (%d, %d) - (%d, %d)",
-           allocation->x,
-           allocation->y,
-           allocation->width,
-           allocation->height);
-  g_debug ("[allocate-child] natural size (%d, %d)",
-           nat_width, nat_height);
-  allocation->x = priv->event_creation_data->x - nat_width / 2;
-  allocation->y = priv->event_creation_data->y + nav_bar_height - nat_height;
-  allocation->width = nat_width;
-  allocation->height = nat_height;
-
-  g_debug ("[allocate-child]: outgoing value (%d, %d) - (%d, %d)",
-           allocation->x,
-           allocation->y,
-           allocation->width,
-           allocation->height);
-
-  gtk_widget_grab_focus (gcal_new_event_widget_get_entry (
-                             GCAL_NEW_EVENT_WIDGET (priv->new_event_widget)));
+  gtk_popover_set_pointing_to (GTK_POPOVER (popover), &rect);
 
   return TRUE;
 }
@@ -801,11 +768,6 @@ gcal_window_constructed (GObject *object)
   g_object_ref_sink (priv->views_switcher);
   gtk_header_bar_set_custom_title (GTK_HEADER_BAR (priv->header_bar),
                                    priv->views_switcher);
-  g_object_bind_property (object,
-                          "new-event-mode",
-                          priv->views_switcher,
-                          "sensitive",
-                          G_BINDING_DEFAULT | G_BINDING_INVERT_BOOLEAN);
 
   /* header_bar: menu */
   menu_button = gd_header_menu_button_new ();
@@ -917,6 +879,13 @@ gcal_window_constructed (GObject *object)
       gtk_widget_get_style_context (GTK_WIDGET (object)),
       "views");
 
+  /* popover and content */
+  priv->popover = gtk_popover_new (GTK_WIDGET(priv->views_stack));
+
+  priv->new_event_widget = gcal_new_event_widget_new ();
+
+  gtk_container_add (GTK_CONTAINER(priv->popover), GTK_WIDGET(priv->new_event_widget));
+
   /* signals connection/handling */
   g_signal_connect (object, "key-press-event",
                     G_CALLBACK (key_pressed), object);
@@ -928,8 +897,6 @@ gcal_window_constructed (GObject *object)
       g_signal_connect (priv->views[i], "create-event",
                         G_CALLBACK (show_new_event_widget), object);
     }
-  g_signal_connect (priv->views_overlay, "get-child-position",
-                    G_CALLBACK (place_new_event_widget), object);
 
   g_signal_connect (priv->search_bar, "notify::search-mode-enabled",
                     G_CALLBACK (gcal_window_search_toggled), object);
@@ -1655,7 +1622,6 @@ void
 gcal_window_new_event (GcalWindow *window)
 {
   GcalWindowPrivate *priv;
-
   gint x, y;
 
   priv = gcal_window_get_instance_private (window);
@@ -1704,8 +1670,7 @@ gcal_window_new_event (GcalWindow *window)
 
   prepare_new_event_widget (GCAL_WINDOW (window));
 
-  gtk_overlay_add_overlay (GTK_OVERLAY (priv->views_overlay),
-                           priv->new_event_widget);
+  place_new_event_widget (priv->popover, x, y);
 }
 
 void


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