[gnome-clocks] Rework code so that the content view is created in the .ui



commit be48004be3f99f54472e46336c1aef7067ead405
Author: Paolo Borelli <pborelli gnome org>
Date:   Sat Aug 16 10:29:57 2014 +0200

    Rework code so that the content view is created in the .ui
    
    This makes code cleaner since it removes some of the magic stuff
    from the ContentView class and should hopefully fix the regression
    with empty pages that the recent refactorings introduced

 data/ui/alarm.ui |   74 ++++++++++++++++++++---------------
 data/ui/world.ui |   74 ++++++++++++++++++++---------------
 src/alarm.vala   |   54 +++++++++++++++----------
 src/widgets.vala |  113 +++++++++++++++++++++++++++---------------------------
 src/world.vala   |   44 ++++++++++++---------
 5 files changed, 199 insertions(+), 160 deletions(-)
---
diff --git a/data/ui/alarm.ui b/data/ui/alarm.ui
index 191e504..e0771d4 100644
--- a/data/ui/alarm.ui
+++ b/data/ui/alarm.ui
@@ -1,48 +1,58 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.6 -->
-  <object class="GtkGrid" id="empty_view">
+  <template class="ClocksAlarmMainPanel" parent="GtkStack">
     <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="halign">center</property>
-    <property name="valign">center</property>
-    <property name="row_spacing">6</property>
+    <signal name="notify::visible-child" handler="visible_child_changed" swapped="no"/>
     <child>
-      <object class="GtkImage" id="image1">
+      <object class="GtkGrid" id="empty_view">
         <property name="visible">True</property>
-        <property name="sensitive">False</property>
         <property name="can_focus">False</property>
-        <property name="icon_name">alarm-symbolic</property>
-        <property name="icon_size">6</property>
+        <property name="halign">center</property>
+        <property name="valign">center</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkImage" id="image1">
+            <property name="visible">True</property>
+            <property name="sensitive">False</property>
+            <property name="can_focus">False</property>
+            <property name="icon_name">alarm-symbolic</property>
+            <property name="icon_size">6</property>
+          </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="GtkLabel" id="label1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Select &lt;b&gt;New&lt;/b&gt; to add an 
alarm</property>
+            <property name="use_markup">True</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
       </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="GtkLabel" id="label1">
+      <object class="ClocksContentView" id="content_view">
         <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="label" translatable="yes">Select &lt;b&gt;New&lt;/b&gt; to add an alarm</property>
-        <property name="use_markup">True</property>
-        <style>
-          <class name="dim-label"/>
-        </style>
+        <signal name="item-activated" handler="item_activated" swapped="no"/>
+        <signal name="delete-selected" handler="delete_selected" swapped="no"/>
+        <signal name="notify::empty" handler="empty_changed" swapped="no"/>
       </object>
-      <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">1</property>
-        <property name="width">1</property>
-        <property name="height">1</property>
-      </packing>
     </child>
-  </object>
-  <template class="ClocksAlarmMainPanel" parent="GtkStack">
-    <property name="visible">True</property>
-    <signal name="notify::visible-child" handler="visible_child_changed" swapped="no"/>
     <child>
       <object class="ClocksAlarmRingingPanel" id="ringing_panel">
         <property name="visible">True</property>
diff --git a/data/ui/world.ui b/data/ui/world.ui
index cd94b5f..c809124 100644
--- a/data/ui/world.ui
+++ b/data/ui/world.ui
@@ -1,48 +1,58 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.0 -->
-  <object class="GtkGrid" id="empty_view">
+  <template class="ClocksWorldMainPanel" parent="GtkStack">
     <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="halign">center</property>
-    <property name="valign">center</property>
-    <property name="row_spacing">6</property>
+    <signal name="notify::visible-child" handler="visible_child_changed" swapped="no"/>
     <child>
-      <object class="GtkImage" id="image1">
+      <object class="GtkGrid" id="empty_view">
         <property name="visible">True</property>
