[gnome-builder] tab: break tab contents into header, content, and footer internal children



commit 27d2299ed8aecb134e3885cba257458e37e96610
Author: Christian Hergert <christian hergert me>
Date:   Sun Nov 23 16:16:55 2014 -0800

    tab: break tab contents into header, content, and footer internal children
    
    This makes it easier for us to transitiona way from the notebook tabs if
    possible. We can use the header area for common shared widgets as well
    as allowing tabs to place special content there.

 src/resources/gnome-builder.gresource.xml |    1 +
 src/resources/ui/gb-devhelp-tab.ui        |   90 ++++++++-------
 src/resources/ui/gb-editor-tab.ui         |  172 +++++++++++++++--------------
 src/resources/ui/gb-tab.ui                |   28 +++++
 src/tabs/gb-tab.c                         |   94 +++++++++++++---
 src/tabs/gb-tab.h                         |   29 +++--
 6 files changed, 260 insertions(+), 154 deletions(-)
---
diff --git a/src/resources/gnome-builder.gresource.xml b/src/resources/gnome-builder.gresource.xml
index 3f83c33..5ee89cd 100644
--- a/src/resources/gnome-builder.gresource.xml
+++ b/src/resources/gnome-builder.gresource.xml
@@ -29,6 +29,7 @@
     <file>ui/gb-preferences-page-editor.ui</file>
     <file>ui/gb-preferences-page-git.ui</file>
     <file>ui/gb-preferences-page-language.ui</file>
+    <file>ui/gb-tab.ui</file>
     <file>ui/gb-tab-label.ui</file>
     <file>ui/gb-workbench.ui</file>
   </gresource>
diff --git a/src/resources/ui/gb-devhelp-tab.ui b/src/resources/ui/gb-devhelp-tab.ui
index 76df1d4..06caecd 100644
--- a/src/resources/ui/gb-devhelp-tab.ui
+++ b/src/resources/ui/gb-devhelp-tab.ui
@@ -5,73 +5,77 @@
     <property name="visible">True</property>
     <property name="can_focus">False</property>
     <property name="orientation">vertical</property>
-    <child>
-      <object class="GtkOverlay" id="overlay">
-        <property name="visible">True</property>
+    <child internal-child="content">
+      <object class="GtkBox">
         <child>
-          <object class="GtkScrolledWindow" id="scroller">
+          <object class="GtkOverlay" id="overlay">
             <property name="visible">True</property>
-            <property name="vexpand">True</property>
             <child>
-              <object class="WebKitWebView" id="web_view">
+              <object class="GtkScrolledWindow" id="scroller">
                 <property name="visible">True</property>
+                <property name="vexpand">True</property>
+                <child>
+                  <object class="WebKitWebView" id="web_view">
+                    <property name="visible">True</property>
+                  </object>
+                </child>
               </object>
             </child>
-          </object>
-        </child>
-        <child type="overlay">
-          <object class="GtkRevealer" id="revealer">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="halign">end</property>
-            <property name="valign">start</property>
-            <child>
-              <object class="GtkFrame" id="frame">
+            <child type="overlay">
+              <object class="GtkRevealer" id="revealer">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <style>
-                  <class name="gb-search-slider"/>
-                </style>
+                <property name="halign">end</property>
+                <property name="valign">start</property>
                 <child>
-                  <object class="GtkBox" id="hbox">
+                  <object class="GtkFrame" id="frame">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="orientation">horizontal</property>
                     <style>
-                      <class name="linked"/>
+                      <class name="gb-search-slider"/>
                     </style>
                     <child>
-                      <object class="GdTaggedEntry" id="search_entry">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="primary-icon-activatable">True</property>
-                        <property name="primary-icon-sensitive">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="go_up_button">
+                      <object class="GtkBox" id="hbox">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="orientation">horizontal</property>
+                        <style>
+                          <class name="linked"/>
+                        </style>
+                        <child>
+                          <object class="GdTaggedEntry" id="search_entry">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="primary-icon-activatable">True</property>
+                            <property name="primary-icon-sensitive">True</property>
+                          </object>
+                        </child>
                         <child>
