1 ---------------------------------------------------------------------------
2 -- @author Julien Danjou <julien@danjou.info>
3 -- @copyright 2009 Julien Danjou
4 -- @release @AWESOME_VERSION@
5 ---------------------------------------------------------------------------
7 local setmetatable
= setmetatable
10 local base
= require("wibox.widget.base")
11 local color
= require("gears.color")
13 --- A progressbar widget.
14 -- awful.widget.progressbar
15 local progressbar
= { mt
= {} }
17 local data
= setmetatable({}, { __mode
= "k" })
19 --- Set the progressbar border color.
20 -- If the value is nil, no border will be drawn.
21 -- @name set_border_color
23 -- @param progressbar The progressbar.
24 -- @param color The border color to set.
26 --- Set the progressbar foreground color.
29 -- @param progressbar The progressbar.
30 -- @param color The progressbar color.
32 --- Set the progressbar background color.
33 -- @name set_background_color
35 -- @param progressbar The progressbar.
36 -- @param color The progressbar background color.
38 --- Set the progressbar to draw vertically. Default is false.
41 -- @param progressbar The progressbar.
42 -- @param vertical A boolean value.
44 --- Set the progressbar to draw ticks. Default is false.
47 -- @param progressbar The progressbar.
48 -- @param ticks A boolean value.
50 --- Set the progressbar ticks gap.
51 -- @name set_ticks_gap
53 -- @param progressbar The progressbar.
54 -- @param value The value.
56 --- Set the progressbar ticks size.
57 -- @name set_ticks_size
59 -- @param progressbar The progressbar.
60 -- @param value The value.
62 --- Set the maximum value the progressbar should handle.
63 -- @name set_max_value
65 -- @param progressbar The progressbar.
66 -- @param value The value.
68 local properties
= { "width", "height", "border_color",
69 "color", "background_color",
70 "vertical", "value", "max_value",
71 "ticks", "ticks_gap", "ticks_size" }
73 function progressbar
.draw(pbar
, wibox
, cr
, width
, height
)
74 local ticks_gap
= data
[pbar
].ticks_gap
or 1
75 local ticks_size
= data
[pbar
].ticks_size
or 4
77 -- We want one pixel wide lines
80 local value
= data
[pbar
].value
81 local max_value
= data
[pbar
].max_value
83 value
= value
/ max_value
86 local over_drawn_width
= width
87 local over_drawn_height
= height
88 local border_width
= 0
89 if data
[pbar
].border_color
then
91 cr
:rectangle(0.5, 0.5, width
- 1, height
- 1)
92 cr
:set_source(color(data
[pbar
].border_color
))
95 over_drawn_width
= width
- 2 -- remove 2 for borders
96 over_drawn_height
= height
- 2 -- remove 2 for borders
100 cr
:rectangle(border_width
, border_width
,
101 over_drawn_width
, over_drawn_height
)
102 cr
:set_source(color(data
[pbar
].color
or "#ff0000"))
105 -- Cover the part that is not set with a rectangle
106 if data
[pbar
].vertical
then
107 local rel_height
= over_drawn_height
* (1 - value
)
108 cr
:rectangle(border_width
,
112 cr
:set_source(color(data
[pbar
].background_color
or "#000000aa"))
115 -- Place smaller pieces over the gradient if ticks are enabled
116 if data
[pbar
].ticks
then
117 for i
=0, height
/ (ticks_size
+ticks_gap
)-border_width
do
118 local rel_offset
= over_drawn_height
/ 1 - (ticks_size
+ticks_gap
) * i
120 if rel_offset
>= rel_height
then
121 cr
:rectangle(border_width
,
127 cr
:set_source(color(data
[pbar
].background_color
or "#000000aa"))
131 local rel_x
= over_drawn_width
* value
132 cr
:rectangle(border_width
+ rel_x
,
134 over_drawn_width
- rel_x
,
136 cr
:set_source(color(data
[pbar
].background_color
or "#000000aa"))
139 if data
[pbar
].ticks
then
140 for i
=0, width
/ (ticks_size
+ticks_gap
)-border_width
do
141 local rel_offset
= over_drawn_width
/ 1 - (ticks_size
+ticks_gap
) * i
143 if rel_offset
<= rel_x
then
144 cr
:rectangle(rel_offset
,
150 cr
:set_source(color(data
[pbar
].background_color
or "#000000aa"))
156 function progressbar
.fit(pbar
, width
, height
)
157 return data
[pbar
].width
, data
[pbar
].height
160 --- Set the progressbar value.
161 -- @param value The progress bar value between 0 and 1.
162 function progressbar
:set_value(value
)
163 local value
= value
or 0
164 local max_value
= data
[self
].max_value
165 data
[self
].value
= math
.min(max_value
, math
.max(0, value
))
166 self
:emit_signal("widget::updated")
170 --- Set the progressbar height.
171 -- @param height The height to set.
172 function progressbar
:set_height(height
)
173 data
[self
].height
= height
174 self
:emit_signal("widget::updated")
178 --- Set the progressbar width.
179 -- @param width The width to set.
180 function progressbar
:set_width(width
)
181 data
[self
].width
= width
182 self
:emit_signal("widget::updated")
186 -- Build properties function
187 for _
, prop
in ipairs(properties
) do
188 if not progressbar
["set_" .. prop
] then
189 progressbar
["set_" .. prop
] = function(pbar
, value
)
190 data
[pbar
][prop
] = value
191 pbar
:emit_signal("widget::updated")
197 --- Create a progressbar widget.
198 -- @param args Standard widget() arguments. You should add width and height
199 -- key to set progressbar geometry.
200 -- @return A progressbar widget.
201 function progressbar
.new(args
)
202 local args
= args
or {}
203 local width
= args
.width
or 100
204 local height
= args
.height
or 20
206 args
.type = "imagebox"
208 local pbar
= base
.make_widget()
210 data
[pbar
] = { width
= width
, height
= height
, value
= 0, max_value
= 1 }
213 for _
, prop
in ipairs(properties
) do
214 pbar
["set_" .. prop
] = progressbar
["set_" .. prop
]
217 pbar
.draw
= progressbar
.draw
218 pbar
.fit
= progressbar
.fit
223 function progressbar
.mt
:__call(...)
224 return progressbar
.new(...)
227 return setmetatable(progressbar
, progressbar
.mt
)
229 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80