[gnome-control-center/gbsneto/panel-headerbar-cleanup: 8/19] panel: Add titlebar to panels




commit d2d3669d34b3cd1814b70a4dc7f5183e98f03cf4
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Wed Jan 19 12:55:02 2022 -0300

    panel: Add titlebar to panels
    
    Make CcPanel override GtkBuildable, and special-case two types
    of children: "content" for the main content, and "titlebar" for
    the titlebar. Those two child types exist merely for convenience,
    since it's still possible to override the entire panel with
    adw_bin_set_child().
    
    For now, no panel is using any of these conveniences.

 shell/cc-panel.c  | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 shell/cc-panel.h  |  11 ++++-
 shell/cc-panel.ui |  38 ++++++++++++++++++
 3 files changed, 165 insertions(+), 2 deletions(-)
---
diff --git a/shell/cc-panel.c b/shell/cc-panel.c
index bca7178cb..e57178e91 100644
--- a/shell/cc-panel.c
+++ b/shell/cc-panel.c
@@ -28,6 +28,22 @@
  * CcPanel is an abstract class used to implement panels for the shell. A
  * panel contains a collection of related settings that are displayed within
  * the shell window.
+ *
+ * # Buildable
+ *
+ * CcPanel implements the GtkBuildable interface, and allows having different
+ * types of children for convenience.
+ *
+ * It is possible to add widgets to the start and end of the panel titlebar
+ * using, respectively, the `titlebar-start` and `titlebar-end` child types.
+ * It is also possible to override the titlebar entirely with a custom titlebar
+ * using the `titlebar` child type.
+ *
+ * Most panels will use the `content` child type, which sets the panel content
+ * beneath the titlebar.
+ *
+ * At last, it is possible to override all custom CcPanel widgets by not setting
+ * any child type.
  */
 
 #include "config.h"
@@ -42,13 +58,24 @@
 
 typedef struct
 {
+  AdwBin       *content_bin;
+  GtkBox       *main_box;
+  AdwBin       *titlebar_bin;
+  AdwHeaderBar *titlebar;
+
   CcShell      *shell;
   GCancellable *cancellable;
   gboolean      folded;
   gchar        *title;
 } CcPanelPrivate;
 
-G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CcPanel, cc_panel, ADW_TYPE_BIN)
+static void cc_panel_buildable_init (GtkBuildableIface *iface);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (CcPanel, cc_panel, ADW_TYPE_BIN,
+                                  G_ADD_PRIVATE (CcPanel)
+                                  G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, cc_panel_buildable_init))
+
+static GtkBuildableIface *parent_buildable_iface;
 
 enum
 {
@@ -70,6 +97,44 @@ static GParamSpec *properties [N_PROPS];
 
 static guint signals [LAST_SIGNAL] = { 0 };
 
+/* GtkBuildable interface */
+
+static void
+cc_panel_buildable_add_child (GtkBuildable *buildable,
+                              GtkBuilder   *builder,
+                              GObject      *child,
+                              const char   *type)
+{
+  CcPanelPrivate *priv = cc_panel_get_instance_private (CC_PANEL (buildable));
+
+  if (GTK_IS_WIDGET (child) && !priv->main_box)
+    {
+      adw_bin_set_child (ADW_BIN (buildable), GTK_WIDGET (child));
+      return;
+    }
+
+  if (g_strcmp0 (type, "content") == 0)
+    adw_bin_set_child (priv->content_bin, GTK_WIDGET (child));
+  else if (g_strcmp0 (type, "titlebar-start") == 0)
+    adw_header_bar_pack_start (priv->titlebar, GTK_WIDGET (child));
+  else if (g_strcmp0 (type, "titlebar-end") == 0)
+    adw_header_bar_pack_end (priv->titlebar, GTK_WIDGET (child));
+  else if (g_strcmp0 (type, "titlebar") == 0)
+    adw_bin_set_child (priv->titlebar_bin, GTK_WIDGET (child));
+  else
+    parent_buildable_iface->add_child (buildable, builder, child, type);
+}
+
+static void
+cc_panel_buildable_init (GtkBuildableIface *iface)
+{
+  parent_buildable_iface = g_type_interface_peek_parent (iface);
+
+  iface->add_child = cc_panel_buildable_add_child;
+}
+
+/* GObject overrides */
+
 static void
 cc_panel_set_property (GObject      *object,
                        guint         prop_id,
@@ -206,6 +271,11 @@ cc_panel_class_init (CcPanelClass *klass)
   g_object_class_install_properties (object_class, N_PROPS, properties);
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/ControlCenter/gtk/cc-panel.ui");
+
+  gtk_widget_class_bind_template_child_private (widget_class, CcPanel, content_bin);
+  gtk_widget_class_bind_template_child_private (widget_class, CcPanel, main_box);
+  gtk_widget_class_bind_template_child_private (widget_class, CcPanel, titlebar_bin);
+  gtk_widget_class_bind_template_child_private (widget_class, CcPanel, titlebar);
 }
 
 static void
@@ -318,3 +388,49 @@ cc_panel_get_folded (CcPanel *panel)
   priv = cc_panel_get_instance_private (panel);
   return priv->folded;
 }
