[geary] Use GtkTemplate for the MainToolbar



commit 4f404b15d47e6107ce2161869cba05e519f2431a
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Mon Oct 31 14:35:02 2016 +0100

    Use GtkTemplate for the MainToolbar
    
    Bug 773728.
    
    Signed-off-by: Niels De Graef <nielsdegraef gmail com>

 po/POTFILES.in                          |    1 +
 src/client/components/main-toolbar.vala |  208 ++++++++------------------
 ui/CMakeLists.txt                       |    1 +
 ui/main-toolbar.ui                      |  242 +++++++++++++++++++++++++++++++
 4 files changed, 307 insertions(+), 145 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index af45d4c..e07a56a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -397,6 +397,7 @@ src/mailer/main.vala
 [type: gettext/glade]ui/gtk/help-overlay.ui
 [type: gettext/glade]ui/gtk/menus.ui
 [type: gettext/glade]ui/login.glade
+[type: gettext/glade]ui/main-toolbar.ui
 [type: gettext/glade]ui/password-dialog.glade
 [type: gettext/glade]ui/preferences.glade
 [type: gettext/glade]ui/remove_confirm.glade
diff --git a/src/client/components/main-toolbar.vala b/src/client/components/main-toolbar.vala
index 2d6e13c..c907eb7 100644
--- a/src/client/components/main-toolbar.vala
+++ b/src/client/components/main-toolbar.vala
@@ -5,6 +5,7 @@
  */
 
 // Draws the main toolbar.