-        <property name="sensitive">False</property>
         <property name="can_focus">False</property>
-        <property name="icon_name">document-open-recent-symbolic</property>
-        <property name="icon-size">6</property>
+        <property name="halign">center</property>
+        <property name="valign">center</property>
+        <property name="row_spacing">6</property>
+        <child>
+          <object class="GtkImage" id="image1">
+            <property name="visible">True</property>
+            <property name="sensitive">False</property>
+            <property name="can_focus">False</property>
+            <property name="icon_name">document-open-recent-symbolic</property>
+            <property name="icon-size">6</property>
+          </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="GtkLabel" id="label1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Select &lt;b&gt;New&lt;/b&gt; to add a world 
clock</property>
+            <property name="use_markup">True</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+            <property name="width">1</property>
+            <property name="height">1</property>
+          </packing>
+        </child>
       </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="GtkLabel" id="label1">
+      <object class="ClocksContentView" id="content_view">
         <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="label" translatable="yes">Select &lt;b&gt;New&lt;/b&gt; to add a world 
clock</property>
-        <property name="use_markup">True</property>
-        <style>
-          <class name="dim-label"/>
-        </style>
+        <signal name="item-activated" handler="item_activated" swapped="no"/>
+        <signal name="delete-selected" handler="delete_selected" swapped="no"/>
+        <signal name="notify::empty" handler="empty_changed" swapped="no"/>
       </object>
-      <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">1</property>
-        <property name="width">1</property>
-        <property name="height">1</property>
-      </packing>
     </child>
-  </object>
-  <template class="ClocksWorldMainPanel" parent="GtkStack">
-    <property name="visible">True</property>
-    <signal name="notify::visible-child" handler="visible_child_changed" swapped="no"/>
     <child>
       <object class="GtkGrid" id="standalone">
         <property name="visible">True</property>