+
+GtkWidget*
+cc_panel_get_content (CcPanel *panel)
+{
+  CcPanelPrivate *priv;
+
+  g_return_val_if_fail (CC_IS_PANEL (panel), NULL);
+
+  priv = cc_panel_get_instance_private (panel);
+  return adw_bin_get_child (priv->content_bin);
+}
+
+void
+cc_panel_set_content (CcPanel   *panel,
+                      GtkWidget *content)
+{
+  CcPanelPrivate *priv;
+
+  g_return_if_fail (CC_IS_PANEL (panel));
+
+  priv = cc_panel_get_instance_private (panel);
+  adw_bin_set_child (priv->content_bin, content);
+}
+
+GtkWidget*
+cc_panel_get_titlebar (CcPanel *panel)
+{
+  CcPanelPrivate *priv;
+
+  g_return_val_if_fail (CC_IS_PANEL (panel), NULL);
+
+  priv = cc_panel_get_instance_private (panel);
+  return adw_bin_get_child (priv->titlebar_bin);
+}
+
+void
+cc_panel_set_titlebar (CcPanel   *panel,
+                       GtkWidget *titlebar)
+{
+  CcPanelPrivate *priv;
+
+  g_return_if_fail (CC_IS_PANEL (panel));
+
+  priv = cc_panel_get_instance_private (panel);
+  adw_bin_set_child (priv->titlebar_bin, titlebar);
+}
diff --git a/shell/cc-panel.h b/shell/cc-panel.h
index da9e1e737..ef7f6c185 100644
--- a/shell/cc-panel.h
+++ b/shell/cc-panel.h
@@ -97,5 +97,14 @@ GCancellable *cc_panel_get_cancellable    (CcPanel     *panel);
 
 gboolean      cc_panel_get_folded         (CcPanel     *panel);
 
-G_END_DECLS
+GtkWidget*    cc_panel_get_content        (CcPanel     *panel);
+
+void          cc_panel_set_content        (CcPanel     *panel,
+                                           GtkWidget   *content);
+
+GtkWidget*    cc_panel_get_titlebar       (CcPanel     *panel);
 
+void          cc_panel_set_titlebar       (CcPanel     *panel,
+                                           GtkWidget   *titlebar);
+
+G_END_DECLS
diff --git a/shell/cc-panel.ui b/shell/cc-panel.ui
index 7c38d323c..4e0f9c5fe 100644
--- a/shell/cc-panel.ui
+++ b/shell/cc-panel.ui
@@ -1,5 +1,43 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <template class="CcPanel" parent="AdwBin">
+    <child>
+      <object class="GtkBox" id="main_box">
+        <property name="hexpand">True</property>
+        <property name="vexpand">True</property>
+        <property name="orientation">vertical</property>
+
+        <child>
+          <object class="AdwBin" id="titlebar_bin">
+            <property name="hexpand">True</property>
+            <child>
+              <object class="AdwHeaderBar" id="titlebar">
+                <property name="show-end-title-buttons">True</property>
+                <property name="show-start-title-buttons" bind-source="CcPanel" bind-property="folded" 
bind-flags="default|sync-create" />
+                <child type="start">
+                  <object class="GtkButton">
+                    <property name="visible" bind-source="CcPanel" bind-property="folded" 
bind-flags="default|sync-create" />
+                    <property name="icon-name">go-previous-symbolic</property>
+                  </object>
+                </child>
+                <property name="title-widget">
+                  <object class="AdwWindowTitle">
+                    <property name="title" bind-source="CcPanel" bind-property="title" 
bind-flags="default|sync-create" />
+                  </object>
+                </property>
+              </object>
+            </child>
+          </object>
+        </child>
+
+        <child>
+          <object class="AdwBin" id="content_bin">
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
+          </object>
+        </child>
+
+      </object>
+    </child>
   </template>
 </interface>


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