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