[gnome-shell/gbsneto/pagination: 29/32] Add pagination to the folder dialog
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/gbsneto/pagination: 29/32] Add pagination to the folder dialog
- Date: Wed, 17 Jun 2020 16:12:23 +0000 (UTC)
commit a0a7e42826eda71485d7c97ed0c15995b9940de5
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Wed May 20 19:20:15 2020 -0300
Add pagination to the folder dialog
Make the folder dialog's app grid horizontal, and add
paginators to it as well. Add a new '_createGrid()'
vfunc, so that FolderView can create its own FolderGrid
instance.
https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1271
data/theme/gnome-shell-sass/widgets/_app-grid.scss | 13 +
js/ui/appDisplay.js | 369 ++++++++++++---------
2 files changed, 219 insertions(+), 163 deletions(-)
---
diff --git a/data/theme/gnome-shell-sass/widgets/_app-grid.scss
b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
index 8d3ae62bde..c183cfeb09 100644
--- a/data/theme/gnome-shell-sass/widgets/_app-grid.scss
+++ b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
@@ -67,6 +67,19 @@ $app_grid_fg_color: #fff;
& > StIcon { icon-size: 16px }
}
}
+
+ & .icon-grid {
+ row-spacing: $base_spacing * 2;
+ column-spacing: $base_spacing * 5;
+ }
+
+ & .page-indicators {
+ margin-bottom: 18px;
+
+ .page-indicator {
+ padding: 15px 12px;
+ }
+ }
}
.app-folder-dialog-container {
padding: 12px;
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 805acbac11..9f18f7b1fa 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -117,13 +117,64 @@ var BaseAppView = GObject.registerClass({
'view-loaded': {},
},
}, class BaseAppView extends St.Widget {
- _init(params = {}) {
+ _init(params = {}, orientation = Clutter.Orientation.VERTICAL) {
super._init(params);
- this._grid = new IconGrid.IconGrid();
+ this._grid = this._createGrid();
// Standard hack for ClutterBinLayout
this._grid.x_expand = true;
+ const vertical = orientation === Clutter.Orientation.VERTICAL;
+
+ // Scroll View
+ this._scrollView = new St.ScrollView({
+ clip_to_allocation: true,
+ x_expand: true,
+ y_expand: true,
+ reactive: true,
+ });
+ this._scrollView.set_policy(
+ vertical ? St.PolicyType.NEVER : St.PolicyType.EXTERNAL,
+ vertical ? St.PolicyType.EXTERNAL : St.PolicyType.NEVER);
+
+ this._canScroll = true; // limiting scrolling speed
+ this._scrollTimeoutId = 0;
+ this._scrollView.connect('scroll-event', this._onScroll.bind(this));
+
+ this._scrollView.add_actor(this._grid);
+
+ const scroll = vertical ? this._scrollView.vscroll : this._scrollView.hscroll;
+ this._adjustment = scroll.adjustment;
+ this._adjustment.connect('notify::value', adj => {
+ this._pageIndicators.setCurrentPosition(adj.value / adj.page_size);
+ });
+
+ // Page Indicators
+ if (vertical)
+ this._pageIndicators = new PageIndicators.AnimatedPageIndicators();
+ else
+ this._pageIndicators = new PageIndicators.PageIndicators(orientation);
+
+ this._pageIndicators.y_expand = vertical;
+ this._pageIndicators.connect('page-activated',
+ (indicators, pageIndex) => {
+ this.goToPage(pageIndex);
+ });
+ this._pageIndicators.connect('scroll-event', (actor, event) => {
+ this._scrollView.event(event, false);
+ });
+
+ // Swipe
+ this._swipeTracker = new SwipeTracker.SwipeTracker(this._scrollView,
+ Shell.ActionMode.OVERVIEW | Shell.ActionMode.POPUP);
+ this._swipeTracker.orientation = orientation;
+ this._swipeTracker.connect('begin', this._swipeBegin.bind(this));
+ this._swipeTracker.connect('update', this._swipeUpdate.bind(this));
+ this._swipeTracker.connect('end', this._swipeEnd.bind(this));
+
+ this._availWidth = 0;
+ this._availHeight = 0;
+
this._items = new Map();
this._orderedItems = [];
@@ -138,6 +189,74 @@ var BaseAppView = GObject.registerClass({
});
}
+ _createGrid() {
+ return new IconGrid.IconGrid();
+ }
+
+ _onScroll(actor, event) {
+ if (this._swipeTracker.canHandleScrollEvent(event))
+ return Clutter.EVENT_PROPAGATE;
+
+ if (!this._canScroll)
+ return Clutter.EVENT_STOP;
+
+ switch (event.get_scroll_direction()) {
+ case Clutter.ScrollDirection.UP:
+ case Clutter.ScrollDirection.LEFT:
+ this.goToPage(this._grid.currentPage - 1);
+ break;
+
+ case Clutter.ScrollDirection.DOWN:
+ case Clutter.ScrollDirection.RIGHT:
+ this.goToPage(this._grid.currentPage + 1);
+ break;
+
+ case Clutter.ScrollDirection.SMOOTH:
+ return Clutter.EVENT_STOP;
+ }
+
+ this._canScroll = false;
+ this._scrollTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
+ SCROLL_TIMEOUT_TIME, () => {
+ this._canScroll = true;
+ this._scrollTimeoutId = 0;
+ return GLib.SOURCE_REMOVE;
+ });
+
+ return Clutter.EVENT_STOP;
+ }
+
+ _swipeBegin(tracker, monitor) {
+ if (monitor !== Main.layoutManager.primaryIndex)
+ return;
+
+ const adjustment = this._adjustment;
+ adjustment.remove_transition('value');
+
+ const progress = adjustment.value / adjustment.page_size;
+ const points = Array.from({ length: this._grid.nPages }, (v, i) => i);
+ const size = tracker.orientation === Clutter.Orientation.VERTICAL
+ ? this._scrollView.height : this._scrollView.width;
+
+ tracker.confirmSwipe(size, points, progress, Math.round(progress));
+ }
+
+ _swipeUpdate(tracker, progress) {
+ const adjustment = this._adjustment;
+ adjustment.value = progress * adjustment.page_size;
+ }
+
+ _swipeEnd(tracker, duration, endProgress) {
+ const adjustment = this._adjustment;
+ const value = endProgress * adjustment.page_size;
+
+ adjustment.ease(value, {
+ mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
+ duration,
+ onComplete: () => this.goToPage(endProgress, false),
+ });
+ }
+
_redisplay() {
let oldApps = this._orderedItems.slice();
let oldAppIds = oldApps.map(icon => icon.id);
@@ -268,7 +387,22 @@ var BaseAppView = GObject.registerClass({
}
}
+ vfunc_allocate(box) {
+ const width = box.get_width();
+ const height = box.get_height();
+
+ this.adaptToSize(width, height);
+
+ super.vfunc_allocate(box);
+ }
+
+ vfunc_map() {
+ this._swipeTracker.enabled = true;
+ super.vfunc_map();
+ }
+
vfunc_unmap() {
+ this._swipeTracker.enabled = false;
this._clearAnimateLater();
super.vfunc_unmap();
}
@@ -294,8 +428,44 @@ var BaseAppView = GObject.registerClass({
this._grid.ease(params);
}
- adaptToSize(_width, _height) {
- throw new GObject.NotImplementedError('adaptToSize in %s'.format(this.constructor.name));
+ goToPage(pageNumber, animate = true) {
+ pageNumber = Math.clamp(pageNumber, 0, this._grid.nPages - 1);
+
+ if (this._grid.currentPage === pageNumber)
+ return;
+
+ this._grid.goToPage(pageNumber, animate);
+ }
+
+ adaptToSize(width, height) {
+ let box = new Clutter.ActorBox();
+ box.x1 = 0;
+ box.x2 = width;
+ box.y1 = 0;
+ box.y2 = height;
+ box = this._scrollView.get_theme_node().get_content_box(box);
+ box = this._grid.get_theme_node().get_content_box(box);
+
+ const availWidth = box.get_width();
+ const availHeight = box.get_height();
+ const oldNPages = this._grid.nPages;
+
+ this._grid.adaptToSize(availWidth, availHeight);
+
+ if (this._availWidth !== availWidth ||
+ this._availHeight !== availHeight ||
+ oldNPages !== this._grid.nPages) {
+ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
+ this._adjustment.value = 0;
+ this._grid.currentPage = 0;
+ this._pageIndicators.setNPages(this._grid.nPages);
+ this._pageIndicators.setCurrentPosition(0);
+ return GLib.SOURCE_REMOVE;
+ });
+ }
+
+ this._availWidth = availWidth;
+ this._availHeight = availHeight;
}
});
@@ -310,59 +480,24 @@ class AppDisplay extends BaseAppView {
this._grid._delegate = this;
+ this._scrollView.add_style_class_name('all-apps');
+
this._stack = new St.Widget({
layout_manager: new Clutter.BinLayout(),
x_expand: true,
y_expand: true,
});
this.add_actor(this._stack);
-
- this._scrollView = new St.ScrollView({
- style_class: 'all-apps',
- x_expand: true,
- y_expand: true,
- reactive: true,
- });
- this._scrollView.add_actor(this._grid);
this._stack.add_actor(this._scrollView);
- this._scrollView.set_policy(St.PolicyType.NEVER,
- St.PolicyType.EXTERNAL);
- this._adjustment = this._scrollView.vscroll.adjustment;
- this._adjustment.connect('notify::value', adj => {
- this._pageIndicators.setCurrentPosition(adj.value / adj.page_size);
- });
-
- this._pageIndicators = new PageIndicators.AnimatedPageIndicators();
- this._pageIndicators.connect('page-activated',
- (indicators, pageIndex) => {
- this.goToPage(pageIndex);
- });
- this._pageIndicators.connect('scroll-event', (actor, event) => {
- this._scrollView.event(event, false);
- });
this.add_actor(this._pageIndicators);
this._folderIcons = [];
- this._scrollView.connect('scroll-event', this._onScroll.bind(this));
-
- this._swipeTracker = new SwipeTracker.SwipeTracker(
- this._scrollView, Shell.ActionMode.OVERVIEW);
- this._swipeTracker.connect('begin', this._swipeBegin.bind(this));
- this._swipeTracker.connect('update', this._swipeUpdate.bind(this));
- this._swipeTracker.connect('end', this._swipeEnd.bind(this));
-
this._currentDialog = null;
this._displayingDialog = false;
this._currentDialogDestroyId = 0;
- this._canScroll = true; // limiting scrolling speed
- this._scrollTimeoutId = 0;
-
- this._availWidth = 0;
- this._availHeight = 0;
-
this._lastOvershootY = -1;
this._lastOvershootTimeoutId = 0;
@@ -400,15 +535,6 @@ class AppDisplay extends BaseAppView {
}
}
- vfunc_allocate(box) {
- box = this.get_theme_node().get_content_box(box);
- let availWidth = box.get_width();
- let availHeight = box.get_height();
- this.adaptToSize(availWidth, availHeight);
-
- super.vfunc_allocate(box);
- }
-
_onDestroy() {
if (this._scrollTimeoutId !== 0) {
GLib.source_remove(this._scrollTimeoutId);
@@ -420,7 +546,6 @@ class AppDisplay extends BaseAppView {
this._keyPressEventId =
global.stage.connect('key-press-event',
this._onKeyPressEvent.bind(this));
- this._swipeTracker.enabled = true;
super.vfunc_map();
}
@@ -429,7 +554,6 @@ class AppDisplay extends BaseAppView {
global.stage.disconnect(this._keyPressEventId);
this._keyPressEventId = 0;
}
- this._swipeTracker.enabled = false;
super.vfunc_unmap();
}
@@ -577,68 +701,14 @@ class AppDisplay extends BaseAppView {
if (this._displayingDialog && this._currentDialog)
this._currentDialog.popdown();
- this._grid.goToPage(pageNumber, animate);
+ super.goToPage(pageNumber, animate);
}
_onScroll(actor, event) {
if (this._displayingDialog || !this._scrollView.reactive)
return Clutter.EVENT_STOP;
- if (this._swipeTracker.canHandleScrollEvent(event))
- return Clutter.EVENT_PROPAGATE;
-
- if (!this._canScroll)
- return Clutter.EVENT_STOP;
-
- let direction = event.get_scroll_direction();
- if (direction == Clutter.ScrollDirection.UP)
- this.goToPage(this._grid.currentPage - 1);
- else if (direction == Clutter.ScrollDirection.DOWN)
- this.goToPage(this._grid.currentPage + 1);
- else
- return Clutter.EVENT_STOP;
-
- this._canScroll = false;
- this._scrollTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
- SCROLL_TIMEOUT_TIME, () => {
- this._canScroll = true;
- this._scrollTimeoutId = 0;
- return GLib.SOURCE_REMOVE;
- });
-
- return Clutter.EVENT_STOP;
- }
-
- _swipeBegin(tracker, monitor) {
- if (monitor !== Main.layoutManager.primaryIndex)
- return;
-
- let adjustment = this._adjustment;
- adjustment.remove_transition('value');
-
- let progress = adjustment.value / adjustment.page_size;
- let points = Array.from({ length: this._grid.nPages }, (v, i) => i);
-
- tracker.confirmSwipe(this._scrollView.height,
- points, progress, Math.round(progress));
- }
-
- _swipeUpdate(tracker, progress) {
- let adjustment = this._adjustment;
- adjustment.value = progress * adjustment.page_size;
- }
-
- _swipeEnd(tracker, duration, endProgress) {
- let adjustment = this._adjustment;
- let value = endProgress * adjustment.page_size;
-
- adjustment.ease(value, {
- mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
- duration,
- onComplete: () => {
- this.goToPage(endProgress, false);
- },
- });
+ return super._onScroll(actor, event);
}
_onKeyPressEvent(actor, event) {
@@ -678,36 +748,6 @@ class AppDisplay extends BaseAppView {
}
- // Called before allocation to calculate dynamic spacing
- adaptToSize(width, height) {
- let box = new Clutter.ActorBox();
- box.x1 = 0;
- box.x2 = width;
- box.y1 = 0;
- box.y2 = height;
- box = this.get_theme_node().get_content_box(box);
- box = this._scrollView.get_theme_node().get_content_box(box);
- box = this._grid.get_theme_node().get_content_box(box);
- let availWidth = box.x2 - box.x1;
- let availHeight = box.y2 - box.y1;
- let oldNPages = this._grid.nPages;
-
- this._grid.adaptToSize(availWidth, availHeight);
-
- if (this._availWidth != availWidth || this._availHeight != availHeight || oldNPages !=
this._grid.nPages) {
- Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
- this._adjustment.value = 0;
- this._grid.currentPage = 0;
- this._pageIndicators.setNPages(this._grid.nPages);
- this._pageIndicators.setCurrentPosition(0);
- return GLib.SOURCE_REMOVE;
- });
- }
-
- this._availWidth = availWidth;
- this._availHeight = availHeight;
- }
-
_resetOvershoot() {
if (this._lastOvershootTimeoutId)
GLib.source_remove(this._lastOvershootTimeoutId);
@@ -945,6 +985,24 @@ var AppSearchProvider = class AppSearchProvider {
}
};
+var FolderGrid = GObject.registerClass(
+class FolderGrid extends IconGrid.IconGrid {
+ _init() {
+ super._init({
+ allow_incomplete_pages: false,
+ orientation: Clutter.Orientation.HORIZONTAL,
+ columns_per_page: 3,
+ rows_per_page: 3,
+ page_halign: Clutter.ActorAlign.CENTER,
+ page_valign: Clutter.ActorAlign.CENTER,
+ });
+ }
+
+ adaptToSize(width, height) {
+ this.layout_manager.adaptToSize(width, height);
+ }
+});
+
var FolderView = GObject.registerClass(
class FolderView extends BaseAppView {
_init(folder, id, parentView) {
@@ -952,7 +1010,7 @@ class FolderView extends BaseAppView {
layout_manager: new Clutter.BinLayout(),
x_expand: true,
y_expand: true,
- });
+ }, Clutter.Orientation.HORIZONTAL);
// If it not expand, the parent doesn't take into account its preferred_width when allocating
// the second time it allocates, so we apply the "Standard hack for ClutterBinLayout"
@@ -962,22 +1020,15 @@ class FolderView extends BaseAppView {
this._parentView = parentView;
this._grid._delegate = this;
- this._scrollView = new St.ScrollView({
- overlay_scrollbars: true,
- x_expand: true,
- y_expand: true,
- });
- this._scrollView.set_policy(St.PolicyType.NEVER, St.PolicyType.EXTERNAL);
- this.add_actor(this._scrollView);
-
- let scrollableContainer = new St.BoxLayout({
+ const box = new St.BoxLayout({
vertical: true,
reactive: true,
x_expand: true,
y_expand: true,
});
- scrollableContainer.add_actor(this._grid);
- this._scrollView.add_actor(scrollableContainer);
+ box.add_actor(this._scrollView);
+ box.add_actor(this._pageIndicators);
+ this.add_actor(box);
let action = new Clutter.PanAction({ interpolate: true });
action.connect('pan', this._onPan.bind(this));
@@ -986,16 +1037,8 @@ class FolderView extends BaseAppView {
this._redisplay();
}
- vfunc_allocate(box) {
- const node = this.get_theme_node();
- const contentBox = node.get_content_box(box);
-
- const [width, height] = contentBox.get_size();
- this.adaptToSize(width, height);
-
- this._grid.topPadding = 0;
-
- super.vfunc_allocate(box);
+ _createGrid() {
+ return new FolderGrid();
}
// Overridden from BaseAppView
@@ -1034,10 +1077,10 @@ class FolderView extends BaseAppView {
}
adaptToSize(width, height) {
- this._parentAvailableWidth = width;
- this._parentAvailableHeight = height;
+ const [, indicatorHeight] = this._pageIndicators.get_preferred_height(-1);
+ height -= indicatorHeight;
- this._grid.adaptToSize(width, height);
+ super.adaptToSize(width, height);
}
_loadApps() {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]