-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclock.lua
256 lines (187 loc) · 7.16 KB
/
clock.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
--[[
A conky clock by Jochen Keil (2013)
based upon Alison Pitt's Air Clock (2009)
This clock is designed to resemble the swiss railway clock:
https://en.wikipedia.org/wiki/Swiss_railway_clock
https://upload.wikimedia.org/wikipedia/de/7/7c/Minutensprunguhr_animiert.gif
From the wikipedia article:
[..]
The second hand is driven by an electrical motor independent of the
master clock. It requires only about 58.5 seconds to circle the face, then the
hand pauses briefly at the top of the clock. It starts a new rotation as soon
as it receives the next minute impulse from the master clock
[..]
This clock also rotates smoothly without "ticks".
It will also stop on top for a configureable delay (look out for the global delay value)
The main drawback is resource usage. For smooth circulation, conky needs to be
updated every 0.1 second. Therefore I strongly recommend to run this in
a seperate conky process.
Additionally, if the update_interval is larger than 1 the seconds hand is not
drawn. Hence, to save battery set update_interval_on_battery to 30 or so.
--]]
require 'cairo'
-- how long to pause the seconds hand
delay = 2
-- r, g, b, a
background_color = { 1, 1, 1, 1 }
surface_bg = nil
surface_hours_hand = nil
surface_minutes_hand = nil
surface_seconds_hand = nil
sub_secs = 0
last_secs = 60
function init(window)
surface_bg = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
window.width, window.height)
surface_hours_hand = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
window.width, window.height)
surface_minutes_hand = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
window.width, window.height)
surface_seconds_hand = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
window.width, window.height)
draw_seconds_hand(window.width / 2, window.height / 2,
math.min(window.width, window.height) / 2)
draw_marks(window.width / 2, window.height / 2,
math.min(window.width, window.height) / 2)
end
function conky_shutdown()
cairo_surface_destroy(surface_bg)
cairo_surface_destroy(surface_hours_hand)
cairo_surface_destroy(surface_minutes_hand)
cairo_surface_destroy(surface_seconds_hand)
end
function draw_marks(xc, yc, clock_r)
local cr = cairo_create(surface_bg)
local minutes_len = clock_r * 0.075
local minutes_thick = clock_r * 0.025
local minutes_color = { 0.0, 0, 0, 1.0 }
local hours_len = clock_r * 0.245
local hours_thick = clock_r * 0.069
local hours_color = { 0.0, 0, 0, 1.0 }
local steps = 360/60
local r,g,b,a = unpack(background_color)
cairo_set_source_rgba(cr, r, g, b, a)
cairo_arc(cr, xc, yc, clock_r, 0, 2 * math.pi)
cairo_fill(cr)
for deg = steps, 360, steps do
local len = minutes_len
local thick = minutes_thick
local r,g,b,a = unpack(minutes_color)
if deg % (360/12) == 0 then
len = hours_len
thick = hours_thick
r,g,b,a = unpack(hours_color)
end
xbegin = xc + (clock_r - len) * math.sin(deg / (180/math.pi))
ybegin = yc - (clock_r - len) * math.cos(deg / (180/math.pi))
xend = xc + clock_r * math.sin(deg / (180/math.pi))
yend = yc - clock_r * math.cos(deg / (180/math.pi))
cairo_move_to(cr,xbegin,ybegin)
cairo_line_to(cr,xend,yend)
cairo_set_line_cap(cr,CAIRO_LINE_CAP_BUTT)
cairo_set_line_width(cr,thick)
cairo_set_source_rgba(cr,r,g,b,a)
cairo_stroke(cr)
end
cairo_destroy(cr)
end
function draw_hours(xc, yc, clock_r, hours_arc)
local hours_cr = cairo_create(surface_hours_hand)
local xbegin=xc+(clock_r * -0.24)*math.sin(hours_arc)
local ybegin=yc-(clock_r * -0.24)*math.cos(hours_arc)
local xend=xc+(clock_r * 0.672)*math.sin(hours_arc)
local yend=yc-(clock_r * 0.672)*math.cos(hours_arc)
cairo_set_operator(hours_cr, CAIRO_OPERATOR_CLEAR)
cairo_paint(hours_cr)
cairo_set_operator(hours_cr, CAIRO_OPERATOR_SOURCE);
cairo_move_to(hours_cr,xbegin,ybegin)
cairo_line_to(hours_cr,xend,yend)
cairo_set_line_width(hours_cr,clock_r * 0.11)
cairo_stroke(hours_cr)
cairo_destroy(hours_cr)
end
function draw_minutes(xc, yc, clock_r, mins_arc)
local mins_cr = cairo_create(surface_minutes_hand)
local xbegin=xc+(clock_r * -0.25)*math.sin(mins_arc)
local ybegin=yc-(clock_r * -0.25)*math.cos(mins_arc)
local xend=xc+(clock_r * 0.94)*math.sin(mins_arc)
local yend=yc-(clock_r * 0.94)*math.cos(mins_arc)
cairo_set_operator(mins_cr, CAIRO_OPERATOR_CLEAR)
cairo_paint(mins_cr)
cairo_set_operator(mins_cr, CAIRO_OPERATOR_SOURCE);
cairo_move_to(mins_cr,xbegin,ybegin)
cairo_line_to(mins_cr,xend,yend)
cairo_set_line_width(mins_cr,clock_r * 0.08)
cairo_stroke(mins_cr)
cairo_destroy(mins_cr)
end
function draw_seconds_hand(xc, yc, clock_r)
local secs_cr = cairo_create(surface_seconds_hand)
local xbegin=xc
local ybegin=yc-(clock_r * -0.34)
local xend=xc
local yend=yc-(clock_r * 0.65)
cairo_set_source_rgba(secs_cr,1.0,0.0,0.0,1.0)
cairo_move_to(secs_cr,xbegin,ybegin)
cairo_line_to(secs_cr,xend,yend)
cairo_set_line_width(secs_cr,clock_r * 0.025)
cairo_stroke(secs_cr)
cairo_arc(secs_cr, xend, yend, clock_r * 0.105, 0, 2 * math.pi)
cairo_fill(secs_cr)
cairo_destroy(secs_cr)
end
function conky_clock()
if conky_window == nil then
return
elseif conky_window.width == 0 or conky_window.height == 0 then
return
end
local first_run = surface_bg == nil
if first_run then init(conky_window) end
local w = conky_window.width
local h = conky_window.height
local cs = cairo_xlib_surface_create(conky_window.display,
conky_window.drawable,
conky_window.visual,
w, h)
local cr = cairo_create(cs)
-- Settings
local update_interval = conky_info["update_interval"]
local clock_r = math.min(w,h) / 2
local xc=w/2
local yc=h/2
local secs = os.date("%S")
if not (last_secs == tonumber(secs)) then sub_secs = 0 end
if last_secs > tonumber(secs) then
local mins=os.date("%M")
local mins_arc=(2*math.pi/60)*mins
draw_minutes(xc, yc, clock_r, mins_arc)
local hours=os.date("%I")
local hours_arc=(2*math.pi/12)*hours+mins_arc/12
draw_hours(xc, yc, clock_r, hours_arc)
end
last_secs = tonumber(secs)
cairo_set_source_surface(cr, surface_bg, 0, 0)
cairo_paint(cr)
cairo_set_source_surface(cr, surface_hours_hand, 0, 0)
cairo_paint(cr)
cairo_set_source_surface(cr, surface_minutes_hand, 0, 0)
cairo_paint(cr)
if update_interval <= 1 then
local secs_arc = 0
if (update_interval < 1) then
secs_arc = 2 * math.pi * (secs + sub_secs) / (60 - delay)
if (secs_arc > 2 * math.pi) then secs_arc = 0 end
sub_secs = sub_secs + update_interval
elseif update_interval == 1 then
secs_arc = 2 * math.pi * ((secs + delay) / 60)
end
cairo_translate(cr, xc, yc)
cairo_rotate(cr, secs_arc)
cairo_translate(cr, -xc, -yc)
cairo_set_source_surface(cr, surface_seconds_hand, 0, 0)
cairo_paint(cr)
end
cairo_destroy(cr)
cairo_surface_destroy(cs)
end