-                          <object class="GtkImage" id="up_image">
+                          <object class="GtkButton" id="go_up_button">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="icon_size">1</property>
-                            <property name="icon_name">go-up-symbolic</property>
+                            <child>
+                              <object class="GtkImage" id="up_image">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="icon_size">1</property>
+                                <property name="icon_name">go-up-symbolic</property>
+                              </object>
+                            </child>
                           </object>
                         </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="go_down_button">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkImage" id="down_image">
+                          <object class="GtkButton" id="go_down_button">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="icon_size">1</property>
-                            <property name="icon_name">go-down-symbolic</property>
+                            <child>
+                              <object class="GtkImage" id="down_image">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="icon_size">1</property>
+                                <property name="icon_name">go-down-symbolic</property>
+                              </object>
+                            </child>
                           </object>
                         </child>
                       </object>
diff --git a/src/resources/ui/gb-editor-tab.ui b/src/resources/ui/gb-editor-tab.ui
index e22d165..56c9fef 100644
--- a/src/resources/ui/gb-editor-tab.ui
+++ b/src/resources/ui/gb-editor-tab.ui
@@ -6,110 +6,114 @@
     <property name="can_focus">False</property>
     <property name="orientation">horizontal</property>
     <property name="expand">True</property>
-    <child>
-      <object class="GtkOverlay" id="overlay">
-        <property name="visible">True</property>
+    <child internal-child="content">
+      <object class="GtkBox" id="content">
         <child>
-          <object class="GtkScrolledWindow" id="scroller">
+          <object class="GtkOverlay" id="overlay">
             <property name="visible">True</property>
-            <property name="expand">True</property>
             <child>
-              <object class="GbSourceView" id="source_view">
+              <object class="GtkScrolledWindow" id="scroller">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="show_line_numbers">True</property>
-                <property name="show_right_margin">True</property>
-                <property name="right_margin_position">80</property>
+                <property name="expand">True</property>
+                <child>
+                  <object class="GbSourceView" id="source_view">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="show_line_numbers">True</property>
+                    <property name="show_right_margin">True</property>
+                    <property name="right_margin_position">80</property>
+                  </object>
+                </child>
               </object>
             </child>
-          </object>
-        </child>
-        <child type="overlay">
-          <object class="GtkProgressBar" id="progress_bar">
-            <property name="visible">False</property>
-            <property name="halign">fill</property>
-            <property name="valign">start</property>
-            <property name="fraction">0.0</property>
-            <style>
-              <class name="osd"/>
-            </style>
-          </object>
-        </child>
-        <child type="overlay">
-          <object class="NautilusFloatingBar" id="floating_bar">
-            <property name="visible">True</property>
-            <property name="halign">end</property>
-            <property name="valign">end</property>
-            <child>
-              <object class="GtkSpinner" id="parsing_spinner">
+            <child type="overlay">
+              <object class="GtkProgressBar" id="progress_bar">
                 <property name="visible">False</property>
-                <property name="active">False</property>
-                <property name="margin-start">6</property>
-                <property name="tooltip-text" translatable="yes">Currently parsing document.</property>
+                <property name="halign">fill</property>
+                <property name="valign">start</property>
+                <property name="fraction">0.0</property>
+                <style>
+                  <class name="osd"/>
+                </style>
               </object>
-              <packing>
-                <property name="pack_type">GTK_PACK_START</property>
-                <property name="position">0</property>
-              </packing>
             </child>
