[gnome-shell] Panel: clean up button construction code



commit e5534e86ab3fc1b280b0f646a6aa811062f0c9ec
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Tue Aug 28 23:10:44 2012 +0200

    Panel: clean up button construction code
    
    We already could build the right part of the panel declaratively according
    to the session mode. Extend that to handle the left and center parts.
    Also, move the mapping from the roles to the classes in panel.js, as it shared
    by all modes.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=682546

 js/ui/main.js        |    3 +-
 js/ui/panel.js       |  136 ++++++++++++++++++++++++-------------------------
 js/ui/sessionMode.js |   73 ++++++---------------------
 3 files changed, 84 insertions(+), 128 deletions(-)
---
diff --git a/js/ui/main.js b/js/ui/main.js
index 271d979..eaefa0c 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -222,8 +222,7 @@ function start() {
 
     sessionMode.createSession();
 
-    panel.startStatusArea();
-
+    panel.init();
     layoutManager.init();
     keyboard.init();
     overview.init();
diff --git a/js/ui/panel.js b/js/ui/panel.js
index 28a5ca3..2b24e3f 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -14,13 +14,14 @@ const St = imports.gi.St;
 const Signals = imports.signals;
 const Atk = imports.gi.Atk;
 
+
+const Config = imports.misc.config;
 const CtrlAltTab = imports.ui.ctrlAltTab;
 const DND = imports.ui.dnd;
 const Layout = imports.ui.layout;
 const Overview = imports.ui.overview;
 const PopupMenu = imports.ui.popupMenu;
 const PanelMenu = imports.ui.panelMenu;
-const DateMenu = imports.ui.dateMenu;
 const Main = imports.ui.main;
 const Tweener = imports.ui.tweener;
 
@@ -221,14 +222,14 @@ const AppMenuButton = new Lang.Class({
     Name: 'AppMenuButton',
     Extends: PanelMenu.Button,
 
-    _init: function(menuManager) {
+    _init: function(panel) {
         this.parent(0.0, null, true);
 
         this.actor.accessible_role = Atk.Role.MENU;
 
         this._startingApps = [];
 
-        this._menuManager = menuManager;
+        this._menuManager = panel.menuManager;
         this._targetApp = null;
         this._appMenuNotifyId = 0;
         this._actionGroupNotifyId = 0;
@@ -899,6 +900,29 @@ const PanelCorner = new Lang.Class({
     }
 });
 
+const PANEL_ITEM_IMPLEMENTATIONS = {
+    'activities': ActivitiesButton,
+    'appMenu': AppMenuButton,
+    'dateMenu': imports.ui.dateMenu.DateMenuButton,
+    'a11y': imports.ui.status.accessibility.ATIndicator,
+    'volume': imports.ui.status.volume.Indicator,
+    'battery': imports.ui.status.power.Indicator,
+    'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
+    'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
+    'powerMenu': imports.gdm.powerMenu.PowerMenuButton,
+    'userMenu': imports.ui.userMenu.UserMenuButton
+};
+
+if (Config.HAVE_BLUETOOTH)
+    PANEL_ITEM_IMPLEMENTATIONS['bluetooth'] =
+        imports.ui.status.bluetooth.Indicator;
+
+try {
+    PANEL_ITEM_IMPLEMENTATIONS['network'] =
+        imports.ui.status.network.NMApplet;
+} catch(e) {
+    log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
+}
 
 const Panel = new Lang.Class({
     Name: 'Panel',
@@ -919,7 +943,7 @@ const Panel = new Lang.Class({
 
         Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._onLockStateChanged));
 
-        this._menus = new PopupMenu.PopupMenuManager(this);
+        this.menuManager = new PopupMenu.PopupMenuManager(this);
 
         this._leftBox = new St.BoxLayout({ name: 'panelLeft' });
         this.actor.add_actor(this._leftBox);
@@ -946,27 +970,6 @@ const Panel = new Lang.Class({
         this.actor.connect('allocate', Lang.bind(this, this._allocate));
         this.actor.connect('button-press-event', Lang.bind(this, this._onButtonPress));
 
-        /* Button on the left side of the panel. */
-        if (Main.sessionMode.hasOverview) {
-            this._activitiesButton = new ActivitiesButton();
-            this._activities = this._activitiesButton.actor;
-            this._leftBox.add(this._activities);
-
-            // The activities button has a pretend menu, so as to integrate
-            // more cleanly with the rest of the panel
-            this._menus.addMenu(this._activitiesButton.menu);
-        }
-
-        if (Main.sessionMode.hasAppMenu) {
-            this._appMenu = new AppMenuButton(this._menus);
-            this._leftBox.add(this._appMenu.actor);
-        }
-
-        /* center */
-        this._dateMenu = new DateMenu.DateMenuButton();
-        this._centerBox.add(this._dateMenu.actor, { y_fill: true });
-        this._menus.addMenu(this._dateMenu.menu);
-
         Main.layoutManager.panelBox.add(this.actor);
         Main.ctrlAltTabManager.addGroup(this.actor, _("Top Bar"), 'start-here-symbolic',
                                         { sortGroup: CtrlAltTab.SortGroup.TOP });
@@ -1086,75 +1089,70 @@ const Panel = new Lang.Class({
     },
 
     openAppMenu: function() {
-        let menu = this._appMenu.menu;
-        if (!this._appMenu.actor.reactive || menu.isOpen)
+        let indicator = this.statusArea.appMenu;
+        if (!indicator) // appMenu not supported by current session mode
+            return;
+
+        let menu = indicator.menu;
+        if (!indicator.actor.reactive || menu.isOpen)
             return;
 
         menu.open();
         menu.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
     },
 
-    startStatusArea: function() {
-        for (let i = 0; i < Main.sessionMode.statusArea.order.length; i++) {
-            let role = Main.sessionMode.statusArea.order[i];
-            let constructor = Main.sessionMode.statusArea.implementation[role];
+    init: function() {
+        let panel = Main.sessionMode.panel;
+        this._initBox(panel.left, this._leftBox);
+        this._initBox(panel.center, this._centerBox);
+        this._initBox(panel.right, this._rightBox);
+    },
+
+    _initBox: function(elements, box) {
+        for (let i = 0; i < elements.length; i++) {
+            let role = elements[i];
+            let constructor = PANEL_ITEM_IMPLEMENTATIONS[role];
             if (!constructor) {
-                // This icon is not implemented (this is a bug)
+                // panel icon is not supported (can happen for
+                // bluetooth or network)
                 continue;
             }
 
-            let indicator = new constructor();
-            this.addToStatusArea(role, indicator, i);
+            let indicator = new constructor(this);
+            this._addToPanelBox(role, indicator, i, box);
         }
     },
 
-    _insertStatusItem: function(actor, position) {
-        let children = this._rightBox.get_children();
-        let i;
-        for (i = children.length - 1; i >= 0; i--) {
-            let rolePosition = children[i]._rolePosition;
-            if (position > rolePosition) {
-                this._rightBox.insert_child_at_index(actor, i + 1);
-                break;
-            }
-        }
-        if (i == -1) {
-            // If we didn't find a position, we must be first
-            this._rightBox.insert_child_at_index(actor, 0);
-        }
-        actor._rolePosition = position;
+    _addToPanelBox: function(role, indicator, position, box) {
+        box.insert_child_at_index(indicator.actor, position);
+        if (indicator.menu)
+            this.menuManager.addMenu(indicator.menu);
+        this.statusArea[role] = indicator;
+        let destroyId = indicator.connect('destroy', Lang.bind(this, function(emitter) {
+            delete this.statusArea[role];
+            emitter.disconnect(destroyId);
+        }));
     },
 
-    addToStatusArea: function(role, indicator, position) {
+    addToStatusArea: function(role, indicator, position, box) {
         if (this.statusArea[role])
             throw new Error('Extension point conflict: there is already a status indicator for role ' + role);
 
         if (!(indicator instanceof PanelMenu.Button))
             throw new TypeError('Status indicator must be an instance of PanelMenu.Button');
 
-        if (!position)
-            position = 0;
-        this._insertStatusItem(indicator.actor, position);
-        if (indicator.menu)
-            this._menus.addMenu(indicator.menu);
-
-        this.statusArea[role] = indicator;
-        let destroyId = indicator.connect('destroy', Lang.bind(this, function(emitter) {
-            delete this.statusArea[role];
-            emitter.disconnect(destroyId);
-        }));
-
+        position = position || 0;
+        let boxes = {
+            left: this._leftBox,
+            center: this._centerBox,
+            right: this._rightBox
+        };
+        let boxContainer = boxes[box] || this._rightBox;
+        this._addToPanelBox(role, indicator, position, boxContainer);
         return indicator;
     },
 
     _onLockStateChanged: function(shield, locked) {
-        if (this._activitiesButton)
-            this._activitiesButton.setLockedState(locked);
-        if (this._appMenu)
-            this._appMenu.setLockedState(locked);
-        if (this._dateMenu)
-            this._dateMenu.setLockedState(locked);
-
         for (let id in this.statusArea)
             this.statusArea[id].setLockedState(locked);
     },
diff --git a/js/ui/sessionMode.js b/js/ui/sessionMode.js
index 55cfed7..e69ce4f 100644
--- a/js/ui/sessionMode.js
+++ b/js/ui/sessionMode.js
@@ -2,37 +2,13 @@
 
 const Lang = imports.lang;
 
-const Config = imports.misc.config;
 const Main = imports.ui.main;
 const Params = imports.misc.params;
 
-
-const STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION = {
-    'a11y': imports.ui.status.accessibility.ATIndicator,
-    'volume': imports.ui.status.volume.Indicator,
-    'battery': imports.ui.status.power.Indicator,
-    'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
-    'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
-    'userMenu': imports.ui.userMenu.UserMenuButton
-};
-
-if (Config.HAVE_BLUETOOTH)
-    STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['bluetooth'] =
-        imports.ui.status.bluetooth.Indicator;
-
-try {
-    STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION['network'] =
-        imports.ui.status.network.NMApplet;
-} catch(e) {
-    log('NMApplet is not supported. It is possible that your NetworkManager version is too old');
-}
-
-
 const DEFAULT_MODE = 'user';
 
 const _modes = {
     'gdm': { hasOverview: false,
-             hasAppMenu: false,
              showCalendarEvents: false,
              allowSettings: false,
              allowExtensions: false,
@@ -42,24 +18,15 @@ const _modes = {
              createSession: Main.createGDMSession,
              createUnlockDialog: Main.createGDMLoginDialog,
              extraStylesheet: null,
-             statusArea: {
-                 order: [
-                     'a11y', 'display', 'keyboard',
-                     'volume', 'battery', 'lockScreen', 'powerMenu'
-                 ],
-                 implementation: {
-                     'a11y': imports.ui.status.accessibility.ATIndicator,
-                     'volume': imports.ui.status.volume.Indicator,
-                     'battery': imports.ui.status.power.Indicator,
-                     'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
-                     'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
-                     'powerMenu': imports.gdm.powerMenu.PowerMenuButton
-                 }
+             panel: {
+                 left: [],
+                 center: ['dateMenu'],
+                 right: ['a11y', 'display', 'keyboard',
+                         'volume', 'battery', 'lockScreen', 'powerMenu']
              }
            },
 
     'initial-setup': { hasOverview: false,
-                       hasAppMenu: false,
                        showCalendarEvents: false,
                        allowSettings: false,
                        allowExtensions: false,
@@ -68,21 +35,14 @@ const _modes = {
                        hasWorkspaces: false,
                        createSession: Main.createInitialSetupSession,
                        extraStylesheet: null,
-                       statusArea: {
-                           order: [
-                               'a11y', 'keyboard', 'volume', 'lockScreen',
-                           ],
-                           implementation: {
-                               'a11y': imports.ui.status.accessibility.ATIndicator,
-                               'keyboard': imports.ui.status.keyboard.XKBIndicator,
-                               'volume': imports.ui.status.volume.Indicator,
-                               'lockScreen': imports.ui.status.lockScreenMenu.Indicator,
-                        }
-                }
-           },
+                       panel: {
+                           left: [],
+                           center: ['dateMenu'],
+                           right: ['a11y', 'keyboard', 'volume', 'lockScreen']
+                       }
+                     },
 
     'user': { hasOverview: true,
-              hasAppMenu: true,
               showCalendarEvents: true,
               allowSettings: true,
               allowExtensions: true,
@@ -92,12 +52,11 @@ const _modes = {
               createSession: Main.createUserSession,
               createUnlockDialog: Main.createSessionUnlockDialog,
               extraStylesheet: null,
-              statusArea: {
-                  order: [
-                      'input-method', 'a11y', 'keyboard', 'volume', 'bluetooth',
-                      'network', 'battery', 'lockScreen', 'userMenu'
-                  ],
-                  implementation: STANDARD_STATUS_AREA_SHELL_IMPLEMENTATION
+              panel: {
+                  left: ['activities', 'appMenu'],
+                  center: ['dateMenu'],
+                  right: ['a11y', 'keyboard', 'volume', 'bluetooth',
+                          'network', 'battery', 'lockScreen', 'userMenu']
               }
             }
 };



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