[gnome-shell/wip/carlosg/appgrid-navigation: 1/2] js/appDisplay: Implement navigation of pages by hovering/clicking edges
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/carlosg/appgrid-navigation: 1/2] js/appDisplay: Implement navigation of pages by hovering/clicking edges
- Date: Wed, 3 Feb 2021 17:35:01 +0000 (UTC)
commit eb6e17dca0b8f3b5d4f5a7499fac0489743778f6
Author: Carlos Garnacho <carlosg gnome org>
Date: Wed Feb 3 12:46:07 2021 +0100
js/appDisplay: Implement navigation of pages by hovering/clicking edges
Add the necessary animations to slide in the icons in the previous/next
pages, also needing to 1) drop the viewport clipping, and 2) extend scrollview
fade effects to let see the pages in the navigated direction(s).
The animation is driven via 2 adjustments, one for each side, so they
can animate independently.
js/ui/appDisplay.js | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 151 insertions(+)
---
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index 4c41a5ef7b..0fe362d979 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -48,6 +48,12 @@ const DIALOG_SHADE_HIGHLIGHT = Clutter.Color.from_pixel(0x00000055);
let discreteGpuAvailable = false;
+var SidePages = {
+ NONE: 0,
+ PREVIOUS: 1 << 0,
+ NEXT: 1 << 1,
+};
+
function _getCategories(info) {
let categoriesStr = info.get_categories();
if (!categoriesStr)
@@ -154,6 +160,10 @@ var BaseAppView = GObject.registerClass({
this._canScroll = true; // limiting scrolling speed
this._scrollTimeoutId = 0;
this._scrollView.connect('scroll-event', this._onScroll.bind(this));
+ this._scrollView.connect('motion-event', this._onMotion.bind(this));
+ this._scrollView.connect('enter-event', this._onMotion.bind(this));
+ this._scrollView.connect('leave-event', this._onLeave.bind(this));
+ this._scrollView.connect('button-press-event', this._onButtonPress.bind(this));
this._scrollView.add_actor(this._grid);
@@ -248,9 +258,21 @@ var BaseAppView = GObject.registerClass({
this._disconnectDnD();
}
+ _updateFadeForNavigation() {
+ let fadeMargin = new Clutter.Margin();
+ fadeMargin.right = (this._pagesShown & SidePages.NEXT) != 0
+ ? -160 : 0;
+ fadeMargin.left = (this._pagesShown & SidePages.PREVIOUS) != 0
+ ? -160 : 0;
+ this._scrollView.update_fade_effect(fadeMargin);
+ }
+
_updateFade() {
const { pagePadding } = this._grid.layout_manager;
+ if (this._pagesShown)
+ return;
+
if (pagePadding.top === 0 &&
pagePadding.right === 0 &&
pagePadding.bottom === 0 &&
@@ -333,6 +355,42 @@ var BaseAppView = GObject.registerClass({
return Clutter.EVENT_STOP;
}
+ _pageForCoords(x, y) {
+ const rtl = this.get_text_direction() === Clutter.TextDirection.RTL;
+ const alloc = this._grid.get_allocation_box();
+
+ let [success, pointerX] = this._grid.get_parent().transform_stage_point(x, y);
+ if (!success)
+ return SidePages.NONE;
+
+ if (pointerX < alloc.get_x())
+ return rtl ? SidePages.NEXT : SidePages.PREVIOUS;
+ else if (pointerX > alloc.get_x() + alloc.get_width())
+ return rtl ? SidePages.PREVIOUS : SidePages.NEXT;
+
+ return SidePages.NONE;
+ }
+
+ _onMotion(actor, event) {
+ let page = this._pageForCoords(...event.get_coords());
+ this._slideSidePages(page);
+
+ return Clutter.EVENT_PROPAGATE;
+ }
+
+ _onButtonPress(actor, event) {
+ let page = this._pageForCoords(...event.get_coords());
+ if (page === SidePages.NEXT &&
+ this._grid.currentPage < this._grid.nPages - 1)
+ this._grid.currentPage++;
+ else if (page === SidePages.PREVIOUS && this._grid.currentPage > 0)
+ this._grid.currentPage--;
+ }
+
+ _onLeave() {
+ this._slideSidePages(SidePages.NONE);
+ }
+
_swipeBegin(tracker, monitor) {
if (monitor !== Main.layoutManager.primaryIndex)
return;
@@ -902,6 +960,99 @@ var BaseAppView = GObject.registerClass({
this._availWidth = availWidth;
this._availHeight = availHeight;
}
+
+ _syncClip() {
+ this._grid.clip_to_view =
+ (!this._prevPageAdjustment || this._prevPageAdjustment.value === 0) &&
+ (!this._nextPageAdjustment || this._nextPageAdjustment.value === 0);
+ }
+
+ _slideSidePages(pages) {
+ if (this._pagesShown === pages)
+ return;
+ this._pagesShown = pages;
+
+ if ((pages & SidePages.NEXT) != 0) {
+ if (!this._nextPageAdjustment) {
+ this._nextPageAdjustment = new St.Adjustment({
+ actor: this,
+ lower: 0,
+ upper: 1,
+ page_size: 0,
+ page_increment: 0,
+ });
+
+ this._nextPageAdjustmentId = this._nextPageAdjustment.connect('notify::value', () => {
+ if (this._grid.currentPage < this._grid.nPages - 1) {
+ let items = this._grid.layout_manager.getItemsAtPage(this._grid.currentPage + 1);
+ items.forEach(item => {
+ item.translation_x = (1 - this._nextPageAdjustment.value) * 100;
+ });
+ }
+ this._syncClip();
+ });
+ }
+
+ this._nextPageAdjustment.ease(1, {
+ duration: 150,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ this._updateFadeForNavigation();
+ } else if ((pages & SidePages.NEXT) == 0 && this._nextPageAdjustment) {
+ this._nextPageAdjustment.ease(0, {
+ duration: 150,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ onComplete: () => {
+ this._nextPageAdjustment.value = 1;
+ this._nextPageAdjustment.disconnect(this._nextPageAdjustmentId);
+ this._nextPageAdjustment = null;
+ this._emptyPageIndicator.visible = false;
+ this._syncClip();
+ this._updateFadeForNavigation();
+ },
+ });
+ }
+
+ if ((pages & SidePages.PREVIOUS) != 0) {
+ if (!this._prevPageAdjustment) {
+ this._prevPageAdjustment = new St.Adjustment({
+ actor: this,
+ lower: 0,
+ upper: 1,
+ page_size: 0,
+ page_increment: 0,
+ });
+
+ this._prevPageAdjustmentId = this._prevPageAdjustment.connect('notify::value', () => {
+ if (this._grid.currentPage > 0) {
+ let items = this._grid.layout_manager.getItemsAtPage(this._grid.currentPage - 1);
+ items.forEach(item => {
+ item.translation_x = (1 - this._prevPageAdjustment.value) * -100;
+ });
+ }
+ this._syncClip();
+ });
+ }
+
+ this._prevPageAdjustment.ease(1, {
+ duration: 150,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ });
+ this._updateFadeForNavigation();
+ } else if ((pages & SidePages.PREVIOUS) === 0 && this._prevPageAdjustment) {
+ this._prevPageAdjustment.ease(0, {
+ duration: 150,
+ mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ onComplete: () => {
+ this._prevPageAdjustment.value = 1;
+ this._prevPageAdjustment.disconnect(this._prevPageAdjustmentId);
+ this._prevPageAdjustment = null;
+ this._syncClip();
+ this._updateFadeForNavigation();
+ },
+ });
+ }
+ }
});
var PageManager = GObject.registerClass({
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]