blob: a3971050a32e0e60e557bc669dda9ac9572a21f3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
import Quickshell
import QtQuick
// The settings window: a normal toplevel, not a layer surface, so Hyprland
// tiles or floats it like any app. The drawer is the quick area; things set
// once and left alone live here. It hosts the pages of the modules that
// declare `settings: true`, from the same module list as the drawer, with a
// list of them down the left.
Scope {
id: root
property list<QtObject> modules
property bool open: false
property string page: ""
readonly property var pages: {
const out = [];
for (let i = 0; i < root.modules.length; i++)
if (root.modules[i].settings) out.push(root.modules[i]);
return out;
}
readonly property QtObject current: root.pages.find(m => m.name === root.page) ?? root.pages[0] ?? null
// An unknown or empty name opens the first page.
function show(name) { root.page = name; root.open = true; }
function close() { root.open = false; }
LazyLoader {
active: root.open
FloatingWindow {
title: "Settings"
implicitWidth: 900
implicitHeight: 640
color: Theme.base
onClosed: root.close()
Item {
anchors.fill: parent
focus: true
Keys.onEscapePressed: root.close()
ListView {
id: side
anchors { top: parent.top; left: parent.left; bottom: parent.bottom; margins: 12 }
width: 200
spacing: 4
model: root.pages
delegate: Rectangle {
id: entry
required property QtObject modelData
readonly property bool selected: root.current === modelData
width: side.width
height: 36
radius: 8
color: selected ? Qt.alpha(Theme.accent, 0.22)
: area.containsMouse ? Qt.alpha(Theme.text, 0.06) : "transparent"
Row {
anchors { left: parent.left; leftMargin: 10; verticalCenter: parent.verticalCenter }
spacing: 10
Text {
text: entry.modelData.icon
font { family: Theme.iconFamily; pixelSize: Theme.fontSize }
color: Theme.text
}
Text {
text: entry.modelData.label
font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 }
color: Theme.text
}
}
MouseArea {
id: area
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: root.page = entry.modelData.name
}
}
}
Rectangle {
id: rule
anchors { top: parent.top; bottom: parent.bottom; left: side.right; leftMargin: 12 }
width: 1
color: Qt.alpha(Theme.text, 0.12)
}
Loader {
id: pageLoader
anchors { top: parent.top; right: parent.right; bottom: parent.bottom; left: rule.right; margins: 16 }
sourceComponent: root.current?.page ?? null
// The Page's back arrow and dismiss close the window;
// go() moves to another settings page by name.
onLoaded: {
if (item && item.back) item.back.connect(root.close);
if (item && item.dismiss) item.dismiss.connect(root.close);
if (item && item.go) item.go.connect(name => root.page = name);
}
Binding {
target: pageLoader.item
property: "icon"
value: root.current ? root.current.icon : ""
when: pageLoader.item !== null
}
}
}
}
}
}
|