appDisplay: Adapt to available extra space showing icon grids

Depending on the available horizontal space, we may want to manipulate
the icon grid and scroll view spacing to result in an optimal layout
that has space left to preview prev/next pages.

The main change here is that, when adapting to the available size, the
space given to a page does not necessarily match the available space,
as we need to be able to show more than one page at a time.

With this decoupling of available and page sizes in place, we now know
how much space there is available in order to extend the padding between
pages, or the fade effect applied to the previewed pages.

Underneath, we rely a bit less on hardcoded CSS paddings, and a bit more
on the StScrollView::content-padding property.

All put together, gives us proper space management from ultra-wide
displays, to display ratios that are close to the optimal grid ratio.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1630>
This commit is contained in:
Carlos Garnacho 2021-02-19 16:45:57 +01:00 committed by Marge Bot
parent ffe11e0560
commit 9e5b357b0b
3 changed files with 99 additions and 25 deletions

View File

@ -125,10 +125,8 @@ $app_grid_fg_color: #fff;
} }
} }
// Some hacks I don't even know
.apps-scroll-view { .apps-scroll-view {
// horizontal padding to make sure scrollbars or dash don't overlap content padding: 0;
padding: 0 88px;
} }
// shutdown and other actions in the grid // shutdown and other actions in the grid
@ -140,20 +138,26 @@ $app_grid_fg_color: #fff;
} }
.page-navigation-hint { .page-navigation-hint {
background: rgba(255, 255, 255, 0.05); width: 300px;
width: 88px;
&.dnd { &.dnd {
background: rgba(255, 255, 255, 0.1); background: rgba(255, 255, 255, 0.1);
} }
&.next { &.next:ltr,
&:ltr { border-radius: 15px 0px 0px 15px; } &.previous:rtl {
&:rtl { border-radius: 0px 15px 15px 0px; } background-gradient-start: rgba(255, 255, 255, 0.05);
background-gradient-end: transparent;
background-gradient-direction: horizontal;
border-radius: 15px 0px 0px 15px;
} }
&.previous {
&:ltr { border-radius: 0px 15px 15px 0px; } &.previous:ltr,
&:rtl { border-radius: 15px 0px 0px 15px; } &.next:rtl {
background-gradient-start: transparent;
background-gradient-end: rgba(255, 255, 255, 0.05);
background-gradient-direction: horizontal;
border-radius: 0px 15px 15px 0px;
} }
} }

View File

