summaryrefslogtreecommitdiff
path: root/accounts/gkleen@sif/shell/quickshell/Clock.qml
diff options
context:
space:
mode:
Diffstat (limited to 'accounts/gkleen@sif/shell/quickshell/Clock.qml')
-rw-r--r--accounts/gkleen@sif/shell/quickshell/Clock.qml283
1 files changed, 283 insertions, 0 deletions
diff --git a/accounts/gkleen@sif/shell/quickshell/Clock.qml b/accounts/gkleen@sif/shell/quickshell/Clock.qml
new file mode 100644
index 00000000..382af168
--- /dev/null
+++ b/accounts/gkleen@sif/shell/quickshell/Clock.qml
@@ -0,0 +1,283 @@
1import QtQml
2import QtQuick
3import Quickshell
4import Custom as Custom
5import QtQuick.Controls
6import QtQuick.Layouts
7import Quickshell.Widgets
8
9Item {
10 id: clockItem
11
12 property bool calendarPopup: true
13
14 width: clock.contentWidth
15 height: parent.height
16 anchors.verticalCenter: parent.verticalCenter
17
18 WrapperMouseArea {
19 id: clockMouseArea
20
21 anchors.fill: parent
22 hoverEnabled: true
23 enabled: clockItem.calendarPopup
24
25 Item {
26 anchors.fill: parent
27
28 Text {
29 id: clock
30 color: "white"
31
32 anchors.verticalCenter: parent.verticalCenter
33
34 Custom.Chrono {
35 id: chrono
36
37 onDateChanged: clock.text = format("W{0:%V-%u} {0:%F} {0:%H:%M:%S%Ez}")
38 }
39
40 font.pointSize: 10
41 font.family: "Fira Sans"
42 font.features: { "tnum": 1 }
43 }
44 }
45 }
46
47 Loader {
48 id: tooltipLoader
49
50 active: false
51
52 Connections {
53 target: clockMouseArea
54 function onContainsMouseChanged() {
55 if (clockMouseArea.containsMouse)
56 tooltipLoader.active = true;
57 }
58 }
59
60 sourceComponent: PopupWindow {
61 id: tooltip
62
63 property bool nextVisible: clockMouseArea.containsMouse || tooltipMouseArea.containsMouse
64
65 anchor {
66 item: clockMouseArea
67 edges: Edges.Bottom | Edges.Left
68 }
69 visible: false
70
71 onNextVisibleChanged: hangTimer.restart()
72
73 Timer {
74 id: hangTimer
75 interval: 100
76 onTriggered: tooltip.visible = tooltip.nextVisible
77 }
78
79 implicitWidth: clockTooltipContent.width
80 implicitHeight: clockTooltipContent.height
81 color: "black"
82
83 onVisibleChanged: {
84 yearCalendar.year = chrono.date.getFullYear();
85 yearCalendar.angleRem = 0;
86 }
87
88 WrapperMouseArea {
89 id: tooltipMouseArea
90
91 hoverEnabled: true
92 enabled: true
93
94 onWheel: event => yearCalendar.scrollYear(event)
95
96 anchors.fill: parent
97
98 WrapperItem {
99 id: clockTooltipContent
100
101 margin: 8
102 leftMargin: 0
103
104 ColumnLayout {
105 Text {
106 id: yearLabel
107
108 horizontalAlignment: Text.AlignHCenter
109
110 font.pointSize: 14
111 font.family: "Fira Sans"
112 font.features: { "tnum": 1 }
113 color: "white"
114
115 text: yearCalendar.year
116
117 Layout.fillWidth: true
118 Layout.bottomMargin: 8
119 }
120
121 GridLayout {
122 property int year: chrono.date.getFullYear()
123
124 id: yearCalendar
125
126 columns: 3
127 columnSpacing: 16
128 rowSpacing: 16
129
130 Layout.alignment: Qt.AlignHCenter
131 Layout.fillWidth: false
132
133 property real angleRem: 0
134 property real sensitivity: 1 / 120
135
136 function scrollYear(event) {
137 angleRem += event.angleDelta.y;
138 const d = Math.round(angleRem * sensitivity);
139 yearCalendar.year += d;
140 angleRem -= d / sensitivity;
141 }
142
143 Connections {
144 target: clockMouseArea
145 function onWheel(event) { yearCalendar.scrollYear(event); }
146 }
147
148 Repeater {
149 model: 12
150
151 GridLayout {
152 columns: 2
153
154 required property int index
155 property int month: index
156
157 id: monthCalendar
158
159 Layout.alignment: Qt.AlignTop | Qt.AlignRight
160 Layout.fillWidth: false
161
162 Text {
163 Layout.column: 1
164 Layout.fillWidth: true
165
166 horizontalAlignment: Text.AlignHCenter
167
168 font.pointSize: 10
169 font.family: "Fira Sans"
170
171 text: new Date(yearCalendar.year, monthCalendar.month, 1).toLocaleString(Qt.locale("en_DK"), "MMMM")
172
173 color: "#ffead3"
174 }
175
176 DayOfWeekRow {
177 locale: grid.locale
178
179 Layout.row: 1
180 Layout.column: 1
181 Layout.fillWidth: true
182
183 delegate: WrapperItem {
184 required property string shortName
185
186 width: dowLabel.contentWidth + 6
187
188 Text {
189 id: dowLabel
190
191 anchors.fill: parent
192
193 font.pointSize: 10
194 font.family: "Fira Sans"
195
196 text: parent.shortName
197 color: "#ffcc66"
198
199 horizontalAlignment: Text.AlignHCenter
200 verticalAlignment: Text.AlignVCenter
201 }
202 }
203 }
204
205 WeekNumberColumn {
206 month: grid.month
207 year: grid.year
208 locale: grid.locale
209
210 Layout.fillHeight: true
211
212 delegate: Text {
213 required property int weekNumber
214
215 opacity: {
216 const simple = new Date(weekNumber == 1 && monthCalendar.month == 12 ? yearCalendar.year + 1 : yearCalendar.year, 0, 1 + (weekNumber - 1) * 7);
217 const dayOfWeek = simple.getDay();
218 const isoWeekStart = simple;
219
220 isoWeekStart.setDate(simple.getDate() - dayOfWeek + 1);
221 if (dayOfWeek > 4) {
222 isoWeekStart.setDate(isoWeekStart.getDate() + 7);
223 }
224
225 for (let i = 0; i < 7; i++) {
226 const dayInWeek = new Date(isoWeekStart);
227 dayInWeek.setDate(dayInWeek.getDate() + i);
228 if (dayInWeek.getMonth() == monthCalendar.month)
229 return 1;
230 }
231
232 return 0;
233 }
234
235 font.pointSize: 10
236 font.family: "Fira Sans"
237 font.features: { "tnum": 1 }
238
239 text: weekNumber
240 color: "#99ffdd"
241
242 horizontalAlignment: Text.AlignRight
243 verticalAlignment: Text.AlignVCenter
244 }
245 }
246
247 MonthGrid {
248 id: grid
249
250 year: yearCalendar.year
251 month: monthCalendar.month
252 locale: Qt.locale("en_DK")
253
254 Layout.fillWidth: true
255 Layout.fillHeight: true
256
257 delegate: Text {
258 required property var model
259
260 opacity: model.month === monthCalendar.month ? 1 : 0
261
262 font.pointSize: 10
263 font.family: "Fira Sans"
264 font.features: { "tnum": 1 }
265
266 property bool today: chrono.date.getFullYear() == model.year && chrono.date.getMonth() == model.month && chrono.date.getDate() == model.day
267
268 text: model.day
269 color: today ? "#ff6699" : "white"
270
271 horizontalAlignment: Text.AlignRight
272 verticalAlignment: Text.AlignVCenter
273 }
274 }
275 }
276 }
277 }
278 }
279 }
280 }
281 }
282 }
283}