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