+[GtkTemplate (ui = "/org/gnome/Geary/main-toolbar.ui")]
 public class MainToolbar : Gtk.Box {
     private Gtk.ActionGroup action_group;
     public FolderPopover copy_folder_menu { get; private set; default = new FolderPopover(); }
@@ -18,24 +19,44 @@ public class MainToolbar : Gtk.Box {
     public bool find_open { get; set; default = false; }
     public int left_pane_width { get; set; }
 
+    // Folder header elements
+    [GtkChild]
     private Gtk.HeaderBar folder_header;
+    [GtkChild]
+    private Gtk.Button compose_new_message_button;
+    [GtkChild]
+    private Gtk.MenuButton empty_menu_button;
+    [GtkChild]
+    private Gtk.ToggleButton search_conversations_button;
+    private Binding guest_header_binding;
+
+    // Conversation header elements
+    [GtkChild]
     private Gtk.HeaderBar conversation_header;
+    [GtkChild]
+    private Gtk.Button reply_sender_button;
+    [GtkChild]
+    private Gtk.Button reply_all_button;
+    [GtkChild]
+    private Gtk.Button forward_button;
+    [GtkChild]
+    private Gtk.MenuButton mark_message_button;
+    [GtkChild]
+    private Gtk.MenuButton copy_message_button;
+    [GtkChild]
+    private Gtk.MenuButton move_message_button;
+    [GtkChild]
     private Gtk.Button archive_button;
+    [GtkChild]
     private Gtk.Button trash_delete_button;
-    private Binding guest_header_binding;
+    [GtkChild]
+    private Gtk.Button undo_button;
+    [GtkChild]
+    private Gtk.ToggleButton find_button;
 
     public MainToolbar() {
-        Object(orientation: Gtk.Orientation.HORIZONTAL, spacing: 0);
-
         this.action_group = GearyApplication.instance.actions;
 
-        folder_header = new Gtk.HeaderBar();
-        conversation_header = new Gtk.HeaderBar();
-        folder_header.get_style_context().add_class("geary-titlebar");
-        folder_header.get_style_context().add_class("geary-titlebar-left");
-        conversation_header.get_style_context().add_class("geary-titlebar");
-        conversation_header.get_style_context().add_class("geary-titlebar-right");
-
         // Instead of putting a separator between the two headerbars, as other applications do,
         // we put a separator at the right end of the left headerbar.  This greatly improves
         // the appearance under the Ambiance theme (see bug #746171).  To get this separator to
@@ -56,85 +77,36 @@ public class MainToolbar : Gtk.Box {
         this.bind_property("show-close-button-right", conversation_header, "show-close-button",
             BindingFlags.SYNC_CREATE);
 
-        // Assemble mark menu.
+        // Assemble the empty/mark menus
+        GearyApplication.instance.load_ui_resource("toolbar_empty_menu.ui");
+        Gtk.Menu empty_menu = (Gtk.Menu) 
GearyApplication.instance.ui_manager.get_widget("/ui/ToolbarEmptyMenu");
         GearyApplication.instance.load_ui_resource("toolbar_mark_menu.ui");
         Gtk.Menu mark_menu = (Gtk.Menu) 
GearyApplication.instance.ui_manager.get_widget("/ui/ToolbarMarkMenu");
-        mark_menu.foreach(GtkUtil.show_menuitem_accel_labels);
-
-        // Toolbar setup.
-        Gee.List<Gtk.Button> insert = new Gee.ArrayList<Gtk.Button>();
 
-        // Compose.
-        insert.add(create_toolbar_button("text-editor-symbolic",
-            GearyController.ACTION_NEW_MESSAGE));
-        add_start(folder_header, create_pill_buttons(insert, false));
-
-        // Assemble the empty menu
-        GearyApplication.instance.load_ui_resource("toolbar_empty_menu.ui");
-        Gtk.Menu empty_menu = (Gtk.Menu) 
GearyApplication.instance.ui_manager.get_widget("/ui/ToolbarEmptyMenu");
-        empty_menu.foreach(GtkUtil.show_menuitem_accel_labels);
-        insert.clear();
-        insert.add(create_menu_button(null, empty_menu, GearyController.ACTION_EMPTY_MENU));
-        Gtk.Box empty = create_pill_buttons(insert, false);
+        // Setup folder header elements
+        setup_button(compose_new_message_button, GearyController.ACTION_NEW_MESSAGE);
+        setup_menu_button(empty_menu_button, empty_menu, GearyController.ACTION_EMPTY_MENU);
 
-        // Search
-        insert.clear();
-        Gtk.Button search_button = create_toggle_button("preferences-system-search-symbolic",
-            GearyController.ACTION_TOGGLE_SEARCH);
-        this.bind_property("search-open", search_button, "active",
+        setup_button(search_conversations_button, GearyController.ACTION_TOGGLE_SEARCH);
+        this.bind_property("search-open", search_conversations_button, "active",
             BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
-        insert.add(search_button);
-        Gtk.Box search = create_pill_buttons(insert, false);
-
-        add_end(folder_header, new Gtk.Separator(Gtk.Orientation.VERTICAL));
-        add_end(folder_header, search);
-        add_end(folder_header, empty);
-
-        // Reply buttons
-        insert.clear();
-        insert.add(create_toolbar_button("mail-reply-sender-symbolic",
-            GearyController.ACTION_REPLY_TO_MESSAGE));
-        insert.add(create_toolbar_button("mail-reply-all-symbolic",
-            GearyController.ACTION_REPLY_ALL_MESSAGE));
-        insert.add(create_toolbar_button("mail-forward-symbolic",
-            GearyController.ACTION_FORWARD_MESSAGE));
-        add_start(conversation_header, create_pill_buttons(insert));
 
-        // Mark, copy, move.
-        insert.clear();
-        insert.add(create_menu_button("marker-symbolic", mark_menu,
-            GearyController.ACTION_MARK_AS_MENU));
-        insert.add(create_popover_button("tag-symbolic", copy_folder_menu,
-            GearyController.ACTION_COPY_MENU));
-        insert.add(create_popover_button("folder-symbolic", move_folder_menu,
-            GearyController.ACTION_MOVE_MENU));
-        add_start(conversation_header, create_pill_buttons(insert));
+        // Setup conversation header elements
+        setup_button(reply_sender_button, GearyController.ACTION_REPLY_TO_MESSAGE);
+        setup_button(reply_all_button, GearyController.ACTION_REPLY_ALL_MESSAGE);
+        setup_button(forward_button, GearyController.ACTION_FORWARD_MESSAGE);
 
-        // Archive, undo, find
-        insert.clear();
-        insert.add(archive_button = create_toolbar_button(null, GearyController.ACTION_ARCHIVE_MESSAGE, 
true));
-        insert.add(trash_delete_button = create_toolbar_button(null, GearyController.ACTION_TRASH_MESSAGE, 
false));
-        Gtk.Box archive_trash_delete = create_pill_buttons(insert);
+        setup_menu_button(mark_message_button, mark_menu, GearyController.ACTION_MARK_AS_MENU);
+        setup_popover_button(copy_message_button, copy_folder_menu, GearyController.ACTION_COPY_MENU);
+        setup_popover_button(move_message_button, move_folder_menu, GearyController.ACTION_MOVE_MENU);
 
-        insert.clear();
-        insert.add(create_toolbar_button(null, GearyController.ACTION_UNDO,
-            false));
-        Gtk.Box undo = create_pill_buttons(insert);
+        setup_button(archive_button, GearyController.ACTION_ARCHIVE_MESSAGE, true);
+        setup_button(trash_delete_button, GearyController.ACTION_TRASH_MESSAGE);
+        setup_button(undo_button, GearyController.ACTION_UNDO);
 
-        Gtk.Button find_button = create_toggle_button(
-            "preferences-system-search-symbolic", GearyController.ACTION_TOGGLE_FIND);
+        setup_button(find_button, GearyController.ACTION_TOGGLE_FIND);
         this.bind_property("find-open", find_button, "active",
             BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
-        insert.clear();
-        insert.add(find_button);
-        Gtk.Box find = create_pill_buttons(insert);
-
-        add_end(conversation_header, find);
-        add_end(conversation_header, undo);
-        add_end(conversation_header, archive_trash_delete);
-
-        pack_start(folder_header, false, false);
-        pack_start(conversation_header, true, true);
 
         Gtk.Settings.get_default().notify["gtk-decoration-layout"].connect(set_window_buttons);
         realize.connect(set_window_buttons);
@@ -143,7 +115,7 @@ public class MainToolbar : Gtk.Box {
     public void update_trash_button(bool is_trash) {
         string action_name = (is_trash ? GearyController.ACTION_TRASH_MESSAGE
             : GearyController.ACTION_DELETE_MESSAGE);
-        setup_button(trash_delete_button, null, action_name, false);
+        setup_button(trash_delete_button, action_name, false);
     }
 
     public void set_conversation_header(Gtk.HeaderBar header) {
@@ -178,19 +150,10 @@ public class MainToolbar : Gtk.Box {
         conversation_header.decoration_layout = ":" + buttons[1];
     }
 
-    // PILLBAR METHODS
-    public virtual void add_start(Gtk.HeaderBar header_bar, Gtk.Widget widget) {
-        header_bar.pack_start(widget);
-    }
-
-    public virtual void add_end(Gtk.HeaderBar header_bar, Gtk.Widget widget) {
-        header_bar.pack_end(widget);
-    }
-
-    public virtual void setup_button(Gtk.Button b, string? icon_name, string action_name,
-        bool show_label = false) {
+    public void setup_button(Gtk.Button b, string action_name, bool show_label = false) {
         Gtk.Action related_action = action_group.get_action(action_name);
         b.focus_on_click = false;
+        b.use_underline = true;
         b.tooltip_text = related_action.tooltip;
         related_action.notify["tooltip"].connect(() => { b.tooltip_text = related_action.tooltip; });
         b.related_action = related_action;
@@ -199,7 +162,7 @@ public class MainToolbar : Gtk.Box {
         // the action's stock ID ... although stock IDs are being deprecated, that's how we specify
         // the icon in the GtkActionEntry (also being deprecated) and GTK+ 3.14 doesn't support that
         // any longer
-        string? icon_to_load = icon_name ?? b.related_action.icon_name;
+        string? icon_to_load = b.related_action.icon_name;
         if (icon_to_load == null)
             icon_to_load = b.related_action.stock_id;
 
@@ -213,36 +176,18 @@ public class MainToolbar : Gtk.Box {
 
         b.always_show_image = true;
 
-        if (!show_label)
+        if (show_label)
+            b.label = related_action.label;
+        else
             b.label = null;
     }
 
     /**
-     * Given an icon and action, creates a button that triggers the action.
-     */
-    public virtual Gtk.Button create_toolbar_button(string? icon_name, string action_name, bool show_label = 
false) {
-        Gtk.Button b = new Gtk.Button();
-        setup_button(b, icon_name, action_name, show_label);
-
-        return b;
-    }
-
-    /**
-     * Given an icon and action, creates a toggle button that triggers the action.
-     */
-    public virtual Gtk.Button create_toggle_button(string? icon_name, string action_name) {
-        Gtk.ToggleButton b = new Gtk.ToggleButton();
-        setup_button(b, icon_name, action_name);
-
-        return b;
-    }
-
-    /**
      * Given an icon, menu, and action, creates a button that triggers the menu and the action.
      */
-    public virtual Gtk.MenuButton create_menu_button(string? icon_name, Gtk.Menu? menu, string action_name) {
-        Gtk.MenuButton b = new Gtk.MenuButton();
-        setup_button(b, icon_name, action_name);
+    public void setup_menu_button(Gtk.MenuButton b, Gtk.Menu menu, string action_name) {
+        setup_button(b, action_name);
+        menu.foreach(GtkUtil.show_menuitem_accel_labels);
         b.popup = menu;
 
         if (b.related_action != null) {
@@ -253,17 +198,14 @@ public class MainToolbar : Gtk.Box {
             // above, invoking would cause an infinite loop otherwise.
             b.related_action = null;
         }
-
-        return b;
     }
 
     /**
      * Given an icon, popover, and action, creates a button that triggers the popover and the action.
      */
-    public virtual Gtk.MenuButton create_popover_button(string? icon_name, Gtk.Popover? popover, string 
action_name) {
-        Gtk.MenuButton b = new Gtk.MenuButton();
-        setup_button(b, icon_name, action_name);
-        b.set_popover(popover);
+    public void setup_popover_button(Gtk.MenuButton b, Gtk.Popover popover, string action_name) {
+        setup_button(b, action_name);
+        b.popover = popover;
         b.clicked.connect(() => popover.show_all());
 
         if (b.related_action != null) {
@@ -274,29 +216,5 @@ public class MainToolbar : Gtk.Box {
             // above, invoking would cause an infinite loop otherwise.
             b.related_action = null;
         }
-
-        return b;
-    }
-
-    /**
-     * Given a list of buttons, creates a "pill-style" tool item that can be appended to this
-     * toolbar.  Optionally adds spacers "before" and "after" the buttons (those terms depending
-     * on Gtk.TextDirection)
-     */
-    public virtual Gtk.Box create_pill_buttons(Gee.Collection<Gtk.Button> buttons,
-        bool before_spacer = true, bool after_spacer = false) {
-        Gtk.Box box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
-        box.valign = Gtk.Align.CENTER;
-        box.halign = Gtk.Align.CENTER;
-
-        if (buttons.size > 1) {
-            box.get_style_context().add_class(Gtk.STYLE_CLASS_RAISED);
-            box.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED);
-        }
-
-        foreach(Gtk.Button button in buttons)
-            box.add(button);
-
-        return box;
     }
 }
diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt
index c3dac11..e2ac935 100644
--- a/ui/CMakeLists.txt
+++ b/ui/CMakeLists.txt
@@ -22,6 +22,7 @@ set(RESOURCE_LIST
   STRIPBLANKS "gtk/help-overlay.ui"
   STRIPBLANKS "gtk/menus.ui"
   STRIPBLANKS "login.glade"
+  STRIPBLANKS "main-toolbar.ui"
   STRIPBLANKS "password-dialog.glade"
   STRIPBLANKS "preferences.glade"
   STRIPBLANKS "remove_confirm.glade"
diff --git a/ui/main-toolbar.ui b/ui/main-toolbar.ui
new file mode 100644
index 0000000..58cff1d
--- /dev/null
+++ b/ui/main-toolbar.ui
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="3.14"/>
+  <template class="MainToolbar" parent="GtkBox">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="orientation">horizontal</property>
+    <property name="spacing">0</property>
+    <child>
+      <object class="GtkHeaderBar" id="folder_header">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <style>
+          <class name="geary-titlebar" />
+          <class name="geary-titlebar-left" />
+        </style>
+        <child>
+          <object class="GtkButton" id="compose_new_message_button">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="compose_new_message_image">
+                <property name="icon_name">text-editor-symbolic</property>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkSeparator" id="header_separator">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkToggleButton" id="search_conversations_button">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="search_conversations_image">
+                <property name="icon_name">preferences-system-search-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkMenuButton" id="empty_menu_button">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="always_show_image">True</property>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <child>
+      <object class="GtkHeaderBar" id="conversation_header">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <style>
+          <class name="geary-titlebar" />
+          <class name="geary-titlebar-right" />
+        </style>
+        <child>
+          <object class="GtkBox" id="reply_forward_buttons">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <style>
+              <class name="raised" />
+              <class name="linked" />
+            </style>
+            <child>
+              <object class="GtkButton" id="reply_sender_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="focus_on_click">False</property>
+                <property name="always_show_image">True</property>
+                <child>
+                  <object class="GtkImage" id="reply_sender_image">
+                    <property name="icon_name">mail-reply-sender-symbolic</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="reply_all_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="focus_on_click">False</property>
+                <property name="always_show_image">True</property>
+                <child>
+                  <object class="GtkImage" id="reply_all_image">
+                    <property name="icon_name">mail-reply-all-symbolic</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="forward_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="focus_on_click">False</property>
+                <property name="always_show_image">True</property>
+                <child>
+                  <object class="GtkImage" id="forward_image">
+                    <property name="icon_name">mail-forward-symbolic</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox" id="mark_copy_move_buttons">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <style>
+              <class name="raised" />
+              <class name="linked" />
+            </style>
+            <child>
+              <object class="GtkMenuButton" id="mark_message_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="focus_on_click">False</property>
+                <property name="always_show_image">True</property>
+                <child>
+                  <object class="GtkImage" id="mark_message_image">
+                    <property name="icon_name">marker-symbolic</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkMenuButton" id="copy_message_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="focus_on_click">False</property>
+                <property name="always_show_image">True</property>
+                <child>
+                  <object class="GtkImage" id="copy_message_image">
+                    <property name="icon_name">tag-symbolic</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkMenuButton" id="move_message_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="focus_on_click">False</property>
+                <property name="always_show_image">True</property>
+                <child>
+                  <object class="GtkImage" id="move_message_image">
+                    <property name="icon_name">folder-symbolic</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkToggleButton" id="find_button">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="find_image">
+                <property name="icon_name">preferences-system-search-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="undo_button">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="focus_on_click">False</property>
+            <property name="always_show_image">True</property>
+            <child>
+              <object class="GtkImage" id="undo_image">
+                <property name="icon_name">preferences-system-search-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="archive_trash_delete_buttons">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <style>
+              <class name="raised" />
+              <class name="linked" />
+            </style>
+            <child>
+              <object class="GtkButton" id="archive_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="focus_on_click">False</property>
+                <property name="always_show_image">True</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkButton" id="trash_delete_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="focus_on_click">False</property>
+                <property name="always_show_image">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="expand">True</property>
+      </packing>
+    </child>
+  </template>
+</interface>


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