12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103 |
- -- @author cedlemo
- local naughty= require("naughty")
- local lgi = require("lgi")
- local cairo = lgi.cairo
- local pango = lgi.Pango
- local pangocairo = lgi.PangoCairo
- local string = require("string")
- local os = require('os')
- local awful = require('awful')
- local wibox = require('wibox')
- local math = math
- local table = table
- local print = print
- ---Functions used in blingbling.
- --@module blingbling.helpers
- local helpers={}
- ---Display values of variables in an awesome popup.
- --Each variables in vars is separated by a "|"
- --@param vars a table of variable
- function helpers.dbg(vars)
- local text = ""
- for i=1, #vars do text = text .. vars[i] .. " | " end
- naughty.notify({ text = text, timeout = 15 })
- end
- ---Convert an hexadecimal color to rgba color.
- --It convert a string variable "#rrggbb" or "#rrggbbaa" (with r,g,b and a which are hexadecimal value) to r, g, b a=1 or r,g,b,a (with r,g,b,a floated value from 0 to 1.
- --The function returns 4 variables.
- --@param my_color a string "#rrggbb" or "#rrggbbaa"
- function helpers.hexadecimal_to_rgba_percent(my_color)
- --check if color is a valid hex color else return white
- if string.find(my_color,"#[0-f][0-f][0-f][0-f][0-f]") then
- --delete #
- my_color=string.gsub(my_color,"^#","")
- r=string.format("%d", "0x"..string.sub(my_color,1,2))
- v=string.format("%d", "0x"..string.sub(my_color,3,4))
- b=string.format("%d", "0x"..string.sub(my_color,5,6))
- if string.sub(my_color,7,8) == "" then
- a=255
- else
- a=string.format("%d", "0x"..string.sub(my_color,7,8))
- end
- else
- r=255
- v=255
- b=255
- a=255
- end
- return r/255,v/255,b/255,a/255
- end
- ---Get red green blue value in parameters and return hexadecimal string
- function helpers.rgb(red, green, blue)
- if type(red) == "number" or type(green) == "number" or type(blue) == "number" then
- return "#"..string.format("%02x",red)..string.format("%02x",green)..string.format("%02x",blue)
- else
- return nil
- end
- end
- ---Get red green blue and alpha value in parameters and return hexadecimal string.
- function helpers.rgba(red, green, blue, alpha)
- if type(red) == "number" or type(green) == "number" or type(blue) == "number" or type(alpha) == "number" then
- return "#"..string.format("%02x",red)..string.format("%02x",green)..string.format("%02x",blue)..string.format("%02x",alpha * 255)
- else
- return nil
- end
- end
- ---Check if an hexadecimal color is fully transparent.
- --Returns true or false
- --@param my_color a string "#rrggbb" or "#rrggbbaa"
- function helpers.is_transparent(my_color)
- --check if color is a valid hex color else return white
- if string.find(my_color,"#[0-f][0-f][0-f][0-f][0-f]") then
- --delete #
- local my_color=string.gsub(my_color,"^#","")
- if string.sub(my_color,7,8) == "" then
- return false
- else
- local alpha=string.format("%d", "0x"..string.sub(my_color,7,8))
- if alpha/1 == 0 then
- return true
- else
- return false
- end
- end
- else
- return false
- end
- end
- ---Split string in different parts which are returned in a table. The delimiter of each part is a pattern given in argument.
- --@param str the string to split
- --@param pat the pattern delimiter
- function helpers.split(str, pat)
- local t = {} -- NOTE: use {n = 0} in Lua-5.0
- local fpat = "(.-)" .. pat
- local last_end = 1
- local s, e, cap = string.find(str,fpat, 1)
- while s do
- if s ~= 1 or cap ~= "" then
- table.insert(t,cap)
- end
- last_end = e+1
- s, e, cap = string.find(str,fpat, last_end)
- end
- if last_end <= #str then
- cap = string.sub(str,last_end)
- table.insert(t, cap)
- end
- return t
- end
- ---Draw tiles in a cairo context.
- --@param cr a cairo context.
- --@param height the height of the surface on which we want tiles
- --@param v_margin value used to define top margin and/or bottom margin (tiles are not drawn on the margins)
- --@param width the width of the surface on which we want tiles
- --@param h_margin value used to define left margin and/or right margin.
- function helpers.draw_background_tiles(cr, height, v_margin , width, h_margin)
- --tiles: width 4 px height 2px horizontal separator=1 px vertical separator=2px
- -- v_separator
- -- _______\ /_______
- -- |_______| |_______|
- -- _______ _______ <--h_separator
- -- |_______| |_______| <--tiles_height
- -- / \
- -- tiles_width
- tiles_width=4
- tiles_height=2
- h_separator=1
- v_separator=2
- --find nb max horizontal lignes we can display with 2 pix squarre and 1 px separator (3px)
- local max_line=math.floor((height - v_margin*2) /(tiles_height+h_separator))
- --what to do with the rest of the height:
- local h_rest=(height - v_margin*2) - (max_line * (tiles_height+h_separator))
- if h_rest >= (tiles_height) then
- max_line= max_line + 1
- h_rest= h_rest - tiles_height
- end
- if h_rest > 0 then
- h_rest =h_rest / 2
- end
- --find nb columns we can draw with tile of 4px width and 2 px separator (6px) and center them horizontaly
- local max_column=math.floor((width - h_margin*2)/6)
- local v_rest=(width- h_margin*2)-(max_column*( tiles_width + v_separator))
- if v_rest >= (tiles_width) then
- max_column= max_column + 1
- v_rest= v_rest - tiles_width
- end
- if v_rest > 0 then
- h_rest =h_rest / 2
- end
- x=width-(tiles_width + v_rest)
- y=height -(v_margin +tiles_height + h_rest)
- for i=1,max_column do
- for j=1,max_line do
- cr:rectangle(x,y,4,2)
- y= y-(tiles_height + h_separator)
- end
- y=height -(v_margin + tiles_height + h_rest)
- x=x-(tiles_width + v_separator)
- end
- end
- ---Draw text on a rectangle which width and height depend on the text width and height.
- --@param cr a cairo context already initialised with oocairo.context_create( )
- --@param text the text to display
- --@param x the x coordinate of the left of the text
- --@param y the y coordinate of the bottom of the text
- --@param text_background_color a string "#rrggbb" or "#rrggbbaa" for the rectangle color
- --@param text_color a string "#rrggbb" or "#rrggbbaa" for the text color
- --@param show_text_centered_on_x a boolean value not mandatory (false by default) if true, x parameter is the coordinate of the middle of the text
- --@param show_text_centered_on_y a boolean value not mandatory (false by default) if true, y parameter is the coordinate of the middle of the text
- --@param show_text_on_left_of_x a boolean value not mandatory (false by default) if true, x parameter is the right of the text
- --@param show_text_on_bottom_of_y a boolean value not mandatory (false by default) if true, y parameter is the top of the text
- function helpers.draw_text_and_background(cr, text, x, y, text_background_color, text_color, text_x_center, text_y_center, text_x_left, text_y_bottom)
- --Text background
- ext=cr:text_extents(text)
- x_modif = 0
- y_modif = 0
- if text_x_centered == true then
- x_modif = ((ext.width + ext.x_bearing) / 2) + ext.x_bearing / 2
- text_x_left = false
- else
- if text_x_left == true then
- x_modif = ext.width + 2 *ext.x_bearing
- else
- x_modif = x_modif
- end
- end
- if text_y_centered == true then
- y_modif = ((ext.height +ext.y_bearing)/2 ) + ext.y_bearing / 2
- text_y_left = false
- else
- if text_y_bottom == true then
- y_modif = ext.height + 2 *ext.y_bearing
- else
- y_modif = y_modif
- end
- end
- cr:rectangle(x + ext.x_bearing - x_modif,y + ext.y_bearing - y_modif,ext.width, ext.height)
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(text_background_color)
- cr:set_source_rgba(r,g,b,a)
- cr:fill()
- --Text
- cr:new_path()
- cr:move_to(x-x_modif,y-y_modif)
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(text_color)
- cr:set_source_rgba(r, g, b, a)
- cr:show_text(text)
- end
- ---Draw text on a rectangle which width and height depend on the text width and height.
- --@param cr a cairo context already initialised
- --@param text the text to display
- --@param x the x coordinate of the left of the text
- --@param y the y coordinate of the bottom of the text
- --@param bg_color a string "#rrggbb" or "#rrggbbaa" for the rectangle color
- --@param fg_color a string "#rrggbb" or "#rrggbbaa" for the text color
- --@param x_position a string "start", "middle" or "end" which define how the drawing will be positioned from x ("start" by default)
- --@param y_position a string "start", "middle" or "end" which define how the drawing will be positioned from y ("start" by default)
- function helpers.draw_layout_and_background(cr, text, x, y, font, bg_color, fg_color, x_position, y_position)
- local layout = pangocairo.create_layout(cr)
- local font_desc = pango.FontDescription.from_string(font)
- layout:set_font_description(font_desc)
- layout.text = text
- local _, logical = layout:get_pixel_extents()
- local height = logical.height
- local width = logical.width
- local text_x = x -- x position start
- local text_y = y -- y position start
- if x_position == "middle" then
- text_x = text_x - width / 2
- elseif x_position == "end" then
- text_x = text_x - width
- end
- if y_position == "middle" then
- text_y = text_y - height / 2
- elseif y_position == "end" then
- text_y = text_y - height
- end
- cr:rectangle(text_x, text_y, width, height)
- local r,g,b,a = helpers.hexadecimal_to_rgba_percent(bg_color)
- cr:set_source_rgba(r,g,b,a)
- cr:fill()
- cr:move_to(text_x, text_y)
- local r,g,b,a = helpers.hexadecimal_to_rgba_percent(fg_color)
- cr:set_source_rgba(r,g,b,a)
- cr:show_layout(layout)
- end
- ---Drawn one foreground arrow with a background arrow that depend on a value.
- --If the value is egal to 0 then the foreground arrow is not drawn.
- --@param cr a cairo context already initialised with oocairo.context_create( )
- --@param x the x coordinate in the cairo context where the arrow start
- --@param y_bottom the bottom corrdinate of the arrows
- --@param y_top the top coordinate of the arrows
- --@param value a number
- --@param background_arrow_color the color of the background arrow, a string "#rrggbb" or "#rrggbbaa"
- --@param arrow_color the color of the foreground arrow, a string "#rrggbb" or "#rrggbbaa"
- --@param arrow_line_color the color of the outline of the foreground arrow , a string "#rrggbb" or "#rrggbbaa"
- --@param up boolean value if false draw a down arrow, if true draw a up arrow
- function helpers.draw_up_down_arrows(cr,x,y_bottom,y_top,value,background_arrow_color, arrow_color, arrow_line_color,up)
- if up ~= false then
- invert = 1
- else
- invert= -1
- end
- --Draw the background arrow
- cr:move_to(x,y_bottom)
- cr:line_to(x,y_top )
- cr:line_to(x-(6 * invert), y_top + (6 * invert))
- cr:line_to(x-(3*invert), y_top + (6 * invert))
- cr:line_to(x-(3*invert), y_bottom)
- cr:line_to(x,y_bottom)
- cr:close_path()
- r,g,b,a = helpers.hexadecimal_to_rgba_percent(background_arrow_color)
- cr:set_source_rgba(r, g, b, a)
- cr:fill()
- --Draw the arrow if value is > 0
- if value > 0 then
- cr:move_to(x,y_bottom)
- cr:line_to(x,y_top )
- cr:line_to(x-(6*invert), y_top + (6 * invert))
- cr:line_to(x-(3*invert), y_top + (6 * invert))
- cr:line_to(x-(3*invert), y_bottom)
- cr:line_to(x,y_bottom)
- cr:close_path()
- r,g,b,a = helpers.hexadecimal_to_rgba_percent(arrow_color)
- cr:set_source_rgba(r, g, b, a)
- cr:fill()
- cr:move_to(x,y_bottom)
- cr:line_to(x,y_top )
- cr:line_to(x-(6*invert), y_top + (6 * invert))
- cr:line_to(x-(3*invert), y_top + (6 * invert))
- cr:line_to(x-(3*invert), y_bottom)
- cr:line_to(x,y_bottom)
- cr:close_path()
- r,g,b,a = helpers.hexadecimal_to_rgba_percent(arrow_line_color)
- cr:set_source_rgba(r, g, b, a)
- cr:set_line_width(1)
- cr:stroke()
- end
- end
- ---Draw a vertical bar with gradient color, so it looks like a cylinder, and it's height depends on a value.
- --@param cr a cairo context already initialised with oocairo.context_create( )
- --@param h_margin the left and right margin of the bar in the cr
- --@param v_margin the top and bottom margin of the bar in the cr
- --@param width the width used to display the left margin, the bar and the right margin
- --@param height the height used to display the top margin, the bar and the bottom margin
- --@param represent a table {background_bar_color = "#rrggbb" or "#rrggbbaa", color = "#rrggbb" or "#rrggbbaa", value =the value used to calculate the height of the bar}
- function helpers.draw_vertical_bar(cr,h_margin,v_margin, width,height, represent)
- x=h_margin
- bar_width=width - 2*h_margin
- bar_height=height - 2*v_margin
- y=v_margin
- if represent["background_bar_color"] == nil then
- r,g,b,a = helpers.hexadecimal_to_rgba_percent("#000000")
- else
- r,g,b,a = helpers.hexadecimal_to_rgba_percent(represent["background_bar_color"])
- end
- cr:rectangle(x,y,bar_width ,bar_height)
- gradient=cairo.pattern_create_linear(h_margin, height/2, width-h_margin, height/2)
- gradient:add_color_stop_rgba(0, r, g, b, 0.5)
- gradient:add_color_stop_rgba(0.5, 1, 1, 1, 0.5)
- gradient:add_color_stop_rgba(1, r, g, b, 0.5)
- cr:set_source(gradient)
- cr:fill()
- if represent["value"] ~= nil and represent["color"] ~= nil then
- x=h_margin
- bar_width=width - 2*h_margin
- bar_height=height - 2*v_margin
- if represent["invert"] == true then
- y=v_margin
- else
- y=height - (bar_height*represent["value"] + v_margin )
- end
- cr:rectangle(x,y,bar_width,bar_height*represent["value"])
- r,g,b,a = helpers.hexadecimal_to_rgba_percent(represent["color"])
- gradient=cairo.pattern_create_linear(0, height/2,width, height/2)
- gradient:add_color_stop_rgba(0, r, g, b, 0.1)
- gradient:add_color_stop_rgba(0.5, r, g, b, 1)
- gradient:add_color_stop_rgba(1, r, g, b, 0.1)
- cr:set_source(gradient)
- cr:fill()
- end
- end
- ---Draw an horizontal bar with gradient color, so it looks like a cylinder, and it's height depends on a value.
- --@param cr a cairo context already initialised with oocairo.context_create( )
- --@param h_margin the left and right margin of the bar in the cr
- --@param v_margin the top and bottom margin of the bar in the cr
- --@param width the width used to display the left margin, the bar and the right margin
- --@param height the height used to display the top margin, the bar and the bottom margin
- --@param represent a table {background_bar_color = "#rrggbb" or "#rrggbbaa", color = "#rrggbb" or "#rrggbbaa", value =the value used to calculate the width of the bar}
- function helpers.draw_horizontal_bar( cr,h_margin,v_margin, width, height, represent)
- x=h_margin
- bar_width=width - 2*h_margin
- bar_height=height - 2*v_margin
- y=v_margin
- if represent["background_bar_color"] == nil then
- r,g,b,a = helpers.hexadecimal_to_rgba_percent("#000000")
- else
- r,g,b,a = helpers.hexadecimal_to_rgba_percent(represent["background_bar_color"])
- end
- cr:rectangle(x,y,bar_width,bar_height)
- gradient=cairo.pattern_create_linear( width /2,v_margin , width/2, height - v_margin)
- gradient:add_color_stop_rgba(0, r, g, b, 0.5)
- gradient:add_color_stop_rgba(0.5, 1, 1, 1, 0.5)
- gradient:add_color_stop_rgba(1, r, g, b, 0.5)
- cr:set_source(gradient)
- cr:fill()
- if represent["value"] ~= nil and represent["color"] ~= nil then
- x=h_margin
- bar_width=width - 2*h_margin
- bar_height=height - 2*v_margin
- if represent["invert"] == true then
- x=width - (h_margin + bar_width*represent["value"] )
- else
- x=h_margin
- end
- cr:rectangle(x,y,bar_width*represent["value"],bar_height)
- r,g,b,a = helpers.hexadecimal_to_rgba_percent(represent["color"])
- gradient=cairo.pattern_create_linear(width /2,0 , width/2, height)
- gradient:add_color_stop_rgba(0, r, g, b, 0.1)
- gradient:add_color_stop_rgba(0.5, r, g, b, 1)
- gradient:add_color_stop_rgba(1, r, g, b, 0.1)
- cr:set_source(gradient)
- cr:fill()
- end
- end
- ---Draw a rectangle width rounded corners.
- --@param cr a cairo context already initialised with oocairo.context_create( )
- --@param x the x coordinate of the left top corner
- --@param y the y corrdinate of the left top corner
- --@param width the width of the rectangle
- --@param height the height of the rectangle
- --@param color a string "#rrggbb" or "#rrggbbaa" for the color of the rectangle
- --@param rounded_size a float value from 0 to 1 (0 is no rounded corner) or a table of float value
- function helpers.draw_rounded_corners_rectangle(cr,x,y,width, height, color, rounded_size)
- if helpers.is_transparent(color) then return nil end
- --if rounded_size =0 it is a classical rectangle (whooooo!)
- local height = height
- local width = width
- local x = x
- local y = y
- local rounded_sizes = {}
- if type(rounded_size) == "number" then
- for i = 1,4 do
- rounded_sizes[i]=rounded_size or 0
- end
- elseif type(rounded_size) == "table" then
- for i = 1,4 do
- rounded_sizes[i] = rounded_size[i] or 0
- end
- end
- radius = height > width and 0.5 * width or 0.5 * height
- PI = 2*math.asin(1)
- r,g,b,a = helpers.hexadecimal_to_rgba_percent(color)
- cr:set_source_rgba(r, g, b, a)
- --top left corner
- cr:arc(x + radius*rounded_sizes[1],
- y + radius*rounded_sizes[1],
- radius*rounded_sizes[1], PI, PI * 1.5)
- --top right corner
- cr:arc(width - radius*rounded_sizes[2],
- y + radius*rounded_sizes[2],
- radius*rounded_sizes[2], PI*1.5, PI * 2)
- --bottom right corner
- cr:arc(width - radius*rounded_sizes[3],
- height - radius*rounded_sizes[3],
- radius*rounded_sizes[3],PI*0, PI * 0.5)
- --bottom left corner
- cr:arc(x + radius*rounded_sizes[4],
- height - radius*rounded_sizes[4],
- radius*rounded_sizes[4],PI*0.5, PI * 1)
- cr:close_path()
- cr:fill()
- end
- ---Set a rectangle width rounded corners that define the area to draw.
- --@param cr a cairo context already initialised with oocairo.context_create( )
- --@param x the x coordinate of the left top corner
- --@param y the y corrdinate of the left top corner
- --@param width the width of the rectangle
- --@param height the height of the rectangle
- --@param rounded_size a float value from 0 to 1 (0 is no rounded corner)
- function helpers.clip_rounded_corners_rectangle(cr,x,y,width, height, rounded_size)
- --if rounded_size =0 it is a classical rectangle (whooooo!)
- local height = height
- local width = width
- local x = x
- local y = y
- local rounded_size = rounded_size or 0.4
- if height > width then
- radius=0.5 * width
- else
- radius=0.5 * height
- end
- PI = 2*math.asin(1)
- --top left corner
- cr:arc(x + radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI, PI * 1.5)
- --top right corner
- cr:arc(width - radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI*1.5, PI * 2)
- --bottom right corner
- cr:arc(width - radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0, PI * 0.5)
- --bottom left corner
- cr:arc(x + radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0.5, PI * 1)
- cr:close_path()
- cr:clip()
- end
- ---Draw a foreground rounded corners rectangle which width depends on a value, and a background rounded corners rectangle.
- --@param cr a cairo context already initialised with oocairo.context_create( )
- --@param x the x coordinate of the left top corner
- --@param y the y corrdinate of the left top corner
- --@param width the width of the background rectangle and the maximal width of th foreground rectangle
- --@param height the height of the background and the foreground rectangles
- --@param background_color a string "#rrggbb" or "#rrggbbaa" for the color of the background rectangle
- --@param graph_color a string "#rrggbb" or "#rrggbbaa" for the color of the foreground rectangle
- --@param rounded_size a float value from 0 to 1 (0 is no rounded corner)
- --@param value_to_represent the percent of the max width used to calculate the width of the foreground rectangle
- --@param graph_line_color a string "#rrggbb" or "#rrggbbaa" for the outiline color of the background rectangle
- function helpers.draw_rounded_corners_horizontal_graph(cr,x,y,width, height, background_color, graph_color, rounded_size, value_to_represent, graph_line_color)
- --if rounded_size =0 it is a classical rectangle (whooooo!)
- local height = height
- local width = width
- local x = x
- local y = y
- local rounded_size = rounded_size or 0.4
- if height > width then
- radius=0.5 * width
- else
- radius=0.5 * height
- end
- PI = 2*math.asin(1)
- --draw the background
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(background_color)
- cr:set_source_rgba(r,g,b,a)
- --top left corner
- cr:arc(x + radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI, PI * 1.5)
- --top right corner
- cr:arc(width - radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI*1.5, PI * 2)
- --bottom right corner
- cr:arc(width - radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0, PI * 0.5)
- --bottom left corner
- cr:arc(x + radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0.5, PI * 1)
- cr:close_path()
- cr:fill()
- --represent the value
- -- value in 0 -> 1
- -- radius*rounded_size | width - 2*( radius*rounded) | radius * rounded_size
- -- | | |
- -- | _________| _______________________|
- -- | | |
- -- v ____v_________ v
- -- /| |\
- -- | | | | (... and yes I don't have a job)
- -- \|______________|/
- --
- --1 => width/ width
- --limit_2 => width -radius / width
- --limit_1 => radius /width
- value = value_to_represent
- limit_2 = (width -(radius * rounded_size)) / width
- limit_1 = radius* rounded_size /width
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(graph_color)
- cr:set_source_rgba(r,g,b,a)
- if value <= 1 and value > limit_2 then
- cr:arc(x + radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI, PI * 1.5)
- ratio = (value - limit_2) / (1 - limit_2)
- cr:arc(width - radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI*1.5, PI *(1.5 +(0.5 * ratio)))
- cr:arc(width - radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*(0.5 - (0.5 * ratio)) , PI * 0.5)
- cr:arc(x + radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0.5, PI * 1)
- cr:close_path()
- cr:fill()
- elseif value <= limit_2 and value > limit_1 then
- cr:arc(x + radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI, PI * 1.5)
- ratio = value / limit_2
- cr:line_to(limit_2*width*ratio,y)
- cr:line_to(limit_2*width*ratio,height)
- cr:arc(x + radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0.5, PI * 1)
- cr:close_path()
- cr:fill()
- elseif value <= limit_1 and value > 0 then
- ratio = value / limit_1
- cr:arc(x + radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI, PI * (1+ (0.5*ratio)))
- cr:arc(x + radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*(1-(0.5 * ratio)) , PI * 1)
- cr:close_path()
- cr:fill()
- end
- if graph_line_color then
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(graph_line_color)
- cr:set_source_rgba(r,g,b,a)
- cr:set_line_width(1)
- if value <= 1 and value > limit_2 then
- cr:arc(x +1+ radius*rounded_size,y+1 + radius*rounded_size, radius*rounded_size,PI, PI * 1.5)
- ratio = (value - limit_2) / (1 - limit_2)
- cr:arc(width-1 - radius*rounded_size,y+1 + radius*rounded_size, radius*rounded_size,PI*1.5, PI *(1.5 +(0.5 * ratio)))
- cr:arc(width-1 - radius*rounded_size,height-1 - radius*rounded_size, radius*rounded_size,PI*(0.5 - (0.5 * ratio)) , PI * 0.5)
- cr:arc(x+1 + radius*rounded_size,height-1 - radius*rounded_size, radius*rounded_size,PI*0.5, PI * 1)
- cr:close_path()
- cr:stroke()
- elseif value <= limit_2 and value > limit_1 then
- cr:arc(x +1+ radius*rounded_size,y+1 + radius*rounded_size, radius*rounded_size,PI, PI * 1.5)
- ratio = value / limit_2
- cr:line_to(limit_2*width*ratio -1 ,y +1)
- cr:line_to(limit_2*width*ratio -1 ,height -1 )
- cr:arc(x +1 + radius*rounded_size,height -1 - radius*rounded_size, radius*rounded_size,PI*0.5, PI * 1)
- cr:close_path()
- cr:stroke()
- elseif value <= limit_1 and value > 0 then
- ratio = value / limit_1
- cr:arc(x +1 + radius*rounded_size,y +1 + radius*rounded_size, radius*rounded_size,PI, PI * (1+ (0.5*ratio)))
- cr:arc(x +1 + radius*rounded_size,height +1 - radius*rounded_size, radius*rounded_size,PI*(1-(0.5 * ratio)) , PI * 1)
- cr:close_path()
- cr:stroke()
- end
- end
- end
- ---Draw a foreground rounded corners rectangle which height depends on a value, and a background rounded corners rectangle.
- --@param cr a cairo context already initialised with oocairo.context_create( )
- --@param x the x coordinate of the left top corner
- --@param y the y corrdinate of the left top corner
- --@param width the width of the background and the foreground rectangles
- --@param height the height of the background rectangle and the maximal height of the foreground rectangle
- --@param background_color a string "#rrggbb" or "#rrggbbaa" for the color of the background rectangle
- --@param graph_color a string "#rrggbb" or "#rrggbbaa" for the color of the foreground rectangle
- --@param rounded_size a float value from 0 to 1 (0 is no rounded corner)
- --@param value_to_represent the percent of the max height used to calculate the height of the foreground rectangle
- --@param graph_line_color a string "#rrggbb" or "#rrggbbaa" for the outiline color of the background rectangle
- function helpers.draw_rounded_corners_vertical_graph(cr,x,y,width, height, background_color, graph_color, rounded_size, value_to_represent, graph_line_color)
- --if rounded_size =0 it is a classical rectangle (whooooo!)
- local height = height
- local width = width
- local x = x
- local y = y
- if rounded_size == nil or rounded_size == 0 then
- --draw the background:
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(background_color)
- cr:set_source_rgba(r,g,b,a)
- cr:move_to(x,y)
- cr:line_to(x,height)
- cr:line_to(width,height)
- cr:line_to(width,y)
- cr:close_path()
- cr:fill()
- --draw the graph:
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(graph_color)
- cr:set_source_rgba(r,g,b,a)
- cr:move_to(x,height)
- cr:line_to(x, height -((height -y)* value_to_represent) )
- cr:line_to(width,height -((height - y)*value_to_represent) )
- cr:line_to(width,height)
- cr:close_path()
- cr:fill()
- if graph_line_color then
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(graph_line_color)
- cr:set_source_rgba(r,g,b,a)
- cr:move_to(x,height)
- cr:line_to(x,height -((height -y)* value_to_represent) )
- cr:line_to(width,height -((height -y)*value_to_represent) )
- cr:line_to(width,height)
- cr:close_path()
- cr:set_line_width(1)
- cr:stroke()
- end
- else
- local rounded_size = rounded_size or 0.4
- if height > width then
- radius=0.5 * width
- else
- radius=0.5 * height
- end
- PI = 2*math.asin(1)
- --draw the background
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(background_color)
- cr:set_source_rgba(r,g,b,a)
- --top left corner
- cr:arc(x + radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI, PI * 1.5)
- --top right corner
- cr:arc(width - radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI*1.5, PI * 2)
- --bottom right corner
- cr:arc(width - radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0, PI * 0.5)
- --bottom left corner
- cr:arc(x + radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0.5, PI * 1)
- cr:close_path()
- cr:fill()
- --represent the value
- -- value in 0 -> 1
- -- radius*rounded_size | height - 2*( radius*rounded) | radius * rounded_size
- -- | | |
- -- | ____| _______________________|
- -- |_______ | |
- -- ___ | | |
- -- /___\ <- | |
- -- | | | |
- -- | |<---- |
- -- |_____| |
- -- \___/<------------
- --
- --1 => height/ height
- --limit_2 => height -radius / height
- --limit_1 => radius /height
- value = value_to_represent
- limit_2 = (height -(radius * rounded_size)) / height
- limit_1 = radius* rounded_size /height
- --dbg({value, limit_2, limit_1})
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(graph_color)
- cr:set_source_rgba(r,g,b,a)
- if value <= 1 and value > limit_2 then
- ratio = (value - limit_2) / (1 - limit_2)
- cr:arc(width - radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0 , PI * 0.5)
- cr:arc(x + radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0.5, PI * 1)
- cr:arc(x + radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI, PI * (1+(0.5* ratio)) )
- cr:arc(width - radius*rounded_size,y + radius*rounded_size, radius*rounded_size,PI*(2 -(0.5* ratio)), PI *2)
- cr:close_path()
- cr:fill()
- elseif value <= limit_2 and value > limit_1 then
- ratio = value / limit_2
- cr:arc(width - radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0 , PI * 0.5)
- cr:arc(x + radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0.5, PI * 1)
- cr:line_to(x,y + height - (height * ratio*limit_2) )
- cr:line_to(width,y+ height - (height * ratio*limit_2) )
- cr:close_path()
- cr:fill()
- elseif value <= limit_1 and value > 0 then
- ratio = value / limit_1
- cr:arc(width - radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*(0.5-( 0.5*ratio)) , PI * 0.5)
- cr:arc(x + radius*rounded_size,height - radius*rounded_size, radius*rounded_size,PI*0.5, PI *(0.5+ (0.5*ratio)))
- cr:close_path()
- cr:fill()
- end
- if graph_line_color then
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(graph_line_color)
- cr:set_source_rgba(r,g,b,a)
- cr:set_line_width(1)
- if value <= 1 and value > limit_2 then
- ratio = (value - limit_2) / (1 - limit_2)
- cr:arc(width -1 - radius*rounded_size,height -1 - radius*rounded_size, radius*rounded_size,PI*0 , PI * 0.5)
- cr:arc(x+1 + radius*rounded_size,height -1 - radius*rounded_size, radius*rounded_size,PI*0.5, PI * 1)
- cr:arc(x+1 + radius*rounded_size,y+1 + radius*rounded_size, radius*rounded_size,PI, PI * (1+(0.5* ratio)) )
- cr:arc(width -1 - radius*rounded_size,y+1 + radius*rounded_size, radius*rounded_size,PI*(2 -(0.5* ratio)), PI *2)
- cr:close_path()
- cr:stroke()
- elseif value <= limit_2 and value > limit_1 then
- ratio = value / limit_2
- cr:arc(width -1 - radius*rounded_size,height -1 - radius*rounded_size, radius*rounded_size,PI*0 , PI * 0.5)
- cr:arc(x+1 + radius*rounded_size,height -1 - radius*rounded_size, radius*rounded_size,PI*0.5, PI * 1)
- cr:line_to(x +1 ,y +1 + height - (height * ratio*limit_2) )
- cr:line_to(width - 1,y +1 + height - (height * ratio*limit_2) )
- cr:close_path()
- cr:stroke()
- elseif value <= limit_1 and value > 0 then
- ratio = value / limit_1
- cr:arc(width -1 - radius*rounded_size,height -1 - radius*rounded_size, radius*rounded_size,PI*(0.5-( 0.5*ratio)) , PI * 0.5)
- cr:arc(x +1 + radius*rounded_size,height -1 - radius*rounded_size, radius*rounded_size,PI*0.5, PI *(0.5+ (0.5*ratio)))
- cr:close_path()
- cr:stroke()
- end
- end
- end
- end
- ---Generate a text in front of a centered rectangle with rounded corners (or not) in a cairo context.
- --It returns a table ={ width = the width of the image, height = the height of the image}
- --@param cr a cairo context already initialised with oocairo.context_create( )
- --@param width the width of the widget
- --@param height the height of the widget
- --@param text the text to display
- --@param padding the left/right/top/bottom padding used to center the text in the background rectangle
- --@param background_color a string "#rrggbb" or "#rrggbbaa" for the color of the background rectangle
- --@param text_color a string "#rrggbb" or "#rrggbbaa" for the color of the text
- --@param font_size define the size of the font
- --@param rounded_size a float value from 0 to 1 (0 is no rounded corner)
- --@param border a color as a string "#rrggbb" or "#rrggbbaa"
- function helpers.generate_rounded_rectangle_with_text(cr, width, height, text, padding, background_color, text_color, font_size, rounded_size, border)
- local data={}
- local padding = padding or 2
- --find the height and width of the image:
- cr:set_font_size(font_size)
- local ext = cr:text_extents(text)
- data.height = (font_size + 2* padding) > height and (font_size + 2* padding) or height
- data.width = (ext.width +ext.x_bearing*2 + 2*padding) > width and (ext.width +ext.x_bearing *2 + 2*padding) or width
- --draw the background
- draw_rounded_corners_rectangle(cr,0,0,data.width, data.height, background_color, rounded_size, border)
- --draw the text
- cr:move_to((data.width/2) -((ext.width+ext.x_bearing*2)/2), (data.height)/2 + (font_size/2))
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(text_color)
- cr:set_font_size(font_size)
- cr:set_source_rgba(r,g,b,a)
- cr:show_text(text)
- return data
- end
- ---Draw a rectangular triangle filled with given color
- --@param cr cairo context
- --@param first point coordinates {x= 1.0, y = 2.0}
- --@param second point coordinates {x= 1.0, y = 2.0}
- --@param third point coordinates {x= 1.0, y = 2.0}
- --@param color a color as a string "#rrggbb" or "#rrggbbaa"
- function helpers.draw_triangle(cr, first, second, third, color)
- local r,g,b,a = helpers.hexadecimal_to_rgba_percent(color)
- cr:new_path()
- cr:set_source_rgba(r,g,b,a)
- cr:move_to(first.x, first.y)
- cr:line_to(second.x, second.y)
- cr:line_to(third.x, third.y)
- cr:close_path()
- cr:fill()
- end
- --- Draw a rectangular triangular outline of the given color
- --@param cr cairo context
- --@param first point coordinates {x= 1.0, y = 2.0}
- --@param second point coordinates {x= 1.0, y = 2.0}
- --@param third point coordinates {x= 1.0, y = 2.0}
- --@param color a color as a string "#rrggbb" or "#rrggbbaa"
- function helpers.draw_triangle_outline(cr, first, second, third, color)
- local r,g,b,a = helpers.hexadecimal_to_rgba_percent(color)
- cr:new_path()
- cr:set_source_rgba(r,g,b,a)
- cr:move_to(first.x, first.y)
- cr:line_to(second.x, second.y)
- cr:line_to(third.x, third.y)
- cr:close_path()
- cr:set_antialias("subpixel")
- cr:set_line_width(1)
- cr:stroke()
- end
- --- Compute the width of each bar in a graph
- --It returns the width of the bar and a value
- --that corresponds to the remaing space divided
- --by 2
- --@param nb_bars the number of bars
- --@param width the width of the graph
- --@param sep the size between two bars
- function compute_bar_width(nb_bars, width, sep)
- local bar_width = 0
- local h_rest = 0
- local total_sep = (nb_bars - 1) * sep
- bar_width=math.floor ((width - total_sep) / nb_bars)
- h_rest = width - (total_sep + nb_bars * bar_width)
- --center the graph according to h_rest (2, 3 or 4)
- if h_rest ==2 or h_rest == 3 then
- h_rest = 1
- end
- if h_rest == 4 then
- h_rest = 2
- end
- return bar_width, h_rest
- end
- function helpers.draw_triangle_using_bars(cr, width, height, h_margin, v_margin, color)
- local nb_bars=5
- local bar_separator = 2
- local bar_width, h_rest = compute_bar_width(nb_bars, width - 2*h_margin, bar_separator)
- x=h_margin+h_rest
- y=height - v_margin
- for i=1, nb_bars do
- cr:rectangle(x,y-((0.2*i)*(height - 2*v_margin)),bar_width,((0.2*i)*(height - 2*v_margin)))
- x=x+(bar_width + bar_separator)
- end
- local r,g,b,a=helpers.hexadecimal_to_rgba_percent(color)
- cr:set_source_rgba(r, g, b, a)
- cr:fill()
- end
- --- Display a value using bars or parts of bar in a triangular form
- --@param cr cairo context
- --@param width width of the graph
- --@param height height of the graph
- --@param h_margin horizontal space left at left and right of the graph
- --@param v_margin vertical space left at top and bottom of the graph
- --@param color the color of the graph
- --@param value to represent
- function helpers.draw_triangle_graph_using_bars(cr, width, height, h_margin, v_margin, color, value)
- local nb_bars=5
- local bar_separator = 2
- local bar_width, h_rest = compute_bar_width(nb_bars, width - 2*h_margin, bar_separator)
- if value > 0 then
- local ranges={0,0.2,0.4,0.6,0.8,1,1.2}
- nb_bars=0
- for i, limite in ipairs(ranges) do
- if value < limite then
- nb_bar = i-1
- break
- end
- end
- x=h_margin + h_rest
- y=height - v_margin
- for i=1, nb_bar do
- if i ~= nb_bar then
- cr:rectangle(x,y-((0.2*i)*(height - 2*v_margin)),bar_width,(0.2*i)*(height - 2*v_margin))
- x=x+(bar_width + bar_separator)
- else
- val_to_display =value - ((nb_bar-1) * 0.2)
- cr:rectangle(x,y-((0.2*i)*(height - 2*v_margin)),bar_width * (val_to_display/0.2),(0.2*i)*(height - 2*v_margin))
- end
- end
- r,g,b,a=helpers.hexadecimal_to_rgba_percent(color)
- cr:set_source_rgba(r, g, b, a)
- cr:fill()
- end
- end
- ---Remove an element from a table using key.
- --@param hash the table
- --@param key the key to remove
- function helpers.hash_remove(hash,key)
- local element = hash[key]
- hash[key] = nil
- return element
- end
- ---Functions for date and calendar
- local function is_leap_year(year)
- return year % 4 == 0 and (year % 100 ~= 0 or year % 400 == 0)
- end
- local days_in_m = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
- ---Get the number of days in a given month of a year.
- --iT returns a number
- --@param month the month we focus on ( 1 to 12 )
- --@param year a number YYYY used to check if it's a leap year.
- function helpers.get_days_in_month(month, year)
- if month == 2 and is_leap_year(year) then
- return 29
- else
- return days_in_m[month]
- end
- end
- ---Find the weeks numbers of a given month.
- --Implementation as per the ISO 8601 definition (http://en.wikipedia.org/wiki/ISO_week_date)
- --Fully compatible with original, returns table with 6 week numbers
- --@param month the month
- --@param year the year
- function helpers.get_ISO8601_weeks_number_of_month(month, year)
- local wday = os.date("*t", os.time{year=year,month=month,day=1}).wday-1
- wday = wday == 0 and 7 or wday
- local yday = os.date("*t", os.time{year=year,month=month,day=1}).yday
- local nweeks = is_leap_year(month == 12 and year+1 or year) and 53 or 52 -- Make a correction for leap weeks!
- local week = math.floor((yday-wday+10)/7) -- First week of the month
- if (week < 1) then week = nweeks+week end
- if (week > nweeks) then week = week-nweeks end
- local t = {week}
- for i = 1, 5 do -- Calculate the next 5 weeks, correct where necessary
- t[i+1] = ((week+i) > nweeks and (week+i)-nweeks or week+i)
- end
- return t
- end
- ---Get the number of cpu cores
- --@return a number
- function helpers.get_nb_cores()
- local f=io.open("/proc/stat")
- local nb=0
- for line in f:lines() do
- if string.find(line,"cpu%d+%s") then nb = nb + 1 end
- end
- return nb
- end
- ---Get the cpu name
- --@return a string describing the cpu
- function helpers.get_cpu_name()
- local file = io.open("/proc/cpuinfo")
- for line in file:lines() do
- local cpu = string.match(line,"model%sname%s:%s*(.*)")
- if cpu then return cpu end
- end
- end
- ---Get all the currently mounted devices
- --@return an indexed table from 1 to n, where each element is a table with the "mnt", and "dev" key.
- function helpers.get_mounted_devices()
- local buf = awful.util.pread("mount")
- buf = helpers.split(buf, "\n")
- local devices = {}
- local n = 0 --devices will be an array of table {dev, mnt} (allowing to keep an alphabetical order on /dev/sxxx
- for i=1,#buf do
- local dev, mnt = string.match(buf[i],"(/dev/[^%s]*)%s+on%s+([^%s]+).*")
- if dev and mnt then
- n=n+1
- devices[n]={mnt=mnt, dev=dev}
- end
- end
- table.sort(devices, function(a,b) return a.dev < b.dev end)
- return devices
- end
- ---Get the total amount of RAM in kb
- --@return a number
- function helpers.get_total_mem_in_kb()
- local file = io.open("/proc/meminfo")
- for line in file:lines() do
- local mem = string.match(line,"MemTotal:%s*(%d*)")
- if mem then return mem end
- end
- end
- ---Get the input device names
- --@return an table with "keyboard" and "mouse" keys
- function helpers.get_input_devices()
- local file = io.open("/proc/bus/input/devices")
- local devices={}
- local i= 0
- for line in file:lines() do
- local name, ev, handlers = nil
- if string.match(line,"I:%s") then
- devices[#devices+1]={}
- end
- name=string.match(line,"N:%sName=\"(.*)\"")
- if (name) then
- devices[#devices].name=name
- end
- ev=string.match(line,"B:%sEV=(.*)")
- if (ev) then
- devices[#devices].ev=ev
- end
- handlers=string.match(line,"H:%sHandlers=(.*)")
- if (handlers) then
- devices[#devices].handlers=handlers
- end
- end
- local inputs={}
- for _,device in ipairs(devices) do
- if string.match(device.ev, "120013") then
- inputs.keyboard= device.name
- end
- if device.handlers and string.match(device.handlers, "mouse") then
- inputs.mouse=device.name
- end
- end
- file:close()
- return inputs
- end
- ---Get the current graphic card
- --@return a string
- function helpers.get_graphic_card()
- local buf = awful.util.pread("lspci | grep VGA")
- local graph_card = string.match(buf,"[^%s]*%s+VGA%s+compatible%s+controller:%s+(.*)")
- return graph_card
- end
- --- Get OS related informations from /etc/os-release
- --@return a key/value table
- function helpers.get_os_release_informations()
- local file = io.open("/etc/os-release")
- local infos = {}
- for line in file:lines() do
- local key,value = string.match(line,"([^%s]+)=%s*\"?([^\"]*)\"?")
- if key and value then
- infos[#infos +1]={key=key,value = value}
- end
- end
- return infos
- end
- --- Function used in order to have a tasklist with icons only
- --The classical usage of it is:
- --awful.widget.tasklist(s, awful.widget.tasklist.filter.currenttags, mytasklist.buttons,nil,icons_only_tasklist)
- function helpers.icons_only_tasklist(w, buttons, label, data, objects)
- w:reset()
- local l = wibox.layout.fixed.horizontal()
- for i, o in ipairs(objects) do
- local cache = data[o]
- if cache then
- ib = cache.ib
- else
- local common = require("awful.widget.common")
- ib = wibox.widget.imagebox()
- ib:buttons(common.create_buttons(buttons, o))
- data[o] = {
- ib = ib
- }
- end
- local text, bg, bg_image, icon = label(o)
- ib:set_image(icon)
- l:add(ib)
- end
- w:add(l)
- end
- ---Function used in widgets in order to create a local table of
- --all the widget properties which are a mix between the properties
- --provided by the user trought the widget interface, or the properties
- --defined by superproperties
- --@param properties a table with the names of all the properties
- --@param data the data table of the module that references all the same widgets
- --@param graph the widget itself
- --@param superproperties the table of the superporperties
- function helpers.load_properties( properties, data, graph, superproperties)
- local props = {}
- for _i, prop in ipairs(properties) do
- props[prop] = data[graph][prop] or superproperties[prop]
- if prop == "v_margin" then
- if data[graph].v_margin and data[graph].v_margin <= data[graph].height/4 then
- props.v_margin = data[graph].v_margin
- end
- end
- if prop == "h_margin" then
- if data[graph].h_margin and data[graph].h_margin <= data[graph].height/3 then
- props.h_margin = data[graph].h_margin
- end
- end
- end
- return props
- end
- return helpers
|