[gnome-shell] app-display: Implement filtering applications by category
- From: Maxim Ermilov <mermilov src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] app-display: Implement filtering applications by category
- Date: Sat, 18 Dec 2010 19:25:30 +0000 (UTC)
commit 4fd24da4e4d61eabda496a9db4e3b5bfb7d8d600
Author: Maxim Ermilov <zaspire rambler ru>
Date: Sat Dec 18 22:18:10 2010 +0300
app-display: Implement filtering applications by category
Add a list of filters to the application view of the view selector, as in the latest mockups
https://bugzilla.gnome.org/show_bug.cgi?id=631537
data/Makefile.am | 1 +
data/gs-applications.menu | 70 ++++++++++++++++----
data/theme/filter-selected.svg | 81 +++++++++++++++++++++++
data/theme/gnome-shell.css | 22 ++++---
js/ui/appDisplay.js | 142 +++++++++++++++++++++++-----------------
5 files changed, 232 insertions(+), 84 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index 8c04198..d8cb906 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -27,6 +27,7 @@ dist_theme_DATA = \
theme/corner-ripple.png \
theme/dash-placeholder.svg \
theme/dialog-error.svg \
+ theme/filter-selected.svg \
theme/gnome-shell.css \
theme/mosaic-view-active.svg \
theme/mosaic-view.svg \
diff --git a/data/gs-applications.menu b/data/gs-applications.menu
index 1d0bfdc..cb4db03 100644
--- a/data/gs-applications.menu
+++ b/data/gs-applications.menu
@@ -1,12 +1,30 @@
<Menu>
- <DefaultLayout>
- <Menuname>Apps</Menuname>
- <Menuname>Games</Menuname>
- <Menuname>Tools</Menuname>
- </DefaultLayout>
+ <DefaultLayout>
+ <Menuname>Accessories</Menuname>
+ <Menuname>Games</Menuname>
+ <Menuname>Graphics</Menuname>
+ <Menuname>Internet</Menuname>
+ <Menuname>Multimedia</Menuname>
+ <Menuname>Office</Menuname>
+ <Menuname>Other</Menuname>
+ </DefaultLayout>
+
<Name>Applications</Name>
<AppDir>/usr/local/share/applications</AppDir>
<DefaultAppDirs/>
+
+ <Menu>
+ <Name>Accessories</Name>
+ <Include>
+ <And>
+ <Category>Utility</Category>
+ <Not>
+ <Category>System</Category>
+ </Not>
+ </And>
+ </Include>
+ </Menu>
+
<Menu>
<Name>Games</Name>
<Include>
@@ -15,21 +33,47 @@
</And>
</Include>
</Menu>
+
<Menu>
- <Name>Tools</Name>
+ <Name>Graphics</Name>
<Include>
- <Category>Development</Category>
<And>
- <Category>System</Category>
- <Not>
- <Category>Settings</Category>
- </Not>
+ <Category>Graphics</Category>
+ </And>
+ </Include>
+ </Menu>
+
+ <Menu>
+ <Name>Internet</Name>
+ <Include>
+ <And>
+ <Category>Network</Category>
+ <Not><Category>Settings</Category></Not>
+ </And>
+ </Include>
+ </Menu>
+
+ <Menu>
+ <Name>Multimedia</Name>
+ <Include>
+ <And>
+ <Category>AudioVideo</Category>
+ <Not><Category>Settings</Category></Not>
+ </And>
+ </Include>
+ </Menu>
+
+ <Menu>
+ <Name>Office</Name>
+ <Include>
+ <And>
+ <Category>Office</Category>
</And>
- <Category>Utility</Category>
</Include>
</Menu>
+
<Menu>
- <Name>Apps</Name>
+ <Name>Other</Name>
<OnlyUnallocated/>
<Include>
<And>
diff --git a/data/theme/filter-selected.svg b/data/theme/filter-selected.svg
new file mode 100644
index 0000000..62c8e5b
--- /dev/null
+++ b/data/theme/filter-selected.svg
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="10"
+ height="20"
+ id="svg10003"
+ version="1.1"
+ inkscape:version="0.47 r22583"
+ sodipodi:docname="filter-selected.svg">
+ <defs
+ id="defs10005">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 32 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="64 : 32 : 1"
+ inkscape:persp3d-origin="32 : 21.333333 : 1"
+ id="perspective10011" />
+ <inkscape:perspective
+ id="perspective9998"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 0.5 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="5.5"
+ inkscape:cx="32"
+ inkscape:cy="10.181818"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ inkscape:window-width="1680"
+ inkscape:window-height="994"
+ inkscape:window-x="0"
+ inkscape:window-y="26"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata10008">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer1"
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ transform="translate(0,-44)">
+ <path
+ inkscape:export-ydpi="90"
+ inkscape:export-xdpi="90"
+ inkscape:export-filename="/home/jimmac/src/cvs/gnome/gnome-shell-design/mockups/app-picker.png"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0"
+ id="rect34320"
+ d="m -0.18726572,54.181804 10.55634072,10.55636 10e-6,-21.11269 z"
+ style="opacity:0.21000001;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ </g>
+</svg>
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index e6b483b..98899a2 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -470,26 +470,28 @@ StTooltip StLabel {
/* Apps */
-.overview-pane {
- width: 440px;
-}
-
.icon-grid {
spacing: 36px;
-shell-grid-item-size: 70px;
}
.all-app {
- padding: 16px 250px 10px 16px;
+ padding: 16px 25px 16px 16px;
+ spacing: 20px;
}
-.app-section-divider-container {
- padding-top: 36px;
- padding-bottom: 36px;
+.app-filter {
+ font-size: 14px;
+ font-weight: bold;
+ height: 40px;
+ color: #aaa;
+ width: 200px;
}
-.app-section-divider {
- height: 2px;
+.app-filter:selected {
+ color: #ffffff;
+ background-image: url("filter-selected.svg");
+ background-position: 190px 10px;
}
#dash > .app-well-app {
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 0cdb5dd..eaeeb15 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -29,10 +29,20 @@ function AlphabeticalView() {
AlphabeticalView.prototype = {
_init: function() {
- this.actor = new St.BoxLayout({ vertical: true });
this._grid = new IconGrid.IconGrid({ xAlign: St.Align.START });
this._appSystem = Shell.AppSystem.get_default();
- this.actor.add(this._grid.actor, { y_align: St.Align.START, expand: true });
+
+ this._filterApp = null;
+
+ let box = new St.BoxLayout({ vertical: true });
+ box.add(this._grid.actor, { y_align: St.Align.START, expand: true });
+
+ this.actor = new St.ScrollView({ x_fill: true,
+ y_fill: false,
+ y_align: St.Align.START,
+ vshadows: true });
+ this.actor.add_actor(box);
+ this.actor.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
},
_removeAll: function() {
@@ -40,20 +50,24 @@ AlphabeticalView.prototype = {
this._apps = [];
},
- _addApp: function(app) {
- let appIcon = new AppWellIcon(this._appSystem.get_app(app.get_id()));
- appIcon.connect('launching', Lang.bind(this, function() {
- this.emit('launching');
- }));
- appIcon._draggable.connect('drag-begin', Lang.bind(this, function() {
- this.emit('drag-begin');
- }));
+ _addApp: function(appInfo) {
+ let appIcon = new AppWellIcon(this._appSystem.get_app(appInfo.get_id()));
this._grid.addItem(appIcon.actor);
+ appIcon._appInfo = appInfo;
+ if (this._filterApp && !this._filterApp(appInfo))
+ appIcon.actor.hide();
+
this._apps.push(appIcon);
},
+ setFilter: function(filter) {
+ this._filterApp = filter;
+ for (let i = 0; i < this._apps.length; i++)
+ this._apps[i].actor.visible = filter(this._apps[i]._appInfo);
+ },
+
refresh: function(apps) {
let ids = [];
for (let i in apps)
@@ -70,8 +84,6 @@ AlphabeticalView.prototype = {
}
};
-Signals.addSignalMethods(AlphabeticalView.prototype);
-
function ViewByCategories() {
this._init();
}
@@ -79,59 +91,78 @@ function ViewByCategories() {
ViewByCategories.prototype = {
_init: function() {
this._appSystem = Shell.AppSystem.get_default();
- this.actor = new St.BoxLayout({ vertical: true });
+ this.actor = new St.BoxLayout({ style_class: 'all-app' });
this.actor._delegate = this;
+
+ this._view = new AlphabeticalView();
+
+ this._filters = new St.BoxLayout({ vertical: true });
+ this.actor.add(this._view.actor, { expand: true, x_fill: true, y_fill: true });
+ this.actor.add(this._filters, { expand: false, y_fill: false, y_align: St.Align.START });
+
this._sections = [];
},
- _updateSections: function(apps) {
- this._removeAll();
+ _selectCategory: function(num) {
+ if (num != -1)
+ this._allFilter.remove_style_pseudo_class('selected');
+ else
+ this._allFilter.add_style_pseudo_class('selected');
- let sections = this._appSystem.get_sections();
- if (!sections)
- return;
- for (let i = 0; i < sections.length; i++) {
- if (i) {
- let actor = new St.Bin({ style_class: 'app-section-divider' });
- let divider = new St.Bin({ style_class: 'app-section-divider-container',
- child: actor,
- x_fill: true });
-
- this.actor.add(divider, { y_fill: false, expand: true });
- }
- let _apps = apps.filter(function(app) {
- return app.get_section() == sections[i];
- });
- this._sections[i] = { view: new AlphabeticalView(),
- apps: _apps,
- name: sections[i] };
- this._sections[i].view.connect('launching', Lang.bind(this, function() {
- this.emit('launching');
- }));
- this._sections[i].view.connect('drag-begin', Lang.bind(this, function() {
- this.emit('drag-begin');
- }));
- this.actor.add(this._sections[i].view.actor, { y_align: St.Align.START, expand: true });
+ this._view.setFilter(Lang.bind(this, function(app) {
+ if (num == -1)
+ return true;
+ return this._sections[num].name == app.get_section();
+ }));
+
+ for (let i = 0; i < this._sections.length; i++) {
+ if (i == num)
+ this._sections[i].filterActor.add_style_pseudo_class('selected');
+ else
+ this._sections[i].filterActor.remove_style_pseudo_class('selected');
}
},
- _removeAll: function() {
- this.actor.destroy_children();
- this._sections.forEach(function (section) { section.view.disconnectAll(); });
+ _addFilter: function(name, num) {
+ let button = new St.Button({ label: name,
+ style_class: 'app-filter',
+ x_align: St.Align.START });
+ this._filters.add(button, { expand: true, x_fill: true, y_fill: false });
+ button.connect('clicked', Lang.bind(this, function() {
+ this._selectCategory(num);
+ }));
+
+ if (num != -1)
+ this._sections[num] = { filterActor: button,
+ name: name };
+ else
+ this._allFilter = button;
+ },
+ _removeAll: function() {
this._sections = [];
+ this._filters.destroy_children();
},
refresh: function(apps) {
- this._updateSections(apps);
- for (let i = 0; i < this._sections.length; i++) {
- this._sections[i].view.refresh(this._sections[i].apps);
- }
+ this._removeAll();
+
+ let sections = this._appSystem.get_sections();
+ this._apps = apps;
+ this._view.refresh(apps);
+
+ this._addFilter(_("All"), -1);
+
+ if (!sections)
+ return;
+
+ for (let i = 0; i < sections.length; i++)
+ this._addFilter(sections[i], i);
+
+ this._selectCategory(-1);
}
};
-Signals.addSignalMethods(ViewByCategories.prototype);
-
/* This class represents a display containing a collection of application items.
* The applications are sorted based on their name.
*/
@@ -146,17 +177,8 @@ AllAppDisplay.prototype = {
Main.queueDeferredWork(this._workId);
}));
- this._scrollView = new St.ScrollView({ x_fill: true,
- y_fill: false,
- vshadows: true });
- this.actor = new St.Bin({ style_class: 'all-app',
- y_align: St.Align.START,
- child: this._scrollView });
-
this._appView = new ViewByCategories();
- this._scrollView.add_actor(this._appView.actor);
-
- this._scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
+ this.actor = new St.Bin({ child: this._appView.actor, x_fill: true, y_fill: true });
this._workId = Main.initializeDeferredWork(this.actor, Lang.bind(this, this._redisplay));
},
@@ -169,8 +191,6 @@ AllAppDisplay.prototype = {
this._appView.refresh(apps);
}
};
-Signals.addSignalMethods(AllAppDisplay.prototype);
-
function BaseAppSearchProvider() {
this._init();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]