triangular_progress_graph.lua 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. -- @author cedlemo
  2. local setmetatable = setmetatable
  3. local ipairs = ipairs
  4. local math = math
  5. --local table = table
  6. local type = type
  7. local string = string
  8. local color = require("gears.color")
  9. local base = require("wibox.widget.base")
  10. local helpers = require("blingbling.helpers")
  11. local superproperties = require('blingbling.superproperties')
  12. ---Triangular progress graph widget.
  13. --@module blingbling.triangular_progress_graph
  14. ---Fill all the widget (width * height) with this color (default is transparent ).
  15. --@usage mypgraph:set_background_color(string) -->"#rrggbbaa"
  16. --@name set_background_color
  17. --@class function
  18. --@param color a string "#rrggbbaa" or "#rrggbb"
  19. ---Define the form of the graph: use five growing bars instead of a triangle.
  20. --@usage mypgraph:set_bar(boolean) --> true or false
  21. --@name set_bar
  22. --@class function
  23. --@param boolean true or false (default is false)
  24. ---Define the top and bottom margin for the graph.
  25. --@usage mypgraph:set_v_margin(integer)
  26. --@name set_v_margin
  27. --@class function
  28. --@param margin an integer for top and bottom margin
  29. ---Define the left and right margin for the graph.
  30. --@usage mypgraph:set_h_margin(integer)
  31. --@name set_h_margin
  32. --@class function
  33. --@param margin an integer for left and right margin
  34. ---Set the color of the graph background.
  35. --@usage mypgraph:set_graph_background_color(string) -->"#rrggbbaa"
  36. --@name set_graph_background_color
  37. --@class function
  38. --@param color a string "#rrggbbaa" or "#rrggbb"
  39. ----Define the graph color.
  40. --@usage mypgraph:set_graph_color(string) -->"#rrggbbaa"
  41. --@name set_graph_color
  42. --@class function
  43. --@param color a string "#rrggbbaa" or "#rrggbb"
  44. ----Define the color of the outline of the graph.
  45. --@usage mypgraph:set_graph_line_color(string) -->"#rrggbbaa"
  46. --@name set_graph_line_color
  47. --@class function
  48. --@param color a string "#rrggbbaa" or "#rrggbb"
  49. ---Display text on the graph or not.
  50. --@usage mypgraph:set_show_text(boolean) --> true or false
  51. --@name set_show_text
  52. --@class function
  53. --@param boolean true or false (default is false)
  54. ---Define displayed text value format string
  55. --@usage mypgraph:set_value_format(string) --> "%2.f"
  56. --@name set_value_format
  57. --@class function
  58. --@param printf format string for display text
  59. ---Define the color of the text.
  60. --@usage mypgraph:set_text_color(string) -->"#rrggbbaa"
  61. --@name set_text_color
  62. --@class function
  63. --@param color a string "#rrggbbaa" or "#rrggbb" defaul is white
  64. ---Define the background color of the text.
  65. --@usage mypgraph:set_text_background_color(string) -->"#rrggbbaa"
  66. --@name set_text_background_color
  67. --@class function
  68. --@param color a string "#rrggbbaa" or "#rrggbb"
  69. ---Define the text font size.
  70. --@usage mypgraph:set_font_size(integer)
  71. --@name set_font_size
  72. --@class function
  73. --@param size the font size
  74. ---Define the text font.
  75. --@usage mypgraph:set_font(string|table)
  76. --The argument can be a string for the font name or a table
  77. --that contains the cairo font informations
  78. --@name set_font
  79. --@class function
  80. --@param the font to use
  81. ---Define the template of the text to display.
  82. --@usage mypgraph:set_label(string)
  83. --By default the text is : (value_send_to_the_widget *100) .. "%"
  84. --static string: example set_label("Volume:") will display "Volume:" on the graph
  85. --dynamic string: use $percent in the string example set_label("Volume $percent %") will display "Volume 10%"
  86. --@name set_label
  87. --@class function
  88. --@param text the text to display
  89. local triangular_progressgraph = { mt = {} }
  90. local data = setmetatable({}, { __mode = "k" })
  91. local properties = {"width", "height", "v_margin", "h_margin",
  92. "background_color", "graph_background_color",
  93. "graph_color","graph_line_color","show_text",
  94. "text_color", "text_background_color",
  95. "label", "font_size","font", "bar", "value_format"
  96. }
  97. function triangular_progressgraph.draw(tp_graph, wibox, cr, width, height)
  98. local props = helpers.load_properties(properties, data, tp_graph, superproperties)
  99. --Generate Background (background color and Tiles)
  100. local r,g,b,a = helpers.hexadecimal_to_rgba_percent(props.background_color)
  101. cr:set_source_rgba(r,g,b,a)
  102. cr:paint()
  103. --Draw the background of the graph:
  104. if props.bar == true then
  105. helpers.draw_triangle_using_bars( cr, width,
  106. height,
  107. props.h_margin,
  108. props.v_margin,
  109. props.graph_background_color)
  110. helpers.draw_triangle_graph_using_bars(cr, width,
  111. height,
  112. props.h_margin,
  113. props.v_margin,
  114. props.graph_color,
  115. data[tp_graph].value
  116. )
  117. else
  118. --Draw graph background
  119. local first = { x = props.h_marging,
  120. y = height - props.v_margin }
  121. local y_range = height - (2 * props.v_margin)
  122. local second = { x = width - props.h_margin,
  123. y = height - (props.v_margin + y_range) }
  124. local third = { x = width - props.h_margin,
  125. y = height - props.v_margin }
  126. helpers.draw_triangle(cr, first, second, third, props.graph_background_color)
  127. if data[tp_graph].value > 0 then
  128. --Draw graph
  129. second = { x = width * data[tp_graph].value - props.h_margin,
  130. y = height -( props.v_margin + (y_range * data[tp_graph].value)) }
  131. third = { x = width * data[tp_graph].value - props.h_margin,
  132. y = height - props.v_margin }
  133. helpers.draw_triangle(cr, first, second, third, props.graph_color)
  134. helpers.draw_triangle_outline(cr, first, second, third, props.graph_line_color)
  135. end
  136. end
  137. --Draw Text and it's background
  138. if props.show_text == true then
  139. local font
  140. if type(props.font) == "string" then
  141. font = props.font .. " " .. props.font_size
  142. elseif type(props.font) == "table" then
  143. font = (props.font.family or "Sans") .. " " .. (props.font.slang or "normal") .. " " .. (props.font.weight or "normal") .. " " .. props.font_size
  144. end
  145. local value = string.format(props.value_format,
  146. data[tp_graph].value * 100)
  147. if props.label then
  148. text = string.gsub(props.label,"$percent", value)
  149. else
  150. text = value .. "%"
  151. end
  152. helpers.draw_layout_and_background(cr,
  153. text,
  154. props.h_margin,
  155. height/2 ,
  156. font,
  157. props.text_background_color,
  158. props.text_color,
  159. "start",
  160. "middle")
  161. end
  162. end
  163. function triangular_progressgraph.fit(tp_graph, width, height)
  164. return data[tp_graph].width, data[tp_graph].height
  165. end
  166. ---Set the tp_graph value.
  167. --@param tp_graph The progress bar.
  168. --@param value The progress bar value between 0 and 1.
  169. local function set_value(tp_graph, value)
  170. local value = value or 0
  171. local max_value = data[tp_graph].max_value
  172. data[tp_graph].value = math.min(max_value, math.max(0, value))
  173. tp_graph:emit_signal("widget::updated")
  174. return tp_graph
  175. end
  176. ---Set the tp_graph height.
  177. -- @param height The height to set.
  178. function triangular_progressgraph:set_height( height)
  179. if height >= 5 then
  180. data[self].height = height
  181. self:emit_signal("widget::updated")
  182. end
  183. return self
  184. end
  185. ---Set the tp_graph width.
  186. --@param width The width to set.
  187. function triangular_progressgraph:set_width( width)
  188. if width >= 5 then
  189. data[self].width = width
  190. self:emit_signal("widget::updated")
  191. end
  192. return self
  193. end
  194. -- Build properties function
  195. for _, prop in ipairs(properties) do
  196. if not triangular_progressgraph["set_" .. prop] then
  197. triangular_progressgraph["set_" .. prop] = function(tp_graph, value)
  198. data[tp_graph][prop] = value
  199. tp_graph:emit_signal("widget::updated")
  200. return tp_graph
  201. end
  202. end
  203. end
  204. --- Create a tp_graph widget.
  205. -- @param args Standard widget() arguments. You should add width and height
  206. -- key to set graph geometry.
  207. -- @return A graph widget.
  208. function triangular_progressgraph.new(args)
  209. local args = args or {}
  210. args.width = args.width or 100
  211. args.height = args.height or 20
  212. if args.width < 5 or args.height < 5 then return end
  213. local tp_graph = base.make_widget()
  214. data[tp_graph] = {}
  215. for _, v in ipairs(properties) do
  216. data[tp_graph][v] = args[v]
  217. end
  218. data[tp_graph].value = 0
  219. data[tp_graph].max_value = 1
  220. -- Set methods
  221. tp_graph.set_value = set_value
  222. tp_graph.add_value = set_value
  223. tp_graph.draw = triangular_progressgraph.draw
  224. tp_graph.fit = triangular_progressgraph.fit
  225. for _, prop in ipairs(properties) do
  226. tp_graph["set_" .. prop] = triangular_progressgraph["set_" .. prop]
  227. end
  228. return tp_graph
  229. end
  230. function triangular_progressgraph.mt:__call(...)
  231. return triangular_progressgraph.new(...)
  232. end
  233. return setmetatable(triangular_progressgraph, triangular_progressgraph.mt)