[gnome-shell/wip/carlosg/appgrid-navigation: 1/3] js/appDisplay: Implement side page previews while DnDing
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/carlosg/appgrid-navigation: 1/3] js/appDisplay: Implement side page previews while DnDing
- Date: Fri, 19 Feb 2021 11:49:45 +0000 (UTC)
commit 7a494d14f2a6f0c80c3b67ce286f2895b062bef9
Author: Carlos Garnacho <carlosg gnome org>
Date: Wed Feb 3 12:51:17 2021 +0100
js/appDisplay: Implement side page previews while DnDing
When DnDing an icon, we show both previous/next page, and optionally
a "placeholder" actor to allow creating new pages. These sides on the
scrollview are drop targets themselves, allowing to drop an app onto
the next/prev page without further navigation.
Still, preserve the checks to maybe switch to prev/next page without
finishing the DnD operation, for finer grained operations.
data/theme/gnome-shell-sass/widgets/_app-grid.scss | 8 ++++
js/ui/appDisplay.js | 52 +++++++++++++++++++++-
2 files changed, 58 insertions(+), 2 deletions(-)
---
diff --git a/data/theme/gnome-shell-sass/widgets/_app-grid.scss
b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
index 051dbc239e..19c3ee5a4b 100644
--- a/data/theme/gnome-shell-sass/widgets/_app-grid.scss
+++ b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
@@ -137,3 +137,11 @@ $app_grid_fg_color: #fff;
border-radius: 99px;
icon-size: $app_icon_size * 0.5;
}
+
+.dnd-placeholder {
+ background: rgba(255,255,255,0.25);
+ width: 80px;
+
+ &:ltr { border-radius: 15px 0px 0px 15px; }
+ &:rtl { border-radius: 0px 15px 15px 0px; }
+}
diff --git a/js/ui/appDisplay.js b/js/ui/appDisplay.js
index a9433fddb5..92adb70961 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -55,6 +55,7 @@ var SidePages = {
NONE: 0,
PREVIOUS: 1 << 0,
NEXT: 1 << 1,
+ EMPTY_PLACEHOLDER: 1 << 2,
};
function _getCategories(info) {
@@ -153,6 +154,7 @@ var BaseAppView = GObject.registerClass({
enable_mouse_scrolling: false,
});
this._scrollView.set_policy(St.PolicyType.EXTERNAL, St.PolicyType.NEVER);
+ this._scrollView._delegate = this;
this._canScroll = true; // limiting scrolling speed
this._scrollTimeoutId = 0;
@@ -184,12 +186,32 @@ var BaseAppView = GObject.registerClass({
this._scrollView.event(event, false);
});
+ // "Empty page" DnD indicator
+ this._emptyPageIndicator = new St.Widget({
+ opacity: 0,
+ reactive: false,
+ visible: false,
+ x_expand: true,
+ y_expand: true,
+ x_align: Clutter.ActorAlign.END,
+ y_align: Clutter.ActorAlign.FILL,
+ });
+ this._emptyPageIndicator.add_style_class_name('dnd-placeholder');
+ this._emptyPageIndicator._delegate = this;
+
+ let scrollContainer = new St.Widget({
+ layout_manager: new Clutter.BinLayout(),
+ clip_to_allocation: true,
+ });
+ scrollContainer.add_child(this._scrollView);
+ scrollContainer.add_child(this._emptyPageIndicator);
+
this._box = new St.BoxLayout({
vertical: true,
x_expand: true,
y_expand: true,
});
- this._box.add_child(this._scrollView);
+ this._box.add_child(scrollContainer);
this._box.add_child(this._pageIndicators);
// Swipe
@@ -572,6 +594,7 @@ var BaseAppView = GObject.registerClass({
dragMotion: this._onDragMotion.bind(this),
};
DND.addDragMonitor(this._dragMonitor);
+ this._slideSidePages(SidePages.PREVIOUS | SidePages.NEXT | SidePages.EMPTY_PLACEHOLDER);
}
_onDragMotion(dragEvent) {
@@ -588,6 +611,16 @@ var BaseAppView = GObject.registerClass({
this._maybeMoveItem(dragEvent);
+ this._dropPage = this._pageForCoords(dragEvent.x, dragEvent.y);
+ if (this._dropPage) {
+ if (this._dropPage === SidePages.NEXT || this._grid.currentPage !== 0) {
+ return DND.DragMotionResult.MOVE_DROP;
+ } else {
+ this._dropPage = null;
+ return DND.DragMotionResult.NO_DROP;
+ }
+ }
+
return DND.DragMotionResult.CONTINUE;
}
@@ -598,12 +631,15 @@ var BaseAppView = GObject.registerClass({
}
this._resetOvershoot();
+ this._slideSidePages(SidePages.NONE);
+ this._dropPage = null;
}
_onDragCancelled() {
// At this point, the positions aren't stored yet, thus _redisplay()
// will move all items to their original positions
this._redisplay();
+ this._slideSidePages(SidePages.NONE);
}
_canAccept(source) {
@@ -627,6 +663,13 @@ var BaseAppView = GObject.registerClass({
this._moveItem(source, page, position);
this._removeDelayedMove();
+ } else if (this._dropPage) {
+ const page = (this._dropPage === SidePages.NEXT)
+ ? this._grid.currentPage + 1
+ : this._grid.currentPage - 1;
+
+ this._moveItem(source, page, 1);
+ this.goToPage(page);
}
return true;
@@ -982,7 +1025,12 @@ var BaseAppView = GObject.registerClass({
this._nextPageAdjustmentId = this._nextPageAdjustment.connect('notify::value', () => {
let translationX = (1 - this._nextPageAdjustment.value) * 100;
translationX = rtl ? -translationX : translationX;
- if (this._grid.currentPage < this._grid.nPages - 1) {
+ if ((pages & SidePages.EMPTY_PLACEHOLDER) !== 0 &&
+ this._grid.currentPage === this._grid.nPages - 1) {
+ this._emptyPageIndicator.visible = true;
+ this._emptyPageIndicator.translation_x = translationX;
+ this._emptyPageIndicator.opacity = this._nextPageAdjustment.value * 255;
+ } else if (this._grid.currentPage < this._grid.nPages - 1) {
const items = this._grid.layout_manager.getItemsAtPage(this._grid.currentPage + 1);
items.forEach(item => (item.translation_x = translationX));
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]