145 lines
4.1 KiB
JavaScript
145 lines
4.1 KiB
JavaScript
|
// -*- 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();
|
||
|
}
|
||
|
});
|