feat(StatusStackModal): Component to replace nested StausModals (#733)

This commit is contained in:
Mikhail Rogachev 2022-06-27 19:23:36 +03:00 committed by GitHub
parent fe355eebf8
commit 84c529d58d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 194 additions and 3 deletions

View File

@ -0,0 +1,80 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
StackLayout {
id: root
property int previousIndex: 0
property int duration: 300
property var items: children
readonly property var previousItem: items[previousIndex]
readonly property var currentItem: items[currentIndex]
clip: true
Component.onCompleted: {
previousIndex = currentIndex
for(var i = 1; i < count; ++i) {
children[i].opacity = 0
}
}
Component {
id: crossFader
ParallelAnimation {
property Item fadeOutTarget
property Item fadeInTarget
readonly property bool direct: previousIndex < currentIndex
NumberAnimation {
target: fadeOutTarget
property: "opacity"
to: 0
duration: root.duration
}
NumberAnimation {
target: fadeInTarget
property: "opacity"
to: 1
duration: root.duration
}
NumberAnimation {
target: fadeOutTarget
property: "x"
from: 0
to: direct ? -root.width : root.width
duration: root.duration
}
NumberAnimation {
target: fadeInTarget
property: "x"
from: direct ? root.width : -root.width
to: 0
duration: root.duration
}
}
}
onCurrentIndexChanged: {
items = root.children;
if (previousItem && currentItem && (previousItem != currentItem)) {
previousItem.visible = true;
currentItem.visible = true;
var crossFaderAnim = crossFader.createObject(parent,
{
fadeOutTarget: previousItem,
fadeInTarget: currentItem
});
crossFaderAnim.restart();
}
previousIndex = currentIndex;
}
}

View File

@ -9,3 +9,4 @@ StatusImageSettings 0.1 StatusImageSettings.qml
StatusModalHeaderSettings 0.1 StatusModalHeaderSettings.qml
StatusTooltipSettings 0.1 StatusTooltipSettings.qml
StatusAppNavBarFilterModel 0.1 StatusAppNavBarFilterModel.qml
StatusAnimatedStack 0.1 StatusAnimatedStack.qml

View File

@ -199,6 +199,7 @@ QC.Popup {
parent: QC.Overlay.overlay
width: 480
// implicitHeight: headerImpl.implicitHeight + contentItem.implicitHeight + footerImpl.implicitHeight
padding: 0
topPadding: padding + headerImpl.implicitHeight
@ -214,7 +215,6 @@ QC.Popup {
color: Theme.palette.backdropColor
}
background: Rectangle {
color: Theme.palette.statusModal.backgroundColor
radius: 8
@ -245,7 +245,7 @@ QC.Popup {
anchors.top: parent.top
anchors.topMargin: hasFloatingButtons ? -18 - height : 0
width: visible ? parent.width : 0
active: showAdvancedHeader
active: statusModal.showAdvancedHeader
}
Spares.StatusModalFooter {
@ -259,7 +259,7 @@ QC.Popup {
id: advancedFooter
anchors.bottom: parent.bottom
width: visible ? parent.width : 0
active: showAdvancedFooter
active: statusModal.showAdvancedFooter
}
}
}

View File

@ -0,0 +1,109 @@
import QtQuick 2.14
import QtQuick.Layouts 1.14
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1
StatusModal {
id: root
/*
stackItems
Attached properties:
canGoNext
replaceItem
Attached properties:
title
acceptButton
*/
property string stackTitle: qsTr("StackModal")
property alias stackItems: stackLayout.children
property alias currentIndex: stackLayout.currentIndex
property alias replaceItem: replaceLoader.sourceComponent
readonly property int itemsCount: stackLayout.children.length
readonly property var currentItem: stackLayout.currentItem
property Item nextButton: StatusButton {
text: qsTr("Next")
enabled: !!currentItem && (typeof(currentItem.canGoNext) == "undefined" || currentItem.canGoNext)
onClicked: currentIndex++
}
property Item finishButton: StatusButton {
text: qsTr("Finish")
onClicked: root.close()
}
function replace(item) { replaceItem = item; }
function updateRightButtons() {
if (replaceItem) {
nextButton.visible = false;
finishButton.visible = false;
} else if (currentIndex < itemsCount - 1) {
nextButton.visible = true;
finishButton.visible = false;
} else {
nextButton.visible = false;
finishButton.visible = true;
}
}
onCurrentIndexChanged: updateRightButtons()
onReplaceItemChanged: updateRightButtons()
width: 640
height: Math.max(implicitHeight, replaceLoader.implicitHeight)
padding: 16
header.title: replaceLoader.item && typeof(replaceLoader.item.title) != "undefined"
? replaceLoader.item.title : stackTitle
leftButtons: StatusRoundButton {
id: backButton
icon.name: "arrow-right"
icon.width: 20
icon.height: 16
rotation: 180
visible: replaceItem || stackLayout.currentIndex > 0
onClicked: {
if (replaceItem)
replaceItem = null;
else
stackLayout.currentIndex--;
}
}
rightButtons: [ nextButton, finishButton ]
Item {
id: content
anchors.fill: parent
implicitWidth: stackLayout.implicitWidth
implicitHeight: stackLayout.implicitHeight
clip: true
StatusAnimatedStack {
id: stackLayout
anchors.fill: parent
visible: !replaceItem
}
Loader {
id: replaceLoader
anchors.fill: parent
visible: item
onItemChanged: {
root.rightButtons = item ? item.rightButtons : [ nextButton, finishButton ]
if (!item && root.itemsCount == 0) {
root.close();
}
}
}
}
}

View File

@ -6,6 +6,7 @@ StatusMenuItem 0.1 StatusMenuItem.qml
StatusMenuItemDelegate 0.1 StatusMenuItemDelegate.qml
StatusMenuHeadline 0.1 StatusMenuHeadline.qml
StatusModal 0.1 StatusModal.qml
StatusStackModal 0.1 StatusStackModal.qml
StatusSearchPopup 0.1 StatusSearchPopup.qml
StatusModalDivider 0.1 StatusModalDivider.qml
StatusSearchPopupMenuItem 0.1 StatusSearchPopupMenuItem.qml