@ -39,8 +39,11 @@ var APP_ICON_TITLE_COLLAPSE_TIME = 100;
const FOLDER_DIALOG_ANIMATION_TIME = 200; const FOLDER_DIALOG_ANIMATION_TIME = 200;
const PAGE_PREVIEW_ANIMATION_TIME = 150; const PAGE_PREVIEW_ANIMATION_TIME = 150;
const PAGE_PREVIEW_FADE_EFFECT_OFFSET = 160; const PAGE_PREVIEW_ANIMATION_START_OFFSET = 100;
const PAGE_PREVIEW_FADE_EFFECT_MAX_OFFSET = 300;
const PAGE_PREVIEW_MAX_ARROW_OFFSET = 80;
const PAGE_INDICATOR_FADE_TIME = 200; const PAGE_INDICATOR_FADE_TIME = 200;
const MAX_PAGE_PADDING = 200;
const OVERSHOOT_THRESHOLD = 20; const OVERSHOOT_THRESHOLD = 20;
const OVERSHOOT_TIMEOUT = 1000; const OVERSHOOT_TIMEOUT = 1000;
@ -322,10 +325,22 @@ var BaseAppView = GObject.registerClass({
_updateFadeForNavigation() { _updateFadeForNavigation() {
const fadeMargin = new Clutter.Margin(); const fadeMargin = new Clutter.Margin();
fadeMargin.right = (this._pagesShown & SidePages.NEXT) !== 0 const rtl = this.get_text_direction() === Clutter.TextDirection.RTL;
? -PAGE_PREVIEW_FADE_EFFECT_OFFSET : 0; const showingNextPage = this._pagesShown & SidePages.NEXT;
fadeMargin.left = (this._pagesShown & SidePages.PREVIOUS) !== 0 const showingPrevPage = this._pagesShown & SidePages.PREVIOUS;
? -PAGE_PREVIEW_FADE_EFFECT_OFFSET : 0;
if ((showingNextPage && !rtl) || (showingPrevPage && rtl)) {
fadeMargin.right = Math.max(
-PAGE_PREVIEW_FADE_EFFECT_MAX_OFFSET,
-(this._availWidth - this._grid.layout_manager.pageWidth) / 2);
}
if ((showingPrevPage && !rtl) || (showingNextPage && rtl)) {
fadeMargin.left = Math.max(
-PAGE_PREVIEW_FADE_EFFECT_MAX_OFFSET,
-(this._availWidth - this._grid.layout_manager.pageWidth) / 2);
}
this._scrollView.update_fade_effect(fadeMargin); this._scrollView.update_fade_effect(fadeMargin);
} }
@ -1077,10 +1092,61 @@ var BaseAppView = GObject.registerClass({
const availWidth = box.get_width(); const availWidth = box.get_width();
const availHeight = box.get_height(); const availHeight = box.get_height();
this._grid.adaptToSize(availWidth, availHeight); const gridRatio = this._grid.layout_manager.columnsPerPage /
this._grid.layout_manager.rowsPerPage;
const spaceRatio = availWidth / availHeight;
let pageWidth, pageHeight;
if (spaceRatio > gridRatio * 1.1) {
// Enough room for some preview
pageHeight = availHeight;
pageWidth = availHeight * gridRatio;
if (spaceRatio > gridRatio * 1.5) {
// Ultra-wide layout, give some extra space for
// the page area, but up to an extent.
const extraPageSpace = Math.min(
(availWidth - pageWidth) / 2, MAX_PAGE_PADDING);
pageWidth += extraPageSpace;
this._grid.layout_manager.pagePadding.left = extraPageSpace / 2;
this._grid.layout_manager.pagePadding.right = extraPageSpace / 2;
}
} else {
// Not enough room, needs to shrink horizontally
pageWidth = availWidth * 0.8;
pageHeight = availHeight;
this._grid.layout_manager.pagePadding.left = availWidth * 0.02;
this._grid.layout_manager.pagePadding.right = availWidth * 0.02;
}
this._grid.adaptToSize(pageWidth, pageHeight);
const horizontalPadding = (availWidth - this._grid.layout_manager.pageWidth) / 2;
const verticalPadding = (availHeight - this._grid.layout_manager.pageHeight) / 2;
this._scrollView.content_padding = new Clutter.Margin({
left: horizontalPadding,
right: horizontalPadding,
top: verticalPadding,
bottom: verticalPadding,
});
this._availWidth = availWidth; this._availWidth = availWidth;
this._availHeight = availHeight; this._availHeight = availHeight;
this._pageIndicatorOffset = horizontalPadding;
this._pageArrowOffset = Math.max(
horizontalPadding - PAGE_PREVIEW_MAX_ARROW_OFFSET, 0);
}
_getIndicatorOffset(page, progress, baseOffset) {
const rtl = this.get_text_direction() === Clutter.TextDirection.RTL;
const translationX =
(1 - progress) * PAGE_PREVIEW_ANIMATION_START_OFFSET;
page = rtl ? -page : page;
return (translationX - baseOffset) * page;
} }
_getPagePreviewAdjustment(page) { _getPagePreviewAdjustment(page) {
@ -1108,18 +1174,18 @@ var BaseAppView = GObject.registerClass({
const indicator = page > 0 const indicator = page > 0
? this._nextPageIndicator : this._prevPageIndicator; ? this._nextPageIndicator : this._prevPageIndicator;
const rtl = this.get_text_direction() === Clutter.TextDirection.RTL;
const notifyId = adjustment.connect('notify::value', () => { const notifyId = adjustment.connect('notify::value', () => {
let translationX = (1 - adjustment.value) * 100 * page;
translationX = rtl ? -translationX : translationX;
const nextPage = this._grid.currentPage + page; const nextPage = this._grid.currentPage + page;
const hasFollowingPage = nextPage >= 0 && const hasFollowingPage = nextPage >= 0 &&
nextPage < this._grid.nPages; nextPage < this._grid.nPages;
if (hasFollowingPage) { if (hasFollowingPage) {
const items = this._grid.getItemsAtPage(nextPage); const items = this._grid.getItemsAtPage(nextPage);
items.forEach(item => (item.translation_x = translationX)); items.forEach(item => {
item.translation_x =
this._getIndicatorOffset(page, adjustment.value, 0);
});
if (!(state & SidePages.DND)) { if (!(state & SidePages.DND)) {
const pageArrow = page > 0 const pageArrow = page > 0
@ -1128,7 +1194,9 @@ var BaseAppView = GObject.registerClass({
pageArrow.set({ pageArrow.set({
visible: true, visible: true,
opacity: adjustment.value * 255, opacity: adjustment.value * 255,
translationX, translation_x: this._getIndicatorOffset(
page, adjustment.value,
this._pageArrowOffset),
}); });
} }
} }
@ -1139,7 +1207,9 @@ var BaseAppView = GObject.registerClass({
indicator.set({ indicator.set({
visible: true, visible: true,
opacity: adjustment.value * 255, opacity: adjustment.value * 255,
translationX, translation_x: this._getIndicatorOffset(
page, adjustment.value,
this._pageIndicatorOffset - indicator.width),
}); });
} }
this._syncClip(); this._syncClip();
@ -1382,6 +1452,7 @@ class AppDisplay extends BaseAppView {
const [, indicatorHeight] = this._pageIndicators.get_preferred_height(-1); const [, indicatorHeight] = this._pageIndicators.get_preferred_height(-1);
height -= indicatorHeight; height -= indicatorHeight;
this._grid.findBestModeForSize(width, height);
super.adaptToSize(width, height); super.adaptToSize(width, height);
} }

View File

@ -1223,7 +1223,7 @@ var IconGrid = GObject.registerClass({
} }
} }
_findBestModeForSize(width, height) { findBestModeForSize(width, height) {
const { pagePadding } = this.layout_manager; const { pagePadding } = this.layout_manager;
width -= pagePadding.left + pagePadding.right; width -= pagePadding.left + pagePadding.right;
height -= pagePadding.top + pagePadding.bottom; height -= pagePadding.top + pagePadding.bottom;
@ -1446,7 +1446,6 @@ var IconGrid = GObject.registerClass({
} }
adaptToSize(width, height) { adaptToSize(width, height) {
this._findBestModeForSize(width, height);
this.layout_manager.adaptToSize(width, height); this.layout_manager.adaptToSize(width, height);
} }