diff --git a/modules/nexus/PageCompRegistry.qml b/modules/nexus/PageCompRegistry.qml index c5614a61..dde05a62 100644 --- a/modules/nexus/PageCompRegistry.qml +++ b/modules/nexus/PageCompRegistry.qml @@ -9,6 +9,7 @@ import qs.modules.nexus.common import qs.modules.nexus.pages import qs.modules.nexus.pages.audio import qs.modules.nexus.pages.bluetooth +import qs.modules.nexus.pages.panels import qs.modules.nexus.pages.wallandstyle QtObject { @@ -67,6 +68,36 @@ QtObject { AppVolumes {} } } + }, + + // System + Component { + PlaceholderComp {} + }, + Component { + PlaceholderComp {} + }, + + // Shell + Component { + // Panels + StackPage { + Component { + PanelsPage {} + } + Component { + DashboardPanel {} + } + Component { + TaskbarPanel {} + } + Component { + LauncherPanel {} + } + Component { + SidebarPanel {} + } + } } ] diff --git a/modules/nexus/common/SectionHeader.qml b/modules/nexus/common/SectionHeader.qml new file mode 100644 index 00000000..442990d5 --- /dev/null +++ b/modules/nexus/common/SectionHeader.qml @@ -0,0 +1,18 @@ +import QtQuick +import QtQuick.Layouts +import Caelestia.Config +import qs.components +import qs.services + +StyledText { + property bool first + + Layout.fillWidth: true + Layout.topMargin: first ? 0 : Tokens.spacing.largeIncreased - ((parent as ColumnLayout).spacing ?? 0) + Layout.bottomMargin: Tokens.spacing.extraSmall + Layout.leftMargin: Tokens.padding.small + + color: Colours.palette.m3onSurfaceVariant + font: Tokens.font.label.medium + elide: Text.ElideRight +} diff --git a/modules/nexus/common/StepperRow.qml b/modules/nexus/common/StepperRow.qml new file mode 100644 index 00000000..f15afa83 --- /dev/null +++ b/modules/nexus/common/StepperRow.qml @@ -0,0 +1,64 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import Caelestia.Config +import qs.components +import qs.components.controls +import qs.services +import qs.modules.nexus.common + +ConnectedRect { + id: root + + property alias label: label.text + property string subtext + property real value + property real from: 0 + property real to: 99 + property real stepSize: 1 + + signal moved(value: real) + + implicitHeight: rowLayout.implicitHeight + rowLayout.anchors.margins * 2 + + RowLayout { + id: rowLayout + + anchors.fill: parent + anchors.margins: Tokens.padding.medium + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.rightMargin: Tokens.padding.largeIncreased + spacing: Tokens.spacing.medium + + ColumnLayout { + Layout.fillWidth: true + spacing: 0 + + StyledText { + id: label + + Layout.fillWidth: true + font: Tokens.font.body.small + elide: Text.ElideRight + } + + StyledText { + Layout.fillWidth: true + visible: root.subtext + text: root.subtext + color: Colours.palette.m3outline + font: Tokens.font.label.small + elide: Text.ElideRight + } + } + + CustomSpinBox { + min: root.from + max: root.to + step: root.stepSize + value: root.value + onValueModified: v => root.moved(v) + } + } +} diff --git a/modules/nexus/pages/PanelsPage.qml b/modules/nexus/pages/PanelsPage.qml new file mode 100644 index 00000000..cdfa27b3 --- /dev/null +++ b/modules/nexus/pages/PanelsPage.qml @@ -0,0 +1,114 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import Caelestia.Config +import qs.components +import qs.services +import qs.modules.nexus.common + +PageBase { + id: root + + title: qsTr("Panels") + + ColumnLayout { + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + width: root.cappedWidth + spacing: Tokens.spacing.extraSmall / 2 + + NavRow { + first: true + icon: "dashboard" + label: qsTr("Dashboard") + status: Config.dashboard.enabled ? qsTr("Enabled") : qsTr("Disabled") + target: 1 + } + + NavRow { + icon: "dock_to_bottom" + label: qsTr("Taskbar") + status: Config.bar.persistent ? qsTr("Always visible") : qsTr("Reveal on hover") + target: 2 + } + + NavRow { + icon: "apps" + label: qsTr("Launcher") + status: Config.launcher.enabled ? qsTr("Enabled") : qsTr("Disabled") + target: 3 + } + + NavRow { + last: true + icon: "dock_to_right" + label: qsTr("Sidebar") + status: Config.sidebar.enabled ? qsTr("Enabled") : qsTr("Disabled") + target: 4 + } + } + + component NavRow: ConnectedRect { + id: navRow + + property alias icon: icon.text + property alias label: label.text + property alias status: status.text + property int target + + Layout.fillWidth: true + implicitHeight: navLayout.implicitHeight + navLayout.anchors.topMargin + navLayout.anchors.bottomMargin + + StateLayer { + onClicked: root.nState.openSubPage(navRow.target) + } + + RowLayout { + id: navLayout + + anchors.fill: parent + anchors.leftMargin: Tokens.padding.largeIncreased + anchors.rightMargin: Tokens.padding.largeIncreased + anchors.topMargin: Tokens.padding.medium + anchors.bottomMargin: Tokens.padding.medium + spacing: Tokens.spacing.medium + + MaterialIcon { + id: icon + + color: Colours.palette.m3onSurfaceVariant + font: Tokens.font.icon.medium + } + + ColumnLayout { + Layout.fillWidth: true + spacing: 0 + + StyledText { + id: label + + Layout.fillWidth: true + font: Tokens.font.body.small + elide: Text.ElideRight + } + + StyledText { + id: status + + Layout.fillWidth: true + color: Colours.palette.m3outline + font: Tokens.font.label.small + elide: Text.ElideRight + animate: true + } + } + + MaterialIcon { + text: "chevron_right" + color: Colours.palette.m3onSurfaceVariant + font: Tokens.font.icon.medium + } + } + } +} diff --git a/modules/nexus/pages/panels/DashboardPanel.qml b/modules/nexus/pages/panels/DashboardPanel.qml new file mode 100644 index 00000000..64d0292e --- /dev/null +++ b/modules/nexus/pages/panels/DashboardPanel.qml @@ -0,0 +1,146 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import Caelestia.Config +import qs.components +import qs.modules.nexus.common + +PageBase { + id: root + + title: qsTr("Dashboard") + isSubPage: true + + ColumnLayout { + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + width: root.cappedWidth + spacing: Tokens.spacing.extraSmall / 2 + + // General + SectionHeader { + first: true + text: qsTr("General") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Enabled") + checked: Config.dashboard.enabled + onToggled: GlobalConfig.dashboard.enabled = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Show on hover") + subtext: qsTr("Reveal when the cursor reaches the screen edge") + checked: Config.dashboard.showOnHover + onToggled: GlobalConfig.dashboard.showOnHover = checked + } + + // Tabs + SectionHeader { + text: qsTr("Tabs") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Dashboard") + checked: Config.dashboard.showDashboard + onToggled: GlobalConfig.dashboard.showDashboard = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Media") + checked: Config.dashboard.showMedia + onToggled: GlobalConfig.dashboard.showMedia = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Performance") + checked: Config.dashboard.showPerformance + onToggled: GlobalConfig.dashboard.showPerformance = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Weather") + checked: Config.dashboard.showWeather + onToggled: GlobalConfig.dashboard.showWeather = checked + } + + // Performance widgets + SectionHeader { + text: qsTr("Performance widgets") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Battery") + checked: Config.dashboard.performance.showBattery + onToggled: GlobalConfig.dashboard.performance.showBattery = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("GPU") + checked: Config.dashboard.performance.showGpu + onToggled: GlobalConfig.dashboard.performance.showGpu = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("CPU") + checked: Config.dashboard.performance.showCpu + onToggled: GlobalConfig.dashboard.performance.showCpu = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Memory") + checked: Config.dashboard.performance.showMemory + onToggled: GlobalConfig.dashboard.performance.showMemory = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Storage") + checked: Config.dashboard.performance.showStorage + onToggled: GlobalConfig.dashboard.performance.showStorage = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Network") + checked: Config.dashboard.performance.showNetwork + onToggled: GlobalConfig.dashboard.performance.showNetwork = checked + } + + // Behaviour + SectionHeader { + text: qsTr("Behaviour") + } + + StepperRow { + Layout.fillWidth: true + first: true + last: true + label: qsTr("Drag threshold") + subtext: qsTr("Pixels dragged before the dashboard opens") + value: Config.dashboard.dragThreshold + from: 0 + to: 200 + stepSize: 5 + onMoved: v => GlobalConfig.dashboard.dragThreshold = v + } + } +} diff --git a/modules/nexus/pages/panels/LauncherPanel.qml b/modules/nexus/pages/panels/LauncherPanel.qml new file mode 100644 index 00000000..ffa2bfcb --- /dev/null +++ b/modules/nexus/pages/panels/LauncherPanel.qml @@ -0,0 +1,147 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import Caelestia.Config +import qs.components +import qs.modules.nexus.common + +PageBase { + id: root + + title: qsTr("Launcher") + isSubPage: true + + ColumnLayout { + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + width: root.cappedWidth + spacing: Tokens.spacing.extraSmall / 2 + + // General + SectionHeader { + first: true + text: qsTr("General") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Enabled") + checked: Config.launcher.enabled + onToggled: GlobalConfig.launcher.enabled = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Show on hover") + subtext: qsTr("Reveal when the cursor reaches the screen edge") + checked: Config.launcher.showOnHover + onToggled: GlobalConfig.launcher.showOnHover = checked + } + + // Display + SectionHeader { + text: qsTr("Display") + } + + StepperRow { + Layout.fillWidth: true + first: true + label: qsTr("Max items shown") + value: Config.launcher.maxShown + from: 1 + to: 20 + stepSize: 1 + onMoved: v => GlobalConfig.launcher.maxShown = v + } + + StepperRow { + Layout.fillWidth: true + label: qsTr("Max wallpapers") + value: Config.launcher.maxWallpapers + from: 1 + to: 30 + stepSize: 1 + onMoved: v => GlobalConfig.launcher.maxWallpapers = v + } + + StepperRow { + Layout.fillWidth: true + last: true + label: qsTr("Drag threshold") + subtext: qsTr("Pixels dragged before the launcher opens") + value: Config.launcher.dragThreshold + from: 0 + to: 200 + stepSize: 5 + onMoved: v => GlobalConfig.launcher.dragThreshold = v + } + + // Behaviour + SectionHeader { + text: qsTr("Behaviour") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Vim keybinds") + subtext: qsTr("Navigate results with Ctrl+hjkl") + checked: GlobalConfig.launcher.vimKeybinds + onToggled: GlobalConfig.launcher.vimKeybinds = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Enable dangerous actions") + subtext: qsTr("Allow actions that shut down or log out") + checked: GlobalConfig.launcher.enableDangerousActions + onToggled: GlobalConfig.launcher.enableDangerousActions = checked + } + + // Fuzzy search + SectionHeader { + text: qsTr("Fuzzy search") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Apps") + checked: GlobalConfig.launcher.useFuzzy.apps + onToggled: GlobalConfig.launcher.useFuzzy.apps = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Actions") + checked: GlobalConfig.launcher.useFuzzy.actions + onToggled: GlobalConfig.launcher.useFuzzy.actions = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Schemes") + checked: GlobalConfig.launcher.useFuzzy.schemes + onToggled: GlobalConfig.launcher.useFuzzy.schemes = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Variants") + checked: GlobalConfig.launcher.useFuzzy.variants + onToggled: GlobalConfig.launcher.useFuzzy.variants = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Wallpapers") + checked: GlobalConfig.launcher.useFuzzy.wallpapers + onToggled: GlobalConfig.launcher.useFuzzy.wallpapers = checked + } + } +} diff --git a/modules/nexus/pages/panels/SidebarPanel.qml b/modules/nexus/pages/panels/SidebarPanel.qml new file mode 100644 index 00000000..0ceaad69 --- /dev/null +++ b/modules/nexus/pages/panels/SidebarPanel.qml @@ -0,0 +1,46 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import Caelestia.Config +import qs.components +import qs.modules.nexus.common + +PageBase { + id: root + + title: qsTr("Sidebar") + isSubPage: true + + ColumnLayout { + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + width: root.cappedWidth + spacing: Tokens.spacing.extraSmall / 2 + + SectionHeader { + first: true + text: qsTr("General") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Enabled") + checked: Config.sidebar.enabled + onToggled: GlobalConfig.sidebar.enabled = checked + } + + StepperRow { + Layout.fillWidth: true + last: true + label: qsTr("Drag threshold") + subtext: qsTr("Pixels dragged before the sidebar opens") + value: Config.sidebar.dragThreshold + from: 0 + to: 200 + stepSize: 5 + onMoved: v => GlobalConfig.sidebar.dragThreshold = v + } + } +} diff --git a/modules/nexus/pages/panels/TaskbarPanel.qml b/modules/nexus/pages/panels/TaskbarPanel.qml new file mode 100644 index 00000000..9fc587ef --- /dev/null +++ b/modules/nexus/pages/panels/TaskbarPanel.qml @@ -0,0 +1,332 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import QtQuick.Layouts +import Caelestia.Config +import qs.components +import qs.modules.nexus.common + +PageBase { + id: root + + title: qsTr("Taskbar") + isSubPage: true + + ColumnLayout { + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + width: root.cappedWidth + spacing: Tokens.spacing.extraSmall / 2 + + // Behaviour + SectionHeader { + first: true + text: qsTr("Behaviour") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Persistent") + subtext: qsTr("Keep the bar visible at all times") + checked: Config.bar.persistent + onToggled: GlobalConfig.bar.persistent = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Show on hover") + subtext: qsTr("Reveal the bar when the cursor reaches the screen edge") + checked: Config.bar.showOnHover + onToggled: GlobalConfig.bar.showOnHover = checked + } + + StepperRow { + Layout.fillWidth: true + last: true + label: qsTr("Drag threshold") + subtext: qsTr("Pixels dragged before the bar reveals") + value: Config.bar.dragThreshold + from: 0 + to: 200 + stepSize: 5 + onMoved: v => GlobalConfig.bar.dragThreshold = v + } + + // Workspaces + SectionHeader { + text: qsTr("Workspaces") + } + + StepperRow { + Layout.fillWidth: true + first: true + label: qsTr("Shown") + subtext: qsTr("Number of workspaces displayed") + value: Config.bar.workspaces.shown + from: 1 + to: 20 + stepSize: 1 + onMoved: v => GlobalConfig.bar.workspaces.shown = v + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Active indicator") + checked: Config.bar.workspaces.activeIndicator + onToggled: GlobalConfig.bar.workspaces.activeIndicator = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Active trail") + checked: Config.bar.workspaces.activeTrail + onToggled: GlobalConfig.bar.workspaces.activeTrail = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Occupied background") + checked: Config.bar.workspaces.occupiedBg + onToggled: GlobalConfig.bar.workspaces.occupiedBg = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Show windows") + subtext: qsTr("Show icons of open windows on each workspace") + checked: Config.bar.workspaces.showWindows + onToggled: GlobalConfig.bar.workspaces.showWindows = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Windows on special workspaces") + checked: Config.bar.workspaces.showWindowsOnSpecialWorkspaces + onToggled: GlobalConfig.bar.workspaces.showWindowsOnSpecialWorkspaces = checked + } + + StepperRow { + Layout.fillWidth: true + label: qsTr("Max window icons") + value: Config.bar.workspaces.maxWindowIcons + from: 0 + to: 20 + stepSize: 1 + onMoved: v => GlobalConfig.bar.workspaces.maxWindowIcons = v + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Per-monitor workspaces") + subtext: qsTr("Show each monitor's workspaces independently") + checked: GlobalConfig.bar.workspaces.perMonitorWorkspaces + onToggled: GlobalConfig.bar.workspaces.perMonitorWorkspaces = checked + } + + // Active window + SectionHeader { + text: qsTr("Active window") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Compact") + checked: Config.bar.activeWindow.compact + onToggled: GlobalConfig.bar.activeWindow.compact = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Inverted") + checked: Config.bar.activeWindow.inverted + onToggled: GlobalConfig.bar.activeWindow.inverted = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Show on hover") + checked: Config.bar.activeWindow.showOnHover + onToggled: GlobalConfig.bar.activeWindow.showOnHover = checked + } + + // Tray + SectionHeader { + text: qsTr("Tray") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Background") + checked: Config.bar.tray.background + onToggled: GlobalConfig.bar.tray.background = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Recolour icons") + checked: Config.bar.tray.recolour + onToggled: GlobalConfig.bar.tray.recolour = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Compact") + checked: Config.bar.tray.compact + onToggled: GlobalConfig.bar.tray.compact = checked + } + + // Status icons + SectionHeader { + text: qsTr("Status icons") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Speakers") + checked: Config.bar.status.showAudio + onToggled: GlobalConfig.bar.status.showAudio = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Microphone") + checked: Config.bar.status.showMicrophone + onToggled: GlobalConfig.bar.status.showMicrophone = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Keyboard layout") + checked: Config.bar.status.showKbLayout + onToggled: GlobalConfig.bar.status.showKbLayout = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Network") + checked: Config.bar.status.showNetwork + onToggled: GlobalConfig.bar.status.showNetwork = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Wi-Fi") + checked: Config.bar.status.showWifi + onToggled: GlobalConfig.bar.status.showWifi = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Bluetooth") + checked: Config.bar.status.showBluetooth + onToggled: GlobalConfig.bar.status.showBluetooth = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Battery") + checked: Config.bar.status.showBattery + onToggled: GlobalConfig.bar.status.showBattery = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Caps lock") + checked: Config.bar.status.showLockStatus + onToggled: GlobalConfig.bar.status.showLockStatus = checked + } + + // Clock + SectionHeader { + text: qsTr("Clock") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Background") + checked: Config.bar.clock.background + onToggled: GlobalConfig.bar.clock.background = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Show date") + checked: Config.bar.clock.showDate + onToggled: GlobalConfig.bar.clock.showDate = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Show icon") + checked: Config.bar.clock.showIcon + onToggled: GlobalConfig.bar.clock.showIcon = checked + } + + // Scroll actions + SectionHeader { + text: qsTr("Scroll actions") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Workspaces") + subtext: qsTr("Scroll over the bar to switch workspaces") + checked: Config.bar.scrollActions.workspaces + onToggled: GlobalConfig.bar.scrollActions.workspaces = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Volume") + checked: Config.bar.scrollActions.volume + onToggled: GlobalConfig.bar.scrollActions.volume = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Brightness") + checked: Config.bar.scrollActions.brightness + onToggled: GlobalConfig.bar.scrollActions.brightness = checked + } + + // Popouts + SectionHeader { + text: qsTr("Popouts") + } + + ToggleRow { + Layout.fillWidth: true + first: true + text: qsTr("Active window") + checked: Config.bar.popouts.activeWindow + onToggled: GlobalConfig.bar.popouts.activeWindow = checked + } + + ToggleRow { + Layout.fillWidth: true + text: qsTr("Tray") + checked: Config.bar.popouts.tray + onToggled: GlobalConfig.bar.popouts.tray = checked + } + + ToggleRow { + Layout.fillWidth: true + last: true + text: qsTr("Status icons") + checked: Config.bar.popouts.statusIcons + onToggled: GlobalConfig.bar.popouts.statusIcons = checked + } + } +}