Big improvements on sidepane auto/manual sizing
See gui-tests.md for the expected sidepane behaviors.
This commit is contained in:
parent
e173253f74
commit
332b6f1c0d
1
TODO.md
1
TODO.md
@ -1,3 +1,4 @@
|
|||||||
|
- Use `asyncio.as_completed()` instead of `gather`
|
||||||
- Resizing pane sets the autoWidthRatio
|
- Resizing pane sets the autoWidthRatio
|
||||||
- Show sidepane when hovering on the left when collapsed/reduced
|
- Show sidepane when hovering on the left when collapsed/reduced
|
||||||
- Header back button
|
- Header back button
|
||||||
|
54
gui-tests.md
Normal file
54
gui-tests.md
Normal file
@ -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.
|
@ -27,11 +27,9 @@ SwipeView {
|
|||||||
interactive: sidePane.reduce
|
interactive: sidePane.reduce
|
||||||
|
|
||||||
SidePane {
|
SidePane {
|
||||||
canAutoSize: false
|
implicitWidth: swipeView.width
|
||||||
autoWidthRatio: 1.0
|
|
||||||
collapse: false
|
collapse: false
|
||||||
reduce: false
|
reduce: false
|
||||||
currentSpacing: theme.spacing
|
|
||||||
visible: swipeView.interactive
|
visible: swipeView.interactive
|
||||||
onVisibleChanged: if (currentIndex != 1) swipeView.setCurrentIndex(1)
|
onVisibleChanged: if (currentIndex != 1) swipeView.setCurrentIndex(1)
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,8 @@ Controls1.SplitView {
|
|||||||
property bool anyPressed: false
|
property bool anyPressed: false
|
||||||
property bool anyResizing: false
|
property bool anyResizing: false
|
||||||
|
|
||||||
property bool canAutoSize: true
|
property bool manuallyResized: false
|
||||||
onAnyPressedChanged: canAutoSize = false
|
onAnyResizingChanged: manuallyResized = true
|
||||||
|
|
||||||
handleDelegate: Item {
|
handleDelegate: Item {
|
||||||
readonly property bool hovered: styleData.hovered
|
readonly property bool hovered: styleData.hovered
|
||||||
|
@ -116,8 +116,8 @@ HPage {
|
|||||||
property bool wasSnapped: false
|
property bool wasSnapped: false
|
||||||
property int referenceWidth: roomHeader.buttonsWidth
|
property int referenceWidth: roomHeader.buttonsWidth
|
||||||
onReferenceWidthChanged: {
|
onReferenceWidthChanged: {
|
||||||
if (chatSplitView.canAutoSize || wasSnapped) {
|
if (! chatSplitView.manuallyResized || wasSnapped) {
|
||||||
if (wasSnapped) { chatSplitView.canAutoSize = true }
|
if (wasSnapped) { chatSplitView.manuallyResized = false }
|
||||||
width = referenceWidth
|
width = referenceWidth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,7 +141,8 @@ HPage {
|
|||||||
|
|
||||||
width: referenceWidth // Initial width
|
width: referenceWidth // Initial width
|
||||||
Layout.minimumWidth: theme.avatar.size
|
Layout.minimumWidth: theme.avatar.size
|
||||||
Layout.maximumWidth: parent.width
|
Layout.maximumWidth:
|
||||||
|
parent.width - theme.minimumSupportedWidthPlusSpacing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,10 @@ HRectangle {
|
|||||||
property int buttonsWidth: viewButtons.Layout.preferredWidth
|
property int buttonsWidth: viewButtons.Layout.preferredWidth
|
||||||
property var activeButton: "members"
|
property var activeButton: "members"
|
||||||
|
|
||||||
property bool collapseButtons: width < 400
|
property bool collapseButtons:
|
||||||
|
viewButtons.implicitWidth > width * 0.33 ||
|
||||||
|
width - viewButtons.implicitWidth <
|
||||||
|
theme.minimumSupportedWidthPlusSpacing
|
||||||
|
|
||||||
id: roomHeader
|
id: roomHeader
|
||||||
color: theme.chat.roomHeader.background
|
color: theme.chat.roomHeader.background
|
||||||
|
@ -8,27 +8,34 @@ import "../Base"
|
|||||||
HRectangle {
|
HRectangle {
|
||||||
id: sidePane
|
id: sidePane
|
||||||
clip: true // Avoid artifacts when collapsed
|
clip: true // Avoid artifacts when collapsed
|
||||||
// opacity: mainUI.accountsPresent && ! reduce ? 1 : 0
|
opacity: mainUI.accountsPresent && ! reduce ? 1 : 0
|
||||||
// visible: opacity > 0
|
visible: opacity > 0
|
||||||
|
|
||||||
|
|
||||||
property bool canAutoSize: true
|
|
||||||
property int parentWidth: parent.width
|
|
||||||
property real autoWidthRatio: theme.sidePane.autoWidthRatio
|
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
|
property int maximumCalculatedWidth: Math.min(
|
||||||
onParentWidthChanged: if (canAutoSize) {
|
manuallyResized ? manualWidth : theme.sidePane.maximumAutoWidth,
|
||||||
width = Qt.binding(() => implicitWidth)
|
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:
|
property int calculatedWidth: Math.min(
|
||||||
Math.min(parentWidth * autoWidthRatio, theme.sidePane.maximumAutoWidth)
|
manuallyResized ? manualWidth: parentWidth * autoWidthRatio,
|
||||||
|
maximumCalculatedWidth
|
||||||
|
)
|
||||||
|
|
||||||
property bool collapse:
|
property bool collapse:
|
||||||
canAutoSize ?
|
(manuallyResizing ? width : calculatedWidth) <
|
||||||
autoWidth < theme.sidePane.autoCollapseBelowWidth :
|
(manuallyResized ?
|
||||||
width <= theme.sidePane.collapsedWidth
|
(theme.sidePane.collapsedWidth + theme.spacing * 2) :
|
||||||
|
theme.sidePane.autoCollapseBelowWidth)
|
||||||
|
|
||||||
property bool reduce:
|
property bool reduce:
|
||||||
window.width < theme.sidePane.autoReduceBelowWindowWidth
|
window.width < theme.sidePane.autoReduceBelowWindowWidth
|
||||||
@ -36,10 +43,11 @@ HRectangle {
|
|||||||
property int implicitWidth:
|
property int implicitWidth:
|
||||||
reduce ? 0 :
|
reduce ? 0 :
|
||||||
collapse ? theme.sidePane.collapsedWidth :
|
collapse ? theme.sidePane.collapsedWidth :
|
||||||
autoWidth
|
calculatedWidth
|
||||||
|
|
||||||
property int currentSpacing:
|
property int currentSpacing:
|
||||||
collapse || reduce ? 0 : theme.spacing
|
width <= theme.sidePane.collapsedWidth + theme.spacing * 2 ?
|
||||||
|
0 : theme.spacing
|
||||||
|
|
||||||
Behavior on currentSpacing { HNumberAnimation {} }
|
Behavior on currentSpacing { HNumberAnimation {} }
|
||||||
Behavior on implicitWidth { HNumberAnimation {} }
|
Behavior on implicitWidth { HNumberAnimation {} }
|
||||||
|
@ -9,6 +9,9 @@ QtObject {
|
|||||||
property int minimumSupportedWidth: 240
|
property int minimumSupportedWidth: 240
|
||||||
property int minimumSupportedHeight: 120
|
property int minimumSupportedHeight: 120
|
||||||
|
|
||||||
|
property int minimumSupportedWidthPlusSpacing: 240 + spacing * 2
|
||||||
|
property int minimumSupportedHeightPlusSpacing: 120 + spacing * 2
|
||||||
|
|
||||||
property int baseElementsHeight: 36
|
property int baseElementsHeight: 36
|
||||||
property int spacing: 8
|
property int spacing: 8
|
||||||
property int animationDuration: 100
|
property int animationDuration: 100
|
||||||
@ -66,14 +69,14 @@ QtObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
property QtObject sidePane: QtObject {
|
property QtObject sidePane: QtObject {
|
||||||
property real autoWidthRatio: 0.3
|
property real autoWidthRatio: 0.33
|
||||||
property int maximumAutoWidth: 300
|
property int maximumAutoWidth: 320
|
||||||
|
|
||||||
property int autoCollapseBelowWidth: 120
|
property int autoCollapseBelowWidth: 128
|
||||||
property int collapsedWidth: avatar.size
|
property int collapsedWidth: avatar.size
|
||||||
|
|
||||||
property int autoReduceBelowWindowWidth:
|
property int autoReduceBelowWindowWidth:
|
||||||
minimumSupportedWidth + collapsedWidth
|
minimumSupportedWidthPlusSpacing + collapsedWidth
|
||||||
|
|
||||||
property color background: colors.background2
|
property color background: colors.background2
|
||||||
|
|
||||||
|
@ -36,20 +36,24 @@ Item {
|
|||||||
id: uiSplitView
|
id: uiSplitView
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onAnyResizingChanged: if (anyResizing) {
|
||||||
|
sidePane.manuallyResizing = true
|
||||||
|
} else {
|
||||||
|
sidePane.manuallyResizing = false
|
||||||
|
sidePane.manuallyResized = true
|
||||||
|
sidePane.manualWidth = sidePane.width
|
||||||
|
}
|
||||||
|
|
||||||
SidePane {
|
SidePane {
|
||||||
id: sidePane
|
id: sidePane
|
||||||
canAutoSize: uiSplitView.canAutoSize
|
|
||||||
|
|
||||||
// Initial width until user manually resizes
|
// Initial width until user manually resizes
|
||||||
width: implicitWidth
|
width: implicitWidth
|
||||||
Layout.minimumWidth: reduce ? 0 : theme.sidePane.collapsedWidth
|
Layout.minimumWidth: reduce ? 0 : theme.sidePane.collapsedWidth
|
||||||
// -1: avoid making swipeview stuff disappear when dragged to max
|
Layout.maximumWidth:
|
||||||
Layout.maximumWidth: parent.width - 1
|
window.width -theme.minimumSupportedWidthPlusSpacing
|
||||||
|
|
||||||
Behavior on Layout.minimumWidth {
|
Behavior on Layout.minimumWidth { HNumberAnimation {} }
|
||||||
// Must run faster than SidePane implicitWidth anim
|
|
||||||
HNumberAnimation { duration: theme.animationDuration / 2 }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StackView {
|
StackView {
|
||||||
|
Loading…
Reference in New Issue
Block a user