remove old Settings, rename new
Lint & Format (JS/TS) / lint-format (pull_request) Successful in 11s
Python / lint-format (pull_request) Successful in 18s
Python / test (pull_request) Successful in 46s
Lint & Format (Rust) / lint-format (pull_request) Successful in 1m39s
C++ / build (pull_request) Successful in 2m26s
Lint & Format (JS/TS) / lint-format (pull_request) Successful in 11s
Python / lint-format (pull_request) Successful in 18s
Python / test (pull_request) Successful in 46s
Lint & Format (Rust) / lint-format (pull_request) Successful in 1m39s
C++ / build (pull_request) Successful in 2m26s
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Io
|
||||
import ZShell
|
||||
import qs.Modules.Settings.Common
|
||||
import qs.Config
|
||||
import qs.Helpers
|
||||
import qs.Components
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
property string cliVersion
|
||||
readonly property int pluginCount: 0
|
||||
property string quickshellVersion
|
||||
|
||||
title: qsTr("About")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
Process {
|
||||
command: ["quickshell", "--version"]
|
||||
running: true
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: root.quickshellVersion = text.trim().split(" ")[1] ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
ConnectedRect {
|
||||
Layout.fillWidth: true
|
||||
first: true
|
||||
implicitHeight: hero.implicitHeight + Appearance.padding.extraLarge * 2
|
||||
last: true
|
||||
|
||||
ColumnLayout {
|
||||
id: hero
|
||||
|
||||
anchors.centerIn: parent
|
||||
spacing: Appearance.spacing.small
|
||||
width: parent.width - Appearance.padding.largeIncreased * 2
|
||||
|
||||
CustomText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: Appearance.spacing.small
|
||||
font.pointSize: Appearance.font.size.large
|
||||
text: "ZShell"
|
||||
}
|
||||
|
||||
CustomText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
color: DynamicColors.palette.m3onSurfaceVariant
|
||||
font.pointSize: Appearance.font.size.medium
|
||||
text: ZUtils.version ? `v${ZUtils.version}` : "…"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// System
|
||||
SectionHeader {
|
||||
text: qsTr("System")
|
||||
}
|
||||
|
||||
InfoRow {
|
||||
first: true
|
||||
label: qsTr("Hostname")
|
||||
value: SystemInfo.hostname
|
||||
}
|
||||
|
||||
InfoRow {
|
||||
label: qsTr("Device")
|
||||
value: SystemInfo.device
|
||||
}
|
||||
|
||||
InfoRow {
|
||||
label: qsTr("Distro")
|
||||
value: SystemInfo.osPrettyName || SystemInfo.osName
|
||||
}
|
||||
|
||||
InfoRow {
|
||||
label: qsTr("Kernel")
|
||||
value: SystemInfo.kernel
|
||||
}
|
||||
|
||||
InfoRow {
|
||||
label: qsTr("Firmware")
|
||||
last: true
|
||||
value: SystemInfo.firmware
|
||||
}
|
||||
|
||||
// Software
|
||||
SectionHeader {
|
||||
text: qsTr("Software")
|
||||
}
|
||||
|
||||
InfoRow {
|
||||
first: true
|
||||
label: qsTr("Shell")
|
||||
value: ZUtils.version || "…"
|
||||
}
|
||||
|
||||
InfoRow {
|
||||
label: qsTr("Quickshell")
|
||||
value: root.quickshellVersion || "…"
|
||||
}
|
||||
|
||||
InfoRow {
|
||||
label: qsTr("Qt")
|
||||
last: true
|
||||
value: ZUtils.qtVersion || "…"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import qs.Components
|
||||
import qs.Config
|
||||
import qs.Helpers
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("All apps")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
Repeater {
|
||||
id: list
|
||||
|
||||
model: [...DesktopEntries.applications.values].sort((a, b) => a.name.localeCompare(b.name))
|
||||
|
||||
ConnectedRect {
|
||||
id: appItem
|
||||
|
||||
required property int index
|
||||
required property DesktopEntry modelData
|
||||
|
||||
Layout.fillWidth: true
|
||||
first: index === 0
|
||||
implicitHeight: appRow.implicitHeight + appRow.anchors.margins * 2
|
||||
last: index === list.count - 1
|
||||
|
||||
StateLayer {
|
||||
onClicked: {
|
||||
root.sState.selectedApp = appItem.modelData;
|
||||
root.sState.openSubPage(2);
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: appRow
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Appearance.padding.largeIncreased
|
||||
anchors.margins: Appearance.padding.normal
|
||||
anchors.rightMargin: Appearance.padding.largeIncreased
|
||||
spacing: Appearance.spacing.small
|
||||
|
||||
IconImage {
|
||||
asynchronous: true
|
||||
implicitSize: Math.round(Appearance.font.size.large * 1.8)
|
||||
source: Quickshell.iconPath(appItem.modelData.icon, "image-missing")
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Appearance.font.size.small
|
||||
text: appItem.modelData.name
|
||||
}
|
||||
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
color: DynamicColors.palette.m3outline
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Appearance.font.size.small
|
||||
text: (appItem.modelData.comment || appItem.modelData.genericName) ?? ""
|
||||
visible: text
|
||||
}
|
||||
}
|
||||
|
||||
MaterialIcon {
|
||||
color: DynamicColors.palette.m3primary
|
||||
fill: 1
|
||||
font.pointSize: Appearance.font.size.small
|
||||
text: "favorite"
|
||||
visible: Strings.testRegexList(Config.launcher.favoriteApps, appItem.modelData.id)
|
||||
}
|
||||
|
||||
MaterialIcon {
|
||||
color: DynamicColors.palette.m3onSurfaceVariant
|
||||
font.pointSize: Appearance.font.size.medium
|
||||
text: "chevron_right"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import qs.Components
|
||||
import qs.Config
|
||||
import qs.Helpers
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
readonly property DesktopEntry app: sState.selectedApp
|
||||
readonly property bool favoriteByRegex: app && matchedByRegex(Config.launcher.favoriteApps, app.id)
|
||||
readonly property bool hiddenByRegex: app && matchedByRegex(Config.launcher.hiddenApps, app.id)
|
||||
|
||||
function isRegexEntry(s: string): bool {
|
||||
return /^\^.*\$$/.test(s);
|
||||
}
|
||||
|
||||
function matchedByRegex(filterList: list<string>, id: string): bool {
|
||||
return filterList.some(f => isRegexEntry(f) && new RegExp(f).test(id));
|
||||
}
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("App info")
|
||||
|
||||
onAppChanged: {
|
||||
// Auto close when app lost
|
||||
if (!app)
|
||||
sState.closeSubPage();
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
// Header
|
||||
RowLayout {
|
||||
Layout.bottomMargin: Appearance.spacing.large
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Appearance.padding.small
|
||||
spacing: Appearance.spacing.large
|
||||
|
||||
IconImage {
|
||||
asynchronous: true
|
||||
implicitSize: Math.round(Appearance.font.size.large * 3)
|
||||
source: Quickshell.iconPath(root.app?.icon, "image-missing")
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
font.pointSize: Appearance.font.size.medium
|
||||
text: root.app?.name ?? ""
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
color: DynamicColors.palette.m3outline
|
||||
font.pointSize: Appearance.font.size.small
|
||||
text: (root.app?.comment || root.app?.genericName) ?? ""
|
||||
visible: text
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Launcher
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("Launcher")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: root.app && Strings.testRegexList(Config.launcher.favoriteApps, root.app.id)
|
||||
enabled: !root.favoriteByRegex
|
||||
first: true
|
||||
subtext: root.favoriteByRegex ? qsTr("Matched by a regex in favoriteApps — edit the config file to change") : qsTr("Pin to the bottom of the launcher")
|
||||
text: qsTr("Favorite")
|
||||
|
||||
onToggled: {
|
||||
const apps = Config.launcher.favoriteApps;
|
||||
Config.launcher.favoriteApps = checked ? [...apps, root.app.id] : apps.filter(a => a !== root.app.id);
|
||||
}
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: root.app && Strings.testRegexList(Config.launcher.hiddenApps, root.app.id)
|
||||
enabled: !root.hiddenByRegex
|
||||
last: true
|
||||
subtext: root.hiddenByRegex ? qsTr("Matched by a regex in hiddenApps — edit the config file to change") : qsTr("Hide from the launcher")
|
||||
text: qsTr("Hidden")
|
||||
|
||||
onToggled: {
|
||||
const apps = Config.launcher.hiddenApps;
|
||||
Config.launcher.hiddenApps = checked ? [...apps, root.app.id] : apps.filter(a => a !== root.app.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Details
|
||||
SectionHeader {
|
||||
text: qsTr("Details")
|
||||
}
|
||||
|
||||
WrapInfoRow {
|
||||
id: appId
|
||||
|
||||
first: true
|
||||
label: qsTr("App ID")
|
||||
labelComp.Layout.preferredWidth: Math.max(labelComp.implicitWidth, command.labelComp.implicitWidth)
|
||||
value: root.app?.id ?? ""
|
||||
}
|
||||
|
||||
WrapInfoRow {
|
||||
id: command
|
||||
|
||||
label: qsTr("Command")
|
||||
labelComp.Layout.preferredWidth: Math.max(labelComp.implicitWidth, appId.labelComp.implicitWidth)
|
||||
last: true
|
||||
value: (root.app?.command ?? []).join(" ")
|
||||
}
|
||||
}
|
||||
|
||||
component WrapInfoRow: ConnectedRect {
|
||||
id: row
|
||||
|
||||
property alias label: label.text
|
||||
readonly property alias labelComp: label
|
||||
property alias value: value.text
|
||||
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: rowLayout.implicitHeight + rowLayout.anchors.margins * 2
|
||||
|
||||
RowLayout {
|
||||
id: rowLayout
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Appearance.padding.largeIncreased
|
||||
anchors.margins: Appearance.padding.normal
|
||||
anchors.rightMargin: Appearance.padding.largeIncreased
|
||||
spacing: Appearance.spacing.small
|
||||
|
||||
CustomText {
|
||||
id: label
|
||||
|
||||
Layout.alignment: Qt.AlignTop
|
||||
font.pointSize: Appearance.font.size.small
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
CustomText {
|
||||
id: value
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: implicitWidth + 1 // Whyyyyyyyyy
|
||||
color: DynamicColors.palette.m3onSurfaceVariant
|
||||
font.pointSize: Appearance.font.size.small
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Widgets
|
||||
import ZShell
|
||||
import qs.Helpers
|
||||
import qs.Components
|
||||
import qs.Config
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
title: qsTr("Apps")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
// Default applications
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("Default applications")
|
||||
}
|
||||
|
||||
DefaultRow {
|
||||
first: true
|
||||
icon: "terminal"
|
||||
status: Config.general.apps.terminal.join(" ")
|
||||
text: qsTr("Terminal")
|
||||
|
||||
onSelected: app => Config.general.apps.terminal = app.command
|
||||
}
|
||||
|
||||
DefaultRow {
|
||||
icon: "volume_up"
|
||||
status: Config.general.apps.audio.join(" ")
|
||||
text: qsTr("Audio")
|
||||
|
||||
onSelected: app => Config.general.apps.audio = app.command
|
||||
}
|
||||
|
||||
DefaultRow {
|
||||
icon: "play_circle"
|
||||
status: Config.general.apps.playback.join(" ")
|
||||
text: qsTr("Media playback")
|
||||
|
||||
onSelected: app => Config.general.apps.playback = app.command
|
||||
}
|
||||
|
||||
DefaultRow {
|
||||
icon: "folder"
|
||||
last: true
|
||||
status: Config.general.apps.explorer.join(" ")
|
||||
text: qsTr("File manager")
|
||||
|
||||
onSelected: app => Config.general.apps.explorer = app.command
|
||||
}
|
||||
|
||||
// Library
|
||||
SectionHeader {
|
||||
text: qsTr("Library")
|
||||
}
|
||||
|
||||
NavRow {
|
||||
first: true
|
||||
icon: "apps"
|
||||
last: true
|
||||
status: qsTr("Browse installed apps, set favorites and hidden")
|
||||
text: qsTr("All apps")
|
||||
|
||||
onClicked: root.sState.openSubPage(1)
|
||||
}
|
||||
}
|
||||
|
||||
component DefaultRow: PopupRow {
|
||||
id: row
|
||||
|
||||
readonly property int popupHeight: root.flickable.height - y + root.flickable.contentY - Appearance.padding.large - Appearance.padding.extraLarge
|
||||
|
||||
signal selected(app: DesktopEntry)
|
||||
|
||||
keepPopupAsChild: {
|
||||
if (root.sState.animatingContainer || root.opacity < 1)
|
||||
return true;
|
||||
|
||||
let p = root.parent;
|
||||
while (p && p.objectName !== "PageContainer")
|
||||
p = p.parent;
|
||||
return p?.opacity < 1;
|
||||
}
|
||||
popup.topMovement: Appearance.padding.large
|
||||
|
||||
Loader {
|
||||
active: row.popup.animDriver > 0
|
||||
anchors.centerIn: parent
|
||||
|
||||
sourceComponent: VerticalFadeListView {
|
||||
id: list
|
||||
|
||||
fadeAmount: 0.05
|
||||
implicitHeight: ZUtils.clamp(row.popupHeight, 200, 800)
|
||||
implicitWidth: 300
|
||||
model: {
|
||||
const apps = [...DesktopEntries.applications.values];
|
||||
const favorited = new Set(apps.filter(a => Strings.testRegexList(Config.launcher.favoriteApps, a.id)));
|
||||
return apps.sort((a, b) => (favorited.has(b) - favorited.has(a)) || a.name.localeCompare(b.name));
|
||||
}
|
||||
|
||||
delegate: StateLayer {
|
||||
id: appItem
|
||||
|
||||
required property int index
|
||||
required property DesktopEntry modelData
|
||||
|
||||
anchors.fill: undefined
|
||||
anchors.left: list.contentItem.left
|
||||
anchors.right: list.contentItem.right
|
||||
implicitHeight: itemLayout.implicitHeight + itemLayout.anchors.margins * 2
|
||||
radius: Appearance.rounding.small
|
||||
|
||||
onClicked: {
|
||||
row.popup.open = false;
|
||||
row.selected(modelData);
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: itemLayout
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: Appearance.padding.normal
|
||||
spacing: Appearance.spacing.small
|
||||
|
||||
IconImage {
|
||||
asynchronous: true
|
||||
implicitSize: Math.round(Appearance.font.size.large * 1.8)
|
||||
source: Quickshell.iconPath(appItem.modelData.icon, "image-missing")
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Appearance.font.size.small
|
||||
text: appItem.modelData.name
|
||||
}
|
||||
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
color: DynamicColors.palette.m3outline
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Appearance.font.size.small
|
||||
text: (appItem.modelData.comment || appItem.modelData.genericName) ?? ""
|
||||
visible: text
|
||||
}
|
||||
}
|
||||
|
||||
MaterialIcon {
|
||||
color: DynamicColors.palette.m3primary
|
||||
fill: 1
|
||||
font.pointSize: Appearance.font.size.small
|
||||
text: "favorite"
|
||||
visible: Strings.testRegexList(Config.launcher.favoriteApps, appItem.modelData.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Services.Pipewire
|
||||
import qs.Modules.Settings.Common
|
||||
import qs.Helpers
|
||||
import qs.Components
|
||||
import qs.Config
|
||||
import qs.Daemons
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("App volumes")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
CustomText {
|
||||
Layout.bottomMargin: Appearance.spacing.small
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Appearance.padding.small
|
||||
color: DynamicColors.palette.m3outline
|
||||
font.pointSize: Appearance.font.size.small
|
||||
text: qsTr("Adjust the volume of individual apps currently playing audio.")
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
ItemList {
|
||||
id: streamList
|
||||
|
||||
color: list.count === 0 ? DynamicColors.tPalette.m3surfaceContainer : "transparent"
|
||||
first: true
|
||||
last: true
|
||||
list.spacing: Appearance.spacing.extraSmall / 2
|
||||
placeholderIcon: "music_off"
|
||||
placeholderText: qsTr("No apps playing audio")
|
||||
showList: true
|
||||
|
||||
delegate: SliderRow {
|
||||
id: stream
|
||||
|
||||
required property int index
|
||||
required property PwNode modelData
|
||||
|
||||
anchors.left: streamList.list.contentItem.left
|
||||
anchors.right: streamList.list.contentItem.right
|
||||
enabled: !stream.modelData?.audio?.muted
|
||||
first: index === 0
|
||||
icon: Icons.getVolumeIcon(stream.modelData?.audio?.volume ?? 0, stream.modelData?.audio?.muted ?? false)
|
||||
label: Audio.getStreamName(stream.modelData)
|
||||
last: index === streamList.list.count - 1
|
||||
value: stream.modelData?.audio?.volume ?? 0
|
||||
valueLabel: Math.round(value * 100) + "%"
|
||||
|
||||
onMoved: v => Audio.setStreamVolume(stream.modelData, v)
|
||||
}
|
||||
model: ScriptModel {
|
||||
values: [...Audio.streams]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.Daemons
|
||||
import qs.Config
|
||||
import qs.Components
|
||||
import qs.Modules.Settings.Common
|
||||
import qs.Helpers
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
title: qsTr("Audio")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
// Output
|
||||
SliderRow {
|
||||
enabled: !Audio.muted
|
||||
first: true
|
||||
icon: Icons.getVolumeIcon(Audio.volume, Audio.muted)
|
||||
label: qsTr("Output")
|
||||
value: Audio.volume
|
||||
valueLabel: Math.round(value * 100) + "%"
|
||||
|
||||
onMoved: v => Audio.setVolume(v)
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Audio.muted
|
||||
text: qsTr("Muted")
|
||||
|
||||
onToggled: Audio.setStreamMuted(Audio.sink, checked)
|
||||
}
|
||||
|
||||
AudioDeviceList {
|
||||
currentId: Audio.sink?.id ?? -1
|
||||
iconName: "speaker"
|
||||
nodes: Audio.sinks
|
||||
placeholderIcon: "speaker"
|
||||
placeholderText: qsTr("No output devices")
|
||||
|
||||
onSelected: node => Audio.setAudioSink(node)
|
||||
}
|
||||
|
||||
// Input
|
||||
SliderRow {
|
||||
Layout.topMargin: Appearance.spacing.large - parent.spacing
|
||||
enabled: !Audio.sourceMuted
|
||||
first: true
|
||||
icon: Icons.getMicVolumeIcon(Audio.sourceVolume, Audio.sourceMuted)
|
||||
label: qsTr("Input")
|
||||
value: Audio.sourceVolume
|
||||
valueLabel: Math.round(value * 100) + "%"
|
||||
|
||||
onMoved: v => Audio.setSourceVolume(v)
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Audio.sourceMuted
|
||||
text: qsTr("Muted")
|
||||
|
||||
onToggled: Audio.setStreamMuted(Audio.source, checked)
|
||||
}
|
||||
|
||||
AudioDeviceList {
|
||||
currentId: Audio.source?.id ?? -1
|
||||
iconName: "mic"
|
||||
nodes: Audio.sources
|
||||
placeholderIcon: "mic_off"
|
||||
placeholderText: qsTr("No input devices")
|
||||
|
||||
onSelected: node => Audio.setAudioSource(node)
|
||||
}
|
||||
|
||||
// Per-app volumes
|
||||
ConnectedRect {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Appearance.spacing.large - parent.spacing
|
||||
first: true
|
||||
implicitHeight: appLayout.implicitHeight + appLayout.anchors.margins * 2
|
||||
last: true
|
||||
|
||||
StateLayer {
|
||||
onClicked: root.sState.openSubPage(1)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: appLayout
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: Appearance.padding.largeIncreased
|
||||
anchors.margins: Appearance.padding.normal
|
||||
anchors.rightMargin: Appearance.padding.largeIncreased
|
||||
spacing: Appearance.spacing.small
|
||||
|
||||
MaterialIcon {
|
||||
font.pointSize: Appearance.font.size.medium
|
||||
text: "tune"
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Appearance.font.size.small
|
||||
text: qsTr("App volumes")
|
||||
}
|
||||
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
animate: true
|
||||
color: DynamicColors.palette.m3outline
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Appearance.font.size.small
|
||||
text: Audio.streams.length === 0 ? qsTr("No apps playing audio") : Audio.streams.length === 1 ? qsTr("1 app playing audio") : qsTr("%1 apps playing audio").arg(Audio.streams.length)
|
||||
}
|
||||
}
|
||||
|
||||
MaterialIcon {
|
||||
color: DynamicColors.palette.m3onSurfaceVariant
|
||||
font.pointSize: Appearance.font.size.medium
|
||||
text: "chevron_right"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick.Layouts
|
||||
import qs.Config
|
||||
import qs.Components
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
readonly property list<MenuItem> clockFormats: [
|
||||
MenuItem {
|
||||
text: qsTr("Long format")
|
||||
value: "dddd d MMM - hh:mm"
|
||||
},
|
||||
MenuItem {
|
||||
text: qsTr("Short format")
|
||||
value: "ddd d MMM - hh:mm"
|
||||
},
|
||||
MenuItem {
|
||||
text: qsTr("Time only")
|
||||
value: "hh:mm"
|
||||
},
|
||||
MenuItem {
|
||||
text: qsTr("Long format seconds")
|
||||
value: "dddd d MMM - hh:mm:ss"
|
||||
},
|
||||
MenuItem {
|
||||
text: qsTr("Short format seconds")
|
||||
value: "ddd d MMM - hh:mm:ss"
|
||||
},
|
||||
MenuItem {
|
||||
text: qsTr("Time only seconds")
|
||||
value: "hh:mm:ss"
|
||||
}
|
||||
]
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("Clock")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
SelectRow {
|
||||
Layout.topMargin: Appearance.spacing.extraSmall / 2 - parent.spacing
|
||||
active: root.clockFormats.find(item => item.value === Config.general.dateFormat)
|
||||
first: true
|
||||
last: true
|
||||
menuItems: root.clockFormats
|
||||
subtext: qsTr("Change how time is displayed in the widget")
|
||||
text: qsTr("Time format")
|
||||
|
||||
onSelected: item => {
|
||||
Config.general.dateFormat = item.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick.Layouts
|
||||
import qs.Config
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("System icons")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
// Visible icons
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("Visible icons")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.bar.tray.showAudio
|
||||
first: true
|
||||
text: qsTr("Speakers")
|
||||
|
||||
onToggled: Config.bar.tray.showAudio = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.bar.tray.showMicrophone
|
||||
text: qsTr("Microphone")
|
||||
|
||||
onToggled: Config.bar.tray.showMicrophone = checked
|
||||
}
|
||||
|
||||
//////// FOR LATER:
|
||||
// ToggleRow {
|
||||
// checked: Config.bar.tray.showNetwork
|
||||
// text: qsTr("Network")
|
||||
//
|
||||
// onToggled: Config.bar.tray.showNetwork = checked
|
||||
// }
|
||||
//
|
||||
// ToggleRow {
|
||||
// checked: Config.bar.tray.showWifi
|
||||
// text: qsTr("Wi-Fi")
|
||||
//
|
||||
// onToggled: Config.bar.tray.showWifi = checked
|
||||
// }
|
||||
//
|
||||
// ToggleRow {
|
||||
// checked: Config.bar.tray.showBluetooth
|
||||
// text: qsTr("Bluetooth")
|
||||
//
|
||||
// onToggled: Config.bar.tray.showBluetooth = checked
|
||||
// }
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.bar.tray.showPower
|
||||
last: true
|
||||
text: qsTr("Battery")
|
||||
|
||||
onToggled: Config.bar.tray.showPower = checked
|
||||
}
|
||||
|
||||
// Behaviour
|
||||
SectionHeader {
|
||||
text: qsTr("Behavior")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.bar.popouts.audio
|
||||
first: true
|
||||
subtext: qsTr("Show a details popout when hovering the audio icons")
|
||||
text: qsTr("Audio popout on hover")
|
||||
|
||||
onToggled: Config.bar.popouts.audio = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.bar.popouts.upower
|
||||
last: true
|
||||
subtext: qsTr("Show a details popout when hovering the power icon")
|
||||
text: qsTr("Power popout on hover")
|
||||
|
||||
onToggled: Config.bar.popouts.upower = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick.Layouts
|
||||
import qs.Config
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("Tray")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
SpinRow {
|
||||
first: true
|
||||
from: 12
|
||||
last: true
|
||||
stepSize: 1
|
||||
text: qsTr("Icon size")
|
||||
to: 24
|
||||
value: Config.bar.tray.trayIconSize
|
||||
|
||||
onMoved: value => Config.bar.tray.trayIconSize = value
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick.Layouts
|
||||
import qs.Config
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("Taskbar")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
// Behavior
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("Behavior")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.bar.autoHide
|
||||
first: true
|
||||
last: true
|
||||
subtext: qsTr("Hide the bar, reveal on hover")
|
||||
text: qsTr("Auto hide")
|
||||
|
||||
onToggled: Config.bar.autoHide = checked
|
||||
}
|
||||
|
||||
// Components
|
||||
SectionHeader {
|
||||
text: qsTr("Components")
|
||||
}
|
||||
|
||||
NavRow {
|
||||
first: true
|
||||
icon: "widgets"
|
||||
status: qsTr("System tray icons")
|
||||
text: qsTr("Tray")
|
||||
|
||||
onClicked: root.sState.openSubPage(6)
|
||||
}
|
||||
|
||||
NavRow {
|
||||
icon: "signal_cellular_alt"
|
||||
status: qsTr("Visible indicators")
|
||||
text: qsTr("Status icons")
|
||||
|
||||
onClicked: root.sState.openSubPage(7)
|
||||
}
|
||||
|
||||
NavRow {
|
||||
icon: "schedule"
|
||||
last: true
|
||||
status: qsTr("Date, icon, background")
|
||||
text: qsTr("Clock")
|
||||
|
||||
onClicked: root.sState.openSubPage(8)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.Config
|
||||
import qs.Components
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("Dashboard")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
// General
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("General")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.enabled
|
||||
first: true
|
||||
last: true
|
||||
text: qsTr("Enabled")
|
||||
|
||||
onToggled: Config.dashboard.enabled = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.Config
|
||||
import qs.Components
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("Launcher")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
// General
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("General")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.launcher.enabled
|
||||
first: true
|
||||
last: true
|
||||
text: qsTr("Enabled")
|
||||
|
||||
onToggled: Config.launcher.enabled = checked
|
||||
}
|
||||
|
||||
// Display
|
||||
SectionHeader {
|
||||
text: qsTr("Display")
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
first: true
|
||||
from: 1
|
||||
stepSize: 1
|
||||
text: qsTr("Max items shown")
|
||||
to: 20
|
||||
value: Config.launcher.maxAppsShown
|
||||
|
||||
onMoved: v => Config.launcher.maxShown = v
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
from: 1
|
||||
stepSize: 1
|
||||
text: qsTr("Max wallpapers")
|
||||
to: 30
|
||||
value: Config.launcher.maxWallpapers
|
||||
|
||||
onMoved: v => Config.launcher.maxWallpapers = v
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
from: 0
|
||||
last: true
|
||||
stepSize: 5
|
||||
subtext: qsTr("Pixels dragged before the launcher opens")
|
||||
text: qsTr("Drag threshold")
|
||||
to: 200
|
||||
value: Config.launcher.dragThreshold
|
||||
|
||||
onMoved: v => Config.launcher.dragThreshold = v
|
||||
}
|
||||
|
||||
// Behavior
|
||||
SectionHeader {
|
||||
text: qsTr("Behavior")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.launcher.enableDangerousActions
|
||||
first: true
|
||||
last: true
|
||||
subtext: qsTr("Allow actions that shut down or log out")
|
||||
text: qsTr("Enable dangerous actions")
|
||||
|
||||
onToggled: Config.launcher.enableDangerousActions = checked
|
||||
}
|
||||
|
||||
// Fuzzy search
|
||||
SectionHeader {
|
||||
text: qsTr("Fuzzy search")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.launcher.useFuzzy.apps
|
||||
first: true
|
||||
text: qsTr("Apps")
|
||||
|
||||
onToggled: Config.launcher.useFuzzy.apps = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.launcher.useFuzzy.actions
|
||||
text: qsTr("Actions")
|
||||
|
||||
onToggled: Config.launcher.useFuzzy.actions = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.launcher.useFuzzy.schemes
|
||||
text: qsTr("Schemes")
|
||||
|
||||
onToggled: Config.launcher.useFuzzy.schemes = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.launcher.useFuzzy.variants
|
||||
text: qsTr("Variants")
|
||||
|
||||
onToggled: Config.launcher.useFuzzy.variants = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.launcher.useFuzzy.wallpapers
|
||||
last: true
|
||||
text: qsTr("Wallpapers")
|
||||
|
||||
onToggled: Config.launcher.useFuzzy.wallpapers = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.Config
|
||||
import qs.Components
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("Resources")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
// General
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("General")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.performance.enabled
|
||||
first: true
|
||||
last: true
|
||||
text: qsTr("Enabled")
|
||||
|
||||
onToggled: Config.dashboard.performance.enabled = checked
|
||||
}
|
||||
|
||||
// Performance widgets
|
||||
SectionHeader {
|
||||
text: qsTr("Performance widgets")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.performance.showBattery
|
||||
first: true
|
||||
text: qsTr("Battery")
|
||||
|
||||
onToggled: Config.dashboard.performance.showBattery = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.performance.showGpu
|
||||
text: qsTr("GPU")
|
||||
|
||||
onToggled: Config.dashboard.performance.showGpu = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.performance.showCpu
|
||||
text: qsTr("CPU")
|
||||
|
||||
onToggled: Config.dashboard.performance.showCpu = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.performance.showMemory
|
||||
text: qsTr("Memory")
|
||||
|
||||
onToggled: Config.dashboard.performance.showMemory = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.performance.showStorage
|
||||
text: qsTr("Storage")
|
||||
|
||||
onToggled: Config.dashboard.performance.showStorage = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.performance.showNetwork
|
||||
last: true
|
||||
text: qsTr("Network")
|
||||
|
||||
onToggled: Config.dashboard.performance.showNetwork = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.Config
|
||||
import qs.Components
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("Sidebar")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("General")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.sidebar.enabled
|
||||
first: true
|
||||
text: qsTr("Enabled")
|
||||
|
||||
onToggled: Config.sidebar.enabled = checked
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
from: 0
|
||||
last: true
|
||||
stepSize: 5
|
||||
subtext: qsTr("Pixels dragged before the sidebar opens")
|
||||
text: qsTr("Drag threshold")
|
||||
to: 200
|
||||
value: Config.sidebar.dragThreshold
|
||||
|
||||
onMoved: v => Config.sidebar.dragThreshold = v
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import QtQuick.Layouts
|
||||
import qs.Config
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
title: qsTr("Panels")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
NavRow {
|
||||
first: true
|
||||
icon: "dock_to_bottom"
|
||||
status: !Config.bar.autoHide ? qsTr("Always visible") : qsTr("Reveal on hover")
|
||||
text: qsTr("Bar")
|
||||
|
||||
onClicked: root.sState.openSubPage(1)
|
||||
}
|
||||
|
||||
NavRow {
|
||||
icon: "dashboard"
|
||||
status: Config.dashboard.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
text: qsTr("Dashboard")
|
||||
|
||||
onClicked: root.sState.openSubPage(2)
|
||||
}
|
||||
|
||||
NavRow {
|
||||
icon: "insert_chart"
|
||||
status: Config.dashboard.performance.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
text: qsTr("Resources")
|
||||
|
||||
onClicked: root.sState.openSubPage(3)
|
||||
}
|
||||
|
||||
NavRow {
|
||||
icon: "apps"
|
||||
status: Config.launcher.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
text: qsTr("Launcher")
|
||||
|
||||
onClicked: root.sState.openSubPage(4)
|
||||
}
|
||||
|
||||
NavRow {
|
||||
icon: "dock_to_right"
|
||||
last: true
|
||||
status: Config.sidebar.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
text: qsTr("Sidebar")
|
||||
|
||||
onClicked: root.sState.openSubPage(5)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import ZShell.Components
|
||||
import qs.Helpers
|
||||
import qs.Components
|
||||
import qs.Config
|
||||
import qs.Modules.Settings
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
title: qsTr("Screenshot effects")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("Effects")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.screenshot.enable_pp
|
||||
first: true
|
||||
text: qsTr("Enable effects")
|
||||
|
||||
onToggled: Config.screenshot.enable_pp = checked
|
||||
}
|
||||
|
||||
SelectRow {
|
||||
active: Config.screenshot.mode === "manual" ? menuItems[0] : menuItems[1]
|
||||
enabled: Config.screenshot.enable_pp
|
||||
last: true
|
||||
subtext: qsTr("Automatic or manual effect values")
|
||||
text: qsTr("Effects mode")
|
||||
|
||||
menuItems: [
|
||||
MenuItem {
|
||||
icon: "build"
|
||||
text: qsTr("Manual")
|
||||
value: "manual"
|
||||
},
|
||||
MenuItem {
|
||||
icon: "rotate_auto"
|
||||
text: qsTr("Auto")
|
||||
value: "auto"
|
||||
}
|
||||
]
|
||||
|
||||
onSelected: item => {
|
||||
Config.screenshot.mode = item.value;
|
||||
Config.save();
|
||||
}
|
||||
}
|
||||
|
||||
SectionHeader {
|
||||
text: qsTr("Rounded corners")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.screenshot.rounding
|
||||
enabled: Config.screenshot.enable_pp && Config.screenshot.mode === "manual"
|
||||
first: true
|
||||
text: qsTr("Enable rounded corners")
|
||||
|
||||
onToggled: Config.screenshot.rounding = checked
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
enabled: Config.screenshot.enable_pp && Config.screenshot.mode === "manual" && Config.screenshot.rounding
|
||||
from: 0
|
||||
last: true
|
||||
stepSize: 1
|
||||
text: qsTr("Corner radius")
|
||||
to: 50
|
||||
value: Config.screenshot.radius
|
||||
|
||||
onMoved: value => {
|
||||
const newVal = Math.floor(value);
|
||||
Config.screenshot.radius = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
SectionHeader {
|
||||
text: qsTr("Shadow")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.screenshot.shadow
|
||||
enabled: Config.screenshot.enable_pp && Config.screenshot.mode === "manual"
|
||||
first: true
|
||||
text: qsTr("Enable shadow")
|
||||
|
||||
onToggled: Config.screenshot.shadow = checked
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
enabled: Config.screenshot.enable_pp && Config.screenshot.mode === "manual" && Config.screenshot.shadow
|
||||
from: 0
|
||||
stepSize: 1
|
||||
text: qsTr("Shadow blur amount")
|
||||
to: 100
|
||||
value: Config.screenshot.shadow_blur
|
||||
|
||||
onMoved: value => {
|
||||
const newVal = Math.floor(value);
|
||||
Config.screenshot.shadow_blur = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
enabled: Config.screenshot.enable_pp && Config.screenshot.mode === "manual" && Config.screenshot.shadow
|
||||
from: -100
|
||||
stepSize: 10
|
||||
text: qsTr("Shadow horizontal offset")
|
||||
to: 100
|
||||
value: Config.screenshot.shadow_offset_x
|
||||
|
||||
onMoved: value => {
|
||||
const newVal = Math.floor(value);
|
||||
Config.screenshot.shadow_offset_x = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
enabled: Config.screenshot.enable_pp && Config.screenshot.mode === "manual" && Config.screenshot.shadow
|
||||
from: -100
|
||||
last: true
|
||||
stepSize: 10
|
||||
text: qsTr("Shadow vertical offset")
|
||||
to: 100
|
||||
value: Config.screenshot.shadow_offset_y
|
||||
|
||||
onMoved: value => {
|
||||
const newVal = Math.floor(value);
|
||||
Config.screenshot.shadow_offset_y = newVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import qs.Config
|
||||
import qs.Components
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("Notifications")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
// Notifications
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("Notifications")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.notifs.showInFullscreen
|
||||
first: true
|
||||
subtext: qsTr("Whether notifications appear over fullscreen apps")
|
||||
text: qsTr("Show in fullscreen")
|
||||
|
||||
onToggled: Config.notifs.showInFullscreen = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.notifs.expire
|
||||
subtext: qsTr("Dismiss notifications after their timeout")
|
||||
text: qsTr("Expire automatically")
|
||||
|
||||
onToggled: Config.notifs.expire = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.notifs.openExpanded
|
||||
subtext: qsTr("Show notifications expanded by default")
|
||||
text: qsTr("Open expanded")
|
||||
|
||||
onToggled: Config.notifs.openExpanded = checked
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
from: 1000
|
||||
stepSize: 500
|
||||
subtext: qsTr("Time before a notification dismisses (ms)")
|
||||
text: qsTr("Default timeout")
|
||||
to: 60000
|
||||
value: Config.notifs.defaultExpireTimeout
|
||||
|
||||
onMoved: v => Config.notifs.defaultExpireTimeout = Math.round(v)
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
from: 1
|
||||
last: true
|
||||
stepSize: 1
|
||||
subtext: qsTr("Notifications shown per group before collapsing")
|
||||
text: qsTr("Group preview count")
|
||||
to: 10
|
||||
value: Config.notifs.groupPreviewNum
|
||||
|
||||
onMoved: v => Config.notifs.groupPreviewNum = Math.round(v)
|
||||
}
|
||||
|
||||
// Toasts
|
||||
SectionHeader {
|
||||
text: qsTr("Toasts")
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
first: true
|
||||
from: 1
|
||||
stepSize: 1
|
||||
subtext: qsTr("Maximum number of toasts shown at once")
|
||||
text: qsTr("Visible toasts")
|
||||
to: 10
|
||||
value: Config.utilities.maxToasts
|
||||
|
||||
onMoved: v => Config.utilities.maxToasts = Math.round(v)
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.utilities.toasts.chargingChanged
|
||||
text: qsTr("Charging changes")
|
||||
|
||||
onToggled: Config.utilities.toasts.chargingChanged = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.utilities.toasts.gameModeChanged
|
||||
text: qsTr("Game mode changes")
|
||||
|
||||
onToggled: Config.utilities.toasts.gameModeChanged = checked
|
||||
}
|
||||
|
||||
// ToggleRow {
|
||||
// checked: Config.utilities.toasts.dndChanged
|
||||
// text: qsTr("Do not disturb changes")
|
||||
//
|
||||
// onToggled: Config.utilities.toasts.dndChanged = checked
|
||||
// }
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.utilities.toasts.audioOutputChanged
|
||||
text: qsTr("Audio output changes")
|
||||
|
||||
onToggled: Config.utilities.toasts.audioOutputChanged = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.utilities.toasts.audioInputChanged
|
||||
last: true
|
||||
text: qsTr("Audio input changes")
|
||||
|
||||
onToggled: Config.utilities.toasts.audioInputChanged = checked
|
||||
}
|
||||
|
||||
// ToggleRow {
|
||||
// checked: Config.utilities.toasts.capsLockChanged
|
||||
// text: qsTr("Caps lock changes")
|
||||
//
|
||||
// onToggled: Config.utilities.toasts.capsLockChanged = checked
|
||||
// }
|
||||
//
|
||||
// ToggleRow {
|
||||
// checked: Config.utilities.toasts.numLockChanged
|
||||
// text: qsTr("Num lock changes")
|
||||
//
|
||||
// onToggled: Config.utilities.toasts.numLockChanged = checked
|
||||
// }
|
||||
//
|
||||
// ToggleRow {
|
||||
// checked: Config.utilities.toasts.kbLayoutChanged
|
||||
// text: qsTr("Keyboard layout changes")
|
||||
//
|
||||
// onToggled: Config.utilities.toasts.kbLayoutChanged = checked
|
||||
// }
|
||||
//
|
||||
// ToggleRow {
|
||||
// checked: Config.utilities.toasts.vpnChanged
|
||||
// text: qsTr("VPN changes")
|
||||
//
|
||||
// onToggled: Config.utilities.toasts.vpnChanged = checked
|
||||
// }
|
||||
//
|
||||
// ToggleRow {
|
||||
// checked: Config.utilities.toasts.nowPlaying
|
||||
// last: true
|
||||
// text: qsTr("Now playing")
|
||||
//
|
||||
// onToggled: Config.utilities.toasts.nowPlaying = checked
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import ZShell.Services
|
||||
import qs.Components
|
||||
import qs.Helpers
|
||||
import qs.Config
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
// GPU options + the config string each maps to (see Gpu::parseType)
|
||||
readonly property list<MenuItem> gpuItems: [
|
||||
MenuItem {
|
||||
text: qsTr("Auto")
|
||||
},
|
||||
MenuItem {
|
||||
text: "NVIDIA"
|
||||
},
|
||||
MenuItem {
|
||||
text: qsTr("Generic")
|
||||
},
|
||||
MenuItem {
|
||||
text: qsTr("None")
|
||||
}
|
||||
]
|
||||
readonly property list<string> gpuValues: ["", "NVIDIA", "GENERIC", "None"]
|
||||
|
||||
function gpuKeyToIndex(key: string): int {
|
||||
const u = (key ?? "").trim().toUpperCase();
|
||||
if (u === "")
|
||||
return 0; // Auto
|
||||
if (u === "NVIDIA")
|
||||
return 1;
|
||||
if (u === "GENERIC")
|
||||
return 2;
|
||||
return 3; // None
|
||||
}
|
||||
|
||||
title: qsTr("Services")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
// Detected running players, used as default-player options
|
||||
Variants {
|
||||
id: playerVariants
|
||||
|
||||
model: [...new Set(Players.list.map(p => Players.getIdentity(p)).filter(id => id))]
|
||||
|
||||
MenuItem {
|
||||
required property string modelData
|
||||
|
||||
activeIcon: "music_note"
|
||||
icon: modelData === Config.services.defaultPlayer ? "check" : ""
|
||||
text: modelData
|
||||
}
|
||||
}
|
||||
|
||||
// Notifications
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("Notifications")
|
||||
}
|
||||
|
||||
NavRow {
|
||||
first: true
|
||||
icon: "notifications"
|
||||
last: true
|
||||
status: qsTr("Notifications, toasts, timeouts")
|
||||
text: qsTr("Notifications")
|
||||
|
||||
onClicked: root.sState.openSubPage(1)
|
||||
}
|
||||
|
||||
// Polling
|
||||
SectionHeader {
|
||||
text: qsTr("Polling")
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
first: true
|
||||
from: 100
|
||||
stepSize: 50
|
||||
subtext: qsTr("How often the media position updates (ms)")
|
||||
text: qsTr("Media refresh")
|
||||
to: 2000
|
||||
value: Config.dashboard.mediaUpdateInterval
|
||||
|
||||
onMoved: v => Config.dashboard.mediaUpdateInterval = v
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
from: 0.5
|
||||
last: true
|
||||
stepSize: 0.5
|
||||
subtext: qsTr("CPU, memory and GPU update interval (seconds)")
|
||||
text: qsTr("System stats refresh")
|
||||
to: 10
|
||||
value: Config.dashboard.resourceUpdateInterval / 1000
|
||||
|
||||
onMoved: v => Config.dashboard.resourceUpdateInterval = Math.round(v * 1000)
|
||||
}
|
||||
|
||||
// Media & lyrics
|
||||
SectionHeader {
|
||||
text: qsTr("Media")
|
||||
}
|
||||
|
||||
SelectRow {
|
||||
active: menuItems.find(i => i.text === Config.services.defaultPlayer) ?? null
|
||||
fallbackIcon: "music_note"
|
||||
fallbackText: Config.services.defaultPlayer || qsTr("Auto")
|
||||
first: true
|
||||
last: true
|
||||
menuItems: playerVariants.instances
|
||||
subtext: qsTr("Preferred media player when several are open")
|
||||
text: qsTr("Default player")
|
||||
|
||||
onSelected: item => Config.services.defaultPlayer = item.text
|
||||
}
|
||||
|
||||
// Input increments
|
||||
SectionHeader {
|
||||
text: qsTr("Input increments")
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
first: true
|
||||
from: 1
|
||||
stepSize: 1
|
||||
subtext: qsTr("Amount the volume changes per input (%)")
|
||||
text: qsTr("Volume step")
|
||||
to: 50
|
||||
value: Math.round(Config.services.audioIncrement * 100)
|
||||
|
||||
onMoved: v => Config.services.audioIncrement = v / 100
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
from: 1
|
||||
stepSize: 1
|
||||
subtext: qsTr("Amount the brightness changes per input (%)")
|
||||
text: qsTr("Brightness step")
|
||||
to: 50
|
||||
value: Math.round(Config.services.brightnessIncrement * 100)
|
||||
|
||||
onMoved: v => Config.services.brightnessIncrement = v / 100
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
from: 1
|
||||
stepSize: 1
|
||||
subtext: qsTr("Lowest allowed brightness (%)")
|
||||
text: qsTr("Brightness minimum")
|
||||
to: 20
|
||||
value: Math.round(Config.services.minBrightness * 100)
|
||||
|
||||
onMoved: v => Config.services.minBrightness = v / 100
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
from: 50
|
||||
last: true
|
||||
stepSize: 5
|
||||
subtext: qsTr("Upper limit for output volume (%)")
|
||||
text: qsTr("Max volume")
|
||||
to: 200
|
||||
value: Math.round(Config.services.maxVolume * 100)
|
||||
|
||||
onMoved: v => Config.services.maxVolume = v / 100
|
||||
}
|
||||
|
||||
// Service tuning
|
||||
SectionHeader {
|
||||
text: qsTr("Service tuning")
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
first: true
|
||||
from: 10
|
||||
stepSize: 2
|
||||
subtext: qsTr("Resolution of the audio visualizer")
|
||||
text: qsTr("Visualizer resolution")
|
||||
to: 120
|
||||
value: Config.services.visualizerBars
|
||||
|
||||
onMoved: v => Config.services.visualiserBars = v
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.general.color.smart
|
||||
subtext: qsTr("Derive theme mode from the wallpaper")
|
||||
text: qsTr("Smart color scheme")
|
||||
|
||||
onToggled: Config.general.color.smart = checked
|
||||
}
|
||||
|
||||
SelectRow {
|
||||
active: root.gpuItems[root.gpuKeyToIndex(Config.services.gpuType)]
|
||||
last: true
|
||||
menuItems: root.gpuItems
|
||||
menuOnTop: true
|
||||
subtext: Gpu.name ? qsTr("Monitoring: %1").arg(Gpu.name) : qsTr("Override for GPU type")
|
||||
text: qsTr("GPU")
|
||||
|
||||
onSelected: item => Config.services.gpuType = root.gpuValues[root.gpuItems.indexOf(item)]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import ZShell.Models
|
||||
import qs.Paths
|
||||
import qs.Helpers
|
||||
import qs.Components
|
||||
import qs.Config
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("Wallpapers")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.small
|
||||
width: root.cappedWidth
|
||||
|
||||
CustomText {
|
||||
Layout.topMargin: Appearance.spacing.large
|
||||
font.pointSize: Appearance.font.size.large
|
||||
text: qsTr("Wallpapers")
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
Layout.fillWidth: true
|
||||
columnSpacing: Appearance.spacing.extraSmall
|
||||
columns: 4
|
||||
rowSpacing: Appearance.spacing.extraSmall
|
||||
visible: localWalls.count > 0
|
||||
|
||||
Repeater {
|
||||
id: localWalls
|
||||
|
||||
model: {
|
||||
const walls = Wallpapers.list;
|
||||
var baseDir = Paths.wallsdir;
|
||||
const categories = {};
|
||||
const list = [];
|
||||
for (const w of walls) {
|
||||
var parentDir = w.parentDir;
|
||||
if (!parentDir.endsWith("/"))
|
||||
parentDir = parentDir + "/";
|
||||
|
||||
if (!baseDir.endsWith("/"))
|
||||
baseDir = baseDir + "/";
|
||||
|
||||
if (parentDir !== baseDir) {
|
||||
const category = Wallpapers.getCategoryFor(w);
|
||||
if (category && (!(category in categories) || categories[category].name.localeCompare(w.name) > 0))
|
||||
categories[category] = w;
|
||||
} else {
|
||||
list.push(w);
|
||||
}
|
||||
}
|
||||
list.push(...Object.values(categories));
|
||||
list.sort((a, b) => ((a.parentDir === baseDir) - (b.parentDir === baseDir)) || a.name.localeCompare(b.name));
|
||||
while (list.length < 4)
|
||||
list.push(null);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
WallItem {
|
||||
required property FileSystemEntry modelData
|
||||
|
||||
enabled: modelData
|
||||
|
||||
// Empty placeholders for sizing
|
||||
opacity: modelData ? 1 : 0
|
||||
source: String(modelData?.path ?? "")
|
||||
|
||||
onClicked: {
|
||||
Wallpapers.setWallpaper(modelData.path);
|
||||
root.sState.closeSubPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
Layout.fillWidth: true
|
||||
active: localWalls.count === 0
|
||||
asynchronous: true
|
||||
visible: active
|
||||
|
||||
sourceComponent: CustomRect {
|
||||
color: DynamicColors.tPalette.m3surfaceContainer
|
||||
implicitHeight: noWallsLayout.implicitHeight + Appearance.padding.extraLarge * 3
|
||||
radius: Appearance.rounding.large
|
||||
|
||||
ColumnLayout {
|
||||
id: noWallsLayout
|
||||
|
||||
anchors.centerIn: parent
|
||||
spacing: Appearance.spacing.extraSmall
|
||||
|
||||
MaterialIcon {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
color: DynamicColors.palette.m3outline
|
||||
text: "hide_image"
|
||||
}
|
||||
|
||||
CustomText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
color: DynamicColors.palette.m3outline
|
||||
text: qsTr("No local wallpapers found")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import ZShell.Components
|
||||
import qs.Helpers
|
||||
import qs.Components
|
||||
import qs.Config
|
||||
import qs.Modules.Settings
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
title: qsTr("Wallpaper & style")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.large
|
||||
width: root.cappedWidth
|
||||
|
||||
Item {
|
||||
id: wallWrapper
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitHeight: cropper.height
|
||||
implicitWidth: root.cappedWidth
|
||||
|
||||
WallpaperCropper {
|
||||
id: cropper
|
||||
}
|
||||
}
|
||||
|
||||
IconTextButton {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
enabled: Config.background.enabled
|
||||
horizontalPadding: Appearance.padding.extraLarge
|
||||
icon: "wallpaper"
|
||||
isRound: true
|
||||
shapeMorph: true
|
||||
text: qsTr("Wallpapers")
|
||||
type: IconTextButton.Tonal
|
||||
verticalPadding: Appearance.padding.normal
|
||||
|
||||
onClicked: root.sState.openSubPage(1) // Wallpaper page
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.background.enabled
|
||||
first: true
|
||||
text: qsTr("Display wallpaper")
|
||||
|
||||
onToggled: Config.background.enabled = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
Layout.topMargin: Appearance.spacing.extraSmall / 2 - parent.spacing
|
||||
checked: DynamicColors.transparency.enabled
|
||||
subtext: qsTr("Base %1, layers %2").arg(DynamicColors.transparency.base).arg(DynamicColors.transparency.layers)
|
||||
text: qsTr("Transparency")
|
||||
|
||||
onToggled: Config.appearance.transparency.enabled = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
Layout.topMargin: Appearance.spacing.extraSmall / 2 - parent.spacing
|
||||
checked: !DynamicColors.light
|
||||
last: true
|
||||
text: qsTr("Dark theme")
|
||||
|
||||
onToggled: DynamicColors.setMode(checked ? "dark" : "light")
|
||||
}
|
||||
|
||||
OverlayRow {
|
||||
id: darkMode
|
||||
|
||||
readonly property string endTime: {
|
||||
var d = new Date(0, 0, 0, 0, 0, 0, 0);
|
||||
d.setMinutes(Config.general.color.scheduleDarkEnd);
|
||||
return Qt.formatTime(d, "hh:mm AP");
|
||||
}
|
||||
readonly property string startTime: {
|
||||
var d = new Date(0, 0, 0, 0, 0, 0, 0);
|
||||
d.setMinutes(Config.general.color.scheduleDarkStart);
|
||||
return Qt.formatTime(d, "hh:mm AP");
|
||||
}
|
||||
|
||||
checked: Config.general.color.scheduleDark
|
||||
first: true
|
||||
subtext: qsTr("Dark mode will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
|
||||
text: qsTr("Schedule dark mode")
|
||||
|
||||
popup: Component {
|
||||
TimeInput {
|
||||
object: Config.general.color
|
||||
settings: ["scheduleDark", "scheduleDarkStart", "scheduleDarkEnd"]
|
||||
|
||||
onApplySettings: (start, end) => {
|
||||
Config.general.color.scheduleDarkStart = start;
|
||||
Config.general.color.scheduleDarkEnd = end;
|
||||
Config.save();
|
||||
ModeScheduler.checkStartup();
|
||||
PopupManager.requestClose();
|
||||
}
|
||||
onClose: PopupManager.requestClose()
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: value => {
|
||||
Config.general.color.scheduleDark = value;
|
||||
}
|
||||
}
|
||||
|
||||
OverlayRow {
|
||||
id: hyprsunset
|
||||
|
||||
readonly property string endTime: {
|
||||
var d = new Date(0, 0, 0, 0, 0, 0, 0);
|
||||
d.setMinutes(Config.general.color.scheduleHyprsunsetEnd);
|
||||
return Qt.formatTime(d, "hh:mm AP");
|
||||
}
|
||||
readonly property string startTime: {
|
||||
var d = new Date(0, 0, 0, 0, 0, 0, 0);
|
||||
d.setMinutes(Config.general.color.scheduleHyprsunsetStart);
|
||||
return Qt.formatTime(d, "hh:mm AP");
|
||||
}
|
||||
|
||||
Layout.topMargin: Appearance.spacing.extraSmall / 2 - parent.spacing
|
||||
checked: Config.general.color.scheduleHyprsunset
|
||||
last: true
|
||||
subtext: qsTr("Hyprsunset will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
|
||||
text: qsTr("Schedule hyprsunset")
|
||||
|
||||
popup: Component {
|
||||
TimeInput {
|
||||
object: Config.general.color
|
||||
settings: ["scheduleHyprsunset", "scheduleHyprsunsetStart", "scheduleHyprsunsetEnd"]
|
||||
|
||||
onApplySettings: (start, end) => {
|
||||
Config.general.color.scheduleHyprsunsetStart = start;
|
||||
Config.general.color.scheduleHyprsunsetEnd = end;
|
||||
Config.save();
|
||||
Hyprsunset.checkStartup();
|
||||
PopupManager.requestClose();
|
||||
}
|
||||
onClose: PopupManager.requestClose()
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: value => {
|
||||
Config.general.color.scheduleHyprsunset = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user