//@ pragma UseQApplication //@ pragma Env QT_QUICK_FLICKABLE_WHEEL_DECELERATION=10000 // launched via qs -p ~/.config/quickshell/$qsConfig/settings.qml import QtQuick import QtQuick.Controls import QtQuick.Window import QtQuick.Layouts import qs import qs.common import qs.common.widgets ApplicationWindow { id: root property real contentPadding: 8 property var pages: [ { name: "About", icon: "info", component: "settings/About.qml" } ] property int currentPage: 0 visible: true onClosing: Qt.quit() title: "hydro-os Settings" minimumWidth: 600 minimumHeight: 400 width: 110 height: 750 color: Appearance.m3colors.m3background ColumnLayout { anchors { fill: parent margins: contentPadding } Keys.onPressed: (event) => { if (event.modifiers === Qt.Key_PageDown) { root.currentPage = Math.min(root.currentPage + 1, root.pages.length - 1); event.accepted = true; } else if (event.key === Qt.Key_PageUp) { root.currentPage = Math.max(root.currentPage - 1, 0); event.accepted = true; } else if (event.key === Qt.Key_Tab) { root.currentPage = (root.currentPage + 1) % root.pages.length; event.accepted = true; } else if (event.key === Qt.Key_BackTab ) { root.currentPage = (root.currentPage - 1 + root.pages.length) % root.pages.length; event.accepted = true; } } // Window content with navigation rail and content pane RowLayout { Layout.fillWidth: true Layout.fillHeight: true spacing: contentPadding Item { id: navRailWrapper Layout.fillHeight: true Layout.margins: 5 implicitWidth: navRail.expanded ? 150 : fab.baseSize Behavior on implicitWidth { animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) } NavigationRail { id: navRail anchors { left: parent.left top: parent.top bottom: parent.bottom } spacing: 10 expanded: root.width > 900 NavigationRailExpandButton { focus: root.visible } FloatingActionButton { id: fab iconText: "edit" buttonText: "Edit config" expanded: navRail.expanded onClicked: { Qt.openUrlExternally(`${Directories.config}/hydro-os/config.json`); } StyledToolTip { extraVisibleCondition: !navRail.expanded content: "Edit shell config file" } } NavigationRailTabArray { currentIndex: root.currentPage expanded: navRail.expanded Repeater { model: root.pages NavigationRailButton { required property var index required property var modelData toggled: root.currentPage === index onClicked: root.currentPage = index; expanded: navRail.expanded buttonIcon: modelData.icon buttonText: modelData.name showToggledHighlight: false } } } Item { Layout.fillHeight: true } } } Rectangle { Layout.fillWidth: true Layout.fillHeight: true color: Appearance.m3colors.m3surfaceContainerLow radius: Appearance.rounding.windowRounding - root.contentPadding Loader { id: pageLoader anchors.fill: parent opacity: 1.0 Connections { target: root function onCurrentPageChanged() { if (pageLoader.sourceComponent !== root.pages[root.currentPage].component) { switchAnim.complete(); switchAnim.start(); } } } SequentialAnimation { id: switchAnim NumberAnimation { target: pageLoader properties: "opacity" from: 1 to: 0 duration: 100 easing.type: Appearance.animation.elementMoveExit.type easing.bezierCurve: Appearance.animationCurves.emphasizedFirstHalf } PropertyAction { target: pageLoader property: "source" value: root.pages[root.currentPage].component } NumberAnimation { target: pageLoader properties: "opacity" from: 0 to: 1 duration: 200 easing.type: Appearance.animation.elementMoveEnter.type easing.bezierCurve: Appearance.animationCurves.emphasizedFirstHalf } } } } } } }