appDisplay: Add page 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
This commit is contained in:
parent
e8b35f4623
commit
dcea8bed6d
@ -41,6 +41,8 @@ dist_theme_DATA = \
|
|||||||
theme/message-tray-background.png \
|
theme/message-tray-background.png \
|
||||||
theme/more-results.svg \
|
theme/more-results.svg \
|
||||||
theme/noise-texture.png \
|
theme/noise-texture.png \
|
||||||
|
theme/page-indicator-active.svg \
|
||||||
|
theme/page-indicator-inactive.svg \
|
||||||
theme/panel-button-border.svg \
|
theme/panel-button-border.svg \
|
||||||
theme/panel-button-highlight-narrow.svg \
|
theme/panel-button-highlight-narrow.svg \
|
||||||
theme/panel-button-highlight-wide.svg \
|
theme/panel-button-highlight-wide.svg \
|
||||||
|
@ -941,6 +941,22 @@ StScrollBar StButton#vhandle:active {
|
|||||||
padding: 0px 88px 10px 88px;
|
padding: 0px 88px 10px 88px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-indicator {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
background-image: url(page-indicator-inactive.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-indicator:hover,
|
||||||
|
.page-indicator:checked{
|
||||||
|
background-image: url(page-indicator-active.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-indicators {
|
||||||
|
spacing: 30px;
|
||||||
|
padding: 0px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
.app-folder-icon {
|
.app-folder-icon {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
}
|
}
|
||||||
|
67
data/theme/page-indicator-active.svg
Normal file
67
data/theme/page-indicator-active.svg
Normal file
@ -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>
|
After Width: | Height: | Size: 2.1 KiB |
67
data/theme/page-indicator-inactive.svg
Normal file
67
data/theme/page-indicator-inactive.svg
Normal file
@ -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>
|
After Width: | Height: | Size: 2.2 KiB |
@ -37,6 +37,12 @@ const INACTIVE_GRID_OPACITY = 77;
|
|||||||
const INACTIVE_GRID_OPACITY_ANIMATION_TIME = 0.15;
|
const INACTIVE_GRID_OPACITY_ANIMATION_TIME = 0.15;
|
||||||
const FOLDER_SUBICON_FRACTION = .4;
|
const FOLDER_SUBICON_FRACTION = .4;
|
||||||
|
|
||||||
|
const INDICATORS_ANIMATION_TIME = 0.5;
|
||||||
|
// 100% means indicators wait for be animated until the previous one
|
||||||
|
// is animated completely. 0% means all animators are animated
|
||||||
|
// at once without delay
|
||||||
|
const INDICATORS_ANIMATION_DELAY_PERCENTAGE = 50;
|
||||||
|
|
||||||
const PAGE_SWITCH_TIME = 0.3;
|
const PAGE_SWITCH_TIME = 0.3;
|
||||||
|
|
||||||
// Recursively load a GMenuTreeDirectory; we could put this in ShellAppSystem too
|
// Recursively load a GMenuTreeDirectory; we could put this in ShellAppSystem too
|
||||||
@ -169,6 +175,90 @@ const PagesBin = new Lang.Class({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const PageIndicators = new Lang.Class({
|
||||||
|
Name:'PageIndicators',
|
||||||
|
|
||||||
|
_init: function() {
|
||||||
|
this.actor = new St.BoxLayout({ style_class: 'page-indicators',
|
||||||
|
vertical: true,
|
||||||
|
x_expand: true, y_expand: true,
|
||||||
|
x_align: Clutter.ActorAlign.END,
|
||||||
|
y_align: Clutter.ActorAlign.CENTER });
|
||||||
|
this._nPages = 0;
|
||||||
|
this._currentPage = undefined;
|
||||||
|
|
||||||
|
this.actor.connect('notify::mapped',
|
||||||
|
Lang.bind(this, this._animateIndicators));
|
||||||
|
},
|
||||||
|
|
||||||
|
setNPages: function(nPages) {
|
||||||
|
if (this._nPages == nPages)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let diff = nPages - this._nPages;
|
||||||
|
if (diff > 0) {
|
||||||
|
for (let i = 0; i < diff; i++) {
|
||||||
|
let pageIndex = this._nPages + i;
|
||||||
|
let indicator = new St.Button({ style_class: 'page-indicator',
|
||||||
|
button_mask: St.ButtonMask.ONE |
|
||||||
|
St.ButtonMask.TWO |
|
||||||
|
St.ButtonMask.THREE,
|
||||||
|
toggle_mode: true,
|
||||||
|
checked: pageIndex == this._currentPage });
|
||||||
|
indicator.connect('clicked', Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this.emit('page-activated', pageIndex);
|
||||||
|
}));
|
||||||
|
this.actor.add_actor(indicator);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let children = this.actor.get_children().splice(diff);
|
||||||
|
for (let i = 0; i < children.length; i++)
|
||||||
|
children[i].destroy();
|
||||||
|
}
|
||||||
|
this._nPages = nPages;
|
||||||
|
},
|
||||||
|
|
||||||
|
setCurrentPage: function(currentPage) {
|
||||||
|
this._currentPage = currentPage;
|
||||||
|
|
||||||
|
let children = this.actor.get_children();
|
||||||
|
for (let i = 0; i < children.length; i++)
|
||||||
|
children[i].set_checked(i == this._currentPage);
|
||||||
|
},
|
||||||
|
|
||||||
|
_animateIndicators: function() {
|
||||||
|
if (!this.actor.mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let children = this.actor.get_children();
|
||||||
|
if (children.length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let timePerChild = INDICATORS_ANIMATION_TIME / this._nPages;
|
||||||
|
let delay = INDICATORS_ANIMATION_DELAY_PERCENTAGE / 100 * timePerChild;
|
||||||
|
|
||||||
|
let [stageX, ] = children[0].get_transformed_position();
|
||||||
|
let offset;
|
||||||
|
let monitor = Main.layoutManager.primaryMonitor;
|
||||||
|
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
|
||||||
|
offset = monitor.x - stageX - children[0].width;
|
||||||
|
else
|
||||||
|
offset = monitor.x + monitor.width - stageX;
|
||||||
|
|
||||||
|
for (let i = 0; i < this._nPages; i++) {
|
||||||
|
children[i].translation_x = offset;
|
||||||
|
Tweener.addTween(children[i],
|
||||||
|
{ translation_x: 0,
|
||||||
|
time: timePerChild,
|
||||||
|
delay: delay * i,
|
||||||
|
transition: 'easeOutQuad'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(PageIndicators.prototype);
|
||||||
|
|
||||||
const AllView = new Lang.Class({
|
const AllView = new Lang.Class({
|
||||||
Name: 'AllView',
|
Name: 'AllView',
|
||||||
Extends: BaseAppView,
|
Extends: BaseAppView,
|
||||||
@ -186,6 +276,13 @@ const AllView = new Lang.Class({
|
|||||||
x_expand:true, y_expand:true });
|
x_expand:true, y_expand:true });
|
||||||
this.actor.add_actor(this._pagesBin);
|
this.actor.add_actor(this._pagesBin);
|
||||||
|
|
||||||
|
this._pageIndicators = new PageIndicators();
|
||||||
|
this._pageIndicators.connect('page-activated', Lang.bind(this,
|
||||||
|
function(indicators, pageIndex) {
|
||||||
|
this.goToPage(pageIndex);
|
||||||
|
}));
|
||||||
|
this.actor.add_actor(this._pageIndicators.actor);
|
||||||
|
|
||||||
this._stack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
this._stack = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||||
let box = new St.BoxLayout({ vertical: true });
|
let box = new St.BoxLayout({ vertical: true });
|
||||||
this._verticalAdjustment = new St.Adjustment();
|
this._verticalAdjustment = new St.Adjustment();
|
||||||
@ -223,6 +320,7 @@ const AllView = new Lang.Class({
|
|||||||
{ value: this._grid.getPageY(this._currentPage),
|
{ value: this._grid.getPageY(this._currentPage),
|
||||||
time: PAGE_SWITCH_TIME,
|
time: PAGE_SWITCH_TIME,
|
||||||
transition: 'easeOutQuad' });
|
transition: 'easeOutQuad' });
|
||||||
|
this._pageIndicators.setCurrentPage(pageNumber);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onScroll: function(actor, event) {
|
_onScroll: function(actor, event) {
|
||||||
@ -331,8 +429,14 @@ const AllView = new Lang.Class({
|
|||||||
this._grid.computePages(availWidth, availHeight);
|
this._grid.computePages(availWidth, availHeight);
|
||||||
// Make sure the view doesn't have a bad adjustment value after screen size changes
|
// Make sure the view doesn't have a bad adjustment value after screen size changes
|
||||||
// and therefore the pages computation.
|
// and therefore the pages computation.
|
||||||
if (this._availWidth != availWidth || this._availHeight != availHeight || oldNPages != this._grid.nPages())
|
if (this._availWidth != availWidth || this._availHeight != availHeight || oldNPages != this._grid.nPages()) {
|
||||||
this._verticalAdjustment.value = 0;
|
this._verticalAdjustment.value = 0;
|
||||||
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
|
||||||
|
function() {
|
||||||
|
this._pageIndicators.setNPages(this._grid.nPages());
|
||||||
|
this._pageIndicators.setCurrentPage(0);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
this._availWidth = availWidth;
|
this._availWidth = availWidth;
|
||||||
this._availHeight = availHeight;
|
this._availHeight = availHeight;
|
||||||
|
Loading…
Reference in New Issue
Block a user