-          </object>
-        </child>
-        <child type="overlay">
-          <object class="GtkRevealer" id="revealer">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="halign">end</property>
-            <property name="valign">start</property>
-            <child>
-              <object class="GtkFrame" id="frame">
+            <child type="overlay">
+              <object class="NautilusFloatingBar" id="floating_bar">
+                <property name="visible">True</property>
+                <property name="halign">end</property>
+                <property name="valign">end</property>
+                <child>
+                  <object class="GtkSpinner" id="parsing_spinner">
+                    <property name="visible">False</property>
+                    <property name="active">False</property>
+                    <property name="margin-start">6</property>
+                    <property name="tooltip-text" translatable="yes">Currently parsing document.</property>
+                  </object>
+                  <packing>
+                    <property name="pack_type">GTK_PACK_START</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+            <child type="overlay">
+              <object class="GtkRevealer" id="revealer">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="margin_end">12</property>
-                <style>
-                  <class name="gb-search-slider"/>
-                </style>
+                <property name="halign">end</property>
+                <property name="valign">start</property>
                 <child>
-                  <object class="GtkBox" id="hbox">
+                  <object class="GtkFrame" id="frame">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="orientation">horizontal</property>
+                    <property name="margin_end">12</property>
                     <style>
-                      <class name="linked"/>
+                      <class name="gb-search-slider"/>
                     </style>
                     <child>
-                      <object class="GdTaggedEntry" id="search_entry">
-                        <property name="visible">True</property>
-                        <property name="tag-close-visible">False</property>
-                        <property name="can_focus">True</property>
-                        <property name="width-request">260</property>
-                        <property name="primary-icon-activatable">True</property>
-                        <property name="primary-icon-sensitive">True</property>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="go_up_button">
+                      <object class="GtkBox" id="hbox">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="orientation">horizontal</property>
+                        <style>
+                          <class name="linked"/>
+                        </style>
                         <child>
-                          <object class="GtkImage" id="up_image">
+                          <object class="GdTaggedEntry" id="search_entry">
+                            <property name="visible">True</property>
+                            <property name="tag-close-visible">False</property>
+                            <property name="can_focus">True</property>
+                            <property name="width-request">260</property>
+                            <property name="primary-icon-activatable">True</property>
+                            <property name="primary-icon-sensitive">True</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkButton" id="go_up_button">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="icon_size">1</property>
-                            <property name="icon_name">go-up-symbolic</property>
+                            <child>
+                              <object class="GtkImage" id="up_image">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="icon_size">1</property>
+                                <property name="icon_name">go-up-symbolic</property>
+                              </object>
+                            </child>
                           </object>
                         </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="go_down_button">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkImage" id="down_image">
+                          <object class="GtkButton" id="go_down_button">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="icon_size">1</property>
-                            <property name="icon_name">go-down-symbolic</property>
+                            <child>
+                              <object class="GtkImage" id="down_image">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="icon_size">1</property>
+                                <property name="icon_name">go-down-symbolic</property>
+                              </object>
+                            </child>
                           </object>
                         </child>
                       </object>
@@ -122,11 +126,15 @@
         </child>
       </object>
     </child>
-    <child>
-      <object class="GtkBox" id="preview_container">
-        <property name="orientation">horizontal</property>
-        <property name="visible">False</property>
-        <property name="hexpand">True</property>
+    <child internal-child="footer">
+      <object class="GtkBox">
+        <child>
+          <object class="GtkBox" id="preview_container">
+            <property name="orientation">horizontal</property>
+            <property name="visible">False</property>
+            <property name="hexpand">True</property>
+          </object>
+        </child>
       </object>
     </child>
   </template>
