------------------------------------------------------------------------------ -- -- Analog clock -- (с) maisvendoo, 09.06.2013 -- ------------------------------------------------------------------------------ local wibox = require("wibox") local capi = {timer = timer} clock = {} ------------------------------------------------------------------------------- -- Clock params ------------------------------------------------------------------------------- clock.width = 300 -- clock width clock.height = 300 -- clock height clock.bg_color = "#00000000" -- background color clock.x = 20 -- x-coordinate clock.y = 20 -- y-coordinate ------------------------------------------------------------------------------- -- Create wibox ------------------------------------------------------------------------------- local clock_wbox = wibox({ bg = clock.bg_color, width = clock.width, height = clock.height}) clock_wbox.ontop = false -- Widget is not on top clock_wbox.visible = true -- Visible clock_wbox:geometry({x = clock.x, y = clock.y}) -- Clock coordinates ------------------------------------------------------------------------------- -- Create widget ------------------------------------------------------------------------------- local clock_widget = wibox.widget.base.make_widget() ------------------------------------------------------------------------------- -- Reference widget size ------------------------------------------------------------------------------- clock_widget.fit = function(clock_widget, width, height) return width, height end ------------------------------------------------------------------------------- -- Draw callback for cairo ------------------------------------------------------------------------------- clock_widget.draw = function(clock_widget, clock_wbox, cr, width, height) -- Any params calculation local radius = width/2 - 5 local cx = width/2 local cy = height/2 local hour_len = 15 local min_len = 7 -- Draw dial -- Draw hour divisions cr:set_line_width (2) cr:set_source_rgba (0.7, 0.7, 0.7, 1) local kx = 1.0 local ky = 1.0 for i = 0,11 do cr:move_to (cx + kx*(radius - hour_len)*math.sin(i*math.rad(30)), cy - kx*(radius - hour_len)*math.cos(i*math.rad(30)) ) cr:line_to (cx + ky*radius*math.sin(i*math.rad(30)), cy - ky*radius*math.cos(i*math.rad(30)) ) cr:stroke () end -- Draw minute divisions cr:set_line_width (1) cr:set_source_rgba (0.7, 0.7, 0.7, 1) for i = 0,59 do cr:move_to (cx + kx*(radius - min_len)*math.sin(i*math.rad(6)), cy - ky*(radius - min_len)*math.cos(i*math.rad(6)) ) cr:line_to (cx + kx*radius*math.sin(i*math.rad(6)), cy - ky*radius*math.cos(i*math.rad(6)) ) cr:stroke () end -- Draw digits on dial local dig_size = 50 local dig_radius = radius/1.3 local n_hours = 12 local extents cr:select_font_face ('Times', 0, 0) cr:set_font_size (dig_size) for i = 1,n_hours do local dig = i*12/n_hours extents = cr:text_extents (dig) local dx = cx + kx*dig_radius*math.sin(i*math.rad(360/n_hours)) local dy = cy - ky*dig_radius*math.cos(i*math.rad(360/n_hours)) local tx = dx - extents.width/2 local ty = dy + extents.height/2 cr:move_to (tx, ty) cr:show_text(dig) end -- Draw arrows -- Get local time local sec = os.date('%S') local min = os.date('%M') local hour = os.date('%H') -- Set arrow length local hour_arrow_len = radius/1.8 local min_arrow_len = radius - min_len - 8 local sec_arrow_len = radius - min_len - 6 -- Draw hour arrow cr:set_line_width (9) cr:set_source_rgba (1, 1, 1, 1) cr:move_to (cx, cy) cr:line_to (cx + hour_arrow_len*math.sin(math.rad((hour + min/60 + sec/3600)*30)), cy - hour_arrow_len*math.cos(math.rad((hour + min/60 + sec/3600)*30)) ) cr:stroke () -- Draw minute arrow cr:set_line_width (4) cr:set_source_rgba (1, 1, 1, 1) cr:move_to (cx, cy) cr:line_to (cx + min_arrow_len*math.sin(math.rad((min + sec/60)*6)), cy - sec_arrow_len*math.cos(math.rad((min + sec/60)*6)) ) cr:stroke () -- Draw second arrow cr:set_line_width (2) cr:set_source_rgba (1, 0.5, 0, 1) cr:move_to (cx, cy) cr:line_to (cx + sec_arrow_len*math.sin(sec*math.rad(6)), cy - sec_arrow_len*math.cos(sec*math.rad(6)) ) cr:stroke () end ------------------------------------------------------------------------------- -- Widget palcement ------------------------------------------------------------------------------- local clock_layout = wibox.layout.fixed.horizontal() clock_layout:add(clock_widget) clock_wbox:set_widget(clock_layout) ------------------------------------------------------------------------------- -- Animation ------------------------------------------------------------------------------- -- Create timer with 100 ms interval local timer = capi.timer{timeout = 0.1} -- Set timer callback timer:connect_signal("timeout", function() clock_wbox.draw() end) -- Start timer timer:start() -- Enable timeout signal timer:emit_signal("timeout") clock.clock_wbox = clock_wbox -- Return clock widget return clock