gnome-shell r125 - trunk/js/ui



Author: danw
Date: Mon Dec 15 20:55:24 2008
New Revision: 125
URL: http://svn.gnome.org/viewvc/gnome-shell?rev=125&view=rev

Log:
change the workspace zooming metaphor in the overlay


Modified:
   trunk/js/ui/workspaces.js

Modified: trunk/js/ui/workspaces.js
==============================================================================
--- trunk/js/ui/workspaces.js	(original)
+++ trunk/js/ui/workspaces.js	Mon Dec 15 20:55:24 2008
@@ -26,7 +26,9 @@
         5: [[0.165, 0.25, 0.28], [0.495, 0.25, 0.28], [0.825, 0.25, 0.28], [0.25, 0.75, 0.4], [0.75, 0.75, 0.4]]
 };
 
-// spacing between workspaces
+// Spacing between workspaces. At the moment, the same spacing is used
+// in both zoomed-in and zoomed-out views; this is slightly
+// metaphor-breaking, but the alternatives are also weird.
 const GRID_SPACING = 15;
 
 function Workspaces(x, y, width, height) {
@@ -45,27 +47,44 @@
 
         let global = Shell.Global.get();
         let windows = global.get_windows();
-        let activeWorkspace = global.screen.get_active_workspace_index();
+        let activeWorkspaceIndex = global.screen.get_active_workspace_index();
+        let activeWorkspace;
 
-        // Create a group for each workspace (which lets us raise all of
-        // its clone windows together when the workspace is activated)
-        // and add the desktop windows
+        // Create a group for each workspace (which lets us raise all
+        // of its clone windows together when the workspace is
+        // activated), figure out their initial grid positions, and
+        // add the desktop windows
         this._workspaces = [];
         for (let w = 0; w < global.screen.n_workspaces; w++) {
             this._workspaces[w] = new Clutter.Group();
+            if (w == activeWorkspaceIndex)
+                activeWorkspace = this._workspaces[w];
             this.actor.add_actor(this._workspaces[w]);
         }
+        activeWorkspace.raise_top();
+        this._positionWorkspaces(global, activeWorkspace);
         this._createDesktopActors(windows);
 
-        // The workspaces will go into a grid that is either square,
-        // or else 1 cell wider than it is tall.
-        // FIXME: need to make the metacity internal layout agree with this!
-        let gridWidth = Math.ceil(Math.sqrt(this._workspaces.length));
-        let gridHeight = Math.ceil(this._workspaces.length / gridWidth);
+        // Create a backdrop rectangle, so that you don't see the
+        // other parts of the overlay (eg, sidebar) through the gaps
+        // between the workspaces when they're zooming in/out
+        this._backdrop = new Clutter.Rectangle({ color: Overlay.OVERLAY_BACKGROUND_COLOR,
+                                                 x: this._backdropX,
+                                                 y: this._backdropY,
+                                                 width: this._backdropWidth,
+                                                 height: this._backdropHeight
+                                               });
+        this.actor.add_actor(this._backdrop);
+        this._backdrop.lower_bottom();
+        Tweener.addTween(this._backdrop,
+                         { x: this._x,
+                           y: this._y,
+                           width: this._width,
+                           height: this._height,
+                           time: Overlay.ANIMATION_TIME,
+                           transition: "easeOutQuad"
+                         });
 
-        let wsWidth = (this._width - (gridWidth - 1) * GRID_SPACING) / gridWidth;
-        let wsHeight = (this._height - (gridHeight - 1) * GRID_SPACING) / gridHeight;
-        let scale = wsWidth / global.screen_width;
 
         // Position/scale the desktop windows and their children. This
         // would be easier if we instead just positioned and scaled
@@ -74,73 +93,72 @@
         // path as they move into place, which looks odd. Positioning
         // everything independently lets us move them in a straight
         // line.
-        for (let w = 0, x = this._x, y = this._y; w < this._workspaces.length; w++) {
+        for (let w = 0; w < this._workspaces.length; w++) {
             let workspace = this._workspaces[w];
+
             let desktop = workspace.get_nth_child(0);
+            desktop.set_position(workspace.zoomedOutX, workspace.zoomedOutY);
+            desktop.origX = desktop.origY = 0;
 
-            if (w == activeWorkspace) {
-                // The currently-active workspace needs to
-                // slide/shrink into place
-                workspace.raise_top();
-                Tweener.addTween(desktop,
-                                 { x: x,
-                                   y: y,
-                                   scale_x: scale,
-                                   scale_y: scale,
-                                   time: Overlay.ANIMATION_TIME,
-                                   transition: "easeOutQuad"
-                                 });
-            } else {
-                // Other workspaces can start out in place; they'll be
-                // revealed as the active workspace shrinks
-                desktop.set_position(x, y);
-                desktop.set_scale(scale, scale);
-            }
+            Tweener.addTween(desktop,
+                             { x: workspace.gridX,
+                               y: workspace.gridY,
+                               scale_x: workspace.gridScale,
+                               scale_y: workspace.gridScale,
+                               time: Overlay.ANIMATION_TIME,
+                               transition: "easeOutQuad"
+                             });
 
             // Now handle the rest of the windows in this workspace
             let wswindows = windows.filter(function (win) { return win.get_workspace() == w; });
 
-            // Do the windows in reverse order so that the active
-            // actor ends up on top
             for (let i = 0, windowIndex = 0; i < wswindows.length; i++) {
                 let win = wswindows[i];
                 if (win.get_window_type() == Meta.WindowType.DESKTOP ||
                     win.is_override_redirect())
                     continue;
 
-                this._createWindowClone(wswindows[i], this._workspaces[w],
-                                        x, y, scale,
+                this._createWindowClone(wswindows[i], workspace,
                                         wswindows.length - windowIndex - 1,
-                                        wswindows.length,
-                                        w == activeWorkspace);
+                                        wswindows.length);
                 windowIndex++;
             }
-
-            x += (wsWidth + GRID_SPACING);
-            if (x >= this._x + this._width - GRID_SPACING) {
-                x = this._x;
-                y += wsHeight + GRID_SPACING;
-            }
         }
     },
 
     hide : function() {
         let global = Shell.Global.get();
-        let activeWorkspace = global.screen.get_active_workspace_index();
+        let activeWorkspaceIndex = global.screen.get_active_workspace_index();
+        let activeWorkspace = this._workspaces[activeWorkspaceIndex];
 
-        this._workspaces[activeWorkspace].raise_top();
-        let windows = this._workspaces[activeWorkspace].get_children();
-        for (let i = 0; i < windows.length; i++) {
-            Tweener.addTween(windows[i],
-                             { x: windows[i].orig_x || 0,
-                               y: windows[i].orig_y || 0,
-                               scale_x: 1.0,
-                               scale_y: 1.0,
-                               time: Overlay.ANIMATION_TIME,
-                               opacity: 255,
-                               transition: "easeOutQuad"
-                             });
+        this._positionWorkspaces(global, activeWorkspace);
+        activeWorkspace.raise_top();
+
+        for (let w = 0; w < this._workspaces.length; w++) {
+            let workspace = this._workspaces[w];
+            let windows = workspace.get_children();
+
+            for (let i = 0; i < windows.length; i++) {
+                Tweener.addTween(windows[i],
+                                 { x: workspace.zoomedOutX + windows[i].origX,
+                                   y: workspace.zoomedOutY + windows[i].origY,
+                                   scale_x: 1.0,
+                                   scale_y: 1.0,
+                                   time: Overlay.ANIMATION_TIME,
+                                   opacity: 255,
+                                   transition: "easeOutQuad"
+                                 });
+            }
         }
+
+        Tweener.addTween(this._backdrop,
+                         { x: this._backdropX,
+                           y: this._backdropY,
+                           width: this._backdropWidth,
+                           height: this._backdropHeight,
+                           time: Overlay.ANIMATION_TIME,
+                           transition: "easeOutQuad"
+                         });
     },
 
     destroy : function() {
@@ -148,6 +166,50 @@
             this._workspaces[w].destroy();
         }
         this._workspaces = [];
+
+        this._backdrop.destroy();
+        this._backdrop = null;
+    },
+
+    _positionWorkspaces : function(global, activeWorkspace) {
+        let gridWidth = Math.ceil(Math.sqrt(this._workspaces.length));
+        let gridHeight = Math.ceil(this._workspaces.length / gridWidth);
+
+        let wsWidth = (this._width - (gridWidth - 1) * GRID_SPACING) / gridWidth;
+        let wsHeight = (this._height - (gridHeight - 1) * GRID_SPACING) / gridHeight;
+        let scale = wsWidth / global.screen_width;
+
+        // Assign workspaces to grid positions
+        for (let w = 0, col = 0, row = 0; w < this._workspaces.length; w++) {
+            let workspace = this._workspaces[w];
+
+            workspace.gridRow = row;
+            workspace.gridCol = col;
+
+            workspace.gridX = this._x + workspace.gridCol * (wsWidth + GRID_SPACING);
+            workspace.gridY = this._y + workspace.gridRow * (wsHeight + GRID_SPACING);
+            workspace.gridScale = scale;
+
+            col++;
+            if (col == gridWidth) {
+                col = 0;
+                row++;
+            }
+        }
+
+        // Now figure out their zoomed-out coordinates
+        for (let w = 0; w < this._workspaces.length; w++) {
+            let workspace = this._workspaces[w];
+
+            workspace.zoomedOutX = (workspace.gridCol - activeWorkspace.gridCol) * (global.screen_width + GRID_SPACING);
+            workspace.zoomedOutY = (workspace.gridRow - activeWorkspace.gridRow) * (global.screen_height + GRID_SPACING);
+        }
+
+        // And the backdrop
+        this._backdropX = this._workspaces[0].zoomedOutX;
+        this._backdropY = this._workspaces[0].zoomedOutY;
+        this._backdropWidth = gridWidth * (global.screen_width + GRID_SPACING) - GRID_SPACING;
+        this._backdropHeight = gridHeight * (global.screen_height + GRID_SPACING) - GRID_SPACING;
     },
 
     _createDesktopActors : function(windows) {
@@ -188,8 +250,8 @@
                                            reactive: true,
                                            x: window.x,
                                            y: window.y });
-        w.orig_x = window.x;
-        w.orig_y = window.y;
+        w.origX = window.x;
+        w.origY = window.y;
         return w;
     },
 
@@ -232,8 +294,7 @@
         return [xCenter, yCenter, fraction];
     },
 
-    _createWindowClone : function(w, workspace, wsX, wsY, wsScale,
-                                  windowIndex, numberOfWindows, animate) {
+    _createWindowClone : function(w, workspace, windowIndex, numberOfWindows) {
         let me = this;
         let global = Shell.Global.get();
 
@@ -247,8 +308,8 @@
 
         let desiredSize = global.screen_width * fraction;
 
-        xCenter = wsX + wsScale * (xCenter * global.screen_width);
-        yCenter = wsY + wsScale * (yCenter * global.screen_height);
+        xCenter = workspace.gridX + workspace.gridScale * (xCenter * global.screen_width);
+        yCenter = workspace.gridY + workspace.gridScale * (yCenter * global.screen_height);
 
         let size = clone.width;
         if (clone.height > size)
@@ -258,26 +319,21 @@
         let scale = desiredSize / size;
         if (scale > 1)
             scale = 1;
-        scale *= wsScale;
+        scale *= workspace.gridScale;
 
         workspace.add_actor(clone);
 
-        if (animate) {
-            Tweener.addTween(clone,
-                             { x: xCenter - 0.5 * scale * w.width,
-                               y: yCenter - 0.5 * scale * w.height,
-                               scale_x: scale,
-                               scale_y: scale,
-                               time: Overlay.ANIMATION_TIME,
-                               opacity: WINDOW_OPACITY,
-                               transition: "easeOutQuad"
-                             });
-        } else {
-            clone.set_position(xCenter - 0.5 * scale * w.width,
-                               yCenter - 0.5 * scale * w.height);
-            clone.set_scale(scale, scale);
-            clone.set_opacity(WINDOW_OPACITY);
-        }
+        clone.set_position(workspace.zoomedOutX + clone.origX,
+                           workspace.zoomedOutY + clone.origY);
+        Tweener.addTween(clone,
+                         { x: xCenter - 0.5 * scale * w.width,
+                           y: yCenter - 0.5 * scale * w.height,
+                           scale_x: scale,
+                           scale_y: scale,
+                           time: Overlay.ANIMATION_TIME,
+                           opacity: WINDOW_OPACITY,
+                           transition: "easeOutQuad"
+                         });
 
         clone.connect("button-press-event",
                       function(clone, event) {



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