--[[
Conky Widgets by londonali1010 (2009)
This script is meant to be a "shell" to hold a suite of widgets for use in Conky.
To configure:
+ Copy the widget's code block (will be framed by --(( WIDGET NAME )) and --(( END WIDGET NAME )), with "[" instead of "(") somewhere between "require 'cairo'" and "function conky_widgets()", ensuring not to paste into another widget's code block
+ To call the widget, add the following just before the last "end" of the entire script:
cr = cairo_create(cs)
NAME_OF_FUNCTION(cr, OPTIONS)
cairo_destroy(cr)
+ Replace OPTIONS with the options for your widget (should be specified in the widget's code block)
Call this script in Conky using the following before TEXT (assuming you save this script to ~/scripts/conky_widgets.lua):
lua_load /home/gehrandt/.conky/conky_widgets.lua
lua_draw_hook_pre widgets
Changelog:
+ v1.0 -- Original release (17.10.2009)
]]
require 'cairo'
--[[ AIR CLOCK WIDGET ]]
--[[ Options (xc, yc, size):
"xc" and "yc" are the x and y coordinates of the centre of the clock, in pixels, relative to the top left of the Conky window
"size" is the total size of the widget, in pixels ]]
function air_clock(cr, xc, yc, size)
local offset = 0
shadow_width = size * 0.03
shadow_xoffset = 0
shadow_yoffset = size * 0.01
if shadow_xoffset >= shadow_yoffset then
offset = shadow_xoffset
else offset = shadow_yoffset
end
local clock_r = (size - 2 * offset) / (2 * 1.25)
show_seconds=true
-- Grab time
local hours=os.date("%I")
local mins=os.date("%M")
local secs=os.date("%S")
secs_arc=(2*math.pi/60)*secs
mins_arc=(2*math.pi/60)*mins
hours_arc=(2*math.pi/12)*hours+mins_arc/12
-- Drop shadow
local ds_pat=cairo_pattern_create_radial(xc+shadow_xoffset,yc+shadow_yoffset,clock_r*1.25,xc+shadow_xoffset,yc+shadow_yoffset,clock_r*1.25+shadow_width)
cairo_pattern_add_color_stop_rgba(ds_pat,0,0,0,0,0) -- ,0,0,0,0.2
cairo_pattern_add_color_stop_rgba(ds_pat,0,0,0,0,0) -- ,1,0,0,0,0
cairo_move_to(cr,0,0)
cairo_line_to(cr,conky_window.width,0)
cairo_line_to(cr,conky_window.width, conky_window.height)
cairo_line_to(cr,0,conky_window.height)
cairo_close_path(cr)
cairo_new_sub_path(cr)
cairo_arc(cr,xc,yc,clock_r*1.25,0,2*math.pi)
cairo_set_source(cr,ds_pat)
cairo_set_fill_rule(cr,CAIRO_FILL_RULE_EVEN_ODD)
cairo_fill(cr)
-- Glassy border
cairo_arc(cr,xc,yc,clock_r*1.25,0,2*math.pi)
cairo_set_source_rgba(cr,0,0,0,0) -- ,0.5,0.5,0.5,0.2
cairo_set_line_width(cr,1)
cairo_stroke(cr)
local border_pat=cairo_pattern_create_linear(xc,yc-clock_r*1.25,xc,yc+clock_r*1.25)
cairo_pattern_add_color_stop_rgba(border_pat,0,0,0,0,0) -- ,0,1,1,1,0.7
cairo_pattern_add_color_stop_rgba(border_pat,0,0,0,0,0) -- ,0.3,1,1,1,0
cairo_pattern_add_color_stop_rgba(border_pat,0,0,0,0,0) -- ,0.5,1,1,1,0
cairo_pattern_add_color_stop_rgba(border_pat,0,0,0,0,0) -- ,0.7,1,1,1,0
cairo_pattern_add_color_stop_rgba(border_pat,0,0,0,0,0) -- ,1,1,1,1,0.7
cairo_set_source(cr,border_pat)
cairo_arc(cr,xc,yc,clock_r*1.125,0,2*math.pi)
cairo_close_path(cr)
cairo_set_line_width(cr,clock_r*0.25)
cairo_stroke(cr)
-- Set clock face
cairo_arc(cr,xc,yc,clock_r,0,2*math.pi)
cairo_close_path(cr)
local face_pat=cairo_pattern_create_radial(xc,yc-clock_r*0.75,0,xc,yc,clock_r)
cairo_pattern_add_color_stop_rgba(face_pat,0,0,0,0,0) -- ,0,1,1,1,0.9
cairo_pattern_add_color_stop_rgba(face_pat,0,0,0,0,0) -- ,0.5,1,1,1,0.9
cairo_pattern_add_color_stop_rgba(face_pat,0,0,0,0,0) -- ,1,0.9,0.9,0.9,0.9
cairo_set_source(cr,face_pat)
cairo_fill_preserve(cr)
cairo_set_source_rgba(cr,0,0,0,0) -- ,0.5,0.5,0.5,0.2
cairo_set_line_width(cr, 1)
cairo_stroke (cr)
-- Draw hour hand
xh=xc+0.7*clock_r*math.sin(hours_arc)
yh=yc-0.7*clock_r*math.cos(hours_arc)
cairo_move_to(cr,xc,yc)
cairo_line_to(cr,xh,yh)
cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND)
cairo_set_line_width(cr,5)
cairo_set_source_rgba(cr,0,0,0,0.
-- ,0,0,0,0.4
cairo_stroke(cr)
-- Draw minute hand
xm=xc+0.9*clock_r*math.sin(mins_arc)
ym=yc-0.9*clock_r*math.cos(mins_arc)
cairo_move_to(cr,xc,yc)
cairo_line_to(cr,xm,ym)
cairo_set_line_width(cr,3)
cairo_stroke(cr)
-- Draw seconds hand
if show_seconds then
xs=xc+0.9*clock_r*math.sin(secs_arc)
ys=yc-0.9*clock_r*math.cos(secs_arc)
cairo_move_to(cr,xc,yc)
cairo_line_to(cr,xs,ys)
cairo_set_line_width(cr,1)
cairo_stroke(cr)
end
end
--[[ END AIR CLOCK WIDGET ]]
--[[ RING WIDGET ]]
--[[ Options (name, arg, max, bg_colour, bg_alpha, xc, yc, radius, thickness, start_angle, end_angle):
"name" is the type of stat to display; you can choose from 'cpu', 'memperc', 'fs_used_perc', 'battery_used_perc'.
"arg" is the argument to the stat type, e.g. if in Conky you would write ${cpu cpu0}, 'cpu0' would be the argument. If you would not use an argument in the Conky variable, use ''.
"max" is the maximum value of the ring. If the Conky variable outputs a percentage, use 100.
"bg_colour" is the colour of the base ring.
"bg_alpha" is the alpha value of the base ring.
"fg_colour" is the colour of the indicator part of the ring.
"fg_alpha" is the alpha value of the indicator part of the ring.
"x" and "y" are the x and y coordinates of the centre of the ring, relative to the top left corner of the Conky window.
"radius" is the radius of the ring.
"thickness" is the thickness of the ring, centred around the radius.
"start_angle" is the starting angle of the ring, in degrees, clockwise from top. Value can be either positive or negative.
"end_angle" is the ending angle of the ring, in degrees, clockwise from top. Value can be either positive or negative, but must be larger (e.g. more clockwise) than start_angle. ]]
function ring(cr, name, arg, max, bgc, bga, fgc, fga, xc, yc, r, t, sa, ea)
local function rgb_to_r_g_b(colour,alpha)
return ((colour / 0x10000) % 0x100) / 255., ((colour / 0x100) % 0x100) / 255., (colour % 0x100) / 255., alpha
end
local function draw_ring(pct)
local angle_0=sa*(2*math.pi/360)-math.pi/2
local angle_f=ea*(2*math.pi/360)-math.pi/2
local pct_arc=pct*(angle_f-angle_0)
-- Draw background ring
cairo_arc(cr,xc,yc,r,angle_0,angle_f)
cairo_set_source_rgba(cr,rgb_to_r_g_b(bgc,bga))
cairo_set_line_width(cr,t)
cairo_stroke(cr)
-- Draw indicator ring
cairo_arc(cr,xc,yc,r,angle_0,angle_0+pct_arc)
cairo_set_source_rgba(cr,rgb_to_r_g_b(fgc,fga))
cairo_stroke(cr)
end
local function setup_ring()
local str = ''
local value = 0
str = string.format('${%s %s}', name, arg)
str = conky_parse(str)
value = tonumber(str)
if value == nil then value = 0 end
pct = value/max
draw_ring(pct)
end
local updates=conky_parse('${updates}')
update_num=tonumber(updates)
if update_num>5 then setup_ring() end
end
--[[ END RING WIDGET ]]
--[[ GRADIENT RING WIDGET ]]
--[[ Options (name, arg, max, colour, alpha, x, y, inner_radius, outer_radius, frac, thickness, start_angle, end_angle):
"name" is the type of stat to display; you can choose from 'cpu', 'memperc', 'fs_used_perc', 'battery_used_perc'.
"arg" is the argument to the stat type, e.g. if in Conky you would write ${cpu cpu0}, 'cpu0' would be the argument. If you would not use an argument in the Conky variable, use ''.
"max" is the maximum value of the ring. If the Conky variable outputs a percentage, use 100.
"fg_colour" is the colour of the ring.
"fg_alpha" is the alpha value of the ring.
"x" and "y" are the x and y coordinates of the centre of the ring, relative to the top left corner of the Conky window.
"inner_radius" is the inner radius of the ring.
"outer_radius" is the outer radius of the ring.
"frac" determines the extent of the gradient around the ring - 2 implies the gradient fades halfway around the ring, 4 equals a quarter of the way, etc...
"thickness" is the thickness of the ring, centred around the radius.
"start_angle" is the starting angle of the ring, in degrees, clockwise from top. Value can be either positive or negative.
"end_angle" is the ending angle of the ring, in degrees, clockwise from top. Value can be either positive or negative, but must be larger (e.g. more clockwise) than start_angle. ]]
function gradient_ring(cr, name, arg, max, fgc, fga, xc, yc, ring_i, ring_o, frac, t, sa, ea)
local function rgb_to_r_g_b(colour,alpha)
return ((colour / 0x10000) % 0x100) / 255., ((colour / 0x100) % 0x100) / 255., (colour % 0x100) / 255., alpha
end
local function draw_gradient_ring(pct)
local angle_0=sa*(2*math.pi/360)-math.pi/2
local angle_f=ea*(2*math.pi/360)-math.pi/2
local pct_arc=pct*(angle_f-angle_0)
for i = 1,max/frac do
cairo_set_source_rgba(cr,rgb_to_r_g_b(fgc,fga*i/max)) --for flat shading of bars
--local pat=cairo_pattern_create_linear(xc-ring_i*math.sin(angle_0+t_arc+2*math.pi*i/max),yc+ring_i*math.cos(angle_0+t_arc+2*math.pi*i/max),xc-ring_o*math.sin(angle_0+t_arc+2*math.pi*i/max),yc+ring_o*math.cos(angle_0+t_arc+2*math.pi*i/max))
--cairo_pattern_add_color_stop_rgba(pat,0,rgb_to_r_g_b(fgc,0))
--cairo_pattern_add_color_stop_rgba(pat,1,rgb_to_r_g_b(fgc,fga*i/max))
--cairo_set_source(cr,pat) -- for gradient shading of bars
cairo_move_to(cr,xc-ring_i*math.cos(angle_0+pct_arc+2*math.pi*i/max),yc-ring_i*math.sin(angle_0+pct_arc+2*math.pi*i/max))
cairo_line_to(cr,xc-ring_o*math.cos(angle_0+pct_arc+2*math.pi*i/max),yc-ring_o*math.sin(angle_0+pct_arc+2*math.pi*i/max))
cairo_set_line_cap(cr,CAIRO_LINE_CAP_ROUND)
cairo_set_line_width(cr,t)
cairo_stroke(cr)
end
end
local function setup_gradient_ring()
local str = ''
local value = 0
str = string.format('${%s %s}', name, arg)
str = conky_parse(str)
value = tonumber(str)
if value == nil then value = 0 end
pct = value/max
draw_gradient_ring(pct)
end
local updates=conky_parse('${updates}')
update_num=tonumber(updates)
if update_num>5 then setup_gradient_ring() end
end
--[[ END GRADIENT RING WIDGET ]]
--[[ PIE WIDGET ]]
--[[ xc,yc - center of the pie
r - radius of the pie ]]
function pie_rings (xc, yc, r)
pat = cairo_pattern_create_radial (xc, yc, 0.2*r, xc, yc, r);
cairo_pattern_add_color_stop_rgba (pat, 0.1, 1, 1, 1, 0);
cairo_pattern_add_color_stop_rgba (pat, 1.0, 1, 1, 1, 0.3);
cairo_set_source (cr, pat);
cairo_arc (cr, xc, yc, r, 0, 2 * math.pi);
cairo_fill (cr);
cairo_pattern_destroy (pat);
cairo_set_font_size (cr, 10)
cairo_select_font_face (cr, "LCDMono",
CAIRO_FONT_SLANT_NORMAL,
CAIRO_FONT_WEIGHT_NORMAL)
cairo_set_line_width (cr, 2.0)
-- Show total mem usage
local str1 = conky_parse(string.format('${mem}'))
local str2 = string.match(str1, "(%d+)")
local str3 = string.match(str1, "(%a+)")
cairo_set_source_rgba(cr, 1, 1, 1, 1)
cairo_move_to (cr, xc-9, yc-1)
cairo_show_text (cr, str2)
cairo_move_to (cr, xc-9, yc+9)
cairo_show_text (cr, str3)
cairo_stroke(cr)
-- Get top mem usage
local str1 = conky_parse(string.format('${mem}'))
local mem = tonumber(string.match(str1, "(%d+)"))
local str1 = conky_parse(string.format('${memperc}'))
local mempct = tonumber(string.match(str1, "(%d+)"))
-- Draw pie
local angle = -90
local angle2 = 0
local tro = 4 -- Text rotational offset (degrees)
local maxprocesses = 7
local maxstrlen = 8
for process = 1, maxprocesses do
cairo_save(cr)
-- Get top process memory usage
local str2 = conky_parse(string.format('${top_mem mem %i}', tonumber(process)))
local mem_process = tonumber(str2)
if mem_process == nil then mem_process = 0 end
local procpct = mem_process / mempct
angle2 = angle + (procpct*360)
if angle2 > 260 then
cairo_restore(cr)
break
end
-- Get top process name
local str2 = conky_parse(string.format('${top_mem name %i} ', tonumber(process)))
local index = string.find(str2,' ')
if (index == nil) then
cairo_restore(cr)
break
elseif (index > maxstrlen) then
str2 = string.sub(str2, 0, maxstrlen)
end
-- Draw pie outline
cairo_set_source_rgba(cr, 1, 1, 1, 0.2)
cairo_arc_negative (cr, xc, yc, 0.2*r, angle2*(math.pi/180), angle*(math.pi/180));
cairo_arc (cr, xc, yc, r, angle*(math.pi/180), angle2*(math.pi/180));
-- cairo_close_path(cr)
cairo_stroke(cr)
-- Draw text
cairo_set_source_rgba(cr, 1, 1, 1, 1)
cairo_move_to(cr, xc, yc)
cairo_rotate(cr, (angle2-((angle2-angle)/2)+tro)*(math.pi/180))
-- cairo_show_text (cr, ' '..(procpct*100))
if (index > maxstrlen) then
cairo_show_text (cr, ' '..str2..'..')
else
cairo_show_text (cr, ' '..str2)
end
angle = angle2 + 3
cairo_stroke(cr)
cairo_restore(cr)
end
if (angle < 264) then
angle2 = 267
cairo_set_source_rgba(cr, 1, 1, 1, 0.2)
cairo_arc_negative (cr, xc, yc, 0.2*r, angle2*(math.pi/180), angle*(math.pi/180));
cairo_arc (cr, xc, yc, r, angle*(math.pi/180), angle2*(math.pi/180));
-- cairo_close_path(cr)
cairo_stroke(cr)
if ((angle2 - angle) > 20) then
cairo_set_source_rgba(cr, 1, 1, 1, 0.5)
cairo_move_to(cr, xc, yc)
cairo_rotate(cr, (angle2-((angle2-angle)/2)+tro+2)*(math.pi/180))
cairo_show_text (cr, ' '..'other')
cairo_stroke(cr)
end
end
end
--[[ END PIE WIDGET ]]
function conky_widgets()
if conky_window == nil then return end
local cs = cairo_xlib_surface_create(conky_window.display, conky_window.drawable, conky_window.visual, conky_window.width, conky_window.height)
cr = cairo_create(cs)
air_clock(cr, 90, 90, 200) -- options: xc, yc, size
cairo_destroy(cr)
cr = cairo_create(cs)
ring(cr, 'time', '+%S', 60, 0xE3E3E3, 0, 0xFFFF00, 0.7, 90, 90, 70, 4, 0, 360) -- options: name, arg, max, bg_colour, bg_alpha, fg_colour, fg_alpha, xc, yc, radius, thickness, start_angle, end_angle
cairo_destroy(cr)
cr = cairo_create(cs)
ring(cr, 'time', '+%M', 60, 0xE3E3E3, 0.1, 0x00CD00, 0.7, 90, 90, 64, 7, 0, 360) -- options: name, arg, max, bg_colour, bg_alpha, fg_colour, fg_alpha, xc, yc, radius, thickness, start_angle, end_angle
cairo_destroy(cr)
cr = cairo_create(cs)
ring(cr, 'time', '+%H', 24, 0xE3E3E3, 0.2, 0xffffff, 0.7, 90, 90, 53, 14, 0, 360) -- options: name, arg, max, bg_colour, bg_alpha, fg_colour, fg_alpha, xc, yc, radius, thickness, start_angle, end_angle
cairo_destroy(cr)
cr = cairo_create(cs)
ring(cr, 'cpu', 'cpu0', 100, 0xFF0000, 0.4, 0xFFFF00, 0, 90, 90, 80, 14, 0, 180) -- options: name, arg, max, bg_colour, bg_alpha, fg_colour, fg_alpha, xc, yc, radius, thickness, start_angle, end_angle
cairo_destroy(cr)
cr = cairo_create(cs)
ring(cr, 'cpu', 'cpu1', 100, 0xFF0000, 0.8, 0xFFFF00, 0, 90, 90, 75, 4, 180, 360) -- options: name, arg, max, bg_colour, bg_alpha, fg_colour, fg_alpha, xc, yc, radius, thickness, start_angle, end_angle
cairo_destroy(cr)
cr = cairo_create(cs)
ring(cr, 'cpu', 'cpu2', 100, 0xFF0000, 0.8, 0xFFFF00, 0, 90, 90, 86, 2, 180, 360) -- options: name, arg, max, bg_colour, bg_alpha, fg_colour, fg_alpha, xc, yc, radius, thickness, start_angle, end_angle
cairo_destroy(cr)
cr = cairo_create(cs)
local w = conky_window.width
local h = conky_window.height
r = 75
xc = 90
yc = 360
local updates=conky_parse('${updates}')
update_num=tonumber(updates)
if update_num>5 then
pie_rings(xc, yc, r)
end
cairo_destroy(cr)
end