gnome-shell/js/ui/sidebar.js
Dan Winship 10afe46195 Add an initial implementation of the sidebar
This still needs design love, and none of the current widgets should be
considered finalized, but it shows the basic ideas.

http://bugzilla.gnome.org/show_bug.cgi?id=581774
2009-05-15 17:04:18 -04:00

154 lines
5.4 KiB
JavaScript

/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Big = imports.gi.Big;
const Clutter = imports.gi.Clutter;
const Shell = imports.gi.Shell;
const Lang = imports.lang;
const Main = imports.ui.main;
const Panel = imports.ui.panel;
const Tweener = imports.ui.tweener;
const Widget = imports.ui.widget;
const WidgetBox = imports.ui.widgetBox;
const SIDEBAR_SPACING = 4;
const SIDEBAR_PADDING = 4;
// The total sidebar width is the widget width plus the widget
// padding, plus the sidebar padding
const SIDEBAR_COLLAPSED_WIDTH = Widget.COLLAPSED_WIDTH + 2 * WidgetBox.WIDGETBOX_PADDING + 2 * SIDEBAR_PADDING;
const SIDEBAR_EXPANDED_WIDTH = Widget.EXPANDED_WIDTH + 2 * WidgetBox.WIDGETBOX_PADDING + 2 * SIDEBAR_PADDING;
// The maximum height of the sidebar would be extending from just
// below the panel to just above the taskbar. Since the taskbar is
// just a temporary hack and it would be too hard to do this the right
// way, we just hardcode its size.
const HARDCODED_TASKBAR_HEIGHT = 24;
const MAXIMUM_SIDEBAR_HEIGHT = Shell.Global.get().screen_height - Panel.PANEL_HEIGHT - HARDCODED_TASKBAR_HEIGHT;
// FIXME, needs to be configurable, obviously
const default_widgets = [
"imports.ui.widget.ClockWidget",
"imports.ui.widget.AppsWidget",
"imports.ui.widget.DocsWidget"
];
function Sidebar() {
this._init();
}
Sidebar.prototype = {
_init : function() {
let global = Shell.Global.get();
// The top-left corner of the sidebar is fixed at:
// x = -WidgetBox.WIDGETBOX_PADDING, y = Panel.PANEL_HEIGHT.
// (The negative X is so that we don't see the rounded
// WidgetBox corners on the screen edge side.)
this.actor = new Clutter.Group({ x: -WidgetBox.WIDGETBOX_PADDING,
y: Panel.PANEL_HEIGHT,
width: SIDEBAR_EXPANDED_WIDTH });
Main.chrome.addActor(this.actor);
// The actual widgets go into a Big.Box inside this.actor. The
// box's width will vary during the expand/collapse animations,
// but this.actor's width will remain constant until we adjust
// it at the end of the animation, because we don't want the
// wm strut to move and cause windows to move multiple times
// during the animation.
this.box = new Big.Box ({ padding_top: SIDEBAR_PADDING,
padding_bottom: SIDEBAR_PADDING,
padding_right: SIDEBAR_PADDING,
padding_left: 0,
spacing: SIDEBAR_SPACING });
this.actor.add_actor(this.box);
this._visible = this.expanded = true;
this._widgets = [];
this.addWidget(new ToggleWidget(this));
for (let i = 0; i < default_widgets.length; i++)
this.addWidget(default_widgets[i]);
},
addWidget: function(widget) {
let widgetBox;
try {
widgetBox = new WidgetBox.WidgetBox(widget);
} catch(e) {
logError(e, "Failed to add widget '" + widget + "'");
return;
}
this.box.append(widgetBox.actor, Big.BoxPackFlags.NONE);
this._widgets.push(widgetBox);
},
show: function() {
this._visible = true;
this.actor.show();
},
hide: function() {
this._visible = false;
this.actor.hide();
},
expand: function() {
this.expanded = true;
for (let i = 0; i < this._widgets.length; i++)
this._widgets[i].expand();
// Updated the strut/stage area after the animation completes
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME,
onComplete: function () {
this.actor.width = SIDEBAR_EXPANDED_WIDTH;
} });
},
collapse: function() {
this.expanded = false;
for (let i = 0; i < this._widgets.length; i++)
this._widgets[i].collapse();
// Updated the strut/stage area after the animation completes
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME,
onComplete: function () {
this.actor.width = SIDEBAR_COLLAPSED_WIDTH;
} });
},
destroy: function() {
this.hide();
for (let i = 0; i < this._widgets.length; i++)
this._widgets[i].destroy();
this.actor.destroy();
}
};
const LEFT_DOUBLE_ARROW = "\u00AB";
const RIGHT_DOUBLE_ARROW = "\u00BB";
function ToggleWidget(sidebar) {
this._init(sidebar);
}
ToggleWidget.prototype = {
__proto__ : Widget.Widget.prototype,
_init : function(sidebar) {
this._sidebar = sidebar;
this.actor = new Clutter.Text({ font_name: "Sans Bold 16px",
text: LEFT_DOUBLE_ARROW,
reactive: true });
this.actor.connect('button-release-event',
Lang.bind(this._sidebar, this._sidebar.collapse));
this.collapsedActor = new Clutter.Text({ font_name: "Sans Bold 16px",
text: RIGHT_DOUBLE_ARROW,
reactive: true });
this.collapsedActor.connect('button-release-event',
Lang.bind(this._sidebar, this._sidebar.expand));
}
};