diff options
author | Gregor Kleen <gkleen@yggdrasil.li> | 2025-08-31 15:54:26 +0200 |
---|---|---|
committer | Gregor Kleen <gkleen@yggdrasil.li> | 2025-08-31 15:54:26 +0200 |
commit | 828893e930886872fcf612bc8958d33fee73b5df (patch) | |
tree | d9e9b55fd1e81c2c757c2918a0f11a18221891c0 /accounts | |
parent | 6eeb381a006d8b5c6bfd81bbb9a542d499aef27d (diff) | |
download | nixos-828893e930886872fcf612bc8958d33fee73b5df.tar nixos-828893e930886872fcf612bc8958d33fee73b5df.tar.gz nixos-828893e930886872fcf612bc8958d33fee73b5df.tar.bz2 nixos-828893e930886872fcf612bc8958d33fee73b5df.tar.xz nixos-828893e930886872fcf612bc8958d33fee73b5df.zip |
...
Diffstat (limited to 'accounts')
-rw-r--r-- | accounts/gkleen@sif/shell/quickshell/Clock.qml | 225 |
1 files changed, 134 insertions, 91 deletions
diff --git a/accounts/gkleen@sif/shell/quickshell/Clock.qml b/accounts/gkleen@sif/shell/quickshell/Clock.qml index 65b842b3..68efb558 100644 --- a/accounts/gkleen@sif/shell/quickshell/Clock.qml +++ b/accounts/gkleen@sif/shell/quickshell/Clock.qml | |||
@@ -4,6 +4,7 @@ import Quickshell | |||
4 | import Custom as Custom | 4 | import Custom as Custom |
5 | import QtQuick.Controls | 5 | import QtQuick.Controls |
6 | import QtQuick.Layouts | 6 | import QtQuick.Layouts |
7 | import Quickshell.Widgets | ||
7 | 8 | ||
8 | Item { | 9 | Item { |
9 | width: clock.contentWidth | 10 | width: clock.contentWidth |
@@ -16,6 +17,16 @@ Item { | |||
16 | anchors.fill: parent | 17 | anchors.fill: parent |
17 | hoverEnabled: true | 18 | hoverEnabled: true |
18 | enabled: true | 19 | enabled: true |
20 | |||
21 | property real angleRem: 0 | ||
22 | property real sensitivity: 1 / 120 | ||
23 | |||
24 | onWheel: event => { | ||
25 | angleRem += event.angleDelta.y; | ||
26 | const d = Math.round(angleRem * sensitivity); | ||
27 | yearCalendar.year += d; | ||
28 | angleRem -= d / sensitivity; | ||
29 | } | ||
19 | } | 30 | } |
20 | 31 | ||
21 | Text { | 32 | Text { |
@@ -43,139 +54,171 @@ Item { | |||
43 | } | 54 | } |
44 | visible: clockMouseArea.containsMouse | 55 | visible: clockMouseArea.containsMouse |
45 | 56 | ||
46 | implicitWidth: yearCalendar.implicitWidth + 16 | 57 | implicitWidth: clockTooltipContent.width |
47 | implicitHeight: yearCalendar.implicitHeight + 16 | 58 | implicitHeight: clockTooltipContent.height |
48 | color: "black" | 59 | color: "black" |
49 | 60 | ||
50 | GridLayout { | 61 | onVisibleChanged: { |
51 | property int year: { const d = new Date(); return d.getFullYear(); } | 62 | const d = new Date(); |
63 | yearCalendar.year = d.getFullYear(); | ||
64 | clockMouseArea.angleRem = 0; | ||
65 | } | ||
66 | |||
67 | WrapperItem { | ||
68 | id: clockTooltipContent | ||
69 | |||
70 | margin: 8 | ||
71 | leftMargin: 0 | ||
52 | 72 | ||
53 | id: yearCalendar | 73 | ColumnLayout { |
74 | Text { | ||
75 | id: yearLabel | ||
54 | 76 | ||
55 | columns: 3 | 77 | horizontalAlignment: Text.AlignHCenter |
56 | columnSpacing: 16 | ||
57 | rowSpacing: 16 | ||
58 | 78 | ||
59 | anchors.centerIn: parent | 79 | font.pointSize: 14 |
80 | font.family: "Fira Sans" | ||
81 | font.features: { "tnum": 1 } | ||
82 | color: "white" | ||
60 | 83 | ||
61 | Repeater { | 84 | text: yearCalendar.year |
62 | model: 12 | 85 | |
86 | Layout.fillWidth: true | ||
87 | Layout.bottomMargin: 8 | ||
88 | } | ||
63 | 89 | ||
64 | GridLayout { | 90 | GridLayout { |
65 | columns: 2 | 91 | property int year: { const d = new Date(); return d.getFullYear(); } |
66 | 92 | ||
67 | required property int index | 93 | id: yearCalendar |
68 | property int month: index | ||
69 | 94 | ||
70 | id: monthCalendar | 95 | columns: 3 |
96 | columnSpacing: 16 | ||
97 | rowSpacing: 16 | ||
71 | 98 | ||
72 | Layout.alignment: Qt.AlignTop | Qt.AlignRight | 99 | Layout.alignment: Qt.AlignHCenter |
73 | Layout.fillWidth: false | 100 | Layout.fillWidth: false |
74 | 101 | ||
75 | Text { | 102 | Repeater { |
76 | Layout.column: 1 | 103 | model: 12 |
77 | Layout.fillWidth: true | ||
78 | 104 | ||
79 | horizontalAlignment: Text.AlignHCenter | 105 | GridLayout { |
106 | columns: 2 | ||
80 | 107 | ||
81 | font.pointSize: 10 | 108 | required property int index |
82 | font.family: "Fira Sans" | 109 | property int month: index |
83 | 110 | ||
84 | text: { | 111 | id: monthCalendar |
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 | 112 | ||
89 | color: "#ffead3" | 113 | Layout.alignment: Qt.AlignTop | Qt.AlignRight |
90 | } | 114 | Layout.fillWidth: false |
91 | 115 | ||
92 | DayOfWeekRow { | 116 | Text { |
93 | locale: grid.locale | 117 | Layout.column: 1 |
118 | Layout.fillWidth: true | ||
94 | 119 | ||
95 | Layout.row: 1 | 120 | horizontalAlignment: Text.AlignHCenter |
96 | Layout.column: 1 | ||
97 | Layout.fillWidth: true | ||
98 | 121 | ||
99 | delegate: Text { | 122 | font.pointSize: 10 |
100 | required property string shortName | 123 | font.family: "Fira Sans" |
101 | 124 | ||
102 | font.pointSize: 10 | 125 | text: { |
103 | font.family: "Fira Mono" | 126 | const date = Date.fromLocaleDateString(Qt.locale(), `${yearCalendar.year}-${monthCalendar.month + 1}-01`, "yyyy-M-dd"); |
127 | return date.toLocaleString(Qt.locale("en_DK"), "MMMM") | ||
128 | } | ||
104 | 129 | ||
105 | text: shortName | 130 | color: "#ffead3" |
106 | color: "#ffcc66" | 131 | } |
107 | 132 | ||
108 | horizontalAlignment: Text.AlignRight | 133 | DayOfWeekRow { |
109 | verticalAlignment: Text.AlignVCenter | 134 | locale: grid.locale |
110 | } | ||
111 | } | ||
112 | 135 | ||
113 | WeekNumberColumn { | 136 | Layout.row: 1 |
114 | month: grid.month | 137 | Layout.column: 1 |
115 | year: grid.year | 138 | Layout.fillWidth: true |
116 | locale: grid.locale | ||
117 | 139 | ||
118 | Layout.fillHeight: true | 140 | delegate: Text { |
141 | required property string shortName | ||
119 | 142 | ||
120 | delegate: Text { | 143 | font.pointSize: 10 |
121 | required property int weekNumber | 144 | font.family: "Fira Mono" |
122 | 145 | ||
123 | opacity: { | 146 | text: shortName |
124 | const simple = new Date(weekNumber == 1 && monthCalendar.month == 12 ? yearCalendar.year + 1 : yearCalendar.year, 0, 1 + (weekNumber - 1) * 7); | 147 | color: "#ffcc66" |
125 | const dayOfWeek = simple.getDay(); | ||
126 | const isoWeekStart = simple; | ||
127 | 148 | ||
128 | isoWeekStart.setDate(simple.getDate() - dayOfWeek + 1); | 149 | horizontalAlignment: Text.AlignRight |
129 | if (dayOfWeek > 4) { | 150 | verticalAlignment: Text.AlignVCenter |
130 | isoWeekStart.setDate(isoWeekStart.getDate() + 7); | ||
131 | } | 151 | } |
152 | } | ||
132 | 153 | ||
133 | for (let i = 0; i < 7; i++) { | 154 | WeekNumberColumn { |
134 | const dayInWeek = new Date(isoWeekStart); | 155 | month: grid.month |
135 | dayInWeek.setDate(dayInWeek.getDate() + i); | 156 | year: grid.year |
136 | if (dayInWeek.getMonth() == monthCalendar.month) | 157 | locale: grid.locale |
137 | return 1; | ||
138 | } | ||
139 | 158 | ||
140 | return 0; | 159 | Layout.fillHeight: true |
141 | } | ||
142 | 160 | ||
143 | font.pointSize: 10 | 161 | delegate: Text { |
144 | font.family: "Fira Sans" | 162 | required property int weekNumber |
145 | font.features: { "tnum": 1 } | ||
146 | 163 | ||
147 | text: weekNumber | 164 | opacity: { |
148 | color: "#99ffdd" | 165 | const simple = new Date(weekNumber == 1 && monthCalendar.month == 12 ? yearCalendar.year + 1 : yearCalendar.year, 0, 1 + (weekNumber - 1) * 7); |
166 | const dayOfWeek = simple.getDay(); | ||
167 | const isoWeekStart = simple; | ||
149 | 168 | ||
150 | horizontalAlignment: Text.AlignRight | 169 | isoWeekStart.setDate(simple.getDate() - dayOfWeek + 1); |
151 | verticalAlignment: Text.AlignVCenter | 170 | if (dayOfWeek > 4) { |
152 | } | 171 | isoWeekStart.setDate(isoWeekStart.getDate() + 7); |
153 | } | 172 | } |
154 | 173 | ||
155 | MonthGrid { | 174 | for (let i = 0; i < 7; i++) { |
156 | id: grid | 175 | const dayInWeek = new Date(isoWeekStart); |
176 | dayInWeek.setDate(dayInWeek.getDate() + i); | ||
177 | if (dayInWeek.getMonth() == monthCalendar.month) | ||
178 | return 1; | ||
179 | } | ||
157 | 180 | ||
158 | year: yearCalendar.year | 181 | return 0; |
159 | month: monthCalendar.month | 182 | } |
160 | locale: Qt.locale("en_DK") | ||
161 | 183 | ||
162 | Layout.fillWidth: true | 184 | font.pointSize: 10 |
163 | Layout.fillHeight: true | 185 | font.family: "Fira Sans" |
186 | font.features: { "tnum": 1 } | ||
164 | 187 | ||
165 | delegate: Text { | 188 | text: weekNumber |
166 | required property var model | 189 | color: "#99ffdd" |
167 | 190 | ||
168 | opacity: model.month === monthCalendar.month ? 1 : 0 | 191 | horizontalAlignment: Text.AlignRight |
192 | verticalAlignment: Text.AlignVCenter | ||
193 | } | ||
194 | } | ||
169 | 195 | ||
170 | font.pointSize: 10 | 196 | MonthGrid { |
171 | font.family: "Fira Sans" | 197 | id: grid |
172 | font.features: { "tnum": 1 } | 198 | |
199 | year: yearCalendar.year | ||
200 | month: monthCalendar.month | ||
201 | locale: Qt.locale("en_DK") | ||
202 | |||
203 | Layout.fillWidth: true | ||
204 | Layout.fillHeight: true | ||
205 | |||
206 | delegate: Text { | ||
207 | required property var model | ||
173 | 208 | ||
174 | text: model.day | 209 | opacity: model.month === monthCalendar.month ? 1 : 0 |
175 | color: model.today ? "#ff6699" : "white" | ||
176 | 210 | ||
177 | horizontalAlignment: Text.AlignRight | 211 | font.pointSize: 10 |
178 | verticalAlignment: Text.AlignVCenter | 212 | font.family: "Fira Sans" |
213 | font.features: { "tnum": 1 } | ||
214 | |||
215 | text: model.day | ||
216 | color: model.today ? "#ff6699" : "white" | ||
217 | |||
218 | horizontalAlignment: Text.AlignRight | ||
219 | verticalAlignment: Text.AlignVCenter | ||
220 | } | ||
221 | } | ||
179 | } | 222 | } |
180 | } | 223 | } |
181 | } | 224 | } |