From 332b6f1c0d2d298ced8e8a08f6d8b24adf1314e8 Mon Sep 17 00:00:00 2001 From: miruka Date: Wed, 17 Jul 2019 13:34:02 -0400 Subject: [PATCH] Big improvements on sidepane auto/manual sizing See gui-tests.md for the expected sidepane behaviors. --- TODO.md | 1 + gui-tests.md | 54 +++++++++++++++++++++++++++++++++++ src/qml/Base/HPage.qml | 4 +-- src/qml/Base/HSplitView.qml | 4 +-- src/qml/Chat/Chat.qml | 7 +++-- src/qml/Chat/RoomHeader.qml | 5 +++- src/qml/SidePane/SidePane.qml | 40 +++++++++++++++----------- src/qml/Theme.qml | 11 ++++--- src/qml/UI.qml | 18 +++++++----- 9 files changed, 108 insertions(+), 36 deletions(-) create mode 100644 gui-tests.md diff --git a/TODO.md b/TODO.md index ba184f86..159b223a 100644 --- a/TODO.md +++ b/TODO.md @@ -1,3 +1,4 @@ +- Use `asyncio.as_completed()` instead of `gather` - Resizing pane sets the autoWidthRatio - Show sidepane when hovering on the left when collapsed/reduced - Header back button diff --git a/gui-tests.md b/gui-tests.md new file mode 100644 index 00000000..d215b53b --- /dev/null +++ b/gui-tests.md @@ -0,0 +1,54 @@ +# Manual GUI tests + +## Sidepane + +All the following statements must be true. + + +For all tests: + +- When the pane collapses, the overall spacing/margins/paddings is 0. +- When the pane expands, the spacing/margins/paddings are restored. + + +Shrink the window (default auto-sizing pane): + +- Pane collapses and spacing reduces with an animation under a certain size. +- Pane disappears (reduces) under an even smaller size. + + +Expand the window (default auto-sizing pane): + +- Pane reappears collapsed from its reduced state above a certain size. +- Pane expands from its collapsed state above a even larger size. +- Pane stop growing past a certain even larger size. + + +Manually drag the pane to resizing. While dragging: + +- Pane correctly collapses and expands when hitting the tresholds. +- Pane size can't go below the collapsed size. +- Pane size can't go above the minimum window content size (240 + margins). + + +Manually drag the pane to its minimum collapsed size: + +- Pane never changes size no matter the window width, *except* to reduce + when the window becomes too thin. + + +Manually drag the pane to its maximum grown size for the current window width: + +- When shrinking the window, the pane stays to its maximum possible width + while respecting the minimum window content size. + It can still reduce if the window is too thin. + +- After shrinking, when growing the window again, the pane grows until reaching + the size it was previously given on manual drag, never more. + + +Shrink the window enough for the pane to be in reduced mode: + +- In a page or room, a left-to-right swipe gesture shows a full-window pane. +- On the full-window pane, a right-to-left swipe goes back to the page/room. +- On the full-window pane, tapping on a room/page properly goes to it. diff --git a/src/qml/Base/HPage.qml b/src/qml/Base/HPage.qml index 45f89969..d3a4103a 100644 --- a/src/qml/Base/HPage.qml +++ b/src/qml/Base/HPage.qml @@ -27,11 +27,9 @@ SwipeView { interactive: sidePane.reduce SidePane { - canAutoSize: false - autoWidthRatio: 1.0 + implicitWidth: swipeView.width collapse: false reduce: false - currentSpacing: theme.spacing visible: swipeView.interactive onVisibleChanged: if (currentIndex != 1) swipeView.setCurrentIndex(1) } diff --git a/src/qml/Base/HSplitView.qml b/src/qml/Base/HSplitView.qml index a8a64963..fd269410 100644 --- a/src/qml/Base/HSplitView.qml +++ b/src/qml/Base/HSplitView.qml @@ -12,8 +12,8 @@ Controls1.SplitView { property bool anyPressed: false property bool anyResizing: false - property bool canAutoSize: true - onAnyPressedChanged: canAutoSize = false + property bool manuallyResized: false + onAnyResizingChanged: manuallyResized = true handleDelegate: Item { readonly property bool hovered: styleData.hovered diff --git a/src/qml/Chat/Chat.qml b/src/qml/Chat/Chat.qml index 5e10bf4a..9b763ab9 100644 --- a/src/qml/Chat/Chat.qml +++ b/src/qml/Chat/Chat.qml @@ -116,8 +116,8 @@ HPage { property bool wasSnapped: false property int referenceWidth: roomHeader.buttonsWidth onReferenceWidthChanged: { - if (chatSplitView.canAutoSize || wasSnapped) { - if (wasSnapped) { chatSplitView.canAutoSize = true } + if (! chatSplitView.manuallyResized || wasSnapped) { + if (wasSnapped) { chatSplitView.manuallyResized = false } width = referenceWidth } } @@ -141,7 +141,8 @@ HPage { width: referenceWidth // Initial width Layout.minimumWidth: theme.avatar.size - Layout.maximumWidth: parent.width + Layout.maximumWidth: + parent.width - theme.minimumSupportedWidthPlusSpacing } } } diff --git a/src/qml/Chat/RoomHeader.qml b/src/qml/Chat/RoomHeader.qml index c9baea11..7861c850 100644 --- a/src/qml/Chat/RoomHeader.qml +++ b/src/qml/Chat/RoomHeader.qml @@ -13,7 +13,10 @@ HRectangle { property int buttonsWidth: viewButtons.Layout.preferredWidth property var activeButton: "members" - property bool collapseButtons: width < 400 + property bool collapseButtons: + viewButtons.implicitWidth > width * 0.33 || + width - viewButtons.implicitWidth < + theme.minimumSupportedWidthPlusSpacing id: roomHeader color: theme.chat.roomHeader.background diff --git a/src/qml/SidePane/SidePane.qml b/src/qml/SidePane/SidePane.qml index 5c580266..5cb6fa54 100644 --- a/src/qml/SidePane/SidePane.qml +++ b/src/qml/SidePane/SidePane.qml @@ -8,27 +8,34 @@ import "../Base" HRectangle { id: sidePane clip: true // Avoid artifacts when collapsed - // opacity: mainUI.accountsPresent && ! reduce ? 1 : 0 - // visible: opacity > 0 + opacity: mainUI.accountsPresent && ! reduce ? 1 : 0 + visible: opacity > 0 - - property bool canAutoSize: true - property int parentWidth: parent.width property real autoWidthRatio: theme.sidePane.autoWidthRatio + property bool manuallyResizing: false + property bool manuallyResized: false + property int manualWidth: 0 - // Needed for SplitView because it breaks the binding on collapse - onParentWidthChanged: if (canAutoSize) { - width = Qt.binding(() => implicitWidth) - } + property int maximumCalculatedWidth: Math.min( + manuallyResized ? manualWidth : theme.sidePane.maximumAutoWidth, + window.width - theme.minimumSupportedWidthPlusSpacing + ) + + property int parentWidth: parent.width + // Needed for SplitView since it breaks the binding when user manual sizes + onParentWidthChanged: width = Qt.binding(() => implicitWidth) - property int autoWidth: - Math.min(parentWidth * autoWidthRatio, theme.sidePane.maximumAutoWidth) + property int calculatedWidth: Math.min( + manuallyResized ? manualWidth: parentWidth * autoWidthRatio, + maximumCalculatedWidth + ) property bool collapse: - canAutoSize ? - autoWidth < theme.sidePane.autoCollapseBelowWidth : - width <= theme.sidePane.collapsedWidth + (manuallyResizing ? width : calculatedWidth) < + (manuallyResized ? + (theme.sidePane.collapsedWidth + theme.spacing * 2) : + theme.sidePane.autoCollapseBelowWidth) property bool reduce: window.width < theme.sidePane.autoReduceBelowWindowWidth @@ -36,10 +43,11 @@ HRectangle { property int implicitWidth: reduce ? 0 : collapse ? theme.sidePane.collapsedWidth : - autoWidth + calculatedWidth property int currentSpacing: - collapse || reduce ? 0 : theme.spacing + width <= theme.sidePane.collapsedWidth + theme.spacing * 2 ? + 0 : theme.spacing Behavior on currentSpacing { HNumberAnimation {} } Behavior on implicitWidth { HNumberAnimation {} } diff --git a/src/qml/Theme.qml b/src/qml/Theme.qml index 148972e7..f1863e53 100644 --- a/src/qml/Theme.qml +++ b/src/qml/Theme.qml @@ -9,6 +9,9 @@ QtObject { property int minimumSupportedWidth: 240 property int minimumSupportedHeight: 120 + property int minimumSupportedWidthPlusSpacing: 240 + spacing * 2 + property int minimumSupportedHeightPlusSpacing: 120 + spacing * 2 + property int baseElementsHeight: 36 property int spacing: 8 property int animationDuration: 100 @@ -66,14 +69,14 @@ QtObject { } property QtObject sidePane: QtObject { - property real autoWidthRatio: 0.3 - property int maximumAutoWidth: 300 + property real autoWidthRatio: 0.33 + property int maximumAutoWidth: 320 - property int autoCollapseBelowWidth: 120 + property int autoCollapseBelowWidth: 128 property int collapsedWidth: avatar.size property int autoReduceBelowWindowWidth: - minimumSupportedWidth + collapsedWidth + minimumSupportedWidthPlusSpacing + collapsedWidth property color background: colors.background2 diff --git a/src/qml/UI.qml b/src/qml/UI.qml index 90bad8f0..65659d6b 100644 --- a/src/qml/UI.qml +++ b/src/qml/UI.qml @@ -36,20 +36,24 @@ Item { id: uiSplitView anchors.fill: parent + onAnyResizingChanged: if (anyResizing) { + sidePane.manuallyResizing = true + } else { + sidePane.manuallyResizing = false + sidePane.manuallyResized = true + sidePane.manualWidth = sidePane.width + } + SidePane { id: sidePane - canAutoSize: uiSplitView.canAutoSize // Initial width until user manually resizes width: implicitWidth Layout.minimumWidth: reduce ? 0 : theme.sidePane.collapsedWidth - // -1: avoid making swipeview stuff disappear when dragged to max - Layout.maximumWidth: parent.width - 1 + Layout.maximumWidth: + window.width -theme.minimumSupportedWidthPlusSpacing - Behavior on Layout.minimumWidth { - // Must run faster than SidePane implicitWidth anim - HNumberAnimation { duration: theme.animationDuration / 2 } - } + Behavior on Layout.minimumWidth { HNumberAnimation {} } } StackView {