shift-shell/initialstart/qml/Wizard.qml

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

254 lines
7.9 KiB
QML
Raw Normal View History

// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import org.kde.kirigami as Kirigami
import org.kde.plasma.private.mobileshell as MobileShell
import initialstart as InitialStart
Kirigami.Page {
id: root
leftPadding: 0
rightPadding: 0
topPadding: 0
bottomPadding: 0
property int currentIndex: 0
readonly property int stepCount: InitialStart.Wizard.stepsCount
property bool showingLanding: true
// filled by items
property var currentStepItem
property var nextStepItem
property var previousStepItem
readonly property bool onFinalPage: currentIndex === (stepCount - 1)
function updateStepItems() {
if (stepRepeater.count === 0) {
return;
}
root.previousStepItem = currentIndex > 0 ? stepRepeater.itemAt(currentIndex - 1) : null;
root.currentStepItem = stepRepeater.itemAt(currentIndex);
root.nextStepItem = currentIndex < stepRepeater.count - 1 ? stepRepeater.itemAt(currentIndex + 1) : null;
}
// step animation
// manually doing the animation is more performant and less glitchy with window resize than a SwipeView
property real previousStepItemX: -root.width
property real currentStepItemX: 0
property real nextStepItemX: root.width
onStepCountChanged: {
// reset position
updateStepItems();
requestPreviousPage();
}
function finishFinalPage() {
// the app exits
InitialStart.Wizard.wizardFinished();
}
function requestNextPage() {
if (currentIndex >= stepCount - 1) {
return;
}
currentIndex++;
updateStepItems();
stepHeading.changeText(currentStepItem.name);
previousStepItemX = -root.width;
currentStepItemX = 0;
nextStepItemX = root.width;
}
function requestPreviousPage() {
if (currentIndex === 0) {
root.showingLanding = true;
landingComponent.returnToLanding();
} else {
currentIndex--;
updateStepItems();
stepHeading.changeText(currentStepItem.name);
previousStepItemX = -root.width;
currentStepItemX = 0;
nextStepItemX = root.width;
}
}
LandingComponent {
id: landingComponent
anchors.fill: parent
enabled: root.showingLanding
visible: root.showingLanding
onRequestNextPage: {
root.showingLanding = false;
root.updateStepItems();
stepHeading.changeText(root.currentStepItem.name);
}
}
Item {
id: stepsComponent
width: parent.width
height: parent.height
// animation when we switch to step stage
opacity: root.showingLanding ? 0 : 1
x: 0
y: root.showingLanding ? overlaySteps.height : 0
// heading for all the wizard steps
Label {
id: stepHeading
opacity: 0
color: "white"
horizontalAlignment: Text.AlignHCenter
font.pointSize: 18
anchors.left: parent.left
anchors.leftMargin: Kirigami.Units.gridUnit
anchors.right: parent.right
anchors.rightMargin: Kirigami.Units.gridUnit
anchors.bottom: parent.bottom
anchors.bottomMargin: root.height * 0.7 + Kirigami.Units.gridUnit
property string toText
function changeText(text) {
stepHeading.text = text;
stepHeading.opacity = 1;
}
}
Rectangle {
id: overlaySteps
clip: true
Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.Window
color: Kirigami.Theme.backgroundColor
topLeftRadius: Kirigami.Units.gridUnit
topRightRadius: Kirigami.Units.gridUnit
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
height: root.height * 0.7
width: Math.min(parent.width, Kirigami.Units.gridUnit * 30)
// all steps are in this container
Item {
anchors.fill: parent
anchors.bottomMargin: stepFooter.implicitHeight
// setup steps
Repeater {
id: stepRepeater
model: InitialStart.Wizard.steps
delegate: MobileShell.BaseItem {
id: item
visible: !root.showingLanding && Math.abs(item.currentIndex - root.currentIndex) <= 1
contentItem: modelData.contentItem
transform: Translate {
x: {
if (item.currentIndex === root.currentIndex - 1) {
return previousStepItemX;
} else if (item.currentIndex === root.currentIndex + 1) {
return nextStepItemX;
} else if (item.currentIndex === root.currentIndex) {
return currentStepItemX;
}
return 0;
}
}
anchors.fill: parent
// pass up the property
property string name: modelData.name
property int currentIndex: model.index
Component.onCompleted: {
root.updateStepItems();
}
}
}
}
// bottom footer
RowLayout {
id: stepFooter
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
Button {
Layout.alignment: Qt.AlignLeft
Layout.leftMargin: Kirigami.Units.gridUnit
Layout.bottomMargin: Kirigami.Units.gridUnit
2023-10-21 22:27:31 +00:00
topPadding: Kirigami.Units.largeSpacing
bottomPadding: Kirigami.Units.largeSpacing
leftPadding: Kirigami.Units.gridUnit
rightPadding: Kirigami.Units.gridUnit
text: i18n("Back")
icon.name: "arrow-left"
onClicked: root.requestPreviousPage()
}
Item {}
Button {
Layout.alignment: Qt.AlignRight
Layout.rightMargin: Kirigami.Units.gridUnit
Layout.bottomMargin: Kirigami.Units.gridUnit
2023-10-21 22:27:31 +00:00
topPadding: Kirigami.Units.largeSpacing
bottomPadding: Kirigami.Units.largeSpacing
leftPadding: Kirigami.Units.gridUnit
rightPadding: Kirigami.Units.gridUnit
visible: !root.onFinalPage
text: i18n("Next")
icon.name: "arrow-right"
onClicked: root.requestNextPage();
}
Button {
Layout.alignment: Qt.AlignRight
Layout.rightMargin: Kirigami.Units.gridUnit
Layout.bottomMargin: Kirigami.Units.gridUnit
2023-10-21 22:27:31 +00:00
topPadding: Kirigami.Units.largeSpacing
bottomPadding: Kirigami.Units.largeSpacing
leftPadding: Kirigami.Units.gridUnit
rightPadding: Kirigami.Units.gridUnit
visible: root.onFinalPage
text: i18n("Finish")
icon.name: "dialog-ok"
onClicked: root.finishFinalPage();
}
}
}
}
}