diff --git a/src/alarm.vala b/src/alarm.vala
index 07e2677..fb63772 100644
--- a/src/alarm.vala
+++ b/src/alarm.vala
@@ -525,6 +525,7 @@ public class MainPanel : Gtk.Stack, Clocks.Clock {
     private List<Item> alarms;
     private GLib.Settings settings;
     private Gtk.Button new_button;
+    [GtkChild]
     private ContentView content_view;
     [GtkChild]
     private Gtk.Widget empty_view;
@@ -561,28 +562,10 @@ public class MainPanel : Gtk.Stack, Clocks.Clock {
         new_button.action_name = "win.new";
         header_bar.pack_start (new_button);
 
-        content_view = new ContentView (empty_view, header_bar);
-        add (content_view);
-
-        content_view.item_activated.connect ((item) => {
-            Item alarm = (Item) item;
-            if (alarm.state == Item.State.SNOOZING) {
-                show_ringing_panel (alarm);
-            } else {
-                edit (alarm);
-            }
-        });
-
-        content_view.delete_selected.connect (() => {
-            foreach (Object i in content_view.get_selected_items ()) {
-                alarms.remove ((Item) i);
-            }
-            save ();
-        });
+        content_view.set_header_bar (header_bar);
 
         load ();
-
-        visible_child = content_view;
+        reset_view ();
         show_all ();
 
         // Start ticking...
@@ -604,13 +587,36 @@ public class MainPanel : Gtk.Stack, Clocks.Clock {
     public signal void ring ();
 
     [GtkCallback]
+    private void item_activated (ContentItem item) {
+        Item alarm = (Item) item;
+        if (alarm.state == Item.State.SNOOZING) {
+            show_ringing_panel (alarm);
+        } else {
+            edit (alarm);
+        }
+    }
+
+    [GtkCallback]
+    private void delete_selected () {
+        foreach (var i in content_view.get_selected_items ()) {
+            alarms.remove ((Item) i);
+        }
+        save ();
+    }
+
+    [GtkCallback]
+    private void empty_changed () {
+        reset_view ();
+    }
+
+    [GtkCallback]
     private void dismiss_ringing_panel () {
-        visible_child = content_view;
+       reset_view ();
     }
 
     [GtkCallback]
     private void visible_child_changed () {
-        if (visible_child == content_view) {
+        if (visible_child == empty_view || visible_child == content_view) {
             header_bar.mode = HeaderBar.Mode.NORMAL;
         } else if (visible_child == ringing_panel) {
             header_bar.mode = HeaderBar.Mode.STANDALONE;
@@ -671,6 +677,10 @@ public class MainPanel : Gtk.Stack, Clocks.Clock {
         visible_child = ringing_panel;
     }
 
+    private void reset_view () {
+        visible_child = content_view.empty ? empty_view : content_view;
+    }
+
     public void activate_new () {
         var dialog = new SetupDialog ((Gtk.Window) get_toplevel (), null, alarms);
         dialog.response.connect ((dialog, response) => {
diff --git a/src/widgets.vala b/src/widgets.vala
index dba08d2..219dc95 100644
--- a/src/widgets.vala
+++ b/src/widgets.vala
@@ -430,9 +430,7 @@ private class IconView : Gtk.IconView {
 public class ContentView : Gtk.Bin {
     public bool empty { get; private set; default = true; }
 
-    private Gtk.Widget empty_page;
     private IconView icon_view;
-    private HeaderBar header_bar;
     private Gtk.Button select_button;
     private Gtk.Button cancel_button;
     private GLib.MenuModel selection_menu;
@@ -440,47 +438,11 @@ public class ContentView : Gtk.Bin {
     private Gtk.Label selection_menubutton_label;
     private Gtk.Grid grid;
     private Gtk.Button delete_button;
+    private HeaderBar? header_bar;
 
-    public ContentView (Gtk.Widget e, HeaderBar b) {
-        empty_page = e;
-        header_bar = b;
-
+    construct {
         icon_view = new IconView ();
 
-        select_button = new Gtk.Button ();
-        Gtk.Image select_button_image = new Gtk.Image.from_icon_name ("object-select-symbolic", 
Gtk.IconSize.MENU);
-        select_button.set_image (select_button_image);
-        select_button.valign = Gtk.Align.CENTER;
-        select_button.no_show_all = true;
-        bind_property ("empty", select_button, "visible", BindingFlags.SYNC_CREATE | 
BindingFlags.INVERT_BOOLEAN);
-        select_button.clicked.connect (() => {
-            icon_view.mode = IconView.Mode.SELECTION;
-        });
-        header_bar.pack_end (select_button);
-
-        cancel_button = new Gtk.Button.with_label (_("Cancel"));
-        cancel_button.no_show_all = true;
-        cancel_button.valign = Gtk.Align.CENTER;
-        cancel_button.clicked.connect (() => {
-            icon_view.mode = IconView.Mode.NORMAL;
-        });
-        header_bar.pack_end (cancel_button);
-
-        var app = (Gtk.Application) GLib.Application.get_default ();
-        selection_menu = app.get_menu_by_id ("selection-menu");
-        selection_menubutton = new Gtk.MenuButton ();
-        selection_menubutton_label = new Gtk.Label (_("Click on items to select them"));
-        Gtk.Arrow selection_menubutton_arrow = new Gtk.Arrow (Gtk.ArrowType.DOWN, Gtk.ShadowType.NONE);
-        Gtk.Grid selection_menubutton_grid = new Gtk.Grid ();
-        selection_menubutton_grid.set_column_spacing (6);
-        selection_menubutton_grid.attach (selection_menubutton_label, 0, 0, 1, 1);
-        selection_menubutton_grid.attach (selection_menubutton_arrow, 1, 0, 1, 1);
-        selection_menubutton.add (selection_menubutton_grid);
-        selection_menubutton.show_all();
-        selection_menubutton.valign = Gtk.Align.CENTER;
-        selection_menubutton.menu_model = selection_menu;
-        selection_menubutton.get_style_context ().add_class ("selection-menu");
-
         var scrolled_window = new Gtk.ScrolledWindow (null, null);
         scrolled_window.add (icon_view);
         scrolled_window.hexpand = true;
@@ -510,18 +472,16 @@ public class ContentView : Gtk.Bin {
 
         var model = icon_view.get_model ();
         model.row_inserted.connect(() => {
-            update_empty_view (model);
+            update_empty (model);
         });
         model.row_deleted.connect(() => {
-            update_empty_view (model);
+            update_empty (model);
         });
 
         icon_view.notify["mode"].connect (() => {
             if (icon_view.mode == IconView.Mode.SELECTION) {
-                header_bar.mode = HeaderBar.Mode.SELECTION;
                 action_bar.show ();
             } else if (icon_view.mode == IconView.Mode.NORMAL) {
-                header_bar.mode = HeaderBar.Mode.NORMAL;
                 action_bar.hide ();
             }
         });
@@ -557,38 +517,33 @@ public class ContentView : Gtk.Bin {
                 } else {
                     Object item;
                     store.get (i, IconView.Column.ITEM, out item);
-                    item_activated (item);
+                    item_activated ((ContentItem) item);
                 }
             }
         });
 
-        add (empty_page);
+        add (grid);
+        grid.show_all ();
     }
 
-    public signal void item_activated (Object item);
+    public signal void item_activated (ContentItem item);
 
     public virtual signal void delete_selected () {
         icon_view.remove_selected ();
     }
 
-    private void update_empty_view (Gtk.TreeModel model) {
+    private void update_empty (Gtk.TreeModel model) {
         Gtk.TreeIter i;
 
-        var child = get_child ();
         if (model.get_iter_first (out i)) {
-            if (child != grid) {
-                remove (child);
-                add (grid);
+            if (empty) {
                 empty = false;
             }
         } else {
-            if (child != empty_page) {
-                remove (child);
-                add (empty_page);
+            if (!empty) {
                 empty = true;
             }
         }
-        show_all ();
     }
 
     public void add_item (ContentItem item) {
@@ -636,6 +591,52 @@ public class ContentView : Gtk.Bin {
         return false;
     }
 
+    public void set_header_bar (HeaderBar bar) {
+        header_bar = bar;
+
+        select_button = new Gtk.Button ();
+        Gtk.Image select_button_image = new Gtk.Image.from_icon_name ("object-select-symbolic", 
Gtk.IconSize.MENU);
+        select_button.set_image (select_button_image);
+        select_button.valign = Gtk.Align.CENTER;
+        select_button.no_show_all = true;
+        bind_property ("empty", select_button, "visible", BindingFlags.SYNC_CREATE | 
BindingFlags.INVERT_BOOLEAN);
+        select_button.clicked.connect (() => {
+            icon_view.mode = IconView.Mode.SELECTION;
+        });
+        header_bar.pack_end (select_button);
+
+        cancel_button = new Gtk.Button.with_label (_("Cancel"));
+        cancel_button.no_show_all = true;
+        cancel_button.valign = Gtk.Align.CENTER;
+        cancel_button.clicked.connect (() => {
+            icon_view.mode = IconView.Mode.NORMAL;
+        });
+        header_bar.pack_end (cancel_button);
+
+        var app = (Gtk.Application) GLib.Application.get_default ();
+        selection_menu = app.get_menu_by_id ("selection-menu");
+        selection_menubutton = new Gtk.MenuButton ();
+        selection_menubutton_label = new Gtk.Label (_("Click on items to select them"));
+        Gtk.Arrow selection_menubutton_arrow = new Gtk.Arrow (Gtk.ArrowType.DOWN, Gtk.ShadowType.NONE);
+        Gtk.Grid selection_menubutton_grid = new Gtk.Grid ();
+        selection_menubutton_grid.set_column_spacing (6);
+        selection_menubutton_grid.attach (selection_menubutton_label, 0, 0, 1, 1);
+        selection_menubutton_grid.attach (selection_menubutton_arrow, 1, 0, 1, 1);
+        selection_menubutton.add (selection_menubutton_grid);
+        selection_menubutton.show_all();
+        selection_menubutton.valign = Gtk.Align.CENTER;
+        selection_menubutton.menu_model = selection_menu;
+        selection_menubutton.get_style_context ().add_class ("selection-menu");
+
+        icon_view.notify["mode"].connect (() => {
+            if (icon_view.mode == IconView.Mode.SELECTION) {
+                header_bar.mode = HeaderBar.Mode.SELECTION;
+            } else if (icon_view.mode == IconView.Mode.NORMAL) {
+                header_bar.mode = HeaderBar.Mode.NORMAL;
+            }
+        });
+    }
+
     public void update_header_bar () {
         switch (header_bar.mode) {
         case HeaderBar.Mode.SELECTION:
diff --git a/src/world.vala b/src/world.vala
index b09321c..81e6993 100644
--- a/src/world.vala
+++ b/src/world.vala
@@ -227,9 +227,10 @@ public class MainPanel : Gtk.Stack, Clocks.Clock {
     private Gtk.Button back_button;
     private Gdk.Pixbuf? day_pixbuf;
     private Gdk.Pixbuf? night_pixbuf;
-    private ContentView content_view;
     private Item standalone_location;
     [GtkChild]
+    private ContentView content_view;
+    [GtkChild]
     private Gtk.Widget empty_view;
     [GtkChild]
     private Gtk.Widget standalone;
@@ -264,11 +265,11 @@ public class MainPanel : Gtk.Stack, Clocks.Clock {
         back_button.set_image (back_button_image);
         back_button.no_show_all = true;
         back_button.clicked.connect (() => {
-            visible_child = content_view;
+            reset_view ();
         });
         header_bar.pack_start (back_button);
 
-        content_view = new ContentView (empty_view, header_bar);
+        content_view.set_header_bar (header_bar);
         content_view.set_sorting(Gtk.SortType.ASCENDING, (item1, item2) => {
             var offset1 = ((Item) item1).location.get_timezone().get_offset();
             var offset2 = ((Item) item2).location.get_timezone().get_offset();
@@ -278,18 +279,6 @@ public class MainPanel : Gtk.Stack, Clocks.Clock {
                 return 1;
             return 0;
         });
-        add (content_view);
-
-        content_view.item_activated.connect ((item) => {
-            show_standalone ((Item) item);
-        });
-
-        content_view.delete_selected.connect (() => {
-            foreach (Object i in content_view.get_selected_items ()) {
-                locations.remove ((Item) i);
-            }
-            save ();
-        });
 
         load ();
 
@@ -299,7 +288,7 @@ public class MainPanel : Gtk.Stack, Clocks.Clock {
             });
         }
 
-        visible_child = content_view;
+        reset_view ();
         show_all ();
 
         // Start ticking...
@@ -313,8 +302,26 @@ public class MainPanel : Gtk.Stack, Clocks.Clock {
     }
 
     [GtkCallback]
+    private void item_activated (ContentItem item) {
+        show_standalone ((Item) item);
+    }
+
+    [GtkCallback]
+    private void delete_selected () {
+        foreach (var i in content_view.get_selected_items ()) {
+            locations.remove ((Item) i);
+        }
+        save ();
+    }
+
+    [GtkCallback]
+    private void empty_changed () {
+        reset_view ();
+    }
+
+    [GtkCallback]
     private void visible_child_changed () {
-        if (visible_child == content_view) {
+        if (visible_child == empty_view || visible_child == content_view) {
             header_bar.mode = HeaderBar.Mode.NORMAL;
         } else if (visible_child == standalone) {
             header_bar.mode = HeaderBar.Mode.STANDALONE;
@@ -407,7 +414,8 @@ public class MainPanel : Gtk.Stack, Clocks.Clock {
     }
 
     public void reset_view () {
-        visible_child = content_view;
+        standalone_location = null;
+        visible_child = content_view.empty ? empty_view : content_view;
     }
 
     public void update_header_bar () {


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