Introduce a SlideLayout layout manager
SlideLayout is a fixed layout that takes care of requesting and allocating the right sizes so its contents can slide horizontally as the actor is resized. Sliding is controlled with a slideX and slideDirection properties, which do the right thing wrt. RTL automatically. Also add a SlidingControl base class that will be used by the overview to pack and slide the workspace thumbnail switcher and the dash. https://bugzilla.gnome.org/show_bug.cgi?id=682050
This commit is contained in:
parent
30179bb60d
commit
93bde0cae2
@ -68,6 +68,7 @@ nobase_dist_js_DATA = \
|
|||||||
ui/shellMountOperation.js \
|
ui/shellMountOperation.js \
|
||||||
ui/notificationDaemon.js \
|
ui/notificationDaemon.js \
|
||||||
ui/overview.js \
|
ui/overview.js \
|
||||||
|
ui/overviewControls.js \
|
||||||
ui/panel.js \
|
ui/panel.js \
|
||||||
ui/panelMenu.js \
|
ui/panelMenu.js \
|
||||||
ui/pointerWatcher.js \
|
ui/pointerWatcher.js \
|
||||||
|
144
js/ui/overviewControls.js
Normal file
144
js/ui/overviewControls.js
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
|
const Clutter = imports.gi.Clutter;
|
||||||
|
const Lang = imports.lang;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Main = imports.ui.main;
|
||||||
|
|
||||||
|
const SIDE_CONTROLS_ANIMATION_TIME = 0.2;
|
||||||
|
|
||||||
|
const SlideDirection = {
|
||||||
|
LEFT: 0,
|
||||||
|
RIGHT: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
const SlideLayout = new Lang.Class({
|
||||||
|
Name: 'SlideLayout',
|
||||||
|
Extends: Clutter.FixedLayout,
|
||||||
|
|
||||||
|
_init: function(params) {
|
||||||
|
this._slideX = 1;
|
||||||
|
this._direction = SlideDirection.LEFT;
|
||||||
|
|
||||||
|
this.parent(params);
|
||||||
|
},
|
||||||
|
|
||||||
|
_getRealSlideDirection: function(child) {
|
||||||
|
let direction = this._direction;
|
||||||
|
|
||||||
|
let rtl = (child.text_direction == Clutter.TextDirection.RTL);
|
||||||
|
if (rtl)
|
||||||
|
direction = (direction == SlideDirection.LEFT) ?
|
||||||
|
SlideDirection.RIGHT : SlideDirection.LEFT;
|
||||||
|
|
||||||
|
return direction;
|
||||||
|
},
|
||||||
|
|
||||||
|
vfunc_get_preferred_width: function(container, forHeight) {
|
||||||
|
let child = container.get_first_child();
|
||||||
|
|
||||||
|
let [minWidth, natWidth] = child.get_preferred_width(forHeight);
|
||||||
|
|
||||||
|
minWidth *= this._slideX;
|
||||||
|
natWidth *= this._slideX;
|
||||||
|
|
||||||
|
return [minWidth, natWidth];
|
||||||
|
},
|
||||||
|
|
||||||
|
vfunc_allocate: function(container, box, flags) {
|
||||||
|
let child = container.get_first_child();
|
||||||
|
|
||||||
|
let [, , natWidth, natHeight] = child.get_preferred_size();
|
||||||
|
let availWidth = Math.round(box.x2 - box.x1);
|
||||||
|
let availHeight = Math.round(box.y2 - box.y1);
|
||||||
|
|
||||||
|
let realDirection = this._getRealSlideDirection(child);
|
||||||
|
let translationX = (realDirection == SlideDirection.LEFT) ?
|
||||||
|
(availWidth - natWidth) : (natWidth - availWidth);
|
||||||
|
|
||||||
|
let actorBox = new Clutter.ActorBox({ x1: translationX,
|
||||||
|
y1: 0,
|
||||||
|
x2: child.x_expand ? availWidth : natWidth,
|
||||||
|
y2: child.y_expand ? availHeight : natHeight });
|
||||||
|
|
||||||
|
child.allocate(actorBox, flags);
|
||||||
|
},
|
||||||
|
|
||||||
|
set slideX(value) {
|
||||||
|
this._slideX = value;
|
||||||
|
this.layout_changed();
|
||||||
|
},
|
||||||
|
|
||||||
|
get slideX() {
|
||||||
|
return this._slideX;
|
||||||
|
},
|
||||||
|
|
||||||
|
set slideDirection(direction) {
|
||||||
|
this._direction = direction;
|
||||||
|
this.layout_changed();
|
||||||
|
},
|
||||||
|
|
||||||
|
get slideDirection() {
|
||||||
|
return this._direction;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const SlidingControl = new Lang.Class({
|
||||||
|
Name: 'SlidingControl',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.visible = true;
|
||||||
|
this.inDrag = false;
|
||||||
|
|
||||||
|
this.layout = new SlideLayout();
|
||||||
|
this.actor = new St.Widget({ layout_manager: this.layout,
|
||||||
|
clip_to_allocation: true });
|
||||||
|
|
||||||
|
Main.overview.connect('showing', Lang.bind(this, this._onOverviewShowing));
|
||||||
|
|
||||||
|
Main.overview.connect('item-drag-begin', Lang.bind(this, this._onDragBegin));
|
||||||
|
Main.overview.connect('item-drag-end', Lang.bind(this, this._onDragEnd));
|
||||||
|
Main.overview.connect('item-drag-cancelled', Lang.bind(this, this._onDragEnd));
|
||||||
|
Main.overview.connect('window-drag-begin', Lang.bind(this, this._onDragBegin));
|
||||||
|
Main.overview.connect('window-drag-cancelled', Lang.bind(this, this._onDragEnd));
|
||||||
|
Main.overview.connect('window-drag-end', Lang.bind(this, this._onDragEnd));
|
||||||
|
},
|
||||||
|
|
||||||
|
getSlide: function() {
|
||||||
|
throw new Error('getSlide() must be overridden');
|
||||||
|
},
|
||||||
|
|
||||||
|
updateSlide: function() {
|
||||||
|
Tweener.addTween(this.layout, { slideX: this.getSlide(),
|
||||||
|
time: SIDE_CONTROLS_ANIMATION_TIME,
|
||||||
|
transition: 'easeOutQuad' });
|
||||||
|
},
|
||||||
|
|
||||||
|
_onOverviewShowing: function() {
|
||||||
|
// reset any translation and make sure the actor is visible when
|
||||||
|
// entering the overview
|
||||||
|
this.visible = true;
|
||||||
|
this.layout.slideX = this.getSlide();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDragBegin: function() {
|
||||||
|
this.inDrag = true;
|
||||||
|
this.updateSlide();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onDragEnd: function() {
|
||||||
|
this.inDrag = false;
|
||||||
|
this.updateSlide();
|
||||||
|
},
|
||||||
|
|
||||||
|
slideIn: function() {
|
||||||
|
this.visible = true;
|
||||||
|
this.updateSlide();
|
||||||
|
},
|
||||||
|
|
||||||
|
slideOut: function() {
|
||||||
|
this.visible = false;
|
||||||
|
this.updateSlide();
|
||||||
|
}
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user