require 'cairo'
--[[ BARGRAPH WIDGET
v1.3 by wlourf (03 march 2010)
This widget draw a simple bar like (old) equalizers on hi-fi systems.
http://u-scripts.blogspot.com/ The arguments are :
- "name" is the type of stat to display; you can choose from 'cpu', 'memperc', 'fs_used_perc', 'battery_used_perc'...
or you can set it to "" if you want to display a numeric value with arg=numeric_value
- "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 bar. If the Conky variable outputs a percentage, use 100.
- "nb_blocks" is the umber of block to draw
- "cap" id the cap of a block, possibles values are CAIRO_LINE_CAP_ROUND , CAIRO_LINE_CAP_SQUARE or CAIRO_LINE_CAP_BUTT
see
http://www.cairographics.org/samples/set_line_cap/ - "xb" and "yb" are the coordinates of the bottom left point of the bar, or the center of the circle if radius>0
- "w" and "h" are the width and the height of a block (without caps), w has no effect for "circle" bar
- "space" is the space betwwen two blocks, can be null or negative
- "bgc" and "bga" are background colors and alpha when the block is not LIGHT OFF
- "fgc" and "fga" are foreground colors and alpha when the block is not LIGHT ON
- "alc" and "ala" are foreground colors and alpha when the block is not LIGHT ON and ALARM ON
- "alarm" is the value where blocks LIGHT ON are in a different color (values from 0 to 100)
- "led_effect" true or false : to show a block with a led effect
- "led_alpha" alpha of the center of the led (values from 0 to 1)
- "smooth" true or false : colors in the bar has a smooth effect
- "mid_color",mid_alpha" : colors of the center of the bar (mid_color can to be set to nil)
- "rotation" : angle of rotation of the bar (values are 0 to 360 degrees). 0 = vertical bar, 90 = horizontal bar
- "radius" : draw the bar on a circle (it's no more a circle, radius = 0 to keep bars)
- "angle_bar" : if radius>0 angle_bar is the angle of the bar
v1.0 (10 Feb. 2010) original release
v1.1 (13 Feb. 2010) numeric values can be passed instead conky stats with parameters name="", arg = numeric_value
v1.2 (28 Feb. 2010) just renamed the widget to bargraph
v1.3 (03 March 2010) added parameters radius & angle_bar to draw the bar in a circular way
]]
function bar_graph(name, arg, max, nb_blocks, cap, xb, yb, w, h, space, bgc, bga, fgc, fga,alc,ala,alarm,led_effect,led_alpha,smooth,mid_color,mid_alpha,rotation,radius, angle_bar)
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 setup_bar_graph()
local value = 0
if name ~="" then
local str = conky_parse(string.format('${%s %s}', name, arg))
value = tonumber(str)
else
value = arg
end
if value==nil then value =0 end
local pct = 100*value/max
local pcb = 100/nb_blocks
cairo_set_line_width (cr, h)
cairo_set_line_cap (cr, cap)
local angle_rot= rotation*math.pi/180
local alpha_bar = (angle_bar*math.pi/180)/2
for pt = 1,nb_blocks do
local light_on=false
--set colors
local col,alpha = bgc,bga
if pct>=(100/nb_blocks/2) then --start after an half bloc
if pct>=(pcb*(pt-1)) then
light_on=true
col,alpha = fgc,fga
if pct>=alarm and (pcb*pt)>alarm then col,alpha = alc,ala end
end
end
--vertical points
local x1=xb
local y1=yb-pt*(h+space)
local radius0 = yb-y1
local x2=xb+radius0*math.sin(angle_rot)
local y2=yb-radius0*math.cos(angle_rot)
--line on angle_rot
local a1=(y2-yb)/(x2-xb)
local b1=y2-a1*x2
--line perpendicular to angle_rot
local a2=-1/a1
local b2=y2-a2*x2
--dots on perpendicular
local xx0,xx1,yy0,yy1=0,0,0,0
if rotation == 90 or rotation == 270 then
xx0,xx1=x2,x2
yy0=yb
yy1=yb+w
else
xx0,xx1=x2,x2+w*math.cos(angle_rot)
yy0=xx0*a2+b2
yy1=xx1*a2+b2
end
local xc,yc
--perpendicular segment
if alpha_bar == 0 then
cairo_move_to (cr, xx0 ,yy0)
cairo_line_to (cr, xx1 ,yy1)
xc,yc=(xx0+xx1)/2,(yy0+yy1)/2
else
cairo_arc( cr,
xb,
yb,
radius+(h+space)*(pt)-h/2,
( -alpha_bar -math.pi/2+angle_rot) ,
( alpha_bar -math.pi/2+angle_rot)
)
xc=xb+ (radius+(h+space)*(pt))*math.sin(angle_rot)
yc=yb- (radius+(h+space)*(pt))*math.cos(angle_rot)
end
--colors
if light_on and led_effect then
local pat = cairo_pattern_create_radial (xc, yc, 0, xc,yc,w/1.5)
cairo_pattern_add_color_stop_rgba (pat, 0, rgb_to_r_g_b(col,led_alpha))
cairo_pattern_add_color_stop_rgba (pat, 1, rgb_to_r_g_b(col,alpha))
cairo_set_source (cr, pat)
cairo_pattern_destroy(pat)
else
cairo_set_source_rgba(cr, rgb_to_r_g_b(col,alpha))
end
if light_on and smooth then
local radius = (nb_blocks+1)*(h+space)
if pt==1 then
xc0,yc0=xc,yc --remember the center of first block
end
cairo_move_to(cr,xc0,yc0)
local pat = cairo_pattern_create_radial (xc0, yc0, 0, xc0,yc0,radius)
cairo_pattern_add_color_stop_rgba (pat, 0, rgb_to_r_g_b(fgc,fga))
cairo_pattern_add_color_stop_rgba (pat, 1, rgb_to_r_g_b(alc,ala))
if mid_color ~=nil then
cairo_pattern_add_color_stop_rgba (pat, 0.5,rgb_to_r_g_b(mid_color,mid_alpha))
end
cairo_set_source (cr, pat)
cairo_pattern_destroy(pat)
end
cairo_stroke (cr);
end
end
--prevent segmentation error
local updates=tonumber(conky_parse('${updates}'))
if updates> 3 then
setup_bar_graph()
end
end
function conky_main()
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)
local x0,y0 = conky_window.width/2, conky_window.height/2
local blocks = 20
local cap_round = CAIRO_LINE_CAP_ROUND
local cap_square = CAIRO_LINE_CAP_SQUARE
local cap_butt = CAIRO_LINE_CAP_BUTT
local w,h=20,10
local s=2
local bgc,bga = 0x00CC66, 0.5
local fgc,fga = 0x66FF00, 1
local alc,ala = 0x00CCFF, 1
local mid_color,mid_alpha = 0xFFFF00, 1.0
local led_effect, led_alpha = true , 1.0
local alarm = 80
local smooth = true
local angle_rot = 0
local radius=0
local angle_bar=0
--reminder : the order of the parameters:
--(name, arg, max, nb_blocks, cap, xb, yb, w, h, space, bgc, bga, fgc, fga,alc,ala,alarm,led_effect,led_alpha,smooth,mid_color,mid_alpha,rotation,radius,angle_bar)
--rotating bar in the middle (does not rotate as a second hand, this is just an example)
--two horizontal lines on the top
--basic example : bottom left
x0,y0 = 10,conky_window.height-10
blocks = 20
w,h=25,10
s=2
bgc,bga = 0x009933, 0.3
fgc,fga = 0x66FF00, 1
alc,ala = 0xFF0000, 1
led_effect, led_alpha = false , 1.0
alarm = 80
smooth = false
angle_rot = 0
--"led effect" example : bottom, 3rd from left
bgc,bga = 0x8B8B7A, 0.2
fgc,fga = 0xCD3333, 0
alc,ala = 0xFF0000, 0
led_effect, led_alpha = true , 1.0
angle_rot=0
blocks = 18
bar_graph('cpu', 'cpu1', 100, blocks, cap_butt, x0, y0-850, 108,1.7,s,bgc,bga, fgc,fga, alc,ala, alarm, led_effect, led_alpha,smooth,mid_color,mid_alpha,angle_rot,radius,angle_bar)
--"led effect" example : bottom, 3rd from left
bgc,bga = 0x8B8B7A, 0.2
fgc,fga = 0xCD3333, 0
alc,ala = 0xFF0000, 0
led_effect, led_alpha = true , 1.0
blocks = 18
bar_graph('cpu', 'cpu2', 100, blocks, cap_butt, x0+115, y0-850, 108,1.7,s,bgc,bga, fgc,fga, alc,ala, alarm, led_effect, led_alpha,smooth,mid_color,mid_alpha,angle_rot,radius,angle_bar)
--"led effect" example : bottom, 3rd from left
bgc,bga = 0x8B8B7A, 0.2
fgc,fga = 0x0000FF, 0
alc,ala = 0xFF0000, 0
led_effect, led_alpha = true , 1.0
blocks = 18
bar_graph('downspeedf', 'eth0', 400, blocks, cap_butt, x0+230, y0-850, 108,1.7,s,bgc,bga, fgc,fga, alc,ala, alarm, led_effect, led_alpha,smooth,mid_color,mid_alpha,angle_rot,radius,angle_bar)
--"led effect" example : bottom, 3rd from left
bgc,bga = 0x8B8B7A, 0.2
fgc,fga = 0x00CDCD, 0
alc,ala = 0xFF0000, 0
led_effect, led_alpha = true , 1.0
blocks = 18
bar_graph('upspeedf', 'eth0', 50, blocks, cap_butt, x0+345, y0-850, 108,1.7,s,bgc,bga, fgc,fga, alc,ala, alarm, led_effect, led_alpha,smooth,mid_color,mid_alpha,angle_rot,radius,angle_bar)
end