[gnome-shell/wip/paging-release2: 11/23] appDisplay: Add pages indicators



commit e2ea1d600458686214b6af7d5adf11f05a58e5fc
Author: Carlos Soriano <carlos soriano89 gmail com>
Date:   Mon Aug 12 19:09:43 2013 +0200

    appDisplay: Add pages indicators
    
    Add indicators to the pagination in AllView, which displays
    how many pages of apps we have and allows the user to
    navigate through them
    
    https://bugzilla.gnome.org/show_bug.cgi?id=706081

 data/Makefile.am                       |    2 +
 data/theme/gnome-shell.css             |   20 +++++-
 data/theme/page-indicator-active.svg   |   67 ++++++++++++++++
 data/theme/page-indicator-inactive.svg |   67 ++++++++++++++++
 js/ui/appDisplay.js                    |  130 +++++++++++++++++++++++++++++++-
 5 files changed, 281 insertions(+), 5 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index 6ad4dca..b2e9817 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -41,6 +41,8 @@ dist_theme_DATA =                             \
        theme/message-tray-background.png       \
        theme/more-results.svg                  \
        theme/noise-texture.png                 \
+       theme/page-indicator-active.svg \
+       theme/page-indicator-inactive.svg       \
        theme/panel-button-border.svg           \
        theme/panel-button-highlight-narrow.svg \
        theme/panel-button-highlight-wide.svg   \
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 24f1c75..b283615 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -936,11 +936,29 @@ StScrollBar StButton#vhandle:active {
 
 .search-display > StBoxLayout,
 .all-apps,
-.frequent-apps > StBoxLayout {
+.frequent-apps > StBoxLayout{
     /* horizontal padding to make sure scrollbars or dash don't overlap content */
     padding: 0px 88px 10px 88px;
 }
 
+.pages-icon-indicator {
+    width: 18px;
+    height: 18px;
+    background-image: url(page-indicator-inactive.svg);
+}
+
+.pages-icon-indicator:hover,
+.pages-icon-indicator:checked{
+    width: 18px;
+    height: 18px;
+    background-image: url(page-indicator-active.svg);
+}
+
+.pages-indicator {
+    spacing: 35px;
+    padding: 0px 10px;
+}
+
 .app-folder-icon {
     padding: 5px;
 }
diff --git a/data/theme/page-indicator-active.svg b/data/theme/page-indicator-active.svg
new file mode 100644
index 0000000..38b720f
--- /dev/null
+++ b/data/theme/page-indicator-active.svg
@@ -0,0 +1,67 @@
+<?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="18"
+   height="18"
+   id="svg4703"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="page-indicator-active.svg">
+  <defs
+     id="defs4705" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="22.197802"
+     inkscape:cx="2.1522887"
+     inkscape:cy="16.782904"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1021"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata4708">
+    <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,2)">
+    <path
+       transform="matrix(0.72823872,0,0,0.8336417,-1512.2872,-525.55618)"
+       d="m 2099.9808,638.83099 c 0,5.29998 -4.9184,9.59645 -10.9854,9.59645 -6.0671,0 -10.9854,-4.29647 
-10.9854,-9.59645 0,-5.29997 4.9183,-9.59645 10.9854,-9.59645 6.067,0 10.9854,4.29648 10.9854,9.59645 z"
+       sodipodi:ry="9.5964489"
+       sodipodi:rx="10.985409"
+       sodipodi:cy="638.83099"
+       sodipodi:cx="2088.9954"
+       id="path4711"
+       style="fill:#fdffff;fill-opacity:0.94117647;stroke:none"
+       sodipodi:type="arc" />
+  </g>
+</svg>
diff --git a/data/theme/page-indicator-inactive.svg b/data/theme/page-indicator-inactive.svg
new file mode 100644
index 0000000..3048f56
--- /dev/null
+++ b/data/theme/page-indicator-inactive.svg
@@ -0,0 +1,67 @@
+<?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="18"
+   height="18"
+   id="svg5266"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="page-indicator-inactive.svg">
+  <defs
+     id="defs5268" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="11.313709"
+     inkscape:cx="13.381365"
+     inkscape:cy="17.859535"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1021"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata5271">
+    <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,2)">
+    <path
+       sodipodi:type="arc"
+       
style="fill:#ffffff;fill-opacity:0;stroke:#ffffff;stroke-width:2.93356276;stroke-miterlimit:4;stroke-opacity:0.39215686;stroke-dasharray:none"
+       id="path5274"
+       sodipodi:cx="2088.9954"
+       sodipodi:cy="638.83099"
+       sodipodi:rx="10.985409"
+       sodipodi:ry="9.5964489"
+       d="m 2099.9808,638.83099 c 0,5.29998 -4.9184,9.59645 -10.9854,9.59645 -6.0671,0 -10.9854,-4.29647 
-10.9854,-9.59645 0,-5.29997 4.9183,-9.59645 10.9854,-9.59645 6.067,0 10.9854,4.29648 10.9854,9.59645 z"
+       transform="matrix(0.63720887,0,0,0.72943648,-1322.1264,-458.98661)" />
+  </g>
+</svg>
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index d87ee55..15a68cd 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -37,6 +37,8 @@ const INACTIVE_GRID_OPACITY = 77;
 const INACTIVE_GRID_OPACITY_ANIMATION_TIME = 0.15;
 const FOLDER_SUBICON_FRACTION = .4;
 
