summaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2022-01-19 12:55:02 -0300
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2022-01-20 02:23:42 +0000
commitd2d3669d34b3cd1814b70a4dc7f5183e98f03cf4 (patch)
treedbf3c524cf0d3bb5a61ff9dec01f46ce68051113 /shell
parent3d06a71b380f14ec8131384aa7eed74d3275eaa8 (diff)
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.
Diffstat (limited to 'shell')
-rw-r--r--shell/cc-panel.c118
-rw-r--r--shell/cc-panel.h11
-rw-r--r--shell/cc-panel.ui38
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>