[gnome-shell] Move workspace controls into a single object



commit c02b57efc3f3927a628008ca27c57c342ed0b5a0
Author: Florian Müllner <fmuellner src gnome org>
Date:   Fri Feb 12 21:12:39 2010 +0100

    Move workspace controls into a single object
    
    Rename WorkspacesViewSwitch to WorkspacesControls and let it manage
    all workspace controls. Do not destroy and recreate the controls bar
    actor on each view change, but add it to the overview once and let it
    update itself.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=610189

 data/theme/gnome-shell.css |    2 +-
 js/ui/overview.js          |   52 +++------
 js/ui/workspacesView.js    |  269 +++++++++++++++++++++++++-------------------
 3 files changed, 172 insertions(+), 151 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 888f76c..ce6b1a9 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -216,7 +216,7 @@ StTooltip {
     height: 48px;
 }
 
-.workspaces-bar, .workspaces-bar * {
+.workspaces-bar {
     spacing: 5px;
 }
 
diff --git a/js/ui/overview.js b/js/ui/overview.js
index 92847b1..bc0304f 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -197,8 +197,8 @@ Overview.prototype = {
         this.infoBar = new InfoBar();
         this._group.add_actor(this.infoBar.actor);
 
-        this._workspacesViewSwitch = new WorkspacesView.WorkspacesViewSwitch();
-        this._workspacesViewSwitch.connect('view-changed', Lang.bind(this, this._onViewChanged));
+        this._workspacesControls = new WorkspacesView.WorkspacesControls();
+        this._workspacesControls.connect('view-changed', Lang.bind(this, this._onViewChanged));
 
         this.visible = false;
         this.animationInProgress = false;
@@ -251,41 +251,21 @@ Overview.prototype = {
         this._workspaces = null;
     },
 
-    _createControlsBar: function() {
-        this._workspacesBar = new St.BoxLayout({ 'pack-start': true,
-                                                 style_class: 'workspaces-bar' });
-        this._workspacesBar.move_by(this._workspacesBarX, this._workspacesBarY);
-
-        let controlsBar = this._workspacesViewSwitch.createControlsBar();
-        let bar = this._workspaces.createControllerBar();
-        this._workspacesBar.add(bar, { expand: true, 'x-fill': true, 'y-fill': true,
-                                       y_align: St.Align.MIDDLE, x_align: St.Align.START });
-        this._workspacesBar.add(controlsBar, {x_align: St.Align.END});
-        this._workspacesBar.width = this._workspacesBarWidth;
-
-        this._group.add_actor(this._workspacesBar);
-        this._workspacesBar.raise(this._workspaces.actor);
-    },
-
     _onViewChanged: function() {
         if (!this.visible)
             return;
-        //Remove old worspacesView
-        this._group.remove_actor(this._workspacesBar);
+        // Remove old workspacesView
         this._workspaces.hide();
         this._group.remove_actor(this._workspaces.actor);
         this._workspaces.destroy();
-        this._workspacesBar.destroy();
 
-        this._workspaces = this._workspacesViewSwitch.createCurrentWorkspaceView(this._workspacesWidth, this._workspacesHeight,
-                                                                             this._workspacesX, this._workspacesY, false);
+        this._workspaces = this._workspacesControls.createCurrentWorkspaceView(this._workspacesWidth, this._workspacesHeight,
+                                                                               this._workspacesX, this._workspacesY, false);
 
-        //Show new workspacesView
+        // Show new workspacesView
         this._group.add_actor(this._workspaces.actor);
         this._dash.actor.raise(this._workspaces.actor);
 
-        this._createControlsBar();
-
         // Set new position and scale to workspaces.
         this.emit('showing');
     },
@@ -472,8 +452,8 @@ Overview.prototype = {
         this._dash.show();
 
         /* TODO: make this stuff dynamic */
-        this._workspaces = this._workspacesViewSwitch.createCurrentWorkspaceView(this._workspacesWidth, this._workspacesHeight,
-                                                                             this._workspacesX, this._workspacesY, true);
+        this._workspaces = this._workspacesControls.createCurrentWorkspaceView(this._workspacesWidth, this._workspacesHeight,
+                                                                               this._workspacesX, this._workspacesY, true);
         this._group.add_actor(this._workspaces.actor);
 
         // The workspaces actor is as big as the screen, so we have to raise the dash above it
@@ -481,7 +461,13 @@ Overview.prototype = {
         // be as big as the screen.
         this._dash.actor.raise(this._workspaces.actor);
 
-        this._createControlsBar();
+        this._workspacesBar = this._workspacesControls.actor;
+        this._workspacesBar.set_position(this._workspacesBarX,
+                                         this._workspacesBarY);
+        this._workspacesBar.width = this._workspacesBarWidth;
+
+        this._group.add_actor(this._workspacesBar);
+        this._workspacesBar.raise(this._workspaces.actor);
 
         // All the the actors in the window group are completely obscured,
         // hiding the group holding them while the Overview is displayed greatly
@@ -511,7 +497,7 @@ Overview.prototype = {
                            onCompleteScope: this
                           });
 
-        // Make Dash fade in so that it doesn't appear to big.
+        // Make Dash fade in so that it doesn't appear too big.
         this._dash.actor.opacity = 0;
         Tweener.addTween(this._dash.actor,
                          { opacity: 255,
@@ -533,9 +519,6 @@ Overview.prototype = {
             this._activeDisplayPane.close();
         this._workspaces.hide();
 
-        this._workspacesBar.destroy();
-        this._workspacesBar = null;
-
         // Create a zoom in effect by transforming the Overview group so that
         // the active workspace fills up the whole screen. The opposite
         // transition is used in show().
@@ -600,6 +583,9 @@ Overview.prototype = {
         this._workspaces.destroy();
         this._workspaces = null;
 
+        this._workspacesBar.destroy();
+        this._workspacesBar = null;
+
         this._dash.hide();
         this._group.hide();
 
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index 7876cf1..6555e3d 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -234,19 +234,23 @@ GenericWorkspacesView.prototype = {
         return [activeWorkspace.gridX, activeWorkspace.gridY];
     },
 
-    _setButtonSensitivity: function(button, sensitive) {
-        if (button == null)
-            return;
-        if (sensitive && !button.reactive) {
-            button.reactive = true;
-            button.opacity = 255;
-        } else if (!sensitive && button.reactive) {
-            button.reactive = false;
-            button.opacity = 85;
-        }
+    createControllerBar: function() {
+        throw new Error("Not implemented");
     },
 
-    createControllerBar: function() {
+    canAddWorkspace: function() {
+        return global.screen.n_workspaces < MAX_WORKSPACES;
+    },
+
+    addWorkspace: function() {
+        throw new Error("Not implemented");
+    },
+
+    canRemoveWorkspace: function() {
+        throw new Error("Not implemented");
+    },
+
+    removeWorkspace: function() {
         throw new Error("Not implemented");
     },
 
@@ -283,9 +287,6 @@ MosaicView.prototype = {
                              width + 2 * Workspace.FRAME_SIZE,
                              height + 2 * Workspace.FRAME_SIZE);
         this._workspaces[global.screen.get_active_workspace_index()].setSelected(true);
-
-        this._removeButton = null;
-        this._addButton = null;
     },
 
     // Assign grid positions to workspaces. We can't just do a simple
@@ -406,8 +407,6 @@ MosaicView.prototype = {
         // this has the side effect of removing the frame border
         let activeIndex = global.screen.get_active_workspace_index();
         this._workspaces[activeIndex].setSelected(true);
-
-        this._updateButtonsVisibility();
     },
 
     _activeWorkspaceChanged: function(wm, from, to, direction) {
@@ -422,45 +421,21 @@ MosaicView.prototype = {
     },
 
     createControllerBar: function() {
-        let actor = new St.BoxLayout({ 'pack-start': true });
-        let bin = new St.Bin();
-        let addButton = new St.Button({ style_class: "workspace-controls add" });
-        this._addButton = addButton;
-        addButton.connect('clicked', Lang.bind(this, this._addNewWorkspace));
-        addButton._delegate = addButton;
-        addButton._delegate.acceptDrop = Lang.bind(this, function(source, actor, x, y, time) {
-            return this._acceptNewWorkspaceDrop(source, actor, x, y, time);
-        });
-        actor.add(bin, { x_align: St.Align.END });
-        bin.set_child(addButton);
-        bin.set_alignment(St.Align.END, St.Align.START);
-
-        bin = new St.Bin();
-        let removeButton = new St.Button({ style_class: "workspace-controls remove" });
-        this._removeButton = removeButton;
-        removeButton.connect('clicked', Lang.bind(this, function() {
-            if (this._workspaces.length <= 1)
-                return;
-            global.screen.remove_workspace(this._workspaces[this._workspaces.length - 1]._metaWorkspace, global.get_current_time());
-        }));
-        actor.add(bin, { expand: true, x_fill: true, x_align: St.Align.END });
-        this._updateButtonsVisibility();
-        bin.set_child(removeButton);
-        bin.set_alignment(St.Align.END, St.Align.START);
-
-        return actor;
+        return null;
     },
 
-    _updateButtonsVisibility: function() {
-        let canRemove = (global.screen.n_workspaces > 1);
-        let canAdd = (global.screen.n_workspaces < MAX_WORKSPACES);
+    addWorkspace: function() {
+        global.screen.append_new_workspace(false, global.get_current_time());
+    },
 
-        this._setButtonSensitivity(this._removeButton, canRemove);
-        this._setButtonSensitivity(this._addButton, canAdd);
+    canRemoveWorkspace: function() {
+        return global.screen.n_workspaces > 1;
     },
 
-    _addNewWorkspace: function() {
-        global.screen.append_new_workspace(false, global.get_current_time());
+    removeWorkspace: function() {
+        let last = this._workspaces.length - 1;
+        global.screen.remove_workspace(this._workspaces[last]._metaWorkspace,
+                                       global.get_current_time());
     },
 
     _acceptNewWorkspaceDrop: function(source, dropActor, x, y, time) {
@@ -522,10 +497,8 @@ SingleView.prototype = {
 
         this.actor.style_class = "workspaces single";
         this._actor.set_clip(x, y, width, height);
-        this._addButton = null;
-        this._removeButton = null;
         this._indicatorsPanel = null;
-        this._indicatorsPanelWidth = null;
+        this._indicatorsPanelWidth = 0;
         this._scroll = null;
         this._lostWorkspaces = [];
         this._scrolling = false;
@@ -988,11 +961,10 @@ SingleView.prototype = {
     },
 
     createControllerBar: function() {
-        let panel = new St.BoxLayout({ style_class: 'single-view-controls',
+        let actor = new St.BoxLayout({ style_class: 'single-view-controls',
                                        pack_start: true,
                                        vertical: true });
 
-        let actor = new St.BoxLayout({ 'pack-start': true });
         let active = global.screen.get_active_workspace_index();
         let adj = new St.Adjustment({ value: active,
                                       lower: 0,
@@ -1024,34 +996,15 @@ SingleView.prototype = {
                 this._scrollToActive(true);
             }));
 
-        let addButton = new St.Button({ style_class: "workspace-controls add" });
-        this._addButton = addButton;
-        addButton.connect('clicked', Lang.bind(this, this._addNewWorkspace));
-        addButton._delegate = addButton;
-        addButton._delegate.acceptDrop = Lang.bind(this, function(source, actor, x, y, time) {
-            return this._acceptNewWorkspaceDrop(source, actor, x, y, time);
-        });
-        actor.add(addButton, {x_align: St.Align.END, y_align: St.Align.START, 'y-fill': false});
-
-        let removeButton = new St.Button({ style_class: "workspace-controls remove" });
-        this._removeButton = removeButton;
-        removeButton.connect('clicked', Lang.bind(this, function() {
-            if (this._workspaces.length <= 1)
-                return;
-            let index = global.screen.get_active_workspace_index();
-            if (index == 0)
-                return;
-            global.screen.remove_workspace(this._workspaces[index]._metaWorkspace, global.get_current_time());
-        }));
-        actor.add(removeButton, { x_align: St.Align.END, y_align: St.Align.START, 'y-fill': false });
-        this._updatePanelVisibility();
-
-        panel.add(this._createPositionalIndicator(), {expand: true, 'x-fill': true, 'y-fill': true});
-        panel.add(this._scroll, { expand: true,
-                                  'x-fill': true,
-                                  'y-fill': false,
+        actor.add(this._createPositionalIndicator(), { expand: true,
+                                                       x_fill: true,
+                                                       y_fill: true });
+        actor.add(this._scroll, { expand: true,
+                                  x_fill: true,
+                                  y_fill: false,
                                   y_align: St.Align.START });
-        actor.add(panel, {expand: true, 'x-fill': true, 'y-fill': true});
+
+        this._updatePanelVisibility();
 
         return actor;
     },
@@ -1087,7 +1040,7 @@ SingleView.prototype = {
     },
 
     _fillPositionalIndicator: function() {
-        if (this._indicatorsPanel == null || this._indicatorsPanelWidth == null)
+        if (this._indicatorsPanel == null || this._indicatorsPanelWidth == 0)
             return;
         let width = this._indicatorsPanelWidth;
         this._indicatorsPanel.remove_all();
@@ -1154,13 +1107,11 @@ SingleView.prototype = {
         return actor;
     },
 
-    _updatePanelVisibility: function() {
-        let canRemove = (global.screen.get_active_workspace_index() != 0);
-        let canAdd = (global.screen.n_workspaces < MAX_WORKSPACES);
-
-        this._setButtonSensitivity(this._removeButton, canRemove);
-        this._setButtonSensitivity(this._addButton, canAdd);
+    canRemoveWorkspace: function() {
+        return global.screen.get_active_workspace_index() != 0;
+    },
 
+    _updatePanelVisibility: function() {
         let showSwitches = (global.screen.n_workspaces > 1);
         if (this._scroll != null) {
             if (showSwitches)
@@ -1177,34 +1128,46 @@ SingleView.prototype = {
         this._fillPositionalIndicator();
     },
 
-    _addNewWorkspace: function() {
+    addWorkspace: function() {
         let ws = global.screen.append_new_workspace(false,
                                                     global.get_current_time());
         ws.activate(global.get_current_time());
     },
 
+    removeWorkspace: function() {
+        let active = global.screen.get_active_workspace_index();
+        global.screen.remove_workspace(this._workspaces[active]._metaWorkspace,
+                                       global.get_current_time());
+    },
+
     _acceptNewWorkspaceDrop: function(source, dropActor, x, y, time) {
-        this._addNewWorkspace();
+        this.addWorkspace();
         return this.acceptNewWorkspaceDrop(source, dropActor, x, y, time);
     }
 };
 
-function WorkspacesViewSwitch() {
+function WorkspacesControls() {
     this._init();
 }
 
-WorkspacesViewSwitch.prototype = {
+WorkspacesControls.prototype = {
     _init: function() {
+        this.actor = null;
         this._gconf = Shell.GConf.get_default();
         this._mosaicViewButton = null;
         this._singleViewButton = null;
-        this._controlsBar = null;
+        this._addButton = null;
+        this._removeButton = null;
 
         let view = this._gconf.get_string(WORKSPACES_VIEW_KEY).toUpperCase();
         if (view in WorkspacesViewType)
             this._currentViewType = WorkspacesViewType[view];
         else
             this._currentViewType = WorkspacesViewType.SINGLE;
+
+        this._currentView = null;
+        this._nWorkspacesNotifyId = 0;
+        this._switchWorkspaceNotifyId = 0;
     },
 
     _setView: function(view) {
@@ -1221,58 +1184,130 @@ WorkspacesViewSwitch.prototype = {
     createCurrentWorkspaceView: function(width, height, x, y, animate) {
         switch (this._currentViewType) {
             case WorkspacesViewType.SINGLE:
-                return new SingleView(width, height, x, y, animate);
+                this._currentView = new SingleView(width, height, x, y, animate);
+                break;
             case WorkspacesViewType.GRID:
-                return new MosaicView(width, height, x, y, animate);
             default:
-                return new MosaicView(width, height, x, y, animate);
+                this._currentView = new MosaicView(width, height, x, y, animate);
+                break;
         }
+        this._updateControlsBar();
+        return this._currentView;
     },
 
-    createControlsBar: function() {
-        let actor = new St.BoxLayout();
+    _updateControlsBar: function() {
+        if (this.actor)
+            this.actor.remove_all();
+        else
+            this.actor = new St.BoxLayout({ style_class: 'workspaces-bar' });
 
-        this._mosaicViewButton = new St.Button({ style_class: "workspace-controls switch-mosaic" });
-        this._mosaicViewButton.set_toggle_mode(true);
+        // View switcher buttons
+        this._mosaicViewButton = new St.Button({ style_class: 'workspace-controls switch-mosaic',
+                                                 toggle_mode: true });
         this._mosaicViewButton.connect('clicked', Lang.bind(this, function() {
             this._setView(WorkspacesViewType.GRID);
         }));
-        actor.add(this._mosaicViewButton, {'y-fill' : false, 'y-align' : St.Align.START});
+        this.actor.add(this._mosaicViewButton, { y_fill: false,
+                                                 y_align: St.Align.START });
 
-        this._singleViewButton = new St.Button({ style_class: "workspace-controls switch-single" });
-        this._singleViewButton.set_toggle_mode(true);
+        this._singleViewButton = new St.Button({ style_class: 'workspace-controls switch-single',
+                                                 toggle_mode: true });
         this._singleViewButton.connect('clicked', Lang.bind(this, function() {
             this._setView(WorkspacesViewType.SINGLE);
         }));
-        actor.add(this._singleViewButton, {'y-fill' : false, 'y-align' : St.Align.START});
+        this.actor.add(this._singleViewButton, { y_fill: false,
+                                                 y_align: St.Align.START });
 
         if (this._currentViewType == WorkspacesViewType.GRID)
             this._mosaicViewButton.set_checked(true);
         else
             this._singleViewButton.set_checked(true);
 
+        // View specific controls
+        let bar = this._currentView.createControllerBar();
+        if (!bar)
+            bar = new St.Bin();
+
+        this.actor.add(bar, { expand: true,
+                              x_fill: true,
+                              y_fill: true,
+                              y_align: St.Align.MIDDLE,
+                              x_align: St.Align.START });
+
+        // Add/remove workspace buttons
+        this._removeButton = new St.Button({ style_class: 'workspace-controls remove' });
+        this._removeButton.connect('clicked', Lang.bind(this, function() {
+            this._currentView.removeWorkspace();
+        }));
+        this.actor.add(this._removeButton, { y_fill: false,
+                                             y_align: St.Align.START });
+
+        this._addButton = new St.Button({ style_class: 'workspace-controls add' });
+        this._addButton.connect('clicked', Lang.bind(this, function() {
+            this._currentView.addWorkspace()
+        }));
+        this._addButton._delegate = this._addButton;
+        this._addButton._delegate.acceptDrop = Lang.bind(this,
+            function(source, actor, x, y, time) {
+                let view = this._currentView;
+                return view._acceptNewWorkspaceDrop(source, actor, x, y, time);
+            });
+        this.actor.add(this._addButton, { y_fill: false,
+                                          y_align: St.Align.START });
+
         this._nWorkspacesNotifyId =
             global.screen.connect('notify::n-workspaces',
                                   Lang.bind(this, this._workspacesChanged));
 
-        actor.connect('destroy', Lang.bind(this, function() {
-            this._controlsBar = null;
-            global.screen.disconnect(this._nWorkspacesNotifyId);
-        }));
+        this._switchWorkspaceNotifyId =
+            global.window_manager.connect('switch-workspace',
+                                          Lang.bind(this, this._updateButtonSensitivity));
+
+        this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
 
-        this._controlsBar = actor;
         this._workspacesChanged();
-        return actor;
+    },
+
+    _onDestroy: function() {
+        this.actor = null;
+        if (this._nWorkspacesNotifyId > 0) {
+            global.screen.disconnect(this._nWorkspacesNotifyId);
+            this._nWorkspacesNotifyId = 0;
+        }
+        if (this._switchWorkspaceNotifyId > 0) {
+            global.window_manager.disconnect(this._switchWorkspaceNotifyId);
+            this._switchWorkspaceNotifyId = 0;
+        }
+    },
+
+    _setButtonSensitivity: function(button, sensitive) {
+        if (button == null)
+            return;
+        button.reactive = sensitive;
+        button.opacity = sensitive ? 255 : 85;
+    },
+
+    _updateButtonSensitivity: function() {
+        this._setButtonSensitivity(this._addButton,
+                                   this._currentView.canAddWorkspace());
+        this._setButtonSensitivity(this._removeButton,
+                                   this._currentView.canRemoveWorkspace());
     },
 
     _workspacesChanged: function() {
-        if (this._controlsBar == null)
+        if (this.actor == null)
             return;
-        if (global.screen.n_workspaces == 1)
-            this._controlsBar.set_opacity(0);
-        else
-            this._controlsBar.set_opacity(255);
+
+        this._updateButtonSensitivity();
+
+        if (global.screen.n_workspaces == 1) {
+            this._mosaicViewButton.hide();
+            this._singleViewButton.hide();
+        } else {
+            this._mosaicViewButton.show();
+            this._singleViewButton.show();
+        }
     }
 };
 
-Signals.addSignalMethods(WorkspacesViewSwitch.prototype);
+Signals.addSignalMethods(WorkspacesControls.prototype);



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