Rewrite SidePane using QQC Drawer
Cleaner approach, gets rid of the HPage swipe view hack, better performances, a lot less complex
This commit is contained in:
parent
5326726c4f
commit
06a6a4c08d
4
TODO.md
4
TODO.md
@ -1,3 +1,7 @@
|
||||
- make pageup/down not slippery again
|
||||
- rename all setfocus() to takefocus()
|
||||
- refactor roomsidepane too
|
||||
- better pane minsize
|
||||
- better cancel for all boxes
|
||||
- Media
|
||||
- Confirmation box after picking file to upload
|
||||
|
72
src/qml/Base/HDrawer.qml
Normal file
72
src/qml/Base/HDrawer.qml
Normal file
@ -0,0 +1,72 @@
|
||||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import "../utils.js" as Utils
|
||||
|
||||
Drawer {
|
||||
id: drawer
|
||||
implicitWidth: calculatedWidth
|
||||
implicitHeight: parent.height
|
||||
|
||||
// FIXME: https://bugreports.qt.io/browse/QTBUG-59141
|
||||
// dragMargin: parent.width / 2
|
||||
|
||||
interactive: collapse
|
||||
position: 1
|
||||
visible: ! collapse
|
||||
modal: false
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
|
||||
background: Rectangle { id: bg; color: theme.colors.strongBackground }
|
||||
|
||||
|
||||
signal userResized(int newWidth)
|
||||
|
||||
property int normalWidth: 300
|
||||
property int minNormalWidth: resizeAreaWidth
|
||||
property int maxNormalWidth: parent.width
|
||||
|
||||
property bool collapse: window.width < 400
|
||||
property int collapseExpandedWidth: parent.width
|
||||
|
||||
property alias color: bg.color
|
||||
property alias resizeAreaWidth: resizeArea.width
|
||||
|
||||
readonly property int calculatedWidth:
|
||||
collapse ?
|
||||
collapseExpandedWidth :
|
||||
Math.max(minNormalWidth, Math.min(normalWidth, maxNormalWidth))
|
||||
|
||||
|
||||
Behavior on width {
|
||||
enabled: ! resizeMouseHandler.drag.active
|
||||
NumberAnimation { duration: 100 }
|
||||
}
|
||||
|
||||
Item {
|
||||
id: resizeArea
|
||||
anchors.right: parent.right
|
||||
width: theme.spacing / 2
|
||||
height: parent.height
|
||||
z: 9999
|
||||
|
||||
MouseArea {
|
||||
id: resizeMouseHandler
|
||||
anchors.fill: parent
|
||||
enabled: ! drawer.collapse
|
||||
acceptedButtons: Qt.LeftButton
|
||||
hoverEnabled: true
|
||||
cursorShape:
|
||||
containsMouse || drag.active ?
|
||||
Qt.SizeHorCursor : Qt.ArrowCursor
|
||||
|
||||
onPressed: canResize = true
|
||||
onReleased: { canResize = false; userResized(drawer.normalWidth) }
|
||||
|
||||
onMouseXChanged:
|
||||
if (canResize)
|
||||
drawer.normalWidth = drawer.calculatedWidth + mouseX
|
||||
|
||||
property bool canResize: false
|
||||
}
|
||||
}
|
||||
}
|
@ -3,14 +3,13 @@ import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../SidePane"
|
||||
|
||||
SwipeView {
|
||||
Page {
|
||||
id: innerPage
|
||||
|
||||
|
||||
default property alias columnChildren: contentColumn.children
|
||||
|
||||
property alias page: innerPage
|
||||
property alias header: innerPage.header
|
||||
property alias footer: innerPage.header
|
||||
property alias flickable: innerFlickable
|
||||
|
||||
property alias headerLabel: innerHeaderLabel
|
||||
property var hideHeaderUnderHeight: null
|
||||
|
||||
@ -19,72 +18,56 @@ SwipeView {
|
||||
|
||||
property bool becomeKeyboardFlickableTarget: true
|
||||
|
||||
id: swipeView
|
||||
clip: true
|
||||
interactive: sidePane.reduce
|
||||
currentIndex: 1
|
||||
|
||||
SidePane {
|
||||
implicitWidth: swipeView.width
|
||||
animateWidth: false // Without this, the SidePane gets auto-focused
|
||||
collapse: false
|
||||
reduce: false
|
||||
visible: swipeView.interactive
|
||||
onVisibleChanged: if (currentIndex != 1) swipeView.setCurrentIndex(1)
|
||||
background: null
|
||||
|
||||
header: Rectangle {
|
||||
implicitWidth: parent ? parent.width : 0
|
||||
color: theme.controls.header.background
|
||||
|
||||
height: innerHeaderLabel.text && (
|
||||
! hideHeaderUnderHeight ||
|
||||
window.height >=
|
||||
hideHeaderUnderHeight +
|
||||
theme.baseElementsHeight +
|
||||
currentSpacing * 2
|
||||
) ? theme.baseElementsHeight : 0
|
||||
|
||||
Behavior on height { HNumberAnimation {} }
|
||||
visible: height > 0
|
||||
|
||||
HLabel {
|
||||
id: innerHeaderLabel
|
||||
anchors.fill: parent
|
||||
textFormat: Text.StyledText
|
||||
font.pixelSize: theme.fontSize.big
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
leftPadding: currentSpacing
|
||||
rightPadding: leftPadding
|
||||
}
|
||||
}
|
||||
|
||||
Page {
|
||||
id: innerPage
|
||||
background: null
|
||||
leftPadding: currentSpacing < theme.spacing ? 0 : currentSpacing
|
||||
rightPadding: leftPadding
|
||||
Behavior on leftPadding { HNumberAnimation {} }
|
||||
|
||||
header: Rectangle {
|
||||
implicitWidth: parent ? parent.width : 0
|
||||
color: theme.controls.header.background
|
||||
HFlickable {
|
||||
id: innerFlickable
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
contentWidth: parent.width
|
||||
contentHeight: contentColumn.childrenRect.height
|
||||
|
||||
height: innerHeaderLabel.text && (
|
||||
! hideHeaderUnderHeight ||
|
||||
window.height >=
|
||||
hideHeaderUnderHeight +
|
||||
theme.baseElementsHeight +
|
||||
currentSpacing * 2
|
||||
) ? theme.baseElementsHeight : 0
|
||||
Component.onCompleted:
|
||||
if (becomeKeyboardFlickableTarget) shortcuts.flickTarget = this
|
||||
|
||||
Behavior on height { HNumberAnimation {} }
|
||||
visible: height > 0
|
||||
|
||||
HLabel {
|
||||
id: innerHeaderLabel
|
||||
anchors.fill: parent
|
||||
textFormat: Text.StyledText
|
||||
font.pixelSize: theme.fontSize.big
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
leftPadding: currentSpacing
|
||||
rightPadding: leftPadding
|
||||
}
|
||||
}
|
||||
|
||||
leftPadding: currentSpacing < theme.spacing ? 0 : currentSpacing
|
||||
rightPadding: leftPadding
|
||||
Behavior on leftPadding { HNumberAnimation {} }
|
||||
|
||||
HFlickable {
|
||||
id: innerFlickable
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
contentWidth: parent.width
|
||||
contentHeight: contentColumn.childrenRect.height
|
||||
|
||||
Component.onCompleted:
|
||||
if (becomeKeyboardFlickableTarget) shortcuts.flickTarget = this
|
||||
|
||||
HColumnLayout {
|
||||
id: contentColumn
|
||||
width: innerFlickable.width
|
||||
height: innerFlickable.height
|
||||
}
|
||||
HColumnLayout {
|
||||
id: contentColumn
|
||||
width: innerFlickable.width
|
||||
height: innerFlickable.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,9 @@ import "../utils.js" as Utils
|
||||
|
||||
HPage {
|
||||
id: chatPage
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
|
||||
// The target will be our EventList, not the page itself
|
||||
becomeKeyboardFlickableTarget: false
|
||||
|
||||
@ -49,9 +52,6 @@ HPage {
|
||||
Behavior on height { HNumberAnimation {} }
|
||||
}
|
||||
|
||||
page.leftPadding: 0
|
||||
page.rightPadding: 0
|
||||
|
||||
HLoader {
|
||||
source: ready ? "ChatSplitView.qml" : "../Base/HBusyIndicator.qml"
|
||||
|
||||
|
@ -8,7 +8,7 @@ import "FileTransfer"
|
||||
|
||||
HSplitView {
|
||||
id: chatSplitView
|
||||
Component.onCompleted: composer.setFocus()
|
||||
Component.onCompleted: composer.takeFocus()
|
||||
|
||||
HColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
|
@ -5,8 +5,6 @@ import "../Dialogs"
|
||||
import "../utils.js" as Utils
|
||||
|
||||
Rectangle {
|
||||
function setFocus() { areaScrollView.forceActiveFocus() }
|
||||
|
||||
property string indent: " "
|
||||
|
||||
property var aliases: window.settings.writeAliases
|
||||
@ -40,6 +38,8 @@ Rectangle {
|
||||
lineTextUntilCursor.match(/ {1,4}/g).slice(-1)[0].length :
|
||||
1
|
||||
|
||||
function takeFocus() { areaScrollView.forceActiveFocus() }
|
||||
|
||||
// property var pr: lineTextUntilCursor
|
||||
// onPrChanged: print(
|
||||
// "y", cursorY, "x", cursorX,
|
||||
|
@ -6,7 +6,7 @@ import "../utils.js" as Utils
|
||||
HTileDelegate {
|
||||
id: accountDelegate
|
||||
spacing: 0
|
||||
topPadding: model.index > 0 ? sidePane.currentSpacing / 2 : 0
|
||||
topPadding: model.index > 0 ? theme.spacing / 2 : 0
|
||||
bottomPadding: topPadding
|
||||
backgroundColor: theme.sidePane.account.background
|
||||
opacity: collapsed && ! forceExpand ?
|
||||
@ -54,7 +54,7 @@ HTileDelegate {
|
||||
title.color: theme.sidePane.account.name
|
||||
title.text: model.data.display_name || model.data.user_id
|
||||
title.font.pixelSize: theme.fontSize.big
|
||||
title.leftPadding: sidePane.currentSpacing
|
||||
title.leftPadding: theme.spacing
|
||||
|
||||
HButton {
|
||||
id: addChat
|
||||
@ -112,7 +112,7 @@ HTileDelegate {
|
||||
text: qsTr("Sign out")
|
||||
onTriggered: Utils.makePopup(
|
||||
"Popups/SignOutPopup.qml",
|
||||
mainUI,
|
||||
window,
|
||||
{ "userId": model.data.user_id },
|
||||
popup => { popup.ok.connect(() => { disconnecting = true }) },
|
||||
)
|
||||
|
@ -5,7 +5,7 @@ import "../utils.js" as Utils
|
||||
|
||||
HTileDelegate {
|
||||
id: roomDelegate
|
||||
spacing: sidePane.currentSpacing
|
||||
spacing: theme.spacing
|
||||
backgroundColor: theme.sidePane.room.background
|
||||
opacity: model.data.left ? theme.sidePane.room.leftRoomOpacity : 1
|
||||
|
||||
@ -110,7 +110,7 @@ HTileDelegate {
|
||||
|
||||
onTriggered: Utils.makePopup(
|
||||
"Popups/LeaveRoomPopup.qml",
|
||||
sidePane,
|
||||
window,
|
||||
{
|
||||
userId: model.user_id,
|
||||
roomId: model.data.room_id,
|
||||
@ -126,7 +126,7 @@ HTileDelegate {
|
||||
|
||||
onTriggered: Utils.makePopup(
|
||||
"Popups/ForgetRoomPopup.qml",
|
||||
sidePane,
|
||||
window,
|
||||
{
|
||||
userId: model.user_id,
|
||||
roomId: model.data.room_id,
|
||||
|
@ -3,108 +3,37 @@ import QtQuick.Layouts 1.12
|
||||
import "../Base"
|
||||
import "../utils.js" as Utils
|
||||
|
||||
Rectangle {
|
||||
HDrawer {
|
||||
id: sidePane
|
||||
clip: true
|
||||
opacity: mainUI.accountsPresent && ! reduce ? 1 : 0
|
||||
visible: opacity > 0
|
||||
|
||||
opacity: mainUI.accountsPresent ? 1 : 0
|
||||
color: theme.sidePane.background
|
||||
normalWidth: window.uiState.sidePaneManualWidth
|
||||
|
||||
onUserResized: {
|
||||
window.uiState.sidePaneManualWidth = newWidth
|
||||
window.uiStateChanged()
|
||||
}
|
||||
|
||||
|
||||
property bool hasFocus: toolBar.filterField.activeFocus
|
||||
property alias sidePaneList: sidePaneList
|
||||
property alias toolBar: toolBar
|
||||
|
||||
property real autoWidthRatio: theme.sidePane.autoWidthRatio
|
||||
property bool manuallyResizing: false
|
||||
property bool manuallyResized: false
|
||||
property int manualWidth: 0
|
||||
property bool animateWidth: true
|
||||
|
||||
Component.onCompleted: {
|
||||
if (window.uiState.sidePaneManualWidth) {
|
||||
manualWidth = window.uiState.sidePaneManualWidth
|
||||
manuallyResized = true
|
||||
}
|
||||
}
|
||||
|
||||
onFocusChanged: if (focus) toolBar.filterField.forceActiveFocus()
|
||||
|
||||
onManualWidthChanged: {
|
||||
window.uiState.sidePaneManualWidth = manualWidth
|
||||
window.uiStateChanged()
|
||||
}
|
||||
|
||||
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 calculatedWidth: Math.min(
|
||||
manuallyResized ? manualWidth * theme.uiScale :
|
||||
parentWidth * autoWidthRatio,
|
||||
|
||||
maximumCalculatedWidth
|
||||
)
|
||||
|
||||
property bool collapse:
|
||||
(manuallyResizing ? width : calculatedWidth) <
|
||||
(manuallyResized ?
|
||||
(theme.sidePane.collapsedWidth + theme.spacing * 2) :
|
||||
theme.sidePane.autoCollapseBelowWidth)
|
||||
|
||||
property bool reduce:
|
||||
window.width < theme.sidePane.autoReduceBelowWindowWidth
|
||||
|
||||
property int implicitWidth:
|
||||
reduce ? 0 :
|
||||
collapse ? theme.sidePane.collapsedWidth :
|
||||
calculatedWidth
|
||||
|
||||
property int currentSpacing:
|
||||
width <= theme.sidePane.collapsedWidth + theme.spacing * 2 ?
|
||||
0 : theme.spacing
|
||||
|
||||
Behavior on currentSpacing { HNumberAnimation {} }
|
||||
Behavior on implicitWidth {
|
||||
HNumberAnimation { factor: animateWidth ? 1 : 0 }
|
||||
}
|
||||
|
||||
|
||||
function setFocus() {
|
||||
forceActiveFocus()
|
||||
if (reduce) {
|
||||
pageLoader.item.currentIndex = 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Keys.enabled: sidePane.hasFocus
|
||||
Keys.onUpPressed: sidePaneList.previous(false) // do not activate
|
||||
Keys.onDownPressed: sidePaneList.next(false)
|
||||
Keys.onEnterPressed: Keys.onReturnPressed(event)
|
||||
Keys.onReturnPressed: if (event.modifiers & Qt.ShiftModifier) {
|
||||
sidePaneList.toggleCollapseAccount()
|
||||
} else {
|
||||
if (window.settings.clearRoomFilterOnEnter) {
|
||||
mainUI.sidePane.toolBar.roomFilter = ""
|
||||
function toggleFocus() {
|
||||
if (toolBar.filterField.activeFocus) {
|
||||
pageLoader.takeFocus()
|
||||
return
|
||||
}
|
||||
|
||||
sidePaneList.activate()
|
||||
}
|
||||
Keys.onEscapePressed: {
|
||||
if (window.settings.clearRoomFilterOnEscape) {
|
||||
mainUI.sidePane.toolBar.roomFilter = ""
|
||||
}
|
||||
mainUI.pageLoader.forceActiveFocus()
|
||||
sidePane.open()
|
||||
toolBar.filterField.forceActiveFocus()
|
||||
}
|
||||
|
||||
|
||||
Behavior on opacity { HOpacityAnimator {} }
|
||||
|
||||
HColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
@ -118,6 +47,7 @@ Rectangle {
|
||||
|
||||
SidePaneToolBar {
|
||||
id: toolBar
|
||||
sidePaneList: sidePaneList
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,6 @@ HListView {
|
||||
{
|
||||
currentIndex = i
|
||||
currentItem.item.toggleCollapse()
|
||||
activate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import "../Base"
|
||||
HRowLayout {
|
||||
id: toolBar
|
||||
|
||||
property SidePaneList sidePaneList
|
||||
readonly property alias addAccountButton: addAccountButton
|
||||
readonly property alias filterField: filterField
|
||||
property alias roomFilter: filterField.text
|
||||
@ -29,8 +30,7 @@ HRowLayout {
|
||||
backgroundColor: theme.sidePane.filterRooms.background
|
||||
bordered: false
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Component.onCompleted: filterField.text = uiState.sidePaneFilter
|
||||
|
||||
onTextChanged: {
|
||||
if (window.uiState.sidePaneFilter == text) return
|
||||
@ -38,12 +38,26 @@ HRowLayout {
|
||||
window.uiStateChanged()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: window
|
||||
// Keep multiple instances of SidePaneToolBar in sync.
|
||||
// This also sets the text on startup.
|
||||
onUiStateChanged: filterField.text = uiState.sidePaneFilter
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Keys.onUpPressed: sidePaneList.previous(false) // do not activate
|
||||
Keys.onDownPressed: sidePaneList.next(false)
|
||||
|
||||
Keys.onEnterPressed: Keys.onReturnPressed(event)
|
||||
Keys.onReturnPressed: {
|
||||
if (event.modifiers & Qt.ShiftModifier) {
|
||||
sidePaneList.toggleCollapseAccount()
|
||||
return
|
||||
}
|
||||
|
||||
if (window.settings.clearRoomFilterOnEnter) text = ""
|
||||
sidePaneList.activate()
|
||||
}
|
||||
|
||||
Keys.onEscapePressed: {
|
||||
if (window.settings.clearRoomFilterOnEscape) text = ""
|
||||
mainUI.pageLoader.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
159
src/qml/UI.qml
159
src/qml/UI.qml
@ -11,7 +11,6 @@ Item {
|
||||
id: mainUI
|
||||
focus: true
|
||||
Component.onCompleted: window.mainUI = mainUI
|
||||
Keys.forwardTo: [shortcuts]
|
||||
|
||||
readonly property alias shortcuts: shortcuts
|
||||
readonly property alias sidePane: sidePane
|
||||
@ -55,107 +54,99 @@ Item {
|
||||
}
|
||||
|
||||
|
||||
HSplitView {
|
||||
id: uiSplitView
|
||||
SidePane {
|
||||
id: sidePane
|
||||
maxNormalWidth: parent.width - theme.minimumSupportedWidth
|
||||
}
|
||||
|
||||
HLoader {
|
||||
id: pageLoader
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: sidePane.width * sidePane.position
|
||||
visible: ! sidePane.hidden || anchors.leftMargin < width
|
||||
|
||||
onAnyResizingChanged: if (anyResizing) {
|
||||
sidePane.manuallyResizing = true
|
||||
} else {
|
||||
sidePane.manuallyResizing = false
|
||||
sidePane.manuallyResized = true
|
||||
sidePane.manualWidth = sidePane.width
|
||||
// onSourceChanged: if (sidePane.collapse) sidePane.close()
|
||||
|
||||
|
||||
property bool isWide: width > theme.contentIsWideAbove
|
||||
|
||||
// List of previously loaded [componentUrl, {properties}]
|
||||
property var history: []
|
||||
property int historyLength: 20
|
||||
|
||||
Component.onCompleted: {
|
||||
if (! py.startupAnyAccountsSaved) {
|
||||
pageLoader.showPage("AddAccount/AddAccount")
|
||||
return
|
||||
}
|
||||
|
||||
let page = window.uiState.page
|
||||
let props = window.uiState.pageProperties
|
||||
|
||||
if (page == "Chat/Chat.qml") {
|
||||
pageLoader.showRoom(props.userId, props.roomId)
|
||||
} else {
|
||||
pageLoader._show(page, props)
|
||||
}
|
||||
}
|
||||
|
||||
SidePane {
|
||||
id: sidePane
|
||||
function _show(componentUrl, properties={}) {
|
||||
history.unshift([componentUrl, properties])
|
||||
if (history.length > historyLength) history.pop()
|
||||
|
||||
// Initial width until user manually resizes
|
||||
width: implicitWidth
|
||||
Layout.minimumWidth: reduce ? 0 : theme.sidePane.collapsedWidth
|
||||
Layout.maximumWidth:
|
||||
window.width - theme.minimumSupportedWidthPlusSpacing
|
||||
|
||||
Behavior on Layout.minimumWidth { HNumberAnimation {} }
|
||||
pageLoader.setSource(componentUrl, properties)
|
||||
}
|
||||
|
||||
HLoader {
|
||||
id: pageLoader
|
||||
function showPage(name, properties={}) {
|
||||
let path = `Pages/${name}.qml`
|
||||
_show(path, properties)
|
||||
|
||||
property bool isWide: width > theme.contentIsWideAbove
|
||||
window.uiState.page = path
|
||||
window.uiState.pageProperties = properties
|
||||
window.uiStateChanged()
|
||||
}
|
||||
|
||||
// List of previously loaded [componentUrl, {properties}]
|
||||
property var history: []
|
||||
property int historyLength: 20
|
||||
function showRoom(userId, roomId) {
|
||||
_show("Chat/Chat.qml", {userId, roomId})
|
||||
|
||||
Component.onCompleted: {
|
||||
if (! py.startupAnyAccountsSaved) {
|
||||
pageLoader.showPage("AddAccount/AddAccount")
|
||||
return
|
||||
}
|
||||
window.uiState.page = "Chat/Chat.qml"
|
||||
window.uiState.pageProperties = {userId, roomId}
|
||||
window.uiStateChanged()
|
||||
}
|
||||
|
||||
let page = window.uiState.page
|
||||
let props = window.uiState.pageProperties
|
||||
function showPrevious(timesBack=1) {
|
||||
timesBack = Math.min(timesBack, history.length - 1)
|
||||
if (timesBack < 1) return false
|
||||
|
||||
if (page == "Chat/Chat.qml") {
|
||||
pageLoader.showRoom(props.userId, props.roomId)
|
||||
} else {
|
||||
pageLoader._show(page, props)
|
||||
}
|
||||
}
|
||||
let [componentUrl, properties] = history[timesBack]
|
||||
|
||||
function _show(componentUrl, properties={}) {
|
||||
history.unshift([componentUrl, properties])
|
||||
if (history.length > historyLength) history.pop()
|
||||
_show(componentUrl, properties)
|
||||
|
||||
pageLoader.setSource(componentUrl, properties)
|
||||
}
|
||||
window.uiState.page = componentUrl
|
||||
window.uiState.pageProperties = properties
|
||||
window.uiStateChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
function showPage(name, properties={}) {
|
||||
let path = `Pages/${name}.qml`
|
||||
_show(path, properties)
|
||||
function takeFocus() {
|
||||
pageLoader.item.forceActiveFocus()
|
||||
if (sidePane.collapse) sidePane.close()
|
||||
}
|
||||
|
||||
window.uiState.page = path
|
||||
window.uiState.pageProperties = properties
|
||||
window.uiStateChanged()
|
||||
}
|
||||
|
||||
function showRoom(userId, roomId) {
|
||||
_show("Chat/Chat.qml", {userId, roomId})
|
||||
onStatusChanged: if (status == Loader.Ready) {
|
||||
pageLoader.takeFocus()
|
||||
appearAnimation.start()
|
||||
}
|
||||
|
||||
window.uiState.page = "Chat/Chat.qml"
|
||||
window.uiState.pageProperties = {userId, roomId}
|
||||
window.uiStateChanged()
|
||||
}
|
||||
|
||||
function showPrevious(timesBack=1) {
|
||||
timesBack = Math.min(timesBack, history.length - 1)
|
||||
if (timesBack < 1) return false
|
||||
|
||||
let [componentUrl, properties] = history[timesBack]
|
||||
|
||||
_show(componentUrl, properties)
|
||||
|
||||
window.uiState.page = componentUrl
|
||||
window.uiState.pageProperties = properties
|
||||
window.uiStateChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
onStatusChanged: if (status == Loader.Ready) {
|
||||
item.forceActiveFocus()
|
||||
appearAnimation.start()
|
||||
}
|
||||
|
||||
clip: appearAnimation.running
|
||||
XAnimator {
|
||||
id: appearAnimation
|
||||
target: pageLoader.item
|
||||
from: -300
|
||||
to: 0
|
||||
easing.type: Easing.OutBack
|
||||
duration: theme.animationDuration * 2
|
||||
}
|
||||
clip: appearAnimation.running
|
||||
XAnimator {
|
||||
id: appearAnimation
|
||||
target: pageLoader.item
|
||||
from: -300
|
||||
to: 0
|
||||
easing.type: Easing.OutBack
|
||||
duration: theme.animationDuration * 2
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,9 +261,6 @@ ui:
|
||||
|
||||
|
||||
sidePane:
|
||||
real autoWidthRatio: 0.33 * uiScale
|
||||
int maximumAutoWidth: 320 * uiScale
|
||||
|
||||
int autoCollapseBelowWidth: 128 * uiScale
|
||||
int collapsedWidth: controls.avatar.size
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user