+const MAX_APPS_PAGES = 20;
+
 const PAGE_SWITCH_TIME = 0.3;
 
 // Recursively load a GMenuTreeDirectory; we could put this in ShellAppSystem too
@@ -143,6 +145,99 @@ const PagesView = new Lang.Class({
     }
 });
 
+const PaginationIconIndicator = new Lang.Class({
+    Name: 'PaginationIconIndicator',
+    
+    _init: function(parent, index) {
+
+        this.actor = new St.Button({ style_class: 'pages-icon-indicator',
+                                     button_mask: St.ButtonMask.ONE || St.ButtonMask.TWO,
+                                     toggle_mode: true,
+                                     can_focus: true });
+        this.actor.connect('clicked', Lang.bind(this, this._onClicked));
+        this.actor._delegate = this;
+        this._parent = parent;
+        this.actor._index = index;
+    },
+
+    _onClicked: function(actor, button) {
+        this._parent.goToPage(this.actor._index, true, true);
+        return false;
+    },
+
+    setChecked: function (checked) {
+        this.actor.set_checked(checked);
+    }
+});
+
+const PaginationIndicator = new Lang.Class({
+    Name:'PaginationIndicator',
+
+    _init: function(params) {
+        params['y_expand'] = true;
+        params['x_expand'] = true;
+        this.actor = new Shell.GenericContainer(params);
+        this.actor.connect('get-preferred-height', Lang.bind(this, this._getPreferredHeight));
+        this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
+        this.actor.connect('allocate', Lang.bind(this, this._allocate));
+        this.actor.connect('style-changed', Lang.bind(this, this._styleChanged));
+        this._spacing = 0;
+    },
+
+    _getPreferredHeight: function(actor, forWidth, alloc) {
+        let [minHeight, natHeight] = this.actor.get_children()[0].get_preferred_height(forWidth);
+        if (this.nPages) {
+            let natHeightPerChild = natHeight + this._spacing;
+            let minHeightPerChild = minHeight + this._spacing;
+            minHeight = this.nPages * minHeightPerChild;
+            natHeight = this.nPages * natHeightPerChild;
+        } else {
+            minHeight = natHeight = 0;
+        }
+        alloc.min_size = 0;
+        alloc.natural_size = natHeight;
+    },
+
+    _getPreferredWidth: function(actor, forHeight, alloc) {
+        let [minWidth, natWidth] = this.actor.get_children()[0].get_preferred_width(forHeight);
+        let totalWidth = natWidth + this._spacing;
+        alloc.min_size = totalWidth;
+        alloc.natural_size = totalWidth;
+    },
+
+    _allocate: function(actor, box, flags) {
+        let children = this.actor.get_children();
+        for (let i in children)
+            this.actor.set_skip_paint(children[i], true);
+        if (children.length < 1)
+            return;
+        let availHeight = box.y2 - box.y1;
+        let availWidth = box.x2 - box.x1;
+        let [minHeight, natHeight] = children[0].get_preferred_height(availWidth);
+        let heightPerChild = natHeight + this._spacing;
+        let [minWidth, natWidth] = children[0].get_preferred_width(natHeight);
+        let widthPerChild = natWidth + this._spacing * 2;
+        let padding = this.actor.get_theme_node().get_padding(St.Side.LEFT);
+        for (let i = 0; i < this.nPages; i++) {
+            let childBox = new Clutter.ActorBox();
+            childBox.x1 =  padding;
+            childBox.x2 = availWidth + padding;
+            childBox.y1 = i * heightPerChild;
+            childBox.y2 = childBox.y1 + heightPerChild;
+            // We currently threat the overflow not painting more indicators
+            if (childBox.y2 > availHeight)
+                break;
+            children[i].allocate(childBox, flags);
+            this.actor.set_skip_paint(children[i], false);
+        }
+    },
+
+    _styleChanged: function() {
+        this._spacing = this.actor.get_theme_node().get_length('spacing');
+        this.actor.queue_relayout();
+    }
+});
+
 const AllView = new Lang.Class({
     Name: 'AllView',
     Extends: BaseAppView,
@@ -159,6 +254,16 @@ const AllView = new Lang.Class({
         this.actor = new St.Widget({ layout_manager: new Clutter.BinLayout(),
                                      x_expand:true, y_expand:true });
         this.actor.add_actor(this._pagesView);
+        this._paginationIndicator = new PaginationIndicator({ style_class: 'pages-indicator',
+                                                              x_align: Clutter.ActorAlign.END,
+                                                              y_align: Clutter.ActorAlign.CENTER });
+        this.actor.add_actor(this._paginationIndicator.actor);
+        for (let i = 0; i < MAX_APPS_PAGES; i++) {
+            let indicatorIcon = new PaginationIconIndicator(this, i);
+            if (i == 0)
+                indicatorIcon.setChecked(true);
+            this._paginationIndicator.actor.add_actor(indicatorIcon.actor);
+        }
 
         this._stack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
         this._box = new St.BoxLayout({ vertical: true });
@@ -191,7 +296,22 @@ const AllView = new Lang.Class({
         this._availHeight = 0;
     },
 
-    goToPage: function(pageNumber, animated) {
+    goToPage: function(pageNumber, updateIndicators, animated) {
+        this.viewGoToPage(pageNumber, animated);
+        if (updateIndicators)
+            this.indicatorsGoToPage(pageNumber);
+    },
+
+    indicatorsGoToPage: function(pageNumber) {
+        let indicators = this._paginationIndicator.actor.get_children();
+        if (this._grid.nPages() > 1) {
+            for (let index in indicators)
+                indicators[index].set_checked(false);
+            this._paginationIndicator.actor.get_child_at_index(this._currentPage).set_checked(true);
+        }
+    },
+
+    viewGoToPage: function(pageNumber, animated) {
         this._currentPage = pageNumber;
         let time = 0;
         if (animated)
@@ -206,11 +326,11 @@ const AllView = new Lang.Class({
         let direction = event.get_scroll_direction();
         if (direction == Clutter.ScrollDirection.UP) {
             if (this._currentPage > 0)
-                this.goToPage(this._currentPage - 1, true);
+                this.goToPage(this._currentPage - 1, true, true);
         } else {
             if (direction == Clutter.ScrollDirection.DOWN) {
                 if (this._currentPage < (this._grid.nPages() - 1))
-                    this.goToPage(this._currentPage + 1, true);
+                    this.goToPage(this._currentPage + 1, true, true);
             }
         }
     },
@@ -311,7 +431,9 @@ const AllView = new Lang.Class({
         this._grid.computePages(availWidth, availHeight);
         
         if (this._availWidth != availWidth || this._availHeight != availHeight || oldNPages != 
this._grid.nPages()) {
-            this.goToPage(0, false);
+            this._paginationIndicator.nPages = this._grid.nPages();
+            this.goToPage(0, false, false);
+            Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() { this.goToPage(0, true, 
false); }));
         }
 
         this._availWidth = availWidth;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]