Merge branch 'main' into feat/llm-chat-tab
C++ / fmt (pull_request) Failing after 3s
C++ / build (pull_request) Failing after 9s
C++ / clang-tidy (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 9s
JS/TS / lint (pull_request) Successful in 10s
Python / static (pull_request) Successful in 28s
Rust / build (pull_request) Successful in 49s
Python / verify (pull_request) Successful in 1m40s
Rust / fmt (pull_request) Successful in 27s
Rust / clippy (pull_request) Successful in 46s
C++ / fmt (pull_request) Failing after 3s
C++ / build (pull_request) Failing after 9s
C++ / clang-tidy (pull_request) Failing after 9s
JS/TS / fmt (pull_request) Successful in 9s
JS/TS / lint (pull_request) Successful in 10s
Python / static (pull_request) Successful in 28s
Rust / build (pull_request) Successful in 49s
Python / verify (pull_request) Successful in 1m40s
Rust / fmt (pull_request) Successful in 27s
Rust / clippy (pull_request) Successful in 46s
This commit is contained in:
@@ -56,14 +56,14 @@ PageBase {
|
||||
CustomText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: Tokens.spacing.small
|
||||
font.pointSize: Tokens.font.size.large
|
||||
font: Tokens.font.headline.large
|
||||
text: "ZShell"
|
||||
}
|
||||
|
||||
CustomText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
color: Colors.palette.m3onSurfaceVariant
|
||||
font.pointSize: Tokens.font.size.normal
|
||||
font: Tokens.font.body.medium
|
||||
text: ZUtils.version ? `v${ZUtils.version}` : "…"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ PageBase {
|
||||
|
||||
IconImage {
|
||||
asynchronous: true
|
||||
implicitSize: Math.round(Tokens.font.size.large * 1.8)
|
||||
implicitSize: Math.round(Tokens.font.icon.large * 1.8)
|
||||
source: Quickshell.iconPath(appItem.modelData.icon, "image-missing")
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ PageBase {
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Tokens.font.size.small
|
||||
font: Tokens.font.body.small
|
||||
text: appItem.modelData.name
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ PageBase {
|
||||
Layout.fillWidth: true
|
||||
color: Colors.palette.m3outline
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Tokens.font.size.small
|
||||
font: Tokens.font.label.small
|
||||
text: (appItem.modelData.comment || appItem.modelData.genericName) ?? ""
|
||||
visible: text
|
||||
}
|
||||
@@ -84,14 +84,14 @@ PageBase {
|
||||
MaterialIcon {
|
||||
color: Colors.palette.m3primary
|
||||
fill: 1
|
||||
font.pointSize: Tokens.font.size.small
|
||||
fontStyle: Tokens.font.icon.small
|
||||
text: "favorite"
|
||||
visible: Strings.testRegexList(Config.launcher.favoriteApps, appItem.modelData.id)
|
||||
}
|
||||
|
||||
MaterialIcon {
|
||||
color: Colors.palette.m3onSurfaceVariant
|
||||
font.pointSize: Tokens.font.size.normal
|
||||
fontStyle: Tokens.font.icon.medium
|
||||
text: "chevron_right"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ PageBase {
|
||||
|
||||
IconImage {
|
||||
asynchronous: true
|
||||
implicitSize: Math.round(Tokens.font.size.large * 3)
|
||||
implicitSize: Math.round(Tokens.font.icon.large.pointSize * 3)
|
||||
source: Quickshell.iconPath(root.app?.icon, "image-missing")
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ PageBase {
|
||||
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
font.pointSize: Tokens.font.size.normal
|
||||
font: Tokens.font.body.medium
|
||||
text: root.app?.name ?? ""
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
@@ -65,7 +65,7 @@ PageBase {
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
color: Colors.palette.m3outline
|
||||
font.pointSize: Tokens.font.size.small
|
||||
font: Tokens.font.body.small
|
||||
text: (root.app?.comment || root.app?.genericName) ?? ""
|
||||
visible: text
|
||||
wrapMode: Text.WordWrap
|
||||
@@ -152,7 +152,7 @@ PageBase {
|
||||
id: label
|
||||
|
||||
Layout.alignment: Qt.AlignTop
|
||||
font.pointSize: Tokens.font.size.small
|
||||
font: Tokens.font.label.small
|
||||
}
|
||||
|
||||
Item {
|
||||
@@ -165,7 +165,6 @@ PageBase {
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: implicitWidth + 1 // Whyyyyyyyyy
|
||||
color: Colors.palette.m3onSurfaceVariant
|
||||
font.pointSize: Tokens.font.size.small
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ PageBase {
|
||||
icon: "apps"
|
||||
last: true
|
||||
settingAnchor: "apps-all-apps"
|
||||
status: qsTr("Browse installed apps, set favorites and hidden")
|
||||
subtext: qsTr("Browse installed apps, set favorites and hidden")
|
||||
text: qsTr("All apps")
|
||||
|
||||
onClicked: root.sState.openSubPage(1)
|
||||
@@ -143,7 +143,7 @@ PageBase {
|
||||
|
||||
IconImage {
|
||||
asynchronous: true
|
||||
implicitSize: Math.round(Tokens.font.size.large * 1.8)
|
||||
implicitSize: Math.round(Tokens.font.icon.large.pointSize * 1.8)
|
||||
source: Quickshell.iconPath(appItem.modelData.icon, "image-missing")
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ PageBase {
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Tokens.font.size.small
|
||||
font: Tokens.font.body.small
|
||||
text: appItem.modelData.name
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ PageBase {
|
||||
Layout.fillWidth: true
|
||||
color: Colors.palette.m3outline
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Tokens.font.size.small
|
||||
font: Tokens.font.body.small
|
||||
text: (appItem.modelData.comment || appItem.modelData.genericName) ?? ""
|
||||
visible: text
|
||||
}
|
||||
@@ -171,7 +171,7 @@ PageBase {
|
||||
MaterialIcon {
|
||||
color: Colors.palette.m3primary
|
||||
fill: 1
|
||||
font.pointSize: Tokens.font.size.small
|
||||
fontStyle: Tokens.font.icon.small
|
||||
text: "favorite"
|
||||
visible: Strings.testRegexList(Config.launcher.favoriteApps, appItem.modelData.id)
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ PageBase {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Tokens.padding.extraSmall
|
||||
color: Colors.palette.m3outline
|
||||
font.pointSize: Tokens.font.size.small
|
||||
text: qsTr("Adjust the volume of individual apps currently playing audio.")
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ PageBase {
|
||||
spacing: Tokens.spacing.small
|
||||
|
||||
MaterialIcon {
|
||||
font.pointSize: Tokens.font.size.normal
|
||||
fontStyle: Tokens.font.icon.medium
|
||||
text: "tune"
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ PageBase {
|
||||
CustomText {
|
||||
Layout.fillWidth: true
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Tokens.font.size.small
|
||||
font: Tokens.font.body.small
|
||||
text: qsTr("App volumes")
|
||||
}
|
||||
|
||||
@@ -123,14 +123,14 @@ PageBase {
|
||||
animate: true
|
||||
color: Colors.palette.m3outline
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: Tokens.font.size.small
|
||||
font: Tokens.font.body.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: Colors.palette.m3onSurfaceVariant
|
||||
font.pointSize: Tokens.font.size.normal
|
||||
fontStyle: Tokens.font.icon.medium
|
||||
text: "chevron_right"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ PageBase {
|
||||
icon: "add"
|
||||
last: true
|
||||
label: qsTr("Add entry")
|
||||
last: true
|
||||
model: {
|
||||
const present = new Set(Config.bar.tray.statusIcons.values.map(item => item.id));
|
||||
return Object.keys(root.builtinIcons).filter(id => !present.has(id)).map(id => ({
|
||||
@@ -65,6 +66,7 @@ PageBase {
|
||||
}));
|
||||
}
|
||||
rootParent: root.flickable
|
||||
settingAnchor: "panels-bar-status-icons-add-item"
|
||||
|
||||
onAccepted: {
|
||||
if (!selectedItem)
|
||||
|
||||
@@ -91,7 +91,7 @@ PageBase {
|
||||
first: true
|
||||
icon: "widgets"
|
||||
settingAnchor: "bar-tray"
|
||||
status: qsTr("System tray icons")
|
||||
subtext: qsTr("System tray icons")
|
||||
text: qsTr("Tray")
|
||||
|
||||
onClicked: root.sState.openSubPage(6)
|
||||
@@ -100,7 +100,7 @@ PageBase {
|
||||
NavRow {
|
||||
icon: "signal_cellular_alt"
|
||||
settingAnchor: "bar-statusicons"
|
||||
status: qsTr("Visible indicators")
|
||||
subtext: qsTr("Visible indicators")
|
||||
text: qsTr("Status icons")
|
||||
|
||||
onClicked: root.sState.openSubPage(7)
|
||||
@@ -110,7 +110,7 @@ PageBase {
|
||||
icon: "schedule"
|
||||
last: true
|
||||
settingAnchor: "bar-clock"
|
||||
status: qsTr("Date, icon, background")
|
||||
subtext: qsTr("Date, icon, background")
|
||||
text: qsTr("Clock")
|
||||
|
||||
onClicked: root.sState.openSubPage(8)
|
||||
|
||||
@@ -33,5 +33,73 @@ PageBase {
|
||||
|
||||
onToggled: Config.dashboard.enabled = checked
|
||||
}
|
||||
|
||||
// Tabs
|
||||
SectionHeader {
|
||||
text: qsTr("Tabs")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
first: true
|
||||
checked: Config.dashboard.showDashboard
|
||||
settingAnchor: "dashboard-show-dashboard"
|
||||
text: qsTr("Dashboard")
|
||||
|
||||
onToggled: Config.dashboard.showDashboard = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.showWeather
|
||||
settingAnchor: "dashboard-show-weather"
|
||||
text: qsTr("Weather")
|
||||
|
||||
onToggled: Config.dashboard.showWeather = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.showMedia
|
||||
settingAnchor: "dashboard-show-media"
|
||||
text: qsTr("Media")
|
||||
|
||||
onToggled: Config.dashboard.showMedia = checked
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.showProcesses
|
||||
settingAnchor: "dashboard-show-processes"
|
||||
text: qsTr("Processes")
|
||||
last: true
|
||||
|
||||
onToggled: Config.dashboard.showProcesses = checked
|
||||
}
|
||||
|
||||
// Behavior
|
||||
SectionHeader {
|
||||
text: qsTr("Behavior")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.dashboard.showOnHover
|
||||
first: true
|
||||
settingAnchor: "dashboard-showonhover"
|
||||
text: qsTr("Show on hover")
|
||||
subtext: qsTr("Dashboard %1 be shown when hovering the middle-top part of the shell").arg(checked ? "will" : "will not")
|
||||
|
||||
onToggled: Config.dashboard.showOnHover = checked
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
from: 30
|
||||
settingAnchor: "dashboard-drag-threshold"
|
||||
stepSize: 20
|
||||
enabled: !Config.dashboard.showOnHover
|
||||
subtext: qsTr("How far you need to drag before the panel opens")
|
||||
text: qsTr("Drag threshold")
|
||||
to: 100
|
||||
value: Config.dashboard.dragThreshold
|
||||
last: true
|
||||
|
||||
onMoved: v => Config.dashboard.dragThreshold = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,10 @@ PageBase {
|
||||
enabled: Object.keys(model).length > 0
|
||||
header: qsTr("Add new entry")
|
||||
icon: "add"
|
||||
onOpenChanged: {
|
||||
root.sState.dimmed = open;
|
||||
}
|
||||
settingAnchor: "panels-sidebar-quick-toggles-add-item"
|
||||
label: qsTr("Add entry")
|
||||
last: true
|
||||
model: {
|
||||
|
||||
@@ -17,7 +17,7 @@ PageBase {
|
||||
first: true
|
||||
icon: "dock_to_bottom"
|
||||
settingAnchor: "panels-bar"
|
||||
status: !Config.bar.autoHide ? qsTr("Always visible") : qsTr("Reveal on hover")
|
||||
subtext: !Config.bar.autoHide ? qsTr("Always visible") : qsTr("Reveal on hover")
|
||||
text: qsTr("Bar")
|
||||
|
||||
onClicked: root.sState.openSubPage(1)
|
||||
@@ -26,7 +26,7 @@ PageBase {
|
||||
NavRow {
|
||||
icon: "dashboard"
|
||||
settingAnchor: "panels-dashboard"
|
||||
status: Config.dashboard.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
subtext: Config.dashboard.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
text: qsTr("Dashboard")
|
||||
|
||||
onClicked: root.sState.openSubPage(2)
|
||||
@@ -35,7 +35,7 @@ PageBase {
|
||||
NavRow {
|
||||
icon: "insert_chart"
|
||||
settingAnchor: "panels-resources"
|
||||
status: Config.dashboard.performance.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
subtext: Config.dashboard.performance.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
text: qsTr("Resources")
|
||||
|
||||
onClicked: root.sState.openSubPage(3)
|
||||
@@ -44,7 +44,7 @@ PageBase {
|
||||
NavRow {
|
||||
icon: "apps"
|
||||
settingAnchor: "panels-launcher"
|
||||
status: Config.launcher.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
subtext: Config.launcher.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
text: qsTr("Launcher")
|
||||
|
||||
onClicked: root.sState.openSubPage(4)
|
||||
@@ -54,7 +54,7 @@ PageBase {
|
||||
icon: "dock_to_right"
|
||||
last: true
|
||||
settingAnchor: "panels-sidebar"
|
||||
status: Config.sidebar.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
subtext: Config.sidebar.enabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
text: qsTr("Sidebar")
|
||||
|
||||
onClicked: root.sState.openSubPage(5)
|
||||
|
||||
@@ -72,7 +72,7 @@ PageBase {
|
||||
icon: "notifications"
|
||||
last: true
|
||||
settingAnchor: "services-notifications"
|
||||
status: qsTr("Notifications, toasts, timeouts")
|
||||
subtext: qsTr("Notifications, toasts, timeouts")
|
||||
text: qsTr("Notifications")
|
||||
|
||||
onClicked: root.sState.openSubPage(1)
|
||||
@@ -202,12 +202,12 @@ PageBase {
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
checked: Config.general.color.smart
|
||||
checked: Config.colors.smart
|
||||
settingAnchor: "services-smart-color-scheme"
|
||||
subtext: qsTr("Derive theme mode from the wallpaper")
|
||||
text: qsTr("Smart color scheme")
|
||||
|
||||
onToggled: Config.general.color.smart = checked
|
||||
onToggled: Config.colors.smart = checked
|
||||
}
|
||||
|
||||
SelectRow {
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import ZShell.Config
|
||||
import qs.Paths
|
||||
import qs.Services
|
||||
import qs.Modules.Settings.Common
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
|
||||
readonly property list<string> fonts: Qt.fontFamilies()
|
||||
readonly property var schemes: [
|
||||
{
|
||||
id: "onedark",
|
||||
label: qsTr("One Dark")
|
||||
},
|
||||
{
|
||||
id: "nord",
|
||||
label: qsTr("Nord")
|
||||
},
|
||||
{
|
||||
id: "dracula",
|
||||
label: qsTr("Dracula")
|
||||
},
|
||||
{
|
||||
id: "darkgreen",
|
||||
label: qsTr("Darkgreen")
|
||||
},
|
||||
{
|
||||
id: "solarized",
|
||||
label: qsTr("Solarized")
|
||||
},
|
||||
{
|
||||
id: "rosepine",
|
||||
label: qsTr("Rosepine")
|
||||
},
|
||||
{
|
||||
id: "gruvbox",
|
||||
label: qsTr("Gruvbox")
|
||||
},
|
||||
{
|
||||
id: "catppuccin",
|
||||
label: qsTr("Catppuccin")
|
||||
},
|
||||
{
|
||||
id: "tokyonight",
|
||||
label: qsTr("Tokyo Night")
|
||||
},
|
||||
{
|
||||
id: "shadotheme",
|
||||
label: qsTr("Shadotheme")
|
||||
}
|
||||
]
|
||||
|
||||
isSubPage: true
|
||||
title: qsTr("Colors & font")
|
||||
|
||||
ColumnLayout {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
spacing: Tokens.spacing.extraSmall / 2
|
||||
width: root.cappedWidth
|
||||
|
||||
SectionHeader {
|
||||
first: true
|
||||
text: qsTr("Colors")
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
text: qsTr("Dynamic colors")
|
||||
first: true
|
||||
subtext: qsTr("Automatic color scheme based on wallpaper is %1").arg(Config.colors.schemeGen ? "enabled" : "disabled")
|
||||
checked: Config.colors.schemeGen
|
||||
settingAnchor: "colors-fonts-dynamic-colors"
|
||||
|
||||
onToggled: {
|
||||
Config.colors.schemeGen = checked;
|
||||
|
||||
if (checked)
|
||||
Colors.setMode(Config.colors.mode);
|
||||
}
|
||||
}
|
||||
|
||||
DialogSelectButton {
|
||||
settingAnchor: "colors-fonts-preset-scheme"
|
||||
model: root.schemes
|
||||
acceptLabel: qsTr("Confirm")
|
||||
enabled: !Config.colors.schemeGen
|
||||
header: qsTr("Select scheme")
|
||||
rowButton.activeItem: root.schemes.find(s => {
|
||||
var regex = new RegExp(Config.colors.presets.name, "i");
|
||||
return regex.test(s.id);
|
||||
}).label ?? ""
|
||||
label: qsTr("Preset scheme")
|
||||
subtext: qsTr("Select preset color scheme")
|
||||
rootParent: root.flickable
|
||||
|
||||
FileView {
|
||||
id: view
|
||||
path: `${Paths.state}/presets.json`
|
||||
|
||||
watchChanges: true
|
||||
onFileChanged: reload()
|
||||
|
||||
JsonAdapter {
|
||||
id: adapter
|
||||
|
||||
property var presets
|
||||
}
|
||||
}
|
||||
|
||||
initialSelect: Config.colors.presets.name.toLowerCase()
|
||||
|
||||
onAccepted: {
|
||||
if (!selectedItem)
|
||||
return;
|
||||
|
||||
const s = selectedItem.toLowerCase();
|
||||
let v = "";
|
||||
let a = "";
|
||||
const existingVariant = Config.colors.presets.variant;
|
||||
const existingAccent = Config.colors.presets.accent;
|
||||
const variantKeys = Object.keys(adapter.presets[s].variants);
|
||||
|
||||
if (existingVariant !== "" && variantKeys.some(v => v === existingVariant))
|
||||
v = existingVariant;
|
||||
|
||||
if (v !== "" && existingAccent !== "" && adapter.presets[s].variants[v]?.accents.some(a => a === existingAccent))
|
||||
a = existingAccent;
|
||||
|
||||
if (a !== "")
|
||||
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`, "-a", `${a}`]);
|
||||
else if (v !== "")
|
||||
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`]);
|
||||
else
|
||||
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${variantKeys[0]}`]);
|
||||
}
|
||||
}
|
||||
|
||||
DialogSelectButton {
|
||||
settingAnchor: "colors-fonts-preset-variant"
|
||||
// qmlformat off
|
||||
model: {
|
||||
const v = adapter.presets[Config.colors.presets.name].variants;
|
||||
const map = Object.keys(v).map(v => ({
|
||||
id: v,
|
||||
label: qsTr("%1%2")
|
||||
.arg(v.charAt(0).toUpperCase())
|
||||
.arg(v.slice(1).toLowerCase())
|
||||
}));
|
||||
|
||||
return map;
|
||||
}
|
||||
// qmlformat on
|
||||
acceptLabel: qsTr("Confirm")
|
||||
enabled: !Config.colors.schemeGen && model.length > 1
|
||||
header: qsTr("Select variant")
|
||||
rowButton.activeItem: {
|
||||
const v = Config.colors.presets.variant ?? "";
|
||||
if (v === "")
|
||||
return "";
|
||||
return qsTr("%1%2").arg(v.charAt(0).toUpperCase()).arg(v.slice(1).toLowerCase());
|
||||
}
|
||||
label: qsTr("Variant")
|
||||
subtext: qsTr("Select preset variant")
|
||||
rootParent: root.flickable
|
||||
|
||||
initialSelect: Config.colors.presets.variant
|
||||
|
||||
onAccepted: {
|
||||
if (!selectedItem)
|
||||
return;
|
||||
|
||||
const v = selectedItem.toLowerCase();
|
||||
const s = Config.colors.presets.name;
|
||||
const existingAccent = Config.colors.presets.accent;
|
||||
let a = "";
|
||||
|
||||
if (existingAccent !== "" && adapter.presets[s].variants[v]?.accents.some(a => a === existingAccent))
|
||||
a = existingAccent;
|
||||
|
||||
if (a !== "")
|
||||
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`, "-a", `${a}`]);
|
||||
else
|
||||
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`]);
|
||||
}
|
||||
}
|
||||
|
||||
DialogSelectButton {
|
||||
settingAnchor: "colors-fonts-preset-accent"
|
||||
// qmlformat off
|
||||
model: {
|
||||
const a = adapter.presets[Config.colors.presets.name].variants[Config.colors.presets.variant]?.accents ?? [];
|
||||
|
||||
if (a.length === 0)
|
||||
return a;
|
||||
|
||||
const map = a.map(a => ({
|
||||
id: a,
|
||||
label: qsTr("%1%2")
|
||||
.arg(a.charAt(0).toUpperCase())
|
||||
.arg(a.slice(1).toLowerCase())
|
||||
}));
|
||||
|
||||
return map;
|
||||
}
|
||||
// qmlformat on
|
||||
acceptLabel: qsTr("Confirm")
|
||||
enabled: !Config.colors.schemeGen && model.length > 1
|
||||
header: qsTr("Select accent")
|
||||
rowButton.activeItem: {
|
||||
const a = Config.colors.presets.accent ?? "";
|
||||
if (a === "")
|
||||
return "";
|
||||
return qsTr("%1%2").arg(a.charAt(0).toUpperCase()).arg(a.slice(1).toLowerCase());
|
||||
}
|
||||
label: qsTr("Accent")
|
||||
last: true
|
||||
subtext: qsTr("Select preset accent")
|
||||
rootParent: root.flickable
|
||||
|
||||
initialSelect: Config.colors.presets.accent
|
||||
|
||||
onAccepted: {
|
||||
if (!selectedItem)
|
||||
return;
|
||||
|
||||
const a = selectedItem.toLowerCase();
|
||||
const v = Config.colors.presets.variant;
|
||||
const s = Config.colors.presets.name;
|
||||
|
||||
Quickshell.execDetached(["zshell-cli", "scheme", "generate", "--preset", `${s}:${v}`, "-a", `${a}`]);
|
||||
}
|
||||
}
|
||||
|
||||
SectionHeader {
|
||||
text: qsTr("Fonts")
|
||||
}
|
||||
|
||||
SearchPopup {
|
||||
id: selectSansFont
|
||||
|
||||
settingAnchor: "colors-fonts-sans-font"
|
||||
model: root.fonts
|
||||
acceptLabel: qsTr("Confirm")
|
||||
enabled: Object.keys(model).length > 0
|
||||
separateContent: false
|
||||
header: qsTr("Select font")
|
||||
first: true
|
||||
rowButton.activeItem: root.fonts.find(s => {
|
||||
var regex = new RegExp(Config.appearance.font.family.sans, "i");
|
||||
return regex.test(s);
|
||||
}) ?? ""
|
||||
label: qsTr("Sans font")
|
||||
subtext: qsTr("Select desired sans font")
|
||||
rootParent: root.flickable
|
||||
|
||||
initialSelect: Config.appearance.font.family.sans
|
||||
|
||||
onAccepted: {
|
||||
if (!selectedItem)
|
||||
return;
|
||||
|
||||
Config.appearance.font.family.sans = selectedItem;
|
||||
}
|
||||
}
|
||||
|
||||
SearchPopup {
|
||||
id: selectMonoFont
|
||||
|
||||
acceptLabel: qsTr("Confirm")
|
||||
enabled: Object.keys(model).length > 0
|
||||
settingAnchor: "colors-fonts-mono-font"
|
||||
separateContent: false
|
||||
header: qsTr("Select font")
|
||||
rowButton.activeItem: root.fonts.find(s => {
|
||||
var regex = new RegExp(Config.appearance.font.family.mono, "i");
|
||||
return regex.test(s);
|
||||
}) ?? ""
|
||||
label: qsTr("Mono font")
|
||||
subtext: qsTr("Select desired mono font")
|
||||
model: root.fonts
|
||||
rootParent: root.flickable
|
||||
|
||||
initialSelect: Config.appearance.font.family.mono
|
||||
|
||||
onAccepted: {
|
||||
if (!selectedItem)
|
||||
return;
|
||||
|
||||
Config.appearance.font.family.mono = selectedItem;
|
||||
}
|
||||
}
|
||||
|
||||
SearchPopup {
|
||||
id: selectClockFont
|
||||
|
||||
acceptLabel: qsTr("Confirm")
|
||||
enabled: Object.keys(model).length > 0
|
||||
separateContent: false
|
||||
settingAnchor: "colors-fonts-clock-font"
|
||||
header: qsTr("Select font")
|
||||
last: true
|
||||
rowButton.activeItem: root.fonts.find(s => {
|
||||
var regex = new RegExp(Config.appearance.font.family.clock, "i");
|
||||
return regex.test(s);
|
||||
}) ?? ""
|
||||
label: qsTr("Clock font")
|
||||
subtext: qsTr("Select desired clock font")
|
||||
model: root.fonts
|
||||
rootParent: root.flickable
|
||||
|
||||
initialSelect: Config.appearance.font.family.clock
|
||||
|
||||
onAccepted: {
|
||||
if (!selectedItem)
|
||||
return;
|
||||
|
||||
Config.appearance.font.family.clock = selectedItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ PageBase {
|
||||
|
||||
CustomText {
|
||||
Layout.topMargin: Tokens.spacing.largeIncreased
|
||||
font.pointSize: Tokens.font.size.large
|
||||
font: Tokens.font.title.small
|
||||
text: qsTr("Wallpapers")
|
||||
}
|
||||
|
||||
|
||||
@@ -33,18 +33,35 @@ PageBase {
|
||||
}
|
||||
}
|
||||
|
||||
IconTextButton {
|
||||
ButtonRow {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
enabled: Config.background.enabled
|
||||
horizontalPadding: Tokens.padding.extraLarge
|
||||
icon: "wallpaper"
|
||||
isRound: true
|
||||
shapeMorph: true
|
||||
text: qsTr("Wallpapers")
|
||||
type: IconTextButton.Tonal
|
||||
verticalPadding: Tokens.padding.small
|
||||
spacing: Tokens.spacing.small
|
||||
|
||||
onClicked: root.sState.openSubPage(1) // Wallpaper page
|
||||
IconTextButton {
|
||||
enabled: Config.background.enabled
|
||||
horizontalPadding: Tokens.padding.extraLarge
|
||||
icon: "wallpaper"
|
||||
isRound: true
|
||||
shapeMorph: true
|
||||
text: qsTr("Wallpapers")
|
||||
type: IconTextButton.Tonal
|
||||
verticalPadding: Tokens.padding.small
|
||||
|
||||
onClicked: root.sState.openSubPage(1) // Wallpaper page
|
||||
}
|
||||
|
||||
IconTextButton {
|
||||
enabled: Config.background.enabled
|
||||
horizontalPadding: Tokens.padding.extraLarge
|
||||
icon: "palette"
|
||||
isRound: true
|
||||
shapeMorph: true
|
||||
text: qsTr("Colors & font")
|
||||
type: IconTextButton.Tonal
|
||||
verticalPadding: Tokens.padding.small
|
||||
|
||||
onClicked: root.sState.openSubPage(2) // Colors & font page
|
||||
}
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
@@ -76,85 +93,116 @@ PageBase {
|
||||
onToggled: Colors.setMode(checked ? "dark" : "light")
|
||||
}
|
||||
|
||||
OverlayRow {
|
||||
id: darkMode
|
||||
|
||||
TimeDialogSelect {
|
||||
readonly property string endTime: {
|
||||
var d = new Date(0, 0, 0, 0, 0, 0, 0);
|
||||
d.setMinutes(Config.general.color.scheduleDarkEnd);
|
||||
d.setMinutes(Config.colors.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);
|
||||
d.setMinutes(Config.colors.scheduleDarkStart);
|
||||
return Qt.formatTime(d, "hh:mm AP");
|
||||
}
|
||||
|
||||
checked: Config.general.color.scheduleDark
|
||||
rowButton.checked: Config.colors.scheduleDark
|
||||
rowButton.onToggled: Config.colors.scheduleDark = rowButton.checked
|
||||
start: Config.colors.scheduleDarkStart
|
||||
end: Config.colors.scheduleDarkEnd
|
||||
first: true
|
||||
last: true
|
||||
settingAnchor: "style-schedule-dark-mode"
|
||||
acceptLabel: qsTr("Apply")
|
||||
rootParent: root.flickable
|
||||
header: qsTr("Select time")
|
||||
subtext: qsTr("Dark mode will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
|
||||
text: qsTr("Schedule dark mode")
|
||||
label: 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;
|
||||
ModeScheduler.checkStartup();
|
||||
PopupManager.requestClose();
|
||||
}
|
||||
onClose: PopupManager.requestClose()
|
||||
}
|
||||
onOpenChanged: {
|
||||
root.sState.dimmed = open;
|
||||
}
|
||||
|
||||
onClicked: value => {
|
||||
Config.general.color.scheduleDark = value;
|
||||
onAccepted: {
|
||||
Config.colors.scheduleDarkStart = startCurrent;
|
||||
Config.colors.scheduleDarkEnd = endCurrent;
|
||||
ModeScheduler.checkStartup();
|
||||
}
|
||||
}
|
||||
|
||||
OverlayRow {
|
||||
id: hyprsunset
|
||||
|
||||
TimeDialogSelect {
|
||||
readonly property string endTime: {
|
||||
var d = new Date(0, 0, 0, 0, 0, 0, 0);
|
||||
d.setMinutes(Config.general.color.scheduleHyprsunsetEnd);
|
||||
d.setMinutes(Config.display.nightlight.scheduleEnd);
|
||||
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);
|
||||
d.setMinutes(Config.display.nightlight.scheduleStart);
|
||||
return Qt.formatTime(d, "hh:mm AP");
|
||||
}
|
||||
|
||||
rowButton.checked: Config.display.nightlight.schedule
|
||||
rowButton.onToggled: Config.display.nightlight.schedule = rowButton.checked
|
||||
start: Config.display.nightlight.scheduleStart
|
||||
end: Config.display.nightlight.scheduleEnd
|
||||
first: true
|
||||
settingAnchor: "style-schedule-nightlight"
|
||||
acceptLabel: qsTr("Apply")
|
||||
rootParent: root.flickable
|
||||
header: qsTr("Select time")
|
||||
subtext: qsTr("Nightlight will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
|
||||
label: qsTr("Schedule nightlight")
|
||||
|
||||
onOpenChanged: {
|
||||
root.sState.dimmed = open;
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
Config.display.nightlight.scheduleStart = startCurrent;
|
||||
Config.display.nightlight.scheduleEnd = endCurrent;
|
||||
Nightlight.checkStartup();
|
||||
}
|
||||
}
|
||||
|
||||
ToggleRow {
|
||||
Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing
|
||||
checked: Config.general.color.scheduleHyprsunset
|
||||
|
||||
checked: Config.display.nightlight.useNative
|
||||
settingAnchor: "display-nightlight-useNative"
|
||||
text: qsTr("Use native")
|
||||
subtext: qsTr("Use native shader nightlight for more features")
|
||||
|
||||
onToggled: Config.display.nightlight.useNative = checked
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing
|
||||
|
||||
from: 2000
|
||||
settingAnchor: "display-nightlight-temp"
|
||||
stepSize: 100
|
||||
subtext: qsTr("How warm/orange the screen will be. Lower is warmer (Kelvin)")
|
||||
text: qsTr("Temperature")
|
||||
to: 6500
|
||||
value: Config.display.nightlight.temp
|
||||
|
||||
onMoved: v => Config.display.nightlight.temp = v
|
||||
}
|
||||
|
||||
SpinRow {
|
||||
Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing
|
||||
|
||||
from: 0
|
||||
settingAnchor: "display-nightlight-fade-duration"
|
||||
enabled: Config.display.nightlight.useNative
|
||||
last: true
|
||||
settingAnchor: "style-schedule-hyprsunset"
|
||||
subtext: qsTr("Hyprsunset will turn on at %1, and turn off at %2.").arg(startTime).arg(endTime)
|
||||
text: qsTr("Schedule hyprsunset")
|
||||
stepSize: 1
|
||||
subtext: qsTr("How long it takes for the gradual nightlight to finish (s)")
|
||||
text: qsTr("Fade duration")
|
||||
to: 60 * 5
|
||||
value: Config.display.nightlight.fadeDuration / 1000
|
||||
|
||||
popup: Component {
|
||||
TimeInput {
|
||||
object: Config.general.color
|
||||
settings: ["scheduleHyprsunset", "scheduleHyprsunsetStart", "scheduleHyprsunsetEnd"]
|
||||
|
||||
onApplySettings: (start, end) => {
|
||||
Config.general.color.scheduleHyprsunsetStart = start;
|
||||
Config.general.color.scheduleHyprsunsetEnd = end;
|
||||
Hyprsunset.checkStartup();
|
||||
PopupManager.requestClose();
|
||||
}
|
||||
onClose: PopupManager.requestClose()
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: value => {
|
||||
Config.general.color.scheduleHyprsunset = value;
|
||||
}
|
||||
onMoved: v => Config.display.nightlight.fadeDuration = v * 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user