[gnome-shell/app-picker-refresh: 16/16] appDisplay: Add additional view showing frequently used apps
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/app-picker-refresh: 16/16] appDisplay: Add additional view showing frequently used apps
- Date: Tue, 19 Feb 2013 11:56:49 +0000 (UTC)
commit 17815dca6ee9c1810688a629dec77f8c83bd0faf
Author: Florian Müllner <fmuellner gnome org>
Date: Mon Feb 18 20:18:08 2013 +0100
appDisplay: Add additional view showing frequently used apps
data/theme/gnome-shell.css | 39 ++++++++++++--
js/ui/appDisplay.js | 128 +++++++++++++++++++++++++++++++++++++++-----
2 files changed, 149 insertions(+), 18 deletions(-)
---
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 2184390..6b1bf92 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -848,13 +848,44 @@ StScrollBar StButton#vhandle:active {
}
.app-display {
- padding: 0px 16px 32px 32px;
+ padding: 8px;
spacing: 20px;
}
-.app-display:rtl {
- padding-left: 16px;
- padding-right: 32px;
+.app-view-controls {
+ border-radius: 8px;
+ border: 1px solid rgba(245,245,245,0.6);
+ width: 250px;
+}
+
+.app-view-controls-bin {
+ padding-right: 10px;
+}
+
+.app-view-control {
+ padding: 4px 16px;
+ background-gradient-start: rgba(254,254,254,0.1);
+ background-gradient-end: rgba(5,5,6,0.1);
+ background-gradient-direction: vertical;
+}
+
+.app-view-control:first-child {
+ border-radius: 8px 0px 0px 8px;
+}
+
+.app-view-control:last-child {
+ border-radius: 0px 8px 8px 0px;
+}
+
+.app-view-control:checked {
+ background-gradient-start: rgba(0,0,0,0.8);
+ background-gradient-end: rgba(5,5,6,0.1);
+ background-gradient-direction: vertical;
+}
+
+StScrollView.frequent-apps StScrollBar {
+ min-width: 0px;
+ width: 0px;
}
.app-folder-icon {
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 1920929..102a138 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -20,6 +20,7 @@ const DND = imports.ui.dnd;
const IconGrid = imports.ui.iconGrid;
const Main = imports.ui.main;
const Overview = imports.ui.overview;
+const OverviewControls = imports.ui.overviewControls;
const PopupMenu = imports.ui.popupMenu;
const Tweener = imports.ui.tweener;
const Workspace = imports.ui.workspace;
@@ -223,6 +224,49 @@ const AlphabeticalView = new Lang.Class({
});
+const FrequentView = new Lang.Class({
+ Name: 'FrequentView',
+
+ _init: function() {
+ this._grid = new IconGrid.IconGrid({ xAlign: St.Align.MIDDLE,
+ columnLimit: 6 });
+ let box = new St.BoxLayout({ vertical: true });
+ box.add(this._grid.actor);
+
+ // HACK: IconGrid currently lacks API to only display items that match
+ // the allocation, so rather than clipping away eventual overflow, we
+ // use an unscrollable ScrollView with hidden scrollbars to nicely
+ // fade out cut off items
+ this.actor = new St.ScrollView({ x_fill: true,
+ y_fill: false,
+ y_align: St.Align.START,
+ x_expand: true,
+ reactive: false,
+ style_class: 'frequent-apps vfade' });
+ this.actor.add_actor(box);
+ this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
+
+ this._usage = Shell.AppUsage.get_default();
+ },
+
+ removeAll: function() {
+ this._grid.removeAll();
+ },
+
+ loadApps: function() {
+ let mostUsed = this._usage.get_most_used ("");
+ for (let i = 0; i < mostUsed.length; i++) {
+ let appIcon = new AppIcon(mostUsed[i]);
+ this._grid.addItem(appIcon.actor, -1);
+ }
+ }
+});
+
+const Views = {
+ FREQUENT: 0,
+ ALL: 1
+};
+
/* This class represents a display containing a collection of application items.
* The applications are sorted based on their name.
*/
@@ -235,30 +279,87 @@ const AppDisplay = new Lang.Class({
Main.queueDeferredWork(this._workId);
}));
- let box = new St.BoxLayout();
- this.actor = new St.Bin({ child: box,
- style_class: 'app-display',
- x_fill: true, y_fill: true });
-
- this._view = new AlphabeticalView({ scrollable: true });
- box.add(this._view.actor, { expand: true });
+ this._views = [];
+
+ let view, button;
+ view = new FrequentView();
+ button = new St.Button({ label: _("Frequent"),
+ style_class: 'app-view-control',
+ x_expand: true });
+ this._views[Views.FREQUENT] = { 'view': view, 'control': button };
+
+ view = new AlphabeticalView({ scrollable: true });
+ button = new St.Button({ label: _("All"),
+ style_class: 'app-view-control',
+ x_expand: true });
+ this._views[Views.ALL] = { 'view': view, 'control': button };
+
+ this.actor = new St.BoxLayout({ style_class: 'app-display',
+ vertical: true,
+ x_expand: true, y_expand: true });
+
+ this._viewStack = new St.Widget({ layout_manager: new Clutter.BinLayout(),
+ x_expand: true, y_expand: true });
+ let bin = new St.Bin({ child: this._viewStack,
+ clip_to_allocation: true,
+ x_fill: true, y_fill: true });
+ this.actor.add(bin, { expand: true });
+
+ let layout = new Clutter.BoxLayout({ homogeneous: true });
+ this._controls = new St.Widget({ style_class: 'app-view-controls',
+ layout_manager: layout });
+ this.actor.add(new St.Bin({ child: this._controls }));
+
+
+ for (let i = 0; i < this._views.length; i++) {
+ this._viewStack.add_actor(this._views[i].view.actor);
+ this._controls.add_actor(this._views[i].control);
+
+ let viewIndex = i;
+ this._views[i].control.connect('clicked', Lang.bind(this,
+ function(actor) {
+ this._showView(viewIndex);
+ }));
+ }
+ this._showView(Views.FREQUENT);
// We need a dummy actor to catch the keyboard focus if the
// user Ctrl-Alt-Tabs here before the deferred work creates
// our real contents
this._focusDummy = new St.Bin({ can_focus: true });
- box.add(this._focusDummy);
+ this._viewStack.add_actor(this._focusDummy);
this._workId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._redisplay));
},
+ _showView: function(activeIndex) {
+ for (let i = 0; i < this._views.length; i++) {
+ let actor = this._views[i].view.actor;
+ let params = { time: OverviewControls.SIDE_CONTROLS_ANIMATION_TIME,
+ opacity: (i == activeIndex) ? 255 : 0 };
+ if (i == activeIndex)
+ actor.visible = true;
+ else
+ params.onComplete = function() { actor.hide(); };
+ Tweener.addTween(actor, params);
+
+ if (i == activeIndex)
+ this._views[i].control.add_style_pseudo_class('checked');
+ else
+ this._views[i].control.remove_style_pseudo_class('checked');
+ }
+ },
+
_removeAll: function() {
- this._view.removeAll();
+ for (let i = 0; i < this._views.length; i++)
+ this._views[i].view.removeAll();
},
_redisplay: function() {
this._removeAll();
+ this._views[Views.FREQUENT].view.loadApps();
+
var tree = this._appSystem.get_tree();
var root = tree.get_root_directory();
@@ -270,11 +371,10 @@ const AppDisplay = new Lang.Class({
if (dir.get_is_nodisplay())
continue;
- if (FOLDER_CATEGORIES.indexOf(dir.get_menu_id()) != -1) {
- this._view.addFolder(dir);
- } else
-
- _loadCategory(dir, this._view);
+ if (FOLDER_CATEGORIES.indexOf(dir.get_menu_id()) != -1)
+ this._views[Views.ALL].view.addFolder(dir);
+ else
+ _loadCategory(dir, this._views[Views.ALL].view);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]