diff --git a/src/resources/ui/gb-tab.ui b/src/resources/ui/gb-tab.ui
new file mode 100644
index 0000000..8676860
--- /dev/null
+++ b/src/resources/ui/gb-tab.ui
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.8 -->
+  <template class="GbTab" parent="GtkBox">
+    <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
+    <child>
+      <object class="GtkBox" id="header_box">
+        <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+        <property name="visible">True</property>
+        <property name="vexpand">False</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkBox" id="content">
+        <property name="orientation">GTK_ORIENTATION_VERTICAL</property>
+        <property name="visible">True</property>
+        <property name="expand">True</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkBox" id="footer_box">
+        <property name="orientation">GTK_ORIENTATION_HORIZONTAL</property>
+        <property name="visible">True</property>
+        <property name="vexpand">False</property>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/src/tabs/gb-tab.c b/src/tabs/gb-tab.c
index 47d1e10..d9555d9 100644
--- a/src/tabs/gb-tab.c
+++ b/src/tabs/gb-tab.c
@@ -22,6 +22,10 @@
 
 struct _GbTabPrivate
 {
+  GtkWidget *content;
+  GtkWidget *footer_box;
+  GtkWidget *header_box;
+
   gchar    *icon_name;
   gchar    *title;
   gboolean  dirty;
@@ -42,11 +46,40 @@ enum {
   LAST_SIGNAL
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (GbTab, gb_tab, GTK_TYPE_BOX)
+static void buildable_init (GtkBuildableIface *iface);
+
+G_DEFINE_TYPE_EXTENDED (GbTab, gb_tab, GTK_TYPE_BOX, 0,
+                        G_ADD_PRIVATE (GbTab)
+                        G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+                                               buildable_init))
 
 static GParamSpec *gParamSpecs [LAST_PROP];
 static guint       gSignals [LAST_SIGNAL];
 
+GtkWidget *
+gb_tab_get_header_area (GbTab *tab)
+{
+  g_return_val_if_fail (GB_IS_TAB (tab), NULL);
+
+  return tab->priv->header_box;
+}
+
+GtkWidget *
+gb_tab_get_footer_area (GbTab *tab)
+{
+  g_return_val_if_fail (GB_IS_TAB (tab), NULL);
+
+  return tab->priv->footer_box;
+}
+
+GtkWidget *
+gb_tab_get_content_area (GbTab *tab)
+{
+  g_return_val_if_fail (GB_IS_TAB (tab), NULL);
+
+  return tab->priv->content;
+}
+
 gboolean
 gb_tab_get_dirty (GbTab *tab)
 {
@@ -130,12 +163,10 @@ gb_tab_thaw_drag (GbTab *tab)
 static void
 gb_tab_finalize (GObject *object)
 {
-  GbTabPrivate *priv;
+  GbTab *tab = (GbTab *)object;
 
-  priv = GB_TAB (object)->priv;
-
-  g_clear_pointer (&priv->icon_name, g_free);
-  g_clear_pointer (&priv->title, g_free);
+  g_clear_pointer (&tab->priv->icon_name, g_free);
+  g_clear_pointer (&tab->priv->title, g_free);
 
   G_OBJECT_CLASS (gb_tab_parent_class)->finalize (object);
 }
@@ -197,13 +228,19 @@ gb_tab_set_property (GObject      *object,
 static void
 gb_tab_class_init (GbTabClass *klass)
 {
-  GObjectClass *object_class;
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-  object_class = G_OBJECT_CLASS (klass);
   object_class->finalize = gb_tab_finalize;
   object_class->get_property = gb_tab_get_property;
   object_class->set_property = gb_tab_set_property;
 
+  gtk_widget_class_set_template_from_resource (widget_class,
+                                               "/org/gnome/builder/ui/gb-tab.ui");
+  gtk_widget_class_bind_template_child_private (widget_class, GbTab, header_box);
+  gtk_widget_class_bind_template_child_private (widget_class, GbTab, content);
+  gtk_widget_class_bind_template_child_private (widget_class, GbTab, footer_box);
+
   gParamSpecs [PROP_DIRTY] =
     g_param_spec_boolean ("dirty",
                          _("Dirty"),
@@ -215,21 +252,19 @@ gb_tab_class_init (GbTabClass *klass)
 
   gParamSpecs[PROP_ICON_NAME] =
     g_param_spec_string ("icon-name",
-                         _ ("Icon Name"),
-                         _ ("The name of the icon to display."),
+                         _("Icon Name"),
+                         _("The name of the icon to display."),
                          NULL,
-                         (G_PARAM_READWRITE |
-                          G_PARAM_STATIC_STRINGS));
+                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (object_class, PROP_ICON_NAME,
                                    gParamSpecs[PROP_ICON_NAME]);
 
   gParamSpecs[PROP_TITLE] =
     g_param_spec_string ("title",
-                         _ ("Title"),
-                         _ ("The title of the tab."),
+                         _("Title"),
+                         _("The title of the tab."),
                          NULL,
-                         (G_PARAM_READWRITE |
-                          G_PARAM_STATIC_STRINGS));
+                         (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (object_class, PROP_TITLE,
                                    gParamSpecs[PROP_TITLE]);
 
@@ -271,4 +306,31 @@ static void
 gb_tab_init (GbTab *tab)
 {
   tab->priv = gb_tab_get_instance_private (tab);
+
+  gtk_widget_init_template (GTK_WIDGET (tab));
+}
+
+static GObject *
+gb_tab_get_internal_child (GtkBuildable *buildable,
+                           GtkBuilder   *builder,
+                           const gchar  *childname)
+{
+  GbTab *tab = (GbTab *)buildable;
+
+  g_return_val_if_fail (GB_IS_TAB (tab), NULL);
+
+  if (g_strcmp0 (childname, "content") == 0)
+    return G_OBJECT (tab->priv->content);
+  else if (g_strcmp0 (childname, "header") == 0)
+    return G_OBJECT (tab->priv->header_box);
+  else if (g_strcmp0 (childname, "footer") == 0)
+    return G_OBJECT (tab->priv->footer_box);
+
+  return NULL;
+}
+
+static void
+buildable_init (GtkBuildableIface *iface)
+{
+  iface->get_internal_child = gb_tab_get_internal_child;
 }
diff --git a/src/tabs/gb-tab.h b/src/tabs/gb-tab.h
index 5f98e3e..f23a9b0 100644
--- a/src/tabs/gb-tab.h
+++ b/src/tabs/gb-tab.h
@@ -52,19 +52,22 @@ struct _GbTabClass
   void (*close)       (GbTab *tab);
 };
 
-GType        gb_tab_get_type      (void) G_GNUC_CONST;
-const gchar *gb_tab_get_title     (GbTab       *tab);
-void         gb_tab_set_title     (GbTab       *tab,
-                                   const gchar *title);
-const gchar *gb_tab_get_icon_name (GbTab       *tab);
-void         gb_tab_set_icon_name (GbTab       *tab,
-                                   const gchar *icon_name);
-gboolean     gb_tab_get_dirty     (GbTab       *tab);
-void         gb_tab_set_dirty     (GbTab       *tab,
-                                   gboolean     dirty);
-void         gb_tab_freeze_drag   (GbTab       *tab);
-void         gb_tab_thaw_drag     (GbTab       *tab);
-void         gb_tab_close         (GbTab       *tab);
+GType        gb_tab_get_type         (void) G_GNUC_CONST;
+const gchar *gb_tab_get_title        (GbTab       *tab);
+void         gb_tab_set_title        (GbTab       *tab,
+                                      const gchar *title);
+const gchar *gb_tab_get_icon_name    (GbTab       *tab);
+void         gb_tab_set_icon_name    (GbTab       *tab,
+                                      const gchar *icon_name);
+gboolean     gb_tab_get_dirty        (GbTab       *tab);
+void         gb_tab_set_dirty        (GbTab       *tab,
+                                      gboolean     dirty);
+void         gb_tab_freeze_drag      (GbTab       *tab);
+void         gb_tab_thaw_drag        (GbTab       *tab);
+void         gb_tab_close            (GbTab       *tab);
+GtkWidget   *gb_tab_get_header_area  (GbTab       *tab);
+GtkWidget   *gb_tab_get_footer_area  (GbTab       *tab);
+GtkWidget   *gb_tab_get_content_area (GbTab       *tab);
 
 G_END_DECLS
 


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