[gnome-shell/wip/carlosg/appgrid-navigation: 1/5] 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/5] js/appDisplay: Implement side page previews while DnDing
- Date: Tue, 23 Feb 2021 16:48:28 +0000 (UTC)
commit 993710a5209d9d11ba20e134a45dbb64ef098e6f
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 | 4 ++
js/ui/appDisplay.js | 63 +++++++++++++++++++---
2 files changed, 60 insertions(+), 7 deletions(-)
---
diff --git a/data/theme/gnome-shell-sass/widgets/_app-grid.scss
b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
index eb9a3f4b91..c28bdb0e60 100644
--- a/data/theme/gnome-shell-sass/widgets/_app-grid.scss
+++ b/data/theme/gnome-shell-sass/widgets/_app-grid.scss
@@ -142,6 +142,10 @@ $app_grid_fg_color: #fff;
background: rgba(255, 255, 255, 0.05);
width: 88px;
+ &.dnd {
+ background: rgba(255, 255, 255, 0.1);
+ }
+
&.next {
&: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 31de33d086..708ee88b3a 100644
--- a/js/ui/appDisplay.js
+++ b/js/ui/appDisplay.js
@@ -56,6 +56,7 @@ var SidePages = {
NONE: 0,
PREVIOUS: 1 << 0,
NEXT: 1 << 1,
+ DND: 1 << 2,
};
function _getCategories(info) {
@@ -154,6 +155,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;
@@ -621,6 +623,7 @@ var BaseAppView = GObject.registerClass({
dragMotion: this._onDragMotion.bind(this),
};
DND.addDragMonitor(this._dragMonitor);
+ this._slideSidePages(SidePages.PREVIOUS | SidePages.NEXT | SidePages.DND);
}
_onDragMotion(dragEvent) {
@@ -637,7 +640,15 @@ var BaseAppView = GObject.registerClass({
this._maybeMoveItem(dragEvent);
- return DND.DragMotionResult.CONTINUE;
+ this._dropPage = this._pageForCoords(dragEvent.x, dragEvent.y);
+ if (!this._dropPage)
+ return DND.DragMotionResult.CONTINUE;
+
+ if (this._dropPage === SidePages.NEXT || this._grid.currentPage !== 0)
+ return DND.DragMotionResult.MOVE_DROP;
+
+ delete this._dropPage;
+ return DND.DragMotionResult.NO_DROP;
}
_onDragEnd() {
@@ -647,12 +658,15 @@ var BaseAppView = GObject.registerClass({
}
this._resetOvershoot();
+ this._slideSidePages(SidePages.NONE);
+ delete this._dropPage;
}
_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) {
@@ -670,8 +684,27 @@ var BaseAppView = GObject.registerClass({
if (!this._canAccept(source))
return false;
- // Dropped before the icon was moved
- if (this._delayedMoveData) {
+ if (this._dropPage) {
+ const increment = this._dropPage === SidePages.NEXT ? 1 : -1;
+ let page = this._findBestPageToAppend(
+ this._grid.currentPage + increment, increment);
+ let position = -1;
+
+ if (page < 0) {
+ // Deny dropping into the previous page(s), if
+ // there's no room for the icon
+ if (this._dropPage === SidePages.PREVIOUS)
+ return false;
+
+ // Append a new page if we need one
+ page = this._grid.nPages;
+ position = 0;
+ }
+
+ this._moveItem(source, page, position);
+ this.goToPage(page);
+ } else if (this._delayedMoveData) {
+ // Dropped before the icon was moved
const { page, position } = this._delayedMoveData;
this._moveItem(source, page, position);
@@ -681,8 +714,8 @@ var BaseAppView = GObject.registerClass({
return true;
}
- _findBestPageToAppend(startPage = 1) {
- for (let i = startPage; i < this._grid.nPages; i++) {
+ _findBestPageToAppend(startPage = 1, inc = 1) {
+ for (let i = startPage; i >= 0 && i < this._grid.nPages; i += inc) {
const pageItems =
this._grid.getItemsAtPage(i).filter(c => c.visible);
@@ -1033,10 +1066,17 @@ var BaseAppView = GObject.registerClass({
let translationX = (1 - adjustment.value) * 100 * multiplier;
translationX = rtl ? -translationX : translationX;
const nextPage = this._grid.currentPage + page;
- if (nextPage >= 0 &&
- nextPage < this._grid.nPages - 1) {
+ const hasFollowingPage = nextPage >= 0 &&
+ nextPage < this._grid.nPages;
+
+ if (hasFollowingPage) {
const items = this._grid.layout_manager.getItemsAtPage(nextPage);
items.forEach(item => (item.translation_x = translationX));
+ }
+ if (hasFollowingPage ||
+ (page > 0 &&
+ this._grid.layout_manager.allow_incomplete_pages &&
+ (state & SidePages.DND) !== 0)) {
indicator.visible = true;
indicator.opacity = adjustment.value * 255;
indicator.translation_x = translationX;
@@ -1071,6 +1111,15 @@ var BaseAppView = GObject.registerClass({
this._pagesShown = state;
const showingNextPage = state & SidePages.NEXT;
const showingPrevPage = state & SidePages.PREVIOUS;
+ const dnd = state & SidePages.DND;
+
+ if (dnd) {
+ this._nextPageIndicator.add_style_class_name('dnd');
+ this._prevPageIndicator.add_style_class_name('dnd');
+ } else {
+ this._nextPageIndicator.remove_style_class_name('dnd');
+ this._nextPageIndicator.remove_style_class_name('dnd');
+ }
if (showingNextPage) {
this._setupPagePreview(1, state);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]