1 ---------------------------------------------------------------------------
2 -- @author Uli Schlachter
3 -- @copyright 2010 Uli Schlachter
4 -- @release @AWESOME_VERSION@
5 ---------------------------------------------------------------------------
7 local setmetatable
= setmetatable
11 local base
= require("wibox.layout.base")
12 local widget_base
= require("wibox.widget.base")
17 --- Draw an align layout.
18 -- @param wibox The wibox that this widget is drawn to.
19 -- @param cr The cairo context to use.
20 -- @param width The available width.
21 -- @param height The available height.
22 -- @return The total space needed by the layout.
23 function align
:draw(wibox
, cr
, width
, height
)
26 local size_limit
= self
.dir
== "y" and height
or width
29 local w
, h
, _
= width
, height
, nil
30 if self
.dir
== "y" then
31 _
, h
= self
.first
:fit(w
, h
)
34 w
, _
= self
.first
:fit(w
, h
)
37 base
.draw_widget(wibox
, cr
, self
.first
, 0, 0, w
, h
)
40 if self
.third
and size_first
< size_limit
then
42 if self
.dir
== "y" then
43 w
, h
= width
, height
- size_first
44 _
, h
= self
.third
:fit(w
, h
)
48 w
, h
= width
- size_first
, height
49 w
, _
= self
.third
:fit(w
, h
)
53 base
.draw_widget(wibox
, cr
, self
.third
, x
, y
, w
, h
)
56 if self
.second
and size_first
+ size_third
< size_limit
then
58 if self
.dir
== "y" then
59 w
, h
= width
, size_limit
- size_first
- size_third
60 local real_w
, real_h
= self
.second
:fit(w
, h
)
61 x
, y
= 0, size_first
+ h
/ 2 - real_h
/ 2
64 w
, h
= size_limit
- size_first
- size_third
, height
65 local real_w
, real_h
= self
.second
:fit(w
, h
)
66 x
, y
= size_first
+ w
/ 2 - real_w
/ 2, 0
69 base
.draw_widget(wibox
, cr
, self
.second
, x
, y
, w
, h
)
73 local function widget_changed(layout
, old_w
, new_w
)
75 old_w
:disconnect_signal("widget::updated", layout
._emit_updated
)
78 widget_base
.check_widget(new_w
)
79 new_w
:connect_signal("widget::updated", layout
._emit_updated
)
81 layout
._emit_updated()
84 --- Set the layout's first widget. This is the widget that is at the left/top
85 function align
:set_first(widget
)
86 widget_changed(self
, self
.first
, widget
)
90 --- Set the layout's second widget. This is the centered one.
91 function align
:set_second(widget
)
92 widget_changed(self
, self
.second
, widget
)
96 --- Set the layout's third widget. This is the widget that is at the right/bottom
97 function align
:set_third(widget
)
98 widget_changed(self
, self
.third
, widget
)
102 --- Fit the align layout into the given space. The align layout will
103 -- take all available space in its direction and the maximum size of
104 -- it's all three inner widgets in the other axis.
105 -- @param orig_width The available width.
106 -- @param orig_height The available height.
107 function align
:fit(orig_width
, orig_height
)
110 for k
, v
in pairs
{self
.first
, self
.second
, self
.third
} do
111 local w
, h
= v
:fit(orig_width
, orig_height
)
113 local max = self
.dir
== "y" and w
or h
115 if max > used_max
then
120 if self
.dir
== "y" then
121 return used_max
, orig_height
123 return orig_width
, used_max
126 function align
:reset()
127 for k
, v
in pairs({ "first", "second", "third" }) do
130 self
:emit_signal("widget::updated")
133 local function get_layout(dir
)
134 local ret
= widget_base
.make_widget()
136 ret
._emit_updated
= function()
137 ret
:emit_signal("widget::updated")
140 for k
, v
in pairs(align
) do
141 if type(v
) == "function" then
149 --- Returns a new horizontal align layout. An align layout can display up to
150 -- three widgets. The widget set via :set_left() is left-aligned. :set_right()
151 -- sets a widget which will be right-aligned. The remaining space between those
152 -- two will be given to the widget set via :set_middle().
153 function align
.horizontal()
154 local ret
= get_layout("x")
156 ret
.set_left
= ret
.set_first
157 ret
.set_middle
= ret
.set_second
158 ret
.set_right
= ret
.set_third
163 --- Returns a new vertical align layout. An align layout can display up to
164 -- three widgets. The widget set via :set_top() is top-aligned. :set_bottom()
165 -- sets a widget which will be bottom-aligned. The remaining space between those
166 -- two will be given to the widget set via :set_middle().
167 function align
.vertical()
168 local ret
= get_layout("y")
170 ret
.set_top
= ret
.set_first
171 ret
.set_middle
= ret
.set_second
172 ret
.set_bottom
= ret
.set_third
179 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80