Remove sidebar
This commit is contained in:
parent
a9bdffc9e6
commit
b8647cc00e
@ -57,63 +57,6 @@
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/sidebar/visible</key>
|
||||
<applyto>/desktop/gnome/shell/sidebar/visible</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>false</default>
|
||||
<locale name="C">
|
||||
<short>Whether or not to display the sidebar</short>
|
||||
<long>
|
||||
Determines whether or not the sidebar is visible.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/sidebar/expanded</key>
|
||||
<applyto>/desktop/gnome/shell/sidebar/expanded</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>true</default>
|
||||
<locale name="C">
|
||||
<short>Whether the sidebar should be in the expanded (wide) mode</short>
|
||||
<long>
|
||||
Controls the expanded/collapsed state of the sidebar.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/sidebar/autohide</key>
|
||||
<applyto>/desktop/gnome/shell/sidebar/autohide</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>bool</type>
|
||||
<default>true</default>
|
||||
<locale name="C">
|
||||
<short>Whether the sidebar should automatically hide itself in compact mode</short>
|
||||
<long>
|
||||
Controls the autohide state of the sidebar.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/sidebar/widgets</key>
|
||||
<applyto>/desktop/gnome/shell/sidebar/widgets</applyto>
|
||||
<owner>gnome-shell</owner>
|
||||
<type>list</type>
|
||||
<list_type>string</list_type>
|
||||
<default>[imports.ui.widget.ClockWidget,imports.ui.widget.AppsWidget,imports.ui.widget.RecentDocsWidget]</default>
|
||||
<locale name="C">
|
||||
<short>The widgets to display in the sidebar</short>
|
||||
<long>
|
||||
The widgets to display in the sidebar, in order from top to bottom. Each widget "name" is actually a JavaScript expression referring to a widget constructor object.
|
||||
</long>
|
||||
</locale>
|
||||
</schema>
|
||||
|
||||
<schema>
|
||||
<key>/schemas/desktop/gnome/shell/disabled_extensions</key>
|
||||
<applyto>/desktop/gnome/shell/disabled_extensions</applyto>
|
||||
|
@ -24,11 +24,8 @@ dist_jsui_DATA = \
|
||||
runDialog.js \
|
||||
search.js \
|
||||
shellDBus.js \
|
||||
sidebar.js \
|
||||
statusMenu.js \
|
||||
tweener.js \
|
||||
widget.js \
|
||||
widgetBox.js \
|
||||
windowAttentionHandler.js \
|
||||
windowManager.js \
|
||||
workspacesView.js \
|
||||
|
@ -24,7 +24,6 @@ const LookingGlass = imports.ui.lookingGlass;
|
||||
const NotificationDaemon = imports.ui.notificationDaemon;
|
||||
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
||||
const ShellDBus = imports.ui.shellDBus;
|
||||
const Sidebar = imports.ui.sidebar;
|
||||
const WindowManager = imports.ui.windowManager;
|
||||
|
||||
const DEFAULT_BACKGROUND_COLOR = new Clutter.Color();
|
||||
@ -32,7 +31,6 @@ DEFAULT_BACKGROUND_COLOR.from_pixel(0x2266bbff);
|
||||
|
||||
let chrome = null;
|
||||
let panel = null;
|
||||
let sidebar = null;
|
||||
let placesManager = null;
|
||||
let overview = null;
|
||||
let runDialog = null;
|
||||
@ -109,7 +107,6 @@ function start() {
|
||||
overview = new Overview.Overview();
|
||||
chrome = new Chrome.Chrome();
|
||||
panel = new Panel.Panel();
|
||||
sidebar = new Sidebar.Sidebar();
|
||||
wm = new WindowManager.WindowManager();
|
||||
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
||||
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
||||
|
264
js/ui/sidebar.js
264
js/ui/sidebar.js
@ -1,264 +0,0 @@
|
||||
/* -*- 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 Mainloop = imports.mainloop;
|
||||
|
||||
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
|
||||
// (counted twice for the widget box, and once again for the
|
||||
// out-of-screen padding), plus the empty space between the border of
|
||||
// the bar and of the windows
|
||||
const SIDEBAR_COLLAPSED_WIDTH = Widget.COLLAPSED_WIDTH + 3 * WidgetBox.WIDGETBOX_PADDING + SIDEBAR_PADDING;
|
||||
const SIDEBAR_EXPANDED_WIDTH = Widget.EXPANDED_WIDTH + 3 * WidgetBox.WIDGETBOX_PADDING + SIDEBAR_PADDING;
|
||||
|
||||
function Sidebar() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
Sidebar.prototype = {
|
||||
_init : function() {
|
||||
// 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 });
|
||||
|
||||
// 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: 0,
|
||||
padding_left: 0,
|
||||
spacing: SIDEBAR_SPACING });
|
||||
this.actor.add_actor(this.box);
|
||||
|
||||
this._gconf = Shell.GConf.get_default();
|
||||
|
||||
this._expanded = this._gconf.get_boolean ("sidebar/expanded");
|
||||
if (!this._expanded)
|
||||
this.actor.width = SIDEBAR_COLLAPSED_WIDTH;
|
||||
|
||||
this._visible = this._gconf.get_boolean ("sidebar/visible");
|
||||
if (this._visible)
|
||||
Main.chrome.addActor(this.actor);
|
||||
|
||||
this._hidden = false;
|
||||
this._hideTimeoutId = 0;
|
||||
this._widgets = [];
|
||||
this.addWidget(new ToggleWidget());
|
||||
|
||||
let default_widgets = this._gconf.get_string_list("sidebar/widgets");
|
||||
for (let i = 0; i < default_widgets.length; i++)
|
||||
this.addWidget(default_widgets[i]);
|
||||
|
||||
this._gconf.connect('changed::sidebar/expanded',
|
||||
Lang.bind(this, this._expandedChanged));
|
||||
this._gconf.connect('changed::sidebar/visible',
|
||||
Lang.bind(this, this._visibleChanged));
|
||||
this._gconf.connect('changed::sidebar/autohide',
|
||||
Lang.bind(this, this._autohideChanged));
|
||||
|
||||
this.actor.connect('enter-event',Lang.bind(this,this._restoreHidden));
|
||||
this.actor.connect('leave-event',Lang.bind(this,this._startHideTimeout));
|
||||
|
||||
this._adjustPosition();
|
||||
this._autohideChanged();
|
||||
},
|
||||
|
||||
addWidget: function(widget) {
|
||||
let widgetBox;
|
||||
try {
|
||||
widgetBox = new WidgetBox.WidgetBox(widget, this._expanded);
|
||||
} catch(e) {
|
||||
logError(e, "Failed to add widget '" + widget + "'");
|
||||
return;
|
||||
}
|
||||
|
||||
this.box.append(widgetBox.actor, Big.BoxPackFlags.NONE);
|
||||
this._widgets.push(widgetBox);
|
||||
this._adjustPosition();
|
||||
},
|
||||
|
||||
_adjustPosition: function() {
|
||||
let primary=global.get_primary_monitor();
|
||||
|
||||
this.actor.y = Math.floor(Math.max(primary.y + Panel.PANEL_HEIGHT,primary.height/2 - this.actor.height/2));
|
||||
this.actor.x = primary.x;
|
||||
},
|
||||
|
||||
_visibleChanged: function() {
|
||||
let visible = this._gconf.get_boolean("sidebar/visible");
|
||||
if (visible == this._visible)
|
||||
return;
|
||||
|
||||
this._visible = visible;
|
||||
if (visible)
|
||||
Main.chrome.addActor(this.actor);
|
||||
else
|
||||
Main.chrome.removeActor(this.actor);
|
||||
},
|
||||
|
||||
_expandedChanged: function() {
|
||||
let expanded = this._gconf.get_boolean("sidebar/expanded");
|
||||
if (expanded == this._expanded)
|
||||
return;
|
||||
|
||||
this._expanded = expanded;
|
||||
if (expanded)
|
||||
this._expand();
|
||||
else
|
||||
this._collapse();
|
||||
},
|
||||
|
||||
_autohideChanged: function() {
|
||||
let autohide = this._gconf.get_boolean("sidebar/autohide");
|
||||
if (autohide == this._autohide)
|
||||
return;
|
||||
|
||||
this._autohide = autohide;
|
||||
if (autohide) {
|
||||
this.actor.set_reactive(true);
|
||||
this._hide();
|
||||
} else {
|
||||
this.actor.set_reactive(false);
|
||||
this._restore();
|
||||
}
|
||||
},
|
||||
|
||||
_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();
|
||||
|
||||
// Update the strut/stage area after the animation completes
|
||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME,
|
||||
onComplete: Lang.bind(this, function () {
|
||||
this.actor.width = SIDEBAR_COLLAPSED_WIDTH;
|
||||
}) });
|
||||
},
|
||||
|
||||
_hide: function() {
|
||||
if (!this._expanded) {
|
||||
this._hidden = true;
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
this._widgets[i].hide();
|
||||
|
||||
// Update the strut/stage area after the animation completes
|
||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME / 2,
|
||||
onComplete: Lang.bind(this, function () {
|
||||
this.actor.width = Math.floor(WidgetBox.WIDGETBOX_PADDING * 2 + SIDEBAR_PADDING);
|
||||
}) });
|
||||
}
|
||||
},
|
||||
|
||||
_restore: function() {
|
||||
if (!this._expanded) {
|
||||
this._hidden = false;
|
||||
for (let i = 0; i < this._widgets.length; i++)
|
||||
this._widgets[i].restore();
|
||||
|
||||
// Updated the strut/stage area after the animation completes
|
||||
Tweener.addTween(this, { time: WidgetBox.ANIMATION_TIME / 2,
|
||||
onComplete: function () {
|
||||
this.actor.width = SIDEBAR_COLLAPSED_WIDTH;
|
||||
} });
|
||||
}
|
||||
},
|
||||
|
||||
_restoreHidden: function(actor, event) {
|
||||
this._cancelHideTimeout();
|
||||
if (this._hidden)
|
||||
this._restore();
|
||||
return false;
|
||||
},
|
||||
|
||||
_startHideTimeout: function(actor, event) {
|
||||
if (!this._expanded) {
|
||||
this._cancelHideTimeout();
|
||||
this._hideTimeoutId = Mainloop.timeout_add_seconds(2, Lang.bind(this,this._hideTimeoutFunc));
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_cancelHideTimeout: function() {
|
||||
if (this._hideTimeoutId != 0) {
|
||||
Mainloop.source_remove(this._hideTimeoutId);
|
||||
this._hideTimeoutId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
_hideTimeoutFunc: function() {
|
||||
this._hide();
|
||||
return false;
|
||||
},
|
||||
|
||||
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() {
|
||||
this._init();
|
||||
}
|
||||
|
||||
ToggleWidget.prototype = {
|
||||
__proto__ : Widget.Widget.prototype,
|
||||
|
||||
_init : function() {
|
||||
this._gconf = Shell.GConf.get_default();
|
||||
|
||||
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, this._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, this._expand));
|
||||
},
|
||||
|
||||
_collapse : function () {
|
||||
this._gconf.set_boolean ("sidebar/expanded", false);
|
||||
},
|
||||
|
||||
_expand : function () {
|
||||
this._gconf.set_boolean ("sidebar/expanded", true);
|
||||
}
|
||||
};
|
@ -18,8 +18,6 @@ const Panel = imports.ui.panel;
|
||||
// Copyright (C) 2004-2005 James M. Cape <jcape@ignore-your.tv>.
|
||||
// Copyright (C) 2008,2009 Red Hat, Inc.
|
||||
|
||||
const SIDEBAR_VISIBLE_KEY = 'sidebar/visible';
|
||||
|
||||
function StatusMenu() {
|
||||
this._init();
|
||||
}
|
||||
@ -128,17 +126,6 @@ StatusMenu.prototype = {
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
|
||||
let gconf = Shell.GConf.get_default();
|
||||
item = new Gtk.CheckMenuItem({ label: _("Sidebar"),
|
||||
active: gconf.get_boolean(SIDEBAR_VISIBLE_KEY) });
|
||||
item.connect('activate', Lang.bind(this,
|
||||
function() {
|
||||
gconf.set_boolean(SIDEBAR_VISIBLE_KEY, this._sidebarItem.active);
|
||||
}));
|
||||
this._menu.append(item);
|
||||
item.show();
|
||||
this._sidebarItem = item;
|
||||
|
||||
item = this._createImageMenuItem(_("System Preferences..."), 'preferences-desktop');
|
||||
item.connect('activate', Lang.bind(this, this._onPreferencesActivate));
|
||||
this._menu.append(item);
|
||||
|
364
js/ui/widget.js
364
js/ui/widget.js
@ -1,364 +0,0 @@
|
||||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
|
||||
const Big = imports.gi.Big;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
const Gio = imports.gi.Gio;
|
||||
const Gtk = imports.gi.Gtk;
|
||||
const Mainloop = imports.mainloop;
|
||||
const Lang = imports.lang;
|
||||
const Pango = imports.gi.Pango;
|
||||
const Shell = imports.gi.Shell;
|
||||
const Signals = imports.signals;
|
||||
const St = imports.gi.St;
|
||||
const Gettext = imports.gettext.domain('gnome-shell');
|
||||
const _ = Gettext.gettext;
|
||||
|
||||
const AppFavorites = imports.ui.appFavorites;
|
||||
const DocInfo = imports.misc.docInfo;
|
||||
|
||||
const COLLAPSED_WIDTH = 24;
|
||||
const EXPANDED_WIDTH = 200;
|
||||
|
||||
const STATE_EXPANDED = 0;
|
||||
const STATE_COLLAPSING = 1;
|
||||
const STATE_COLLAPSED = 2;
|
||||
const STATE_EXPANDING = 3;
|
||||
const STATE_POPPING_OUT = 4;
|
||||
const STATE_POPPED_OUT = 5;
|
||||
const STATE_POPPING_IN = 6;
|
||||
|
||||
function Widget() {
|
||||
}
|
||||
|
||||
Widget.prototype = {
|
||||
// _init():
|
||||
//
|
||||
// Your widget constructor. Your constructor function should look
|
||||
// like:
|
||||
//
|
||||
// function MyWidgetType() {
|
||||
// this._init.apply(this, arguments);
|
||||
// }
|
||||
//
|
||||
// and your _init method should start by doing:
|
||||
//
|
||||
// Widget.Widget.prototype._init.apply(this, arguments);
|
||||
//
|
||||
// The _init method must define a field named "actor" containing
|
||||
// the Clutter.Actor to show in expanded mode. This actor will be
|
||||
// clipped to Widget.EXPANDED_WIDTH. Most widgets will also define
|
||||
// a field named "title" containing the title string to show above
|
||||
// the widget in the sidebar.
|
||||
//
|
||||
// If you want to have a separate collapsed view, you can define a
|
||||
// field "collapsedActor" containing the Clutter.Actor to show in
|
||||
// that mode. (It may be the same actor.) This actor will be
|
||||
// clipped to Widget.COLLAPSED_WIDTH, and will normally end up
|
||||
// having the same height as the main actor.
|
||||
//
|
||||
// If you do not set a collapsedActor, then you must set a title,
|
||||
// since that is what will be displayed in collapsed mode, and
|
||||
// in this case (and only in this case), the widget will support
|
||||
// pop-out, meaning that if the user hovers over its title while
|
||||
// the sidebar is collapsed, the widget's expanded view will pop
|
||||
// out of the sidebar until either the cursor moves out of it,
|
||||
// or else the widget calls this.activated() on itself.
|
||||
_init: function (initialState) {
|
||||
this.state = initialState;
|
||||
},
|
||||
|
||||
// destroy():
|
||||
//
|
||||
// Optional. Will be called when the widget is removed from the
|
||||
// sidebar. (Note that you don't need to destroy the actors,
|
||||
// since they will be destroyed for you.)
|
||||
|
||||
// collapse():
|
||||
//
|
||||
// Optional. Called during the sidebar collapse process, at the
|
||||
// point when the expanded sidebar has slid offscreen, but the
|
||||
// collapsed sidebar has not yet slid onscreen.
|
||||
|
||||
// expand():
|
||||
//
|
||||
// Optional. Called during the sidebar expand process, at the
|
||||
// point when the collapsed sidebar has slid offscreen, but the
|
||||
// expanded sidebar has not yet slid onscreen.
|
||||
|
||||
// activated():
|
||||
//
|
||||
// Emits the "activated" signal for you, which will cause pop-out
|
||||
// to end.
|
||||
activated: function() {
|
||||
this.emit('activated');
|
||||
}
|
||||
|
||||
// state:
|
||||
//
|
||||
// A field set on your widget by the sidebar. Will contain one of
|
||||
// the Widget.STATE_* values. (Eg, Widget.STATE_EXPANDED).
|
||||
};
|
||||
|
||||
Signals.addSignalMethods(Widget.prototype);
|
||||
|
||||
|
||||
function ClockWidget() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
||||
ClockWidget.prototype = {
|
||||
__proto__ : Widget.prototype,
|
||||
|
||||
_init: function() {
|
||||
Widget.prototype._init.apply(this, arguments);
|
||||
|
||||
this.actor = new Clutter.Text({ font_name: "Sans Bold 16px",
|
||||
text: "",
|
||||
// Give an explicit height to ensure
|
||||
// it's the same in both modes
|
||||
height: COLLAPSED_WIDTH });
|
||||
|
||||
this.collapsedActor = new St.DrawingArea({ width: COLLAPSED_WIDTH,
|
||||
height: COLLAPSED_WIDTH });
|
||||
this.collapsedActor.connect('repaint', Lang.bind(this, this._repaintClock));
|
||||
|
||||
this._update();
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (this.timer)
|
||||
Mainloop.source_remove(this.timer);
|
||||
},
|
||||
|
||||
expand: function() {
|
||||
this._update();
|
||||
},
|
||||
|
||||
collapse: function() {
|
||||
this._update();
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
this.currentTime = new Date();
|
||||
let msec_remaining = 60000 - (1000 * this.currentTime.getSeconds() +
|
||||
this.currentTime.getMilliseconds());
|
||||
if (msec_remaining < 500) {
|
||||
this.currentTime.setMinutes(this.currentTime.getMinutes() + 1);
|
||||
msec_remaining += 60000;
|
||||
}
|
||||
|
||||
if (this.state == STATE_COLLAPSED || this.state == STATE_COLLAPSING)
|
||||
this.collapsedActor.queue_repaint();
|
||||
else
|
||||
this._updateText();
|
||||
|
||||
if (this.timer)
|
||||
Mainloop.source_remove(this.timer);
|
||||
this.timer = Mainloop.timeout_add(msec_remaining, Lang.bind(this, this._update));
|
||||
return false;
|
||||
},
|
||||
|
||||
_updateText: function(time) {
|
||||
// Translators: This is a time format.
|
||||
this.actor.set_text(this.currentTime.toLocaleFormat(_("%H:%M")));
|
||||
},
|
||||
|
||||
_repaintClock: function(area) {
|
||||
Shell.draw_clock(area,
|
||||
this.currentTime.getHours() % 12,
|
||||
this.currentTime.getMinutes());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const ITEM_ICON_SIZE = 48;
|
||||
const ITEM_PADDING = 1;
|
||||
const ITEM_SPACING = 4;
|
||||
|
||||
const ITEM_BG_COLOR = new Clutter.Color();
|
||||
ITEM_BG_COLOR.from_pixel(0x00000000);
|
||||
const ITEM_NAME_COLOR = new Clutter.Color();
|
||||
ITEM_NAME_COLOR.from_pixel(0x000000ff);
|
||||
|
||||
function LauncherWidget() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
||||
LauncherWidget.prototype = {
|
||||
__proto__ : Widget.prototype,
|
||||
|
||||
addItem : function(info) {
|
||||
let item = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
width: EXPANDED_WIDTH,
|
||||
height: ITEM_ICON_SIZE,
|
||||
padding: ITEM_PADDING,
|
||||
spacing: ITEM_SPACING,
|
||||
reactive: true });
|
||||
item._info = info;
|
||||
item.append(info.createIcon(ITEM_ICON_SIZE), Big.BoxPackFlags.NONE);
|
||||
item.append(new Clutter.Text({ color: ITEM_NAME_COLOR,
|
||||
font_name: "Sans 14px",
|
||||
ellipsize: Pango.EllipsizeMode.END,
|
||||
text: info.name }),
|
||||
Big.BoxPackFlags.NONE);
|
||||
|
||||
this.actor.append(item, Big.BoxPackFlags.NONE);
|
||||
item.connect('button-press-event', Lang.bind(this, this._buttonPress));
|
||||
item.connect('button-release-event', Lang.bind(this, this._buttonRelease));
|
||||
item.connect('leave-event', Lang.bind(this, this._leave));
|
||||
item.connect('enter-event', Lang.bind(this, this._enter));
|
||||
|
||||
if (!this.collapsedActor)
|
||||
return;
|
||||
|
||||
item = new Big.Box({ width: COLLAPSED_WIDTH,
|
||||
height: COLLAPSED_WIDTH,
|
||||
padding: ITEM_PADDING,
|
||||
reactive: true });
|
||||
item._info = info;
|
||||
item.append(info.createIcon(COLLAPSED_WIDTH - 2 * ITEM_PADDING),
|
||||
Big.BoxPackFlags.NONE);
|
||||
|
||||
this.collapsedActor.append(item, Big.BoxPackFlags.NONE);
|
||||
item.connect('button-press-event', Lang.bind(this, this._buttonPress));
|
||||
item.connect('button-release-event', Lang.bind(this, this._buttonRelease));
|
||||
item.connect('leave-event', Lang.bind(this, this._leave));
|
||||
item.connect('enter-event', Lang.bind(this, this._enter));
|
||||
},
|
||||
|
||||
clear : function() {
|
||||
let children, i;
|
||||
|
||||
children = this.actor.get_children();
|
||||
for (i = 0; i < children.length; i++)
|
||||
children[i].destroy();
|
||||
|
||||
if (this.collapsedActor) {
|
||||
children = this.collapsedActor.get_children();
|
||||
for (i = 0; i < children.length; i++)
|
||||
children[i].destroy();
|
||||
}
|
||||
},
|
||||
|
||||
_buttonPress : function(item) {
|
||||
Clutter.grab_pointer(item);
|
||||
item._buttonDown = true;
|
||||
item._inItem = true;
|
||||
this._updateItemState(item);
|
||||
return true;
|
||||
},
|
||||
|
||||
_leave : function(item, evt) {
|
||||
if (evt.get_source() == item && item._buttonDown) {
|
||||
item._inItem = false;
|
||||
this._updateItemState(item);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_enter : function(item, evt) {
|
||||
if (evt.get_source() == item && item._buttonDown) {
|
||||
item._inItem = true;
|
||||
this._updateItemState(item);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
_buttonRelease : function(item) {
|
||||
Clutter.ungrab_pointer(item);
|
||||
item._buttonDown = false;
|
||||
this._updateItemState(item);
|
||||
|
||||
if (item._inItem) {
|
||||
item._info.launch();
|
||||
this.activated();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
_updateItemState : function(item) {
|
||||
if (item._buttonDown && item._inItem) {
|
||||
item.padding_top = item.padding_left = 2 * ITEM_PADDING;
|
||||
item.padding_bottom = item.padding_right = 0;
|
||||
} else
|
||||
item.padding = ITEM_PADDING;
|
||||
}
|
||||
};
|
||||
|
||||
function AppsWidgetInfo(appInfo) {
|
||||
this._init(appInfo);
|
||||
}
|
||||
|
||||
AppsWidgetInfo.prototype = {
|
||||
_init : function(appInfo) {
|
||||
this._info = appInfo;
|
||||
this.name = appInfo.get_name();
|
||||
},
|
||||
|
||||
createIcon : function(size) {
|
||||
return this._info.create_icon_texture(size);
|
||||
},
|
||||
|
||||
launch : function() {
|
||||
this._info.launch();
|
||||
}
|
||||
};
|
||||
|
||||
function AppsWidget() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
||||
AppsWidget.prototype = {
|
||||
__proto__ : LauncherWidget.prototype,
|
||||
|
||||
_init : function() {
|
||||
Widget.prototype._init.apply(this, arguments);
|
||||
|
||||
this.title = _("Applications");
|
||||
this.actor = new Big.Box({ spacing: 2 });
|
||||
this.collapsedActor = new Big.Box({ spacing: 2});
|
||||
|
||||
let appSystem = Shell.AppSystem.get_default();
|
||||
let apps = AppFavorites.getAppFavorites().getFavorites();
|
||||
for (let i = 0; i < apps.length; i++) {
|
||||
this.addItem(new AppsWidgetInfo(apps[i]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function RecentDocsWidget() {
|
||||
this._init.apply(this, arguments);
|
||||
}
|
||||
|
||||
RecentDocsWidget.prototype = {
|
||||
__proto__ : LauncherWidget.prototype,
|
||||
|
||||
_init : function() {
|
||||
Widget.prototype._init.apply(this, arguments);
|
||||
|
||||
this.title = _("Recent Documents");
|
||||
this.actor = new Big.Box({ spacing: 2 });
|
||||
|
||||
this._recentManager = Gtk.RecentManager.get_default();
|
||||
this._recentManager.connect('changed', Lang.bind(this, this._recentChanged));
|
||||
this._recentChanged();
|
||||
},
|
||||
|
||||
_recentChanged: function() {
|
||||
let i;
|
||||
|
||||
this.clear();
|
||||
|
||||
let items = [];
|
||||
let docs = this._recentManager.get_items();
|
||||
for (i = 0; i < docs.length; i++) {
|
||||
let docInfo = new DocInfo.DocInfo (docs[i]);
|
||||
|
||||
items.push(docInfo);
|
||||
}
|
||||
|
||||
items.sort(function (a,b) { return b.timestamp - a.timestamp; });
|
||||
for (i = 0; i < Math.min(items.length, 5); i++)
|
||||
this.addItem(items[i]);
|
||||
}
|
||||
};
|
@ -1,395 +0,0 @@
|
||||
/* -*- 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 Mainloop = imports.mainloop;
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Tweener = imports.ui.tweener;
|
||||
const Widget = imports.ui.widget;
|
||||
|
||||
const WIDGETBOX_BG_COLOR = new Clutter.Color();
|
||||
WIDGETBOX_BG_COLOR.from_pixel(0xf0f0f0ff);
|
||||
const BLACK = new Clutter.Color();
|
||||
BLACK.from_pixel(0x000000ff);
|
||||
|
||||
const WIDGETBOX_PADDING = 2;
|
||||
const ANIMATION_TIME = 0.5;
|
||||
const POP_IN_LAG = 250; /* milliseconds */
|
||||
|
||||
function WidgetBox(widget, expanded) {
|
||||
this._init(widget, expanded);
|
||||
}
|
||||
|
||||
WidgetBox.prototype = {
|
||||
_init: function(widget, expanded) {
|
||||
this.state = expanded ? Widget.STATE_EXPANDED : Widget.STATE_COLLAPSED;
|
||||
|
||||
if (widget instanceof Widget.Widget) {
|
||||
this._widget = widget;
|
||||
this._widget.state = this.state;
|
||||
} else {
|
||||
let ctor = this._ctorFromName(widget);
|
||||
this._widget = new ctor(this.state);
|
||||
}
|
||||
|
||||
if (!this._widget.actor)
|
||||
throw new Error("widget has no actor");
|
||||
else if (!this._widget.title && !this._widget.collapsedActor)
|
||||
throw new Error("widget has neither title nor collapsedActor");
|
||||
|
||||
this.state = expanded ? Widget.STATE_EXPANDED : Widget.STATE_COLLAPSED;
|
||||
|
||||
// The structure of a WidgetBox:
|
||||
//
|
||||
// The top level is a Clutter.Group, which exists to make
|
||||
// pop-out work correctly; when another widget pops out, its
|
||||
// width will increase, which will in turn cause the sidebar's
|
||||
// width to increase, which will cause the sidebar to increase
|
||||
// the width of each of its children (the WidgetBoxes). But we
|
||||
// don't want the non-popped-out widgets to expand, so we make
|
||||
// the top-level actor be a Clutter.Group, which will accept
|
||||
// the new width from the Sidebar, but not impose it on its
|
||||
// own child.
|
||||
//
|
||||
// Inside the toplevel group is a horizontal Big.Box
|
||||
// containing 2 Clutter.Groups; one for the collapsed state
|
||||
// (cgroup) and one for the expanded state (egroup). Each
|
||||
// group contains a single vertical Big.Box (cbox and ebox
|
||||
// respectively), which have the appropriate fixed width. The
|
||||
// cbox contains either the collapsed widget actor or else the
|
||||
// rotated title. The ebox contains the horizontal title (if
|
||||
// any), separator line, and the expanded widget actor. (If
|
||||
// the widget doesn't have a collapsed actor, and therefore
|
||||
// supports pop-out, then it will also have a vertical line
|
||||
// between the two groups, which will only be shown during
|
||||
// pop-out.)
|
||||
//
|
||||
// In the expanded view, cgroup is hidden and egroup is shown.
|
||||
// When animating to the collapsed view, first the ebox is
|
||||
// slid offscreen by giving it increasingly negative x
|
||||
// coordinates within egroup. Then once it's fully offscreen,
|
||||
// we hide egroup, show cgroup, and slide cbox back in in the
|
||||
// same way.
|
||||
//
|
||||
// The pop-out view works similarly to the second half of the
|
||||
// collapsed-to-expanded transition, except that the
|
||||
// horizontal title gets hidden to avoid duplication.
|
||||
|
||||
this.actor = new Clutter.Group();
|
||||
this._hbox = new Big.Box({ background_color: WIDGETBOX_BG_COLOR,
|
||||
padding_top: WIDGETBOX_PADDING,
|
||||
padding_bottom: WIDGETBOX_PADDING,
|
||||
padding_right: WIDGETBOX_PADDING,
|
||||
// Left padding is here to make up for
|
||||
// the X offset used for the sidebar
|
||||
// to hide its rounded corners
|
||||
padding_left: 2 * WIDGETBOX_PADDING,
|
||||
spacing: WIDGETBOX_PADDING,
|
||||
corner_radius: WIDGETBOX_PADDING,
|
||||
orientation: Big.BoxOrientation.HORIZONTAL,
|
||||
reactive: true });
|
||||
this.actor.add_actor(this._hbox);
|
||||
|
||||
this._cgroup = new Clutter.Group({ clip_to_allocation: true });
|
||||
this._hbox.append(this._cgroup, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._cbox = new Big.Box({ width: Widget.COLLAPSED_WIDTH,
|
||||
clip_to_allocation: true });
|
||||
this._cgroup.add_actor(this._cbox);
|
||||
|
||||
if (this._widget.collapsedActor) {
|
||||
if (this._widget.collapsedActor == this._widget.actor)
|
||||
this._singleActor = true;
|
||||
else {
|
||||
this._cbox.append(this._widget.collapsedActor,
|
||||
Big.BoxPackFlags.NONE);
|
||||
}
|
||||
} else {
|
||||
let vtitle = new Clutter.Text({ font_name: "Sans 16px",
|
||||
text: this._widget.title,
|
||||
rotation_angle_z: -90.0 });
|
||||
let signalId = vtitle.connect('notify::allocation',
|
||||
function () {
|
||||
vtitle.disconnect(signalId);
|
||||
vtitle.set_anchor_point(vtitle.natural_width, 0);
|
||||
vtitle.set_size(vtitle.natural_height,
|
||||
vtitle.natural_width);
|
||||
});
|
||||
this._vtitle = vtitle;
|
||||
this._cbox.append(this._vtitle, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._vline = new Clutter.Rectangle({ color: BLACK, width: 1 });
|
||||
this._hbox.append(this._vline, Big.BoxPackFlags.NONE);
|
||||
this._vline.hide();
|
||||
|
||||
// Set up pop-out
|
||||
this._eventHandler = this._hbox.connect('captured-event',
|
||||
Lang.bind(this, this._popEventHandler));
|
||||
this._activationHandler = this._widget.connect('activated',
|
||||
Lang.bind(this, this._activationHandler));
|
||||
}
|
||||
|
||||
this._egroup = new Clutter.Group({ clip_to_allocation: true });
|
||||
this._hbox.append(this._egroup, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._ebox = new Big.Box({ spacing: WIDGETBOX_PADDING,
|
||||
width: Widget.EXPANDED_WIDTH,
|
||||
clip_to_allocation: true });
|
||||
this._egroup.add_actor(this._ebox);
|
||||
|
||||
if (this._widget.title) {
|
||||
this._htitle = new Clutter.Text({ font_name: "Sans 16px",
|
||||
text: this._widget.title });
|
||||
this._ebox.append(this._htitle, Big.BoxPackFlags.NONE);
|
||||
|
||||
this._hline = new Clutter.Rectangle({ color: BLACK, height: 1 });
|
||||
this._ebox.append(this._hline, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
|
||||
this._ebox.append(this._widget.actor, Big.BoxPackFlags.NONE);
|
||||
|
||||
if (expanded)
|
||||
this._setWidgetExpanded();
|
||||
else
|
||||
this._setWidgetCollapsed();
|
||||
},
|
||||
|
||||
// Given a name like "imports.ui.widget.ClockWidget", turn that
|
||||
// into a constructor function
|
||||
_ctorFromName: function(name) {
|
||||
// Make sure it's a valid import
|
||||
if (!name.match(/^imports(\.[a-zA-Z0-9_]+)+$/))
|
||||
throw new Error("widget name must start with 'imports.'");
|
||||
if (name.match(/^imports\.gi\./))
|
||||
throw new Error("cannot import widget from GIR");
|
||||
|
||||
let ctor = eval(name);
|
||||
|
||||
// Make sure it's really a constructor
|
||||
if (!ctor || typeof(ctor) != "function")
|
||||
throw new Error("widget name is not a constructor");
|
||||
|
||||
// Make sure it's a widget
|
||||
let proto = ctor.prototype;
|
||||
while (proto && proto != Widget.Widget.prototype)
|
||||
proto = proto.__proto__;
|
||||
if (!proto)
|
||||
throw new Error("widget does not inherit from Widget prototype");
|
||||
|
||||
return ctor;
|
||||
},
|
||||
|
||||
expand: function() {
|
||||
Tweener.addTween(this._cbox, { x: -Widget.COLLAPSED_WIDTH,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._expandPart1Complete,
|
||||
onCompleteScope: this });
|
||||
this.state = this._widget.state = Widget.STATE_EXPANDING;
|
||||
},
|
||||
|
||||
_setWidgetExpanded: function() {
|
||||
this._cgroup.hide();
|
||||
this._egroup.show();
|
||||
|
||||
if (this._singleActor) {
|
||||
this._widget.actor.get_parent().remove_actor(this._widget.actor);
|
||||
this._ebox.append(this._widget.actor, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
|
||||
if (this._htitle) {
|
||||
this._htitle.show();
|
||||
this._hline.show();
|
||||
}
|
||||
},
|
||||
|
||||
_expandPart1Complete: function() {
|
||||
this._cbox.x = 0;
|
||||
this._setWidgetExpanded();
|
||||
|
||||
if (this._widget.expand) {
|
||||
try {
|
||||
this._widget.expand();
|
||||
} catch (e) {
|
||||
logError(e, 'Widget failed to expand');
|
||||
}
|
||||
}
|
||||
|
||||
this._ebox.x = -Widget.EXPANDED_WIDTH;
|
||||
Tweener.addTween(this._ebox, { x: 0,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._expandComplete,
|
||||
onCompleteScope: this });
|
||||
},
|
||||
|
||||
_expandComplete: function() {
|
||||
this.state = this._widget.state = Widget.STATE_EXPANDED;
|
||||
},
|
||||
|
||||
collapse: function() {
|
||||
Tweener.addTween(this._ebox, { x: -Widget.EXPANDED_WIDTH,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._collapsePart1Complete,
|
||||
onCompleteScope: this });
|
||||
this.state = this._widget.state = Widget.STATE_COLLAPSING;
|
||||
},
|
||||
|
||||
_setWidgetCollapsed: function() {
|
||||
this._egroup.hide();
|
||||
this._cgroup.show();
|
||||
|
||||
if (this._singleActor) {
|
||||
this._widget.actor.get_parent().remove_actor(this._widget.actor);
|
||||
this._cbox.append(this._widget.actor, Big.BoxPackFlags.NONE);
|
||||
}
|
||||
|
||||
if (this._htitle) {
|
||||
this._htitle.hide();
|
||||
this._hline.hide();
|
||||
}
|
||||
|
||||
if (this._vtitle)
|
||||
this._cbox.height = this._ebox.height;
|
||||
},
|
||||
|
||||
_collapsePart1Complete: function() {
|
||||
this._ebox.x = 0;
|
||||
this._setWidgetCollapsed();
|
||||
|
||||
if (this._widget.collapse) {
|
||||
try {
|
||||
this._widget.collapse();
|
||||
} catch (e) {
|
||||
logError(e, 'Widget failed to collapse');
|
||||
}
|
||||
}
|
||||
|
||||
this._cbox.x = -Widget.COLLAPSED_WIDTH;
|
||||
Tweener.addTween(this._cbox, { x: 0,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._collapseComplete,
|
||||
onCompleteScope: this });
|
||||
},
|
||||
|
||||
_collapseComplete: function() {
|
||||
this.state = this._widget.state = Widget.STATE_COLLAPSED;
|
||||
},
|
||||
|
||||
_popEventHandler: function(actor, event) {
|
||||
let type = event.type();
|
||||
|
||||
if (type == Clutter.EventType.ENTER) {
|
||||
this._clearPopInTimeout();
|
||||
if (this.state == Widget.STATE_COLLAPSED ||
|
||||
this.state == Widget.STATE_COLLAPSING) {
|
||||
this._popOut();
|
||||
return false;
|
||||
}
|
||||
} else if (type == Clutter.EventType.LEAVE &&
|
||||
(this.state == Widget.STATE_POPPED_OUT ||
|
||||
this.state == Widget.STATE_POPPING_OUT)) {
|
||||
// If moving into another actor within this._hbox, let the
|
||||
// event be propagated
|
||||
let into = event.get_related();
|
||||
while (into) {
|
||||
if (into == this._hbox)
|
||||
return false;
|
||||
into = into.get_parent();
|
||||
}
|
||||
|
||||
// Else, moving out of this._hbox
|
||||
this._setPopInTimeout();
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_activationHandler: function() {
|
||||
if (this.state == Widget.STATE_POPPED_OUT)
|
||||
this._popIn();
|
||||
},
|
||||
|
||||
_popOut: function() {
|
||||
if (this.state != Widget.STATE_COLLAPSED &&
|
||||
this.state != Widget.STATE_COLLAPSING)
|
||||
return;
|
||||
|
||||
this._vline.show();
|
||||
this._egroup.show();
|
||||
this._ebox.x = -Widget.EXPANDED_WIDTH;
|
||||
Tweener.addTween(this._ebox, { x: 0,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._popOutComplete,
|
||||
onCompleteScope: this });
|
||||
this.state = this._widget.state = Widget.STATE_POPPING_OUT;
|
||||
|
||||
Main.chrome.trackActor(this._hbox, { affectsStruts: false });
|
||||
},
|
||||
|
||||
_popOutComplete: function() {
|
||||
this.state = this._widget.state = Widget.STATE_POPPED_OUT;
|
||||
},
|
||||
|
||||
_setPopInTimeout: function() {
|
||||
this._clearPopInTimeout();
|
||||
this._popInTimeout = Mainloop.timeout_add(POP_IN_LAG, Lang.bind(this, function () { this._popIn(); return false; }));
|
||||
},
|
||||
|
||||
_clearPopInTimeout: function() {
|
||||
if (this._popInTimeout) {
|
||||
Mainloop.source_remove(this._popInTimeout);
|
||||
delete this._popInTimeout;
|
||||
}
|
||||
},
|
||||
|
||||
_popIn: function() {
|
||||
this._clearPopInTimeout();
|
||||
|
||||
if (this.state != Widget.STATE_POPPED_OUT &&
|
||||
this.state != Widget.STATE_POPPING_OUT)
|
||||
return;
|
||||
|
||||
Tweener.addTween(this._ebox, { x: -Widget.EXPANDED_WIDTH,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad",
|
||||
onComplete: this._popInComplete,
|
||||
onCompleteScope: this });
|
||||
},
|
||||
|
||||
_popInComplete: function() {
|
||||
this.state = this._widget.state = Widget.STATE_COLLAPSED;
|
||||
this._vline.hide();
|
||||
this._egroup.hide();
|
||||
this._ebox.x = 0;
|
||||
|
||||
Main.chrome.untrackActor(this._hbox);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if (this.state == Widget.STATE_COLLAPSED)
|
||||
Tweener.addTween(this._cbox, { x: -Widget.COLLAPSED_WIDTH,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad" });
|
||||
},
|
||||
|
||||
restore: function() {
|
||||
if (this.state == Widget.STATE_COLLAPSED)
|
||||
Tweener.addTween(this._cbox, { x: 0,
|
||||
time: ANIMATION_TIME / 2,
|
||||
transition: "easeOutQuad" });
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
if (this._widget.destroy)
|
||||
this._widget.destroy();
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user