mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
f20cd85e79
Autoformat
415 lines
13 KiB
QML
415 lines
13 KiB
QML
import QtQuick
|
|
import QtQuick.Layouts
|
|
import QtQuick.Controls
|
|
import Quickshell
|
|
import Quickshell.Wayland
|
|
import qs.Commons
|
|
import qs.Services
|
|
import qs.Widgets
|
|
|
|
NPanel {
|
|
id: root
|
|
|
|
preferredWidth: 520
|
|
preferredHeight: 600
|
|
preferredWidthRatio: 0.4
|
|
preferredHeightRatio: 0.6
|
|
panelAnchorHorizontalCenter: true
|
|
panelAnchorVerticalCenter: true
|
|
panelKeyboardFocus: true
|
|
|
|
// Prevent closing during setup
|
|
backgroundClickEnabled: false
|
|
draggable: false
|
|
|
|
property int currentStep: 0
|
|
property int totalSteps: 4
|
|
|
|
// Setup wizard data
|
|
property string selectedWallpaperDirectory: Settings.defaultWallpapersDirectory
|
|
property string selectedWallpaper: ""
|
|
property real selectedScaleRatio: 1.0
|
|
property string selectedBarPosition: "top"
|
|
property bool selectedDimDesktop: true
|
|
|
|
panelContent: Component {
|
|
Item {
|
|
id: container
|
|
anchors.fill: parent
|
|
|
|
ColumnLayout {
|
|
id: wizardContent
|
|
anchors.fill: parent
|
|
anchors.margins: Style.marginXL
|
|
spacing: Style.marginL
|
|
|
|
// Override ESC key to prevent closing during setup
|
|
Shortcut {
|
|
sequences: ["Escape"]
|
|
enabled: root.active
|
|
onActivated: {
|
|
|
|
// Do nothing - prevent ESC from closing the setup wizard
|
|
}
|
|
context: Qt.WindowShortcut
|
|
}
|
|
|
|
// Step content - takes most of the space
|
|
Item {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
Layout.minimumHeight: 300
|
|
|
|
StackLayout {
|
|
id: stepStack
|
|
anchors.fill: parent
|
|
currentIndex: currentStep
|
|
|
|
// Step 0: Welcome - Beautiful centered design
|
|
Item {
|
|
ColumnLayout {
|
|
anchors.centerIn: parent
|
|
width: Math.min(parent.width - Style.marginXL * 2, 420)
|
|
spacing: Style.marginXL
|
|
|
|
// Logo with subtle glow effect
|
|
Item {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 120
|
|
Layout.alignment: Qt.AlignHCenter
|
|
|
|
Rectangle {
|
|
anchors.centerIn: parent
|
|
width: 120
|
|
height: 120
|
|
radius: width / 2
|
|
color: Color.mPrimary
|
|
opacity: 0.08
|
|
scale: 1.3
|
|
}
|
|
|
|
Image {
|
|
anchors.centerIn: parent
|
|
width: 110
|
|
height: 110
|
|
source: "https://assets.noctalia.dev/noctalia-logo.svg"
|
|
fillMode: Image.PreserveAspectFit
|
|
smooth: true
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: Color.mSurfaceVariant
|
|
radius: width / 2
|
|
border.color: Color.mOutline
|
|
border.width: 2
|
|
visible: parent.status === Image.Error
|
|
|
|
NIcon {
|
|
icon: "sparkles"
|
|
pointSize: Style.fontSizeXXL * 1.5
|
|
color: Color.mPrimary
|
|
anchors.centerIn: parent
|
|
}
|
|
}
|
|
|
|
// Subtle pulse animation
|
|
SequentialAnimation on scale {
|
|
running: true
|
|
loops: Animation.Infinite
|
|
NumberAnimation {
|
|
from: 1.0
|
|
to: 1.05
|
|
duration: 2000
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
NumberAnimation {
|
|
from: 1.05
|
|
to: 1.0
|
|
duration: 2000
|
|
easing.type: Easing.InOutQuad
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Welcome text with gradient feel
|
|
ColumnLayout {
|
|
Layout.fillWidth: true
|
|
Layout.alignment: Qt.AlignHCenter
|
|
spacing: Style.marginM
|
|
|
|
NText {
|
|
text: "Welcome to Noctalia! ✨"
|
|
pointSize: Style.fontSizeXXL * 1.4
|
|
font.weight: Style.fontWeightBold
|
|
color: Color.mOnSurface
|
|
Layout.fillWidth: true
|
|
horizontalAlignment: Text.AlignHCenter
|
|
}
|
|
|
|
NText {
|
|
text: "Let's make your desktop uniquely yours"
|
|
pointSize: Style.fontSizeL
|
|
color: Color.mOnSurfaceVariant
|
|
Layout.fillWidth: true
|
|
horizontalAlignment: Text.AlignHCenter
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
|
|
// Friendly subtext
|
|
Rectangle {
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Style.marginL
|
|
Layout.preferredHeight: childrenRect.height + Style.marginM * 2
|
|
color: Color.mSurfaceVariant
|
|
radius: Style.radiusL
|
|
opacity: 0.4
|
|
|
|
NText {
|
|
anchors.centerIn: parent
|
|
width: parent.width - Style.marginL * 2
|
|
text: I18n.tr("setup.welcome.note")
|
|
pointSize: Style.fontSizeM
|
|
color: Color.mOnSurfaceVariant
|
|
horizontalAlignment: Text.AlignHCenter
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Step 1: Wallpaper Setup
|
|
SetupWallpaperStep {
|
|
id: step1
|
|
selectedDirectory: root.selectedWallpaperDirectory
|
|
selectedWallpaper: root.selectedWallpaper
|
|
onDirectoryChanged: function (directory) {
|
|
root.selectedWallpaperDirectory = directory
|
|
root.applyWallpaperSettings()
|
|
}
|
|
onWallpaperChanged: function (wallpaper) {
|
|
root.selectedWallpaper = wallpaper
|
|
root.applyWallpaperSettings()
|
|
}
|
|
}
|
|
|
|
// Step 2: UI Configuration
|
|
SetupCustomizeStep {
|
|
id: step2
|
|
selectedScaleRatio: root.selectedScaleRatio
|
|
selectedBarPosition: root.selectedBarPosition
|
|
selectedDimDesktop: root.selectedDimDesktop
|
|
onScaleRatioChanged: function (ratio) {
|
|
root.selectedScaleRatio = ratio
|
|
root.applyUISettings()
|
|
}
|
|
onBarPositionChanged: function (position) {
|
|
root.selectedBarPosition = position
|
|
root.applyUISettings()
|
|
}
|
|
onDimDesktopChanged: function (dim) {
|
|
root.selectedDimDesktop = dim
|
|
root.applyUISettings()
|
|
}
|
|
}
|
|
|
|
// Step 3: Appearance - Dark mode and color source
|
|
SetupAppearanceStep {
|
|
id: step3
|
|
}
|
|
}
|
|
}
|
|
|
|
// Elegant divider
|
|
Rectangle {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 1
|
|
color: Color.mOutline
|
|
opacity: 0.2
|
|
}
|
|
|
|
// Modern progress indicator with labels
|
|
Item {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 32
|
|
|
|
RowLayout {
|
|
anchors.centerIn: parent
|
|
spacing: Style.marginM
|
|
|
|
Repeater {
|
|
model: [{
|
|
"icon": "sparkles",
|
|
"label": "Welcome"
|
|
}, {
|
|
"icon": "image",
|
|
"label": "Wallpaper"
|
|
}, {
|
|
"icon": "settings",
|
|
"label": "Customize"
|
|
}, {
|
|
"icon": "palette",
|
|
"label": "Appearance"
|
|
}]
|
|
delegate: RowLayout {
|
|
spacing: Style.marginS
|
|
|
|
Rectangle {
|
|
width: 24
|
|
height: 24
|
|
radius: width / 2
|
|
color: index <= currentStep ? Color.mPrimary : Color.mSurfaceVariant
|
|
border.color: index === currentStep ? Color.mPrimary : "transparent"
|
|
border.width: index === currentStep ? 2 : 0
|
|
|
|
NIcon {
|
|
icon: modelData.icon
|
|
pointSize: Style.fontSizeS
|
|
color: index <= currentStep ? Color.mOnPrimary : Color.mOnSurfaceVariant
|
|
anchors.centerIn: parent
|
|
}
|
|
|
|
Behavior on color {
|
|
ColorAnimation {
|
|
duration: Style.animationNormal
|
|
}
|
|
}
|
|
}
|
|
|
|
NText {
|
|
text: modelData.label
|
|
pointSize: Style.fontSizeS
|
|
color: index <= currentStep ? Color.mPrimary : Color.mOnSurfaceVariant
|
|
font.weight: index === currentStep ? Style.fontWeightBold : Style.fontWeightRegular
|
|
|
|
Behavior on color {
|
|
ColorAnimation {
|
|
duration: Style.animationNormal
|
|
}
|
|
}
|
|
}
|
|
|
|
// Connector line
|
|
Rectangle {
|
|
width: 40
|
|
height: 2
|
|
radius: 1
|
|
color: index < currentStep ? Color.mPrimary : Color.mSurfaceVariant
|
|
visible: index < totalSteps - 1
|
|
|
|
Behavior on color {
|
|
ColorAnimation {
|
|
duration: Style.animationNormal
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Smooth navigation buttons
|
|
Item {
|
|
Layout.fillWidth: true
|
|
Layout.preferredHeight: 44
|
|
Layout.topMargin: Style.marginS
|
|
|
|
RowLayout {
|
|
anchors.fill: parent
|
|
spacing: Style.marginM
|
|
|
|
NButton {
|
|
text: "Skip Setup"
|
|
outlined: true
|
|
visible: currentStep === 0
|
|
Layout.preferredHeight: 44
|
|
onClicked: {
|
|
root.completeSetup()
|
|
}
|
|
}
|
|
|
|
Item {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
NButton {
|
|
text: "← Back"
|
|
outlined: true
|
|
visible: currentStep > 0
|
|
Layout.preferredHeight: 44
|
|
onClicked: {
|
|
if (currentStep > 0) {
|
|
currentStep--
|
|
}
|
|
}
|
|
}
|
|
|
|
NButton {
|
|
text: currentStep === totalSteps - 1 ? "All Done!" : "Continue →"
|
|
Layout.preferredHeight: 44
|
|
onClicked: {
|
|
if (currentStep < totalSteps - 1) {
|
|
currentStep++
|
|
} else {
|
|
root.completeSetup()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function completeSetup() {
|
|
Logger.log("SetupWizard", "Completing setup with selected options")
|
|
|
|
if (selectedWallpaperDirectory !== Settings.data.wallpaper.directory) {
|
|
Settings.data.wallpaper.directory = selectedWallpaperDirectory
|
|
WallpaperService.refreshWallpapersList()
|
|
}
|
|
|
|
if (selectedWallpaper !== "") {
|
|
WallpaperService.changeWallpaper(selectedWallpaper, undefined)
|
|
}
|
|
|
|
Settings.data.general.scaleRatio = selectedScaleRatio
|
|
Settings.data.bar.position = selectedBarPosition
|
|
Settings.data.general.dimDesktop = selectedDimDesktop
|
|
Settings.data.general.setupCompleted = true
|
|
|
|
Settings.saveImmediate()
|
|
Logger.log("SetupWizard", "Setup completed successfully")
|
|
root.close()
|
|
}
|
|
|
|
function applyWallpaperSettings() {
|
|
if (selectedWallpaperDirectory !== Settings.data.wallpaper.directory) {
|
|
Settings.data.wallpaper.directory = selectedWallpaperDirectory
|
|
WallpaperService.refreshWallpapersList()
|
|
}
|
|
|
|
if (selectedWallpaper !== "") {
|
|
WallpaperService.changeWallpaper(selectedWallpaper, undefined)
|
|
}
|
|
}
|
|
|
|
function applyUISettings() {
|
|
Settings.data.general.scaleRatio = selectedScaleRatio
|
|
Settings.data.bar.position = selectedBarPosition
|
|
Settings.data.general.dimDesktop = selectedDimDesktop
|
|
}
|
|
|
|
Component.onCompleted: {
|
|
Logger.log("SetupWizard", "Setup wizard opened")
|
|
// Initialize selections from existing settings to avoid overwriting user config
|
|
if (Settings && Settings.data) {
|
|
selectedScaleRatio = Settings.data.general.scaleRatio
|
|
selectedBarPosition = Settings.data.bar.position
|
|
selectedDimDesktop = Settings.data.general.dimDesktop
|
|
selectedWallpaperDirectory = Settings.data.wallpaper.directory || Settings.defaultWallpapersDirectory
|
|
}
|
|
}
|
|
}
|