change the workspace zooming metaphor in the overlay
svn path=/trunk/; revision=125
This commit is contained in:
parent
249e65ee30
commit
d07433d445
@ -26,7 +26,9 @@ const POSITIONS = {
|
||||
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 @@ Workspaces.prototype = {
|
||||
|
||||
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 @@ Workspaces.prototype = {
|
||||
// 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);
|
||||
|
||||
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);
|
||||
}
|
||||
let desktop = workspace.get_nth_child(0);
|
||||
desktop.set_position(workspace.zoomedOutX, workspace.zoomedOutY);
|
||||
desktop.origX = desktop.origY = 0;
|
||||
|
||||
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 @@ Workspaces.prototype = {
|
||||
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 @@ Workspaces.prototype = {
|
||||
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 @@ Workspaces.prototype = {
|
||||
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 @@ Workspaces.prototype = {
|
||||
|
||||
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 @@ Workspaces.prototype = {
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user