aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/Settings.qml
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
                    }
                }
            }
        }
    }
}