[gnome-control-center] shell: Allow panels to register custom widgets in the shell header



commit dcb88a861dff1337d1a73249254c0145287b2ec8
Author: Richard Hughes <richard hughsie com>
Date:   Mon Jan 9 15:19:13 2012 +0000

    shell: Allow panels to register custom widgets in the shell header
    
    This allows us to add the kill switch in the various different panels to match
    the mockups, and also allows us to connect up any custom functionality the
    designers want.
    
    For example, in the bluetooth panel we might want to allow the GtkLabel to be
    edited to change the bluetooth device name.

 shell/cc-shell.c             |   21 +++++++++++++++++++
 shell/cc-shell.h             |    5 ++++
 shell/gnome-control-center.c |   46 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 0 deletions(-)
---
diff --git a/shell/cc-shell.c b/shell/cc-shell.c
index 1145b8b..25efcce 100644
--- a/shell/cc-shell.c
+++ b/shell/cc-shell.c
@@ -236,3 +236,24 @@ cc_shell_get_toplevel (CcShell *shell)
   return NULL;
 }
 
+void
+cc_shell_embed_widget_in_header (CcShell *shell, GtkWidget *widget)
+{
+  CcShellClass *class;
+
+  g_return_if_fail (CC_IS_SHELL (shell));
+
+  class = (CcShellClass *) G_OBJECT_GET_CLASS (shell);
+
+  if (!class->embed_widget_in_header)
+    {
+      g_warning ("Object of type \"%s\" does not implement required virtual"
+                 " function \"embed_widget_in_header\",",
+                 G_OBJECT_TYPE_NAME (shell));
+      return FALSE;
+    }
+  else
+    {
+      return class->embed_widget_in_header (shell, widget);
+    }
+}
diff --git a/shell/cc-shell.h b/shell/cc-shell.h
index 3ab8062..a879e53 100644
--- a/shell/cc-shell.h
+++ b/shell/cc-shell.h
@@ -89,6 +89,8 @@ struct _CcShellClass
                                            const gchar **argv,
                                            GError      **error);
   GtkWidget * (*get_toplevel)             (CcShell      *shell);
+  void        (*embed_widget_in_header)   (CcShell      *shell,
+                                           GtkWidget    *widget);
 };
 
 GType           cc_shell_get_type                 (void) G_GNUC_CONST;
@@ -102,6 +104,9 @@ gboolean        cc_shell_set_active_panel_from_id (CcShell      *shell,
                                                    GError      **error);
 GtkWidget *     cc_shell_get_toplevel             (CcShell      *shell);
 
+void            cc_shell_embed_widget_in_header   (CcShell      *shell,
+                                                   GtkWidget    *widget);
+
 G_END_DECLS
 
 #endif /* _CC_SHELL_H */
diff --git a/shell/gnome-control-center.c b/shell/gnome-control-center.c
index 85d7062..c4cabda 100644
--- a/shell/gnome-control-center.c
+++ b/shell/gnome-control-center.c
@@ -69,6 +69,7 @@ struct _GnomeControlCenterPrivate
   GtkWidget  *window;
   GtkWidget  *search_entry;
   GtkWidget  *lock_button;
+  GPtrArray  *custom_widgets;
 
   GMenuTree  *menu_tree;
   GtkListStore *store;
@@ -201,6 +202,23 @@ activate_panel (GnomeControlCenter *shell,
 }
 
 static void
+_shell_remove_all_custom_widgets (GnomeControlCenterPrivate *priv)
+{
+  GtkBox *box;
+  GtkWidget *widget;
+  guint i;
+
+  /* remove from the header */
+  box = GTK_BOX (W (priv->builder, "topright"));
+  for (i = 0; i < priv->custom_widgets->len; i++)
+    {
+        widget = g_ptr_array_index (priv->custom_widgets, i);
+        gtk_container_remove (GTK_CONTAINER (box), widget);
+    }
+  g_ptr_array_set_size (priv->custom_widgets, 0);
+}
+
+static void
 shell_show_overview_page (GnomeControlCenterPrivate *priv)
 {
   gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), OVERVIEW_PAGE);
@@ -220,6 +238,9 @@ shell_show_overview_page (GnomeControlCenterPrivate *priv)
   gtk_window_set_default_icon_name (priv->default_window_icon);
   gtk_window_set_icon_name (GTK_WINDOW (priv->window),
                             priv->default_window_icon);
+
+  /* clear any custom widgets */
+  _shell_remove_all_custom_widgets (priv);
 }
 
 void
@@ -810,6 +831,20 @@ notebook_switch_page_cb (GtkNotebook               *book,
 }
 
 /* CcShell implementation */
+static void
+_shell_embed_widget_in_header (CcShell      *shell,
+                               GtkWidget    *widget)
+{
+  GnomeControlCenterPrivate *priv = GNOME_CONTROL_CENTER (shell)->priv;
+  GtkBox *box;
+
+  /* add to header */
+  box = GTK_BOX (W (priv->builder, "topright"));
+  gtk_box_pack_end (box, widget, FALSE, FALSE, 0);
+  g_ptr_array_add (priv->custom_widgets, g_object_ref (widget));
+}
+
+/* CcShell implementation */
 static gboolean
 _shell_set_active_panel_from_id (CcShell      *shell,
                                  const gchar  *start_id,
@@ -823,6 +858,8 @@ _shell_set_active_panel_from_id (CcShell      *shell,
   GIcon *gicon;
   GnomeControlCenterPrivate *priv = GNOME_CONTROL_CENTER (shell)->priv;
 
+  /* clear any custom widgets */
+  _shell_remove_all_custom_widgets (priv);
 
   iter_valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->store),
                                               &iter);
@@ -919,6 +956,11 @@ gnome_control_center_dispose (GObject *object)
 {
   GnomeControlCenterPrivate *priv = GNOME_CONTROL_CENTER (object)->priv;
 
+  if (priv->custom_widgets)
+    {
+      g_ptr_array_unref (priv->custom_widgets);
+      priv->custom_widgets = NULL;
+    }
   if (priv->window)
     {
       gtk_widget_destroy (priv->window);
@@ -1005,6 +1047,7 @@ gnome_control_center_class_init (GnomeControlCenterClass *klass)
   object_class->finalize = gnome_control_center_finalize;
 
   shell_class->set_active_panel_from_id = _shell_set_active_panel_from_id;
+  shell_class->embed_widget_in_header = _shell_embed_widget_in_header;
   shell_class->get_toplevel = _shell_get_toplevel;
 }
 
@@ -1083,6 +1126,9 @@ gnome_control_center_init (GnomeControlCenter *self)
   g_signal_connect (gtk_builder_get_object (priv->builder, "home-button"),
                     "clicked", G_CALLBACK (home_button_clicked_cb), self);
 
+  /* keep a list of custom widgets to unload on panel change */
+  priv->custom_widgets = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+
   /* load the available settings panels */
   setup_model (self);
 



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