me like nix
1import QtQuick
2import QtQuick.Layouts
3import Quickshell
4import "../../config" as Config
5import "../../services" as Services
6import "components"
7import "popouts"
8
9PanelWindow {
10 id: sidebar
11
12 required property var modelData
13 screen: modelData
14
15 anchors {
16 left: true
17 top: true
18 bottom: true
19 }
20 margins.left: 0
21 margins.top: 0
22 margins.bottom: 0
23 implicitWidth: 48
24 color: "transparent"
25
26 property string activePopout: ""
27 property real popoutAnchorY: height / 2
28
29 function togglePopout(name) {
30 if (activePopout === name)
31 activePopout = ""
32 else
33 activePopout = name
34 }
35
36 function openPopoutAt(name, item) {
37 var pos = item.mapToItem(barBg, 0, item.height / 2)
38 popoutAnchorY = pos.y
39 togglePopout(name)
40 }
41
42 Rectangle {
43 id: barBg
44 anchors.fill: parent
45 radius: Config.Appearance.rounding.large
46 color: Qt.rgba(
47 Config.Colours.mantle.r,
48 Config.Colours.mantle.g,
49 Config.Colours.mantle.b,
50 Config.Appearance.barOpacity
51 )
52
53 ColumnLayout {
54 anchors.fill: parent
55 anchors.leftMargin: 4
56 anchors.rightMargin: 4
57 anchors.topMargin: 10
58 anchors.bottomMargin: 10
59 spacing: Config.Appearance.spacing.normal
60
61 // NixOS Logo
62 LogoButton {
63 id: logoButton
64 Layout.alignment: Qt.AlignHCenter
65 onClicked: sidebar.openPopoutAt("session", logoButton)
66 }
67
68 // Top spacer
69 Item { Layout.fillHeight: true }
70
71 // Vertical Clock
72 VerticalClock {
73 Layout.alignment: Qt.AlignHCenter
74 onClicked: sidebar.togglePopout("dashboard")
75 }
76
77 // Weather
78 Text {
79 Layout.alignment: Qt.AlignHCenter
80 font.pixelSize: 14
81 text: Services.Weather.icon
82 visible: Services.Weather.icon !== ""
83 }
84 Text {
85 Layout.alignment: Qt.AlignHCenter
86 color: Config.Colours.subtext0
87 font.family: Config.Appearance.font.family
88 font.pixelSize: 10
89 text: Services.Weather.temp
90 visible: Services.Weather.temp !== ""
91 }
92
93 // Bottom spacer
94 Item { Layout.fillHeight: true }
95
96 // Tray pill
97 Rectangle {
98 Layout.fillWidth: true
99 implicitHeight: trayLayout.implicitHeight + Config.Appearance.padding.normal * 2
100 radius: Config.Appearance.rounding.full
101 color: Config.Colours.surface0
102 clip: true
103 visible: tray.count > 0
104
105 ColumnLayout {
106 id: trayLayout
107 anchors.horizontalCenter: parent.horizontalCenter
108 anchors.verticalCenter: parent.verticalCenter
109 spacing: Config.Appearance.spacing.small
110
111 Tray { id: tray }
112 }
113 }
114
115 // Status icons pill
116 Rectangle {
117 Layout.fillWidth: true
118 implicitHeight: statusCol.implicitHeight + Config.Appearance.padding.normal * 2
119 radius: Config.Appearance.rounding.full
120 color: Config.Colours.surface0
121 clip: true
122
123 ColumnLayout {
124 id: statusCol
125 anchors.horizontalCenter: parent.horizontalCenter
126 anchors.verticalCenter: parent.verticalCenter
127 spacing: Config.Appearance.spacing.small
128
129 // Volume
130 SidebarIcon {
131 id: volumeIcon
132 Layout.alignment: Qt.AlignHCenter
133 iconText: Services.Audio.muted ? "\uf026" : (Services.Audio.volume > 50 ? "\uf028" : "\uf027")
134 iconColor: Config.Colours.maroon
135 onClicked: sidebar.openPopoutAt("audio", volumeIcon)
136 }
137
138 // Network
139 SidebarIcon {
140 id: networkIcon
141 Layout.alignment: Qt.AlignHCenter
142 iconText: {
143 if (!Services.Network.connected) return "\uf071"
144 if (Services.Network.isEthernet) return "\udb80\ude00"
145 return "\uf1eb"
146 }
147 iconColor: Config.Colours.green
148 onClicked: sidebar.openPopoutAt("network", networkIcon)
149 }
150
151 // Battery / Power Profile
152 SidebarIcon {
153 id: batteryIcon
154 Layout.alignment: Qt.AlignHCenter
155 visible: Services.Battery.hasBattery
156 iconText: {
157 if (Services.Battery.status === "Charging") return "\uf0e7"
158 var p = Services.Battery.percent
159 if (p > 75) return "\uf240"
160 if (p > 50) return "\uf241"
161 if (p > 25) return "\uf242"
162 if (p > 10) return "\uf243"
163 return "\uf244"
164 }
165 iconColor: {
166 if (Services.Battery.status === "Charging") return Config.Colours.green
167 if (Services.Battery.percent <= 20) return Config.Colours.red
168 return Config.Colours.green
169 }
170 onClicked: sidebar.openPopoutAt("powerprofile", batteryIcon)
171 }
172 }
173 }
174
175 }
176 }
177
178 // Popout windows
179 DashboardPopout {
180 show: sidebar.activePopout === "dashboard"
181 parentWindow: sidebar
182 anchorY: sidebar.height / 2
183 onClose: sidebar.activePopout = ""
184 }
185
186 SessionPopout {
187 show: sidebar.activePopout === "session"
188 parentWindow: sidebar
189 anchorY: sidebar.popoutAnchorY
190 onClose: sidebar.activePopout = ""
191 }
192
193 AudioPopout {
194 show: sidebar.activePopout === "audio"
195 parentWindow: sidebar
196 anchorY: sidebar.popoutAnchorY
197 onClose: sidebar.activePopout = ""
198 }
199
200 NetworkPopout {
201 show: sidebar.activePopout === "network"
202 parentWindow: sidebar
203 anchorY: sidebar.popoutAnchorY
204 onClose: sidebar.activePopout = ""
205 }
206
207 PowerProfilePopout {
208 show: sidebar.activePopout === "powerprofile"
209 parentWindow: sidebar
210 anchorY: sidebar.popoutAnchorY
211 onClose: sidebar.activePopout = ""
212 }
213}