[gnome-control-center/extensible-shell] Add ability for panels and pages to know if they are active or not



commit c0baaca4ed11d6a0542c10ea5d1636b9ec78af1c
Author: William Jon McCann <jmccann redhat com>
Date:   Mon Jan 18 05:11:05 2010 -0500

    Add ability for panels and pages to know if they are active or not
    
    This will allow them to know if they should be doing stuff or not.

 capplets/appearance/cc-appearance-panel.c    |   18 +++--
 capplets/display/cc-display-panel.c          |    4 +
 capplets/keyboard/cc-keyboard-panel.c        |   30 +++++++-
 capplets/mouse/cc-mouse-panel.c              |    3 +
 libgnome-control-center-extension/cc-page.c  |   53 +++++++++++++
 libgnome-control-center-extension/cc-page.h  |    8 ++
 libgnome-control-center-extension/cc-panel.c |  102 ++++++++++++++++++++++++++
 libgnome-control-center-extension/cc-panel.h |    8 ++
 shell/control-center.c                       |    5 +
 9 files changed, 222 insertions(+), 9 deletions(-)
---
diff --git a/capplets/appearance/cc-appearance-panel.c b/capplets/appearance/cc-appearance-panel.c
index 0d11c91..dece94f 100644
--- a/capplets/appearance/cc-appearance-panel.c
+++ b/capplets/appearance/cc-appearance-panel.c
@@ -50,9 +50,7 @@
 struct CcAppearancePanelPrivate
 {
         GtkWidget *notebook;
-        CcPage    *theme_page;
         CcPage    *background_page;
-        CcPage    *font_page;
 };
 
 enum {
@@ -67,9 +65,9 @@ G_DEFINE_DYNAMIC_TYPE (CcAppearancePanel, cc_appearance_panel, CC_TYPE_PANEL)
 
 static void
 cc_appearance_panel_set_property (GObject      *object,
-                                guint         prop_id,
-                                const GValue *value,
-                                GParamSpec   *pspec)
+                                  guint         prop_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
 {
         switch (prop_id) {
         default:
@@ -80,9 +78,9 @@ cc_appearance_panel_set_property (GObject      *object,
 
 static void
 cc_appearance_panel_get_property (GObject    *object,
-                                guint       prop_id,
-                                GValue     *value,
-                                GParamSpec *pspec)
+                                  guint       prop_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
 {
         switch (prop_id) {
         default:
@@ -133,6 +131,10 @@ setup_panel (CcAppearancePanel *panel)
         g_free (display_name);
         gtk_notebook_append_page (GTK_NOTEBOOK (panel->priv->notebook), GTK_WIDGET (panel->priv->background_page), label);
         gtk_widget_show (GTK_WIDGET (panel->priv->background_page));
+
+        g_object_set (panel,
+                      "current-page", panel->priv->background_page,
+                      NULL);
 }
 
 static GObject *
diff --git a/capplets/display/cc-display-panel.c b/capplets/display/cc-display-panel.c
index bc69775..f64e594 100644
--- a/capplets/display/cc-display-panel.c
+++ b/capplets/display/cc-display-panel.c
@@ -101,6 +101,10 @@ setup_panel (CcDisplayPanel *panel)
 
         gtk_notebook_set_show_tabs (GTK_NOTEBOOK (panel->priv->notebook),
                                     FALSE);
+
+        g_object_set (panel,
+                      "current-page", panel->priv->display_page,
+                      NULL);
 }
 
 static GObject *
diff --git a/capplets/keyboard/cc-keyboard-panel.c b/capplets/keyboard/cc-keyboard-panel.c
index 7f30084..140dd53 100644
--- a/capplets/keyboard/cc-keyboard-panel.c
+++ b/capplets/keyboard/cc-keyboard-panel.c
@@ -50,7 +50,7 @@ enum {
 
 static void     cc_keyboard_panel_class_init     (CcKeyboardPanelClass *klass);
 static void     cc_keyboard_panel_init           (CcKeyboardPanel      *keyboard_panel);
-static void     cc_keyboard_panel_finalize       (GObject             *object);
+static void     cc_keyboard_panel_finalize       (GObject              *object);
 
 G_DEFINE_DYNAMIC_TYPE (CcKeyboardPanel, cc_keyboard_panel, CC_TYPE_PANEL)
 
@@ -81,12 +81,36 @@ cc_keyboard_panel_get_property (GObject    *object,
 }
 
 static void
+on_notebook_switch_page (GtkNotebook     *notebook,
+                         GtkNotebookPage *page,
+                         guint            page_num,
+                         CcKeyboardPanel *panel)
+{
+        if (page_num == 0) {
+                g_object_set (panel,
+                              "current-page",
+                              panel->priv->keyboard_page,
+                              NULL);
+        } else {
+                g_object_set (panel,
+                              "current-page",
+                              panel->priv->shortcuts_page,
+                              NULL);
+        }
+}
+
+static void
 setup_panel (CcKeyboardPanel *panel)
 {
         GtkWidget *label;
         char      *display_name;
 
         panel->priv->notebook = gtk_notebook_new ();
+        g_signal_connect (panel->priv->notebook,
+                          "switch-page",
+                          G_CALLBACK (on_notebook_switch_page),
+                          panel);
+
         gtk_container_add (GTK_CONTAINER (panel), panel->priv->notebook);
         gtk_widget_show (panel->priv->notebook);
 
@@ -112,6 +136,10 @@ setup_panel (CcKeyboardPanel *panel)
                                   GTK_WIDGET (panel->priv->shortcuts_page),
                                   label);
         gtk_widget_show (GTK_WIDGET (panel->priv->shortcuts_page));
+
+        g_object_set (panel,
+                      "current-page", panel->priv->keyboard_page,
+                      NULL);
 }
 
 static GObject *
diff --git a/capplets/mouse/cc-mouse-panel.c b/capplets/mouse/cc-mouse-panel.c
index aa78dc2..12f4f95 100644
--- a/capplets/mouse/cc-mouse-panel.c
+++ b/capplets/mouse/cc-mouse-panel.c
@@ -97,6 +97,9 @@ setup_panel (CcMousePanel *panel)
 
         gtk_notebook_set_show_tabs (GTK_NOTEBOOK (panel->priv->notebook),
                                     FALSE);
+        g_object_set (panel,
+                      "current-page", panel->priv->mouse_page,
+                      NULL);
 }
 
 static GObject *
diff --git a/libgnome-control-center-extension/cc-page.c b/libgnome-control-center-extension/cc-page.c
index 9b95aed..f9f03dc 100644
--- a/libgnome-control-center-extension/cc-page.c
+++ b/libgnome-control-center-extension/cc-page.c
@@ -34,6 +34,8 @@ struct CcPagePrivate
 {
         char            *id;
         char            *display_name;
+
+        gboolean         is_active;
 };
 
 enum {
@@ -42,6 +44,13 @@ enum {
         PROP_DISPLAY_NAME,
 };
 
+enum {
+        ACTIVE_CHANGED,
+        LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
 static void     cc_page_class_init    (CcPageClass *klass);
 static void     cc_page_init          (CcPage      *page);
 static void     cc_page_finalize      (GObject     *object);
@@ -110,6 +119,37 @@ cc_page_get_property (GObject    *object,
         }
 }
 
+static void
+cc_page_real_active_changed (CcPage  *page,
+                             gboolean is_active)
+{
+        page->priv->is_active = is_active;
+        g_debug ("Page %s is %s",
+                 page->priv->id,
+                 page->priv->is_active ? "active" : "inactive");
+}
+
+void
+cc_page_set_active (CcPage  *page,
+                    gboolean is_active)
+{
+        g_return_if_fail (CC_IS_PAGE (page));
+
+        g_object_ref (page);
+        gtk_widget_queue_resize (GTK_WIDGET (page));
+        if (page->priv->is_active != is_active) {
+                g_signal_emit (page, signals [ACTIVE_CHANGED], 0, is_active);
+        }
+        g_object_unref (page);
+}
+
+gboolean
+cc_page_is_active (CcPage  *page)
+{
+        g_return_val_if_fail (CC_IS_PAGE (page), FALSE);
+        return page->priv->is_active;
+}
+
 static GObject *
 cc_page_constructor (GType                  type,
                      guint                  n_construct_properties,
@@ -134,8 +174,21 @@ cc_page_class_init (CcPageClass *klass)
         object_class->constructor = cc_page_constructor;
         object_class->finalize = cc_page_finalize;
 
+        klass->active_changed = cc_page_real_active_changed;
+
         g_type_class_add_private (klass, sizeof (CcPagePrivate));
 
+        signals [ACTIVE_CHANGED]
+                = g_signal_new ("active-changed",
+                                G_TYPE_FROM_CLASS (object_class),
+                                G_SIGNAL_RUN_FIRST,
+                                G_STRUCT_OFFSET (CcPageClass, active_changed),
+                                NULL,
+                                NULL,
+                                g_cclosure_marshal_VOID__BOOLEAN,
+                                G_TYPE_NONE,
+                                1, G_TYPE_BOOLEAN);
+
         g_object_class_install_property (object_class,
                                          PROP_ID,
                                          g_param_spec_string ("id",
diff --git a/libgnome-control-center-extension/cc-page.h b/libgnome-control-center-extension/cc-page.h
index 8ab20e0..36f2968 100644
--- a/libgnome-control-center-extension/cc-page.h
+++ b/libgnome-control-center-extension/cc-page.h
@@ -44,10 +44,18 @@ typedef struct
 typedef struct
 {
         GtkAlignmentClass   parent_class;
+
+        void (* active_changed)           (CcPage  *page,
+                                           gboolean is_active);
 } CcPageClass;
 
 GType               cc_page_get_type               (void);
 
+gboolean            cc_page_is_active              (CcPage  *page);
+
+void                cc_page_set_active             (CcPage  *page,
+                                                    gboolean is_active);
+
 G_END_DECLS
 
 #endif /* __CC_PAGE_H */
diff --git a/libgnome-control-center-extension/cc-panel.c b/libgnome-control-center-extension/cc-panel.c
index 6d53f6d..29783ab 100644
--- a/libgnome-control-center-extension/cc-panel.c
+++ b/libgnome-control-center-extension/cc-panel.c
@@ -27,6 +27,7 @@
 #include <gio/gio.h>
 
 #include "cc-panel.h"
+#include "cc-page.h"
 
 #define CC_PANEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_PANEL, CcPanelPrivate))
 
@@ -36,6 +37,9 @@ struct CcPanelPrivate
         char            *display_name;
         char            *category;
         char            *current_location;
+
+        gboolean         is_active;
+        CcPage          *current_page;
 };
 
 enum {
@@ -44,8 +48,16 @@ enum {
         PROP_DISPLAY_NAME,
         PROP_CATEGORY,
         PROP_CURRENT_LOCATION,
+        PROP_CURRENT_PAGE,
 };
 
+enum {
+        ACTIVE_CHANGED,
+        LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
 static void     cc_panel_class_init    (CcPanelClass *klass);
 static void     cc_panel_init          (CcPanel      *panel);
 static void     cc_panel_finalize      (GObject       *object);
@@ -69,6 +81,32 @@ _cc_panel_set_display_name (CcPanel    *panel,
 }
 
 static void
+_cc_panel_set_current_page (CcPanel    *panel,
+                            CcPage     *page)
+{
+        CcPage *old;
+
+        if (page == panel->priv->current_page)
+                return;
+
+        old = panel->priv->current_page;
+        panel->priv->current_page = page;
+        if (old != NULL) {
+                cc_page_set_active (old, FALSE);
+        }
+        if (panel->priv->current_page != NULL) {
+                g_object_ref (panel->priv->current_page);
+                cc_page_set_active (panel->priv->current_page,
+                                    panel->priv->is_active);
+        }
+        if (old != NULL) {
+                g_object_unref (old);
+        }
+
+        g_object_notify (G_OBJECT (panel), "current-page");
+}
+
+static void
 cc_panel_set_property (GObject      *object,
                        guint         prop_id,
                        const GValue *value,
@@ -85,6 +123,9 @@ cc_panel_set_property (GObject      *object,
         case PROP_DISPLAY_NAME:
                 _cc_panel_set_display_name (self, g_value_get_string (value));
                 break;
+        case PROP_CURRENT_PAGE:
+                _cc_panel_set_current_page (self, g_value_get_object (value));
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -108,12 +149,52 @@ cc_panel_get_property (GObject    *object,
         case PROP_DISPLAY_NAME:
                 g_value_set_string (value, self->priv->display_name);
                 break;
+        case PROP_CURRENT_PAGE:
+                g_value_set_object (value, self->priv->current_page);
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
         }
 }
 
+static void
+cc_panel_real_active_changed (CcPanel *panel,
+                              gboolean is_active)
+{
+        if (panel->priv->is_active == is_active)
+                return;
+
+        panel->priv->is_active = is_active;
+        if (panel->priv->current_page != NULL) {
+                cc_page_set_active (panel->priv->current_page, is_active);
+        }
+        g_debug ("Panel %s is %s",
+                 panel->priv->id,
+                 panel->priv->is_active ? "active" : "inactive");
+}
+
+void
+cc_panel_set_active (CcPanel *panel,
+                     gboolean is_active)
+{
+        g_return_if_fail (CC_IS_PANEL (panel));
+
+        g_object_ref (panel);
+        gtk_widget_queue_resize (GTK_WIDGET (panel));
+        if (panel->priv->is_active != is_active) {
+                g_signal_emit (panel, signals [ACTIVE_CHANGED], 0, is_active);
+        }
+        g_object_unref (panel);
+}
+
+gboolean
+cc_panel_is_active (CcPanel *panel)
+{
+        g_return_val_if_fail (CC_IS_PANEL (panel), FALSE);
+        return panel->priv->is_active;
+}
+
 static GObject *
 cc_panel_constructor (GType                  type,
                       guint                  n_construct_properties,
@@ -138,8 +219,21 @@ cc_panel_class_init (CcPanelClass *klass)
         object_class->constructor = cc_panel_constructor;
         object_class->finalize = cc_panel_finalize;
 
+        klass->active_changed = cc_panel_real_active_changed;
+
         g_type_class_add_private (klass, sizeof (CcPanelPrivate));
 
+        signals [ACTIVE_CHANGED]
+                = g_signal_new ("active-changed",
+                                G_TYPE_FROM_CLASS (object_class),
+                                G_SIGNAL_RUN_FIRST,
+                                G_STRUCT_OFFSET (CcPanelClass, active_changed),
+                                NULL,
+                                NULL,
+                                g_cclosure_marshal_VOID__BOOLEAN,
+                                G_TYPE_NONE,
+                                1, G_TYPE_BOOLEAN);
+
         g_object_class_install_property (object_class,
                                          PROP_ID,
                                          g_param_spec_string ("id",
@@ -154,6 +248,14 @@ cc_panel_class_init (CcPanelClass *klass)
                                                               "display name",
                                                               NULL,
                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
+                                         PROP_CURRENT_PAGE,
+                                         g_param_spec_object ("current-page",
+                                                              "",
+                                                              "",
+                                                              CC_TYPE_PAGE,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
 }
 
 static void
diff --git a/libgnome-control-center-extension/cc-panel.h b/libgnome-control-center-extension/cc-panel.h
index 162e366..aef36fe 100644
--- a/libgnome-control-center-extension/cc-panel.h
+++ b/libgnome-control-center-extension/cc-panel.h
@@ -46,10 +46,18 @@ typedef struct
 typedef struct
 {
         GtkAlignmentClass   parent_class;
+
+        void (* active_changed)           (CcPanel *panel,
+                                           gboolean is_active);
 } CcPanelClass;
 
 GType               cc_panel_get_type               (void);
 
+gboolean            cc_panel_is_active              (CcPanel *panel);
+
+void                cc_panel_set_active             (CcPanel *panel,
+                                                     gboolean is_active);
+
 G_END_DECLS
 
 #endif /* __CC_PANEL_H */
diff --git a/shell/control-center.c b/shell/control-center.c
index 3930e5c..c686e1f 100644
--- a/shell/control-center.c
+++ b/shell/control-center.c
@@ -39,6 +39,7 @@ typedef struct
   GSList *icon_views;
 
   gchar  *current_title;
+  CcPanel *current_panel;
 
   GtkListStore *store;
   GtkTreeModel *filter;
@@ -341,9 +342,11 @@ item_activated_cb (GtkIconView *icon_view,
   panel = g_hash_table_lookup (panels, id);
   if (panel != NULL)
     {
+      data->current_panel = panel;
       gtk_container_set_border_width (GTK_CONTAINER (panel), 12);
       index = gtk_notebook_append_page (GTK_NOTEBOOK (notebook), GTK_WIDGET (panel), NULL);
       gtk_widget_show_all (GTK_WIDGET (panel));
+      cc_panel_set_active (panel, TRUE);
       gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), index);
       gtk_widget_show (W (data->builder, "home-button"));
       gtk_window_set_title (GTK_WINDOW (data->window), data->current_title);
@@ -371,6 +374,8 @@ home_button_clicked_cb (GtkButton *button,
   widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (data->notebook), page);
   gtk_widget_hide (widget);
   gtk_notebook_remove_page (GTK_NOTEBOOK (data->notebook), page);
+  if (data->current_panel != NULL)
+    cc_panel_set_active (data->current_panel, FALSE);
 
   gtk_window_set_title (GTK_WINDOW (data->window), "System Settings");
 



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