diff --git a/README.rst b/README.rst index 480afcc..e5d6040 100644 --- a/README.rst +++ b/README.rst @@ -551,6 +551,10 @@ static_text: +--------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ | alpha | Transpacency level. | +--------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| halign | Horizontal alignment (left, center, right). default = left | ++--------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| valign | Vertical alignment (bottom, center, top). default = bottom | ++--------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ variable_text: -------------- @@ -576,6 +580,7 @@ variable_text: +--------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ | alpha | Transpacency level. | +--------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ - - - +| halign | Horizontal alignment (left, center, right). default = left | ++--------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ +| valign | Vertical alignment (bottom, center, top). default = bottom | ++--------------------------------+----------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/conky_draw.lua b/conky_draw.lua index 234107d..5a2f428 100644 --- a/conky_draw.lua +++ b/conky_draw.lua @@ -1,5 +1,5 @@ require 'cairo' -package.path = package.path .. ';' .. os.getenv("HOME") .. '/.conky/conky-draw/?.lua' +package.path = package.path .. ';' .. os.getenv("HOME") .. '/.config/conky/?.lua' require 'conky_draw_config' @@ -25,23 +25,23 @@ function get_conky_value(conky_value, is_number) end function get_critical_or_not_suffix (value, threshold, change_color_on_critical, change_alpha_on_critical, change_thickness_on_critical) - local result = { - color = '', - alpha = '', - thickness = '' - } - if value >= threshold then - if change_color_on_critical then - result.color = '_critical' - end - if change_alpha_on_critical then - result.alpha = '_critical' - end - if change_thickness_on_critical then - result.thickness = '_critical' + local result = { + color = '', + alpha = '', + thickness = '' + } + if value >= threshold then + if change_color_on_critical then + result.color = '_critical' + end + if change_alpha_on_critical then + result.alpha = '_critical' + end + if change_thickness_on_critical then + result.thickness = '_critical' + end end - end - return result + return result end function draw_background(display, element) @@ -64,13 +64,13 @@ function draw_background(display, element) cairo_set_source_rgba(display, hexa_to_rgb(element.color, element.alpha)) if element.outline_thickness > 0 then - cairo_fill_preserve(display) - cairo_set_source_rgba(display, hexa_to_rgb(element.outline_color, element.outline_alpha)) - cairo_set_line_width(display, element.outline_thickness) - cairo_stroke(display) + cairo_fill_preserve(display) + cairo_set_source_rgba(display, hexa_to_rgb(element.outline_color, element.outline_alpha)) + cairo_set_line_width(display, element.outline_thickness) + cairo_stroke(display) else - -- fill the background - cairo_fill(display) + -- fill the background + cairo_fill(display) end end @@ -84,32 +84,32 @@ function draw_line(display, element) local from_y = element.from.y if not element.graduated then - -- draw line - cairo_set_source_rgba(display, hexa_to_rgb(element.color, element.alpha)) - cairo_set_line_width(display, element.thickness); - cairo_move_to(display, element.from.x, element.from.y); - cairo_rel_line_to(display, x_side, y_side); + -- draw line + cairo_set_source_rgba(display, hexa_to_rgb(element.color, element.alpha)) + cairo_set_line_width(display, element.thickness); + cairo_move_to(display, element.from.x, element.from.y); + cairo_rel_line_to(display, x_side, y_side); else - if element.number_graduation == 0 or element.space_between_graduation == 0 then - error ("The values of number_graduation and space_between_graduation must be non-zero as they are used as divisors. Dividing by zero causes undefined behavior (usually it results in an 'inf').") - end - - -- draw graduated line - cairo_set_source_rgba(display, hexa_to_rgb(element.color, element.alpha)) - cairo_set_line_width(display, element.thickness); - local space_graduation_x = (x_side-x_side/element.space_between_graduation+1)/element.number_graduation - local space_graduation_y =(y_side-y_side/element.space_between_graduation+1)/element.number_graduation - local space_x = x_side/element.number_graduation-space_graduation_x - local space_y = y_side/element.number_graduation-space_graduation_y - - if math.floor (element.number_graduation) > 0 then - for i=1,element.number_graduation do - cairo_move_to(display,from_x,from_y) - from_x=from_x+space_x+space_graduation_x - from_y=from_y+space_y+space_graduation_y - cairo_rel_line_to(display,space_x,space_y) + if element.number_graduation == 0 or element.space_between_graduation == 0 then + error ("The values of number_graduation and space_between_graduation must be non-zero as they are used as divisors. Dividing by zero causes undefined behavior (usually it results in an 'inf').") + end + + -- draw graduated line + cairo_set_source_rgba(display, hexa_to_rgb(element.color, element.alpha)) + cairo_set_line_width(display, element.thickness); + local space_graduation_x = (x_side-x_side/element.space_between_graduation+1)/element.number_graduation + local space_graduation_y =(y_side-y_side/element.space_between_graduation+1)/element.number_graduation + local space_x = x_side/element.number_graduation-space_graduation_x + local space_y = y_side/element.number_graduation-space_graduation_y + + if math.floor (element.number_graduation) > 0 then + for i=1,element.number_graduation do + cairo_move_to(display,from_x,from_y) + from_x=from_x+space_x+space_graduation_x + from_y=from_y+space_y+space_graduation_y + cairo_rel_line_to(display,space_x,space_y) + end end - end end cairo_stroke(display) end @@ -117,7 +117,7 @@ end function draw_bar_graph(display, element) -- draw a bar graph if element.max_value == 0 then - error ("The value of max_value must be non-zero as it is used a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") + error ("The value of max_value must be non-zero as it is used a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") end -- get current value @@ -158,38 +158,37 @@ function draw_bar_graph(display, element) -- draw background lines draw_line(display, background_line) - if element.graduated then - if element.space_between_graduation == 0 or element.number_graduation == 0 then - error ("The values of number_graduation and space_between_graduation must be non-zero as they are used as divisors. Dividing by zero causes undefined behavior (usually it results in an 'inf').") - end - - -- draw bar line if graduated - cairo_set_source_rgba(display, hexa_to_rgb(bar_line.color, bar_line.alpha)) - cairo_set_line_width(display, bar_line.thickness); - local from_x = bar_line.from.x - local from_y = bar_line.from.y - local space_graduation_x = (x_side-x_side/element.space_between_graduation+1)/element.number_graduation - local space_graduation_y =(y_side-y_side/element.space_between_graduation+1)/element.number_graduation - local space_x = x_side/element.number_graduation-space_graduation_x - local space_y = y_side/element.number_graduation-space_graduation_y - - local number_of_bars_to_fill = math.floor(value / element.max_value * element.number_graduation) - - if math.floor (number_of_bars_to_fill) > 0 then - for i=1,number_of_bars_to_fill do - cairo_move_to(display,from_x,from_y) - from_x=from_x+space_x+space_graduation_x - from_y=from_y+space_y+space_graduation_y - cairo_rel_line_to(display,space_x,space_y) + if element.graduated then + if element.space_between_graduation == 0 or element.number_graduation == 0 then + error ("The values of number_graduation and space_between_graduation must be non-zero as they are used as divisors. Dividing by zero causes undefined behavior (usually it results in an 'inf').") end - end - cairo_stroke(display) - else - -- draw bar line if not graduated - draw_line(display,bar_line); - end + -- draw bar line if graduated + cairo_set_source_rgba(display, hexa_to_rgb(bar_line.color, bar_line.alpha)) + cairo_set_line_width(display, bar_line.thickness); + local from_x = bar_line.from.x + local from_y = bar_line.from.y + local space_graduation_x = (x_side-x_side/element.space_between_graduation+1)/element.number_graduation + local space_graduation_y =(y_side-y_side/element.space_between_graduation+1)/element.number_graduation + local space_x = x_side/element.number_graduation-space_graduation_x + local space_y = y_side/element.number_graduation-space_graduation_y + + local number_of_bars_to_fill = math.floor(value / element.max_value * element.number_graduation) + + if math.floor (number_of_bars_to_fill) > 0 then + for i=1,number_of_bars_to_fill do + cairo_move_to(display,from_x,from_y) + from_x=from_x+space_x+space_graduation_x + from_y=from_y+space_y+space_graduation_y + cairo_rel_line_to(display,space_x,space_y) + end + end + cairo_stroke(display) + else + -- draw bar line if not graduated + draw_line(display,bar_line); + end end @@ -210,34 +209,33 @@ function draw_ring(display, element) cairo_set_line_width(display, element.thickness); -- draw the ring if not element.graduated then - -- draw the ring if not graduated - arc_drawer(display, element.center.x, element.center.y, element.radius, start_angle, end_angle) - cairo_stroke(display); + -- draw the ring if not graduated + arc_drawer(display, element.center.x, element.center.y, element.radius, start_angle, end_angle) + cairo_stroke(display); else - -- draw the ring if graduated - if element.number_graduation == 0 then - error ("The value of number_graduation must be non-zero as it is used as a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") - end - local angle_between_graduation = math.rad(element.angle_between_graduation) - local graduation_size = math.abs(end_angle-start_angle)/element.number_graduation - angle_between_graduation - local current_start = start_angle - - if math.floor(element.number_graduation) > 0 then - for i=1, element.number_graduation do - arc_drawer(display, element.center.x, element.center.y, element.radius, current_start, current_start+graduation_size* orientation) - current_start= current_start+ (graduation_size+angle_between_graduation)* orientation - cairo_stroke(display); + -- draw the ring if graduated + if element.number_graduation == 0 then + error ("The value of number_graduation must be non-zero as it is used as a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") + end + local angle_between_graduation = math.rad(element.angle_between_graduation) + local graduation_size = math.abs(end_angle-start_angle)/element.number_graduation - angle_between_graduation + local current_start = start_angle + + if math.floor(element.number_graduation) > 0 then + for i=1, element.number_graduation do + arc_drawer(display, element.center.x, element.center.y, element.radius, current_start, current_start+graduation_size* orientation) + current_start= current_start+ (graduation_size+angle_between_graduation)* orientation + cairo_stroke(display); + end end - end end - end function draw_ring_graph(display, element) -- draw a ring graph if element.max_value == 0 then - error ("The value of max_value must be non-zero as it is used a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") + error ("The value of max_value must be non-zero as it is used a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") end -- get current value @@ -289,35 +287,35 @@ function draw_ring_graph(display, element) -- draw background rings draw_ring(display, background_ring) if not element.graduated then - -- draw bar ring if not graduated - draw_ring(display, bar_ring) + -- draw bar ring if not graduated + draw_ring(display, bar_ring) else - -- draw bar ring if graduated - local start_angle, end_angle = math.rad(element.start_angle), math.rad(element.end_angle) - local arc_drawer = cairo_arc - local orientation = 1 - if start_angle > end_angle then - arc_drawer = cairo_arc_negative - orientation = -1 - end - cairo_set_source_rgba(display, hexa_to_rgb(bar_ring.color, bar_ring.alpha)) - cairo_set_line_width(display, bar_ring.thickness); - - local angle_between_graduation = math.rad(element.angle_between_graduation) - local graduation_size = math.abs(end_angle-start_angle)/element.number_graduation - angle_between_graduation - local current_start = start_angle - bar_degrees=math.rad(bar_degrees) - - if (graduation_size+angle_between_graduation)*orientation == 0 then - error ("A division by zero would lead to an infinitely running for loop.") - end - if math.floor(bar_degrees/(graduation_size+angle_between_graduation)*orientation) > 0 then - for i=1, bar_degrees/(graduation_size+angle_between_graduation)*orientation do - arc_drawer(display, element.center.x, element.center.y, element.radius, current_start, current_start+graduation_size* orientation) - current_start= current_start+ (graduation_size+angle_between_graduation)* orientation - cairo_stroke(display); + -- draw bar ring if graduated + local start_angle, end_angle = math.rad(element.start_angle), math.rad(element.end_angle) + local arc_drawer = cairo_arc + local orientation = 1 + if start_angle > end_angle then + arc_drawer = cairo_arc_negative + orientation = -1 + end + cairo_set_source_rgba(display, hexa_to_rgb(bar_ring.color, bar_ring.alpha)) + cairo_set_line_width(display, bar_ring.thickness); + + local angle_between_graduation = math.rad(element.angle_between_graduation) + local graduation_size = math.abs(end_angle-start_angle)/element.number_graduation - angle_between_graduation + local current_start = start_angle + bar_degrees=math.rad(bar_degrees) + + if (graduation_size+angle_between_graduation)*orientation == 0 then + error ("A division by zero would lead to an infinitely running for loop.") + end + if math.floor(bar_degrees/(graduation_size+angle_between_graduation)*orientation) > 0 then + for i=1, bar_degrees/(graduation_size+angle_between_graduation)*orientation do + arc_drawer(display, element.center.x, element.center.y, element.radius, current_start, current_start+graduation_size* orientation) + current_start= current_start+ (graduation_size+angle_between_graduation)* orientation + cairo_stroke(display); + end end - end end end @@ -326,7 +324,7 @@ end function draw_ellipse_graph(display, element) -- draw a ellipse graph if element.max_value == 0 then - error ("The value of max_value must be non-zero as it is used a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") + error ("The value of max_value must be non-zero as it is used a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") end -- get current value @@ -383,46 +381,46 @@ function draw_ellipse_graph(display, element) if not element.graduated then - -- draw ellipse bar if not graduated - draw_ellipse(display, bar_ellipse) + -- draw ellipse bar if not graduated + draw_ellipse(display, bar_ellipse) else - -- draw ellipse bar if graduated - if element.number_graduation == 0 then - error ("The value of number_graduation must be non-zero as it is used as a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") - end - - local start_angle, end_angle = math.rad(element.start_angle), math.rad(element.end_angle) - local arc_drawer = cairo_arc - local orientation = 1 - if start_angle > end_angle then - arc_drawer = cairo_arc_negative - orientation = -1 - end - cairo_set_source_rgba(display, hexa_to_rgb(bar_ellipse.color, bar_ellipse.alpha)) - cairo_set_line_width(display, bar_ellipse.thickness); - - local angle_between_graduation = math.rad(element.angle_between_graduation) - local graduation_size = math.abs(end_angle-start_angle)/element.number_graduation - angle_between_graduation - local current_start = start_angle - bar_degrees=math.rad(bar_degrees) - - if (graduation_size+angle_between_graduation)*orientation == 0 then - error ("A division by zero would lead to an infinitely running for loop.") - end - - if math.floor(bar_degrees/(graduation_size+angle_between_graduation)*orientation) > 0 then - for i=1, bar_degrees/(graduation_size+angle_between_graduation)*orientation do - cairo_save(display) - cairo_translate (display, element.center.x + element.width / 2., element.center.y + element.height / 2.) - - cairo_scale (display, element.width / 2., element.height / 2.) - arc_drawer(display, element.center.x, element.center.y, element.radius, current_start, current_start+graduation_size* orientation) - current_start= current_start+ (graduation_size+angle_between_graduation)* orientation - - cairo_restore(display) - cairo_stroke(display); + -- draw ellipse bar if graduated + if element.number_graduation == 0 then + error ("The value of number_graduation must be non-zero as it is used as a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") + end + + local start_angle, end_angle = math.rad(element.start_angle), math.rad(element.end_angle) + local arc_drawer = cairo_arc + local orientation = 1 + if start_angle > end_angle then + arc_drawer = cairo_arc_negative + orientation = -1 + end + cairo_set_source_rgba(display, hexa_to_rgb(bar_ellipse.color, bar_ellipse.alpha)) + cairo_set_line_width(display, bar_ellipse.thickness); + + local angle_between_graduation = math.rad(element.angle_between_graduation) + local graduation_size = math.abs(end_angle-start_angle)/element.number_graduation - angle_between_graduation + local current_start = start_angle + bar_degrees=math.rad(bar_degrees) + + if (graduation_size+angle_between_graduation)*orientation == 0 then + error ("A division by zero would lead to an infinitely running for loop.") + end + + if math.floor(bar_degrees/(graduation_size+angle_between_graduation)*orientation) > 0 then + for i=1, bar_degrees/(graduation_size+angle_between_graduation)*orientation do + cairo_save(display) + cairo_translate (display, element.center.x + element.width / 2., element.center.y + element.height / 2.) + + cairo_scale (display, element.width / 2., element.height / 2.) + arc_drawer(display, element.center.x, element.center.y, element.radius, current_start, current_start+graduation_size* orientation) + current_start= current_start+ (graduation_size+angle_between_graduation)* orientation + + cairo_restore(display) + cairo_stroke(display); + end end - end end end @@ -434,7 +432,7 @@ function draw_ellipse(display, element) local start_angle, end_angle = math.rad(element.start_angle), math.rad(element.end_angle) local rotation_angle = math.rad(element.rotation_angle) -- direction of the ellipse changes the function we must call - local arc_drawer = cairo_arc + local arc_drawer = cairo_arc local orientation = 1 if start_angle > end_angle then arc_drawer = cairo_arc_negative @@ -446,81 +444,114 @@ function draw_ellipse(display, element) if not element.graduated then - -- draw simple ellipse - cairo_save(display) - cairo_translate (display, element.center.x, element.center.y) - cairo_scale (display, element.width / 2., element.height / 2.) - arc_drawer(display, 0., 0., 1., start_angle, end_angle) - - cairo_restore(display) - cairo_stroke(display) + -- draw simple ellipse + cairo_save(display) + cairo_translate (display, element.center.x, element.center.y) + cairo_scale (display, element.width / 2., element.height / 2.) + arc_drawer(display, 0., 0., 1., start_angle, end_angle) + + cairo_restore(display) + cairo_stroke(display) else - -- draw graduated ellipse - if element.number_graduation == 0 then - error ("The value of number_graduation must be non-zero as it is used as a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") - end - local angle_between_graduation = math.rad(element.angle_between_graduation) - local graduation_size = math.abs(end_angle-start_angle)/element.number_graduation - angle_between_graduation - local current_start = start_angle - - if math.floor(element.number_graduation) > 0 then - for i=1, element.number_graduation do - cairo_save(display) - cairo_translate (display, element.center.x, element.center.y) - cairo_scale (display, element.width / 2., element.height / 2.) - arc_drawer(display, 0., 0., 1., current_start, current_start+graduation_size* orientation) - current_start= current_start+ (graduation_size+angle_between_graduation)* orientation - cairo_restore(display) - cairo_stroke(display); + -- draw graduated ellipse + if element.number_graduation == 0 then + error ("The value of number_graduation must be non-zero as it is used as a divisor. Dividing by zero causes undefined behavior (usually it results in an 'inf').") + end + local angle_between_graduation = math.rad(element.angle_between_graduation) + local graduation_size = math.abs(end_angle-start_angle)/element.number_graduation - angle_between_graduation + local current_start = start_angle + + if math.floor(element.number_graduation) > 0 then + for i=1, element.number_graduation do + cairo_save(display) + cairo_translate (display, element.center.x, element.center.y) + cairo_scale (display, element.width / 2., element.height / 2.) + arc_drawer(display, 0., 0., 1., current_start, current_start+graduation_size* orientation) + current_start= current_start+ (graduation_size+angle_between_graduation)* orientation + cairo_restore(display) + cairo_stroke(display); + end end - end end end function draw_variable_text(display, element) - cairo_save(display) - cairo_move_to (display,element.from.x,element.from.y) - cairo_rotate(display,element.rotation_angle* (math.pi / 180)) - cairo_set_source_rgba(display,hexa_to_rgb(element.color, element.alpha)) - cairo_set_font_size (display, element.font_size) - local font_slant = CAIRO_FONT_SLANT_NORMAL - if element.italic then - font_slant=CAIRO_FONT_SLANT_ITALIC - end - local font_weight = CAIRO_FONT_WEIGHT_NORMAL - if element.bold then - font_weight=CAIRO_FONT_WEIGHT_BOLD - end - cairo_select_font_face(display,element.font,font_slant,font_weight) - local text = get_conky_value(element.conky_value,false) - cairo_show_text (display,text) - - cairo_restore(display) - cairo_stroke (display) + cairo_save(display) + cairo_set_source_rgba(display,hexa_to_rgb(element.color, element.alpha)) + cairo_set_font_size (display, element.font_size) + local font_slant = CAIRO_FONT_SLANT_NORMAL + if element.italic then + font_slant=CAIRO_FONT_SLANT_ITALIC + end + local font_weight = CAIRO_FONT_WEIGHT_NORMAL + if element.bold then + font_weight=CAIRO_FONT_WEIGHT_BOLD + end + cairo_select_font_face(display,element.font,font_slant,font_weight) + local text = get_conky_value(element.conky_value,false) + + local extents=cairo_text_extents_t:create() + cairo_text_extents(display, text, extents) + local x = element.from.x + if element.halign == "center" then + x = x - (extents.width / 2 + extents.x_bearing) + elseif element.halign == "right" then + x = x - extents.width + end + local y = element.from.y + if element.valign == "center" then + y = y - (extents.height / 2 + extents.y_bearing) + elseif element.valign == "top" then + y = y + extents.height + end + + cairo_move_to (display,x,y) + cairo_rotate(display,element.rotation_angle* (math.pi / 180)) + + cairo_show_text (display,text) + + cairo_restore(display) + cairo_stroke (display) end function draw_static_text(display, element) - cairo_save(display) - cairo_move_to (display,element.from.x,element.from.y) - cairo_rotate(display,element.rotation_angle* (math.pi / 180)) - cairo_set_source_rgba(display,hexa_to_rgb(element.color, element.alpha)) - cairo_set_font_size (display, element.font_size) - local font_slant = CAIRO_FONT_SLANT_NORMAL - if element.italic then + cairo_save(display) + cairo_set_source_rgba(display,hexa_to_rgb(element.color, element.alpha)) + cairo_set_font_size (display, element.font_size) + local font_slant = CAIRO_FONT_SLANT_NORMAL + if element.italic then font_slant=CAIRO_FONT_SLANT_ITALIC - end - local font_weight = CAIRO_FONT_WEIGHT_NORMAL - if element.bold then + end + local font_weight = CAIRO_FONT_WEIGHT_NORMAL + if element.bold then font_weight=CAIRO_FONT_WEIGHT_BOLD - end - cairo_select_font_face(display,element.font,font_slant,font_weight) + end + cairo_select_font_face(display,element.font,font_slant,font_weight) + + local extents=cairo_text_extents_t:create() + cairo_text_extents(display, element.text, extents) + local x = element.from.x + if element.halign == "center" then + x = x - (extents.width / 2 + extents.x_bearing) + elseif element.halign == "right" then + x = x - extents.width + end + local y = element.from.y + if element.valign == "center" then + y = y - (extents.height / 2 + extents.y_bearing) + elseif element.valign == "top" then + y = y + extents.height + end + + cairo_move_to (display,x,y) + cairo_rotate(display,element.rotation_angle* (math.pi / 180)) - cairo_show_text (display,element.text) + cairo_show_text (display,element.text) - cairo_restore(display) - cairo_stroke (display) + cairo_restore(display) + cairo_stroke (display) end @@ -711,6 +742,8 @@ defaults = { bold=false, italic=false, alpha=1.0, + halign="left", + valign="bottom", draw_function = draw_static_text, }, clock = {