Added Expand Modes
Added set_expand function with options of "none" "outside" or "inside" modes. The "inside" mode is the default and will result in the original behavior. The main benefit is being able to actually center a widget in the available space with options of how to draw the outside widgets (expand to take the space, or not.) Further functionality can be had by ommiting one of the outside widgets. Set default layout mode in the constructor. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
601dc232db
commit
fbba41ddaa
|
@ -8,6 +8,7 @@ local setmetatable = setmetatable
|
||||||
local table = table
|
local table = table
|
||||||
local pairs = pairs
|
local pairs = pairs
|
||||||
local type = type
|
local type = type
|
||||||
|
local floor = math.floor
|
||||||
local base = require("wibox.layout.base")
|
local base = require("wibox.layout.base")
|
||||||
local widget_base = require("wibox.widget.base")
|
local widget_base = require("wibox.widget.base")
|
||||||
|
|
||||||
|
@ -19,49 +20,90 @@ local align = {}
|
||||||
-- @param cr The cairo context to use.
|
-- @param cr The cairo context to use.
|
||||||
-- @param width The available width.
|
-- @param width The available width.
|
||||||
-- @param height The available height.
|
-- @param height The available height.
|
||||||
-- @return The total space needed by the layout.
|
|
||||||
function align:draw(wibox, cr, width, height)
|
function align:draw(wibox, cr, width, height)
|
||||||
local size_first = 0
|
local size_first = 0
|
||||||
local size_third = 0
|
local size_remains = self.dir == "y" and height or width
|
||||||
local size_limit = self.dir == "y" and height or width
|
|
||||||
|
|
||||||
|
if self._expand ~= "inside" and self.second then
|
||||||
|
local w, h = base.fit_widget(self.second, width, height)
|
||||||
|
local size_second = self.dir == "y" and h or w
|
||||||
|
if size_second >= size_remains then
|
||||||
|
base.draw_widget(wibox, cr, self.second, 0, 0, width, height)
|
||||||
|
return
|
||||||
|
else
|
||||||
|
size_remains = floor((size_remains - size_second) / 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
if self.first then
|
if self.first then
|
||||||
local w, h, _ = width, height, nil
|
local w, h, _ = width, height, nil
|
||||||
|
if self._expand ~= "outside" or not self.second then
|
||||||
if self.dir == "y" then
|
if self.dir == "y" then
|
||||||
_, h = base.fit_widget(self.first, w, h)
|
_, h = base.fit_widget(self.first, width, size_remains)
|
||||||
size_first = h
|
size_first = h
|
||||||
|
if self._expand == "inside" or not self.second then
|
||||||
|
size_remains = size_remains - h
|
||||||
|
end
|
||||||
else
|
else
|
||||||
w, _ = base.fit_widget(self.first, w, h)
|
w, _ = base.fit_widget(self.first, size_remains, height)
|
||||||
size_first = w
|
size_first = w
|
||||||
|
if self._expand == "inside" or not self.second then
|
||||||
|
size_remains = size_remains - w
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if self.dir == "y" then
|
||||||
|
h = size_remains
|
||||||
|
else
|
||||||
|
w = size_remains
|
||||||
|
end
|
||||||
end
|
end
|
||||||
base.draw_widget(wibox, cr, self.first, 0, 0, w, h)
|
base.draw_widget(wibox, cr, self.first, 0, 0, w, h)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.third and size_first < size_limit then
|
if self.third and size_remains > 0 then
|
||||||
local w, h, x, y, _
|
local w, h, _ = width, height, nil
|
||||||
|
if self._expand ~= "outside" then
|
||||||
if self.dir == "y" then
|
if self.dir == "y" then
|
||||||
w, h = width, height - size_first
|
_, h = base.fit_widget(self.third, width, size_remains)
|
||||||
_, h = base.fit_widget(self.third, w, h)
|
if self._expand == "inside" then
|
||||||
x, y = 0, height - h
|
size_remains = size_remains - h
|
||||||
size_third = h
|
|
||||||
else
|
|
||||||
w, h = width - size_first, height
|
|
||||||
w, _ = base.fit_widget(self.third, w, h)
|
|
||||||
x, y = width - w, 0
|
|
||||||
size_third = w
|
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
w, _ = base.fit_widget(self.third, size_remains, height)
|
||||||
|
if self._expand == "inside" then
|
||||||
|
size_remains = size_remains - w
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if self.dir == "y" then
|
||||||
|
h = size_remains
|
||||||
|
else
|
||||||
|
w = size_remains
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local x, y = width - w, height - h
|
||||||
base.draw_widget(wibox, cr, self.third, x, y, w, h)
|
base.draw_widget(wibox, cr, self.third, x, y, w, h)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.second and size_first + size_third < size_limit then
|
if self.second and size_remains > 0 then
|
||||||
local x, y, w, h
|
local x, y, w, h = 0, 0, width, height
|
||||||
|
if self._expand == "inside" then
|
||||||
if self.dir == "y" then
|
if self.dir == "y" then
|
||||||
w, h = width, size_limit - size_first - size_third
|
h = size_remains
|
||||||
x, y = 0, size_first
|
x, y = 0, size_first
|
||||||
else
|
else
|
||||||
w, h = size_limit - size_first - size_third, height
|
w = size_remains
|
||||||
x, y = size_first, 0
|
x, y = size_first, 0
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
if self.dir == "y" then
|
||||||
|
_, h = base.fit_widget(self.second, width, size_remains)
|
||||||
|
y = floor( (height - h)/2 )
|
||||||
|
else
|
||||||
|
w, _ = base.fit_widget(self.second, width, size_remains)
|
||||||
|
x = floor( (width -w)/2 )
|
||||||
|
end
|
||||||
|
end
|
||||||
base.draw_widget(wibox, cr, self.second, x, y, w, h)
|
base.draw_widget(wibox, cr, self.second, x, y, w, h)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -120,6 +162,26 @@ function align:fit(orig_width, orig_height)
|
||||||
end
|
end
|
||||||
return used_in_dir, used_in_other
|
return used_in_dir, used_in_other
|
||||||
end
|
end
|
||||||
|
--- Set the expand mode which determines how sub widgets expand to take up
|
||||||
|
-- unused space. Options are:
|
||||||
|
-- "inside" - Default option. Size of outside widgets is determined using their
|
||||||
|
-- fit function. Second, middle, or center widget expands to fill
|
||||||
|
-- remaining space.
|
||||||
|
-- "outside" - Center widget is sized using its fit function and placed in the
|
||||||
|
-- center of the allowed space. Outside widgets expand (or contract)
|
||||||
|
-- to fill remaining space on their side.
|
||||||
|
-- "none" - All widgets are sized using their fit function, drawn to only the
|
||||||
|
-- returned space, or remaining space, whichever is smaller. Center
|
||||||
|
-- widget gets priority.
|
||||||
|
-- @param mode How to use unused space. "inside" (default) "outside" or "none"
|
||||||
|
function align:set_expand(mode)
|
||||||
|
if mode == "none" or mode == "outside" then
|
||||||
|
self._expand = mode
|
||||||
|
else
|
||||||
|
self._expand = "inside"
|
||||||
|
end
|
||||||
|
self:emit_signal("widget::updated")
|
||||||
|
end
|
||||||
|
|
||||||
function align:reset()
|
function align:reset()
|
||||||
for k, v in pairs({ "first", "second", "third" }) do
|
for k, v in pairs({ "first", "second", "third" }) do
|
||||||
|
@ -141,6 +203,8 @@ local function get_layout(dir)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ret:set_expand("inside")
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue