awful.widget.layout: add support for margins
[awesome.git] / lib / awful / widget / layout / horizontal.lua.in
blob5f518fd9e7a54b0120f44735afdac2a15d1d5405
1 -------------------------------------------------
2 -- @author Gregor Best <farhaven@googlemail.com>
3 -- @copyright 2009 Gregor Best
4 -- @release @AWESOME_VERSION@
5 -------------------------------------------------
7 -- Grab environment
8 local ipairs = ipairs
9 local type = type
10 local table = table
11 local math = math
12 local util = require("awful.util")
13 local default = require("awful.widget.layout.default")
14 local margins = awful.widget.layout.margins
16 --- Horizontal widget layout
17 module("awful.widget.layout.horizontal")
19 local function horizontal(direction, bounds, widgets, screen)
20 local geometries = { }
21 local x = 0
23 -- we are only interested in tables and widgets
24 local keys = util.table.keys_filter(widgets, "table", "widget")
26 for _, k in ipairs(keys) do
27 local v = widgets[k]
28 if type(v) == "table" then
29 local layout = v.layout or default
30 if margins[v] then
31 bounds.width = bounds.width - (margins[v].left or 0) - (margins[v].right or 0)
32 bounds.height = bounds.height - (margins[v].top or 0) - (margins[v].bottom or 0)
33 end
34 local g = layout(bounds, v, screen)
35 if margins[v] then
36 x = x + (margins[v].left or 0)
37 end
38 for _, v in ipairs(g) do
39 v.x = v.x + x
40 table.insert(geometries, v)
41 end
42 bounds = g.free
43 if margins[v] then
44 x = x + g.free.x + (margins[v].right or 0)
45 y = y + (margins[v].top or 0)
46 bounds.width = bounds.width - (margins[v].right or 0) - (margins[v].left or 0)
47 else
48 x = x + g.free.x
49 end
50 elseif type(v) == "widget" then
51 local g
52 if v.visible then
53 g = v:extents(screen)
54 if margins[v] then
55 g.width = g.width + (margins[v].left or 0) + (margins[v].right or 0)
56 g.height = g.height + (margins[v].top or 0) + (margins[v].bottom or 0)
57 end
58 else
59 g = {
60 width = 0,
61 height = 0,
63 end
64 g.ratio = 1
65 if g.height > 0 then
66 g.ratio = g.width / g.height
67 end
68 if g.width > bounds.width then
69 g.width = bounds.width
70 end
71 g.height = bounds.height
73 if margins[v] then
74 g.y = (margins[v].top or 0)
75 else
76 g.y = 0
77 end
79 if v.resize and g.width > 0 then
80 g.width = math.floor(g.height * g.ratio)
81 end
83 if direction == "leftright" then
84 if margins[v] then
85 g.x = x + (margins[v].left or 0)
86 else
87 g.x = x
88 end
89 x = x + g.width
90 else
91 if margins[v] then
92 g.x = x + bounds.width - g.width + (margins[v].left or 0)
93 else
94 g.x = x + bounds.width - g.width
95 end
96 end
97 bounds.width = bounds.width - g.width
99 table.insert(geometries, g)
103 geometries.free = util.table.clone(bounds)
104 geometries.free.x = x
105 geometries.free.y = 0
107 return geometries
110 function flex(bounds, widgets, screen)
111 local geometries = {
112 free = util.table.clone(bounds)
114 -- the flex layout always uses the complete available place, thus we return
115 -- no usable free area
116 geometries.free.width = 0
118 -- we are only interested in tables and widgets
119 local keys = util.table.keys_filter(widgets, "table", "widget")
120 local nelements = 0
122 for _, k in ipairs(keys) do
123 local v = widgets[k]
124 if type(v) == "table" then
125 nelements = nelements + 1
126 elseif type(v) == "widget" then
127 local g = v:extents()
128 if v.resize and g.width > 0 and g.height > 0 then
129 bounds.width = bounds.width - bounds.height
130 elseif g.width > 0 and g.height > 0 then
131 nelements = nelements + 1
136 nelements = (nelements == 0) and 1 or nelements
138 local x = 0
139 local width = bounds.width / nelements
141 for _, k in ipairs(util.table.keys(widgets)) do
142 local v = widgets[k]
143 if type(v) == "table" then
144 local layout = v.layout or default
145 local g = layout(bounds, v, screen)
146 for _, v in ipairs(g) do
147 v.x = v.x + x
148 table.insert(geometries, v)
150 bounds = g.free
151 elseif type(v) == "widget" then
152 local g = v:extents(screen)
153 g.resize = v.resize
155 if v.resize and g.width > 0 and g.height > 0 then
156 g.width = bounds.height
157 g.height = bounds.height
158 g.x = x
159 g.y = bounds.y
160 x = x + g.width
161 elseif g.width > 0 and g.height > 0 then
162 g.x = x
163 g.y = bounds.y
164 g.width = math.floor(width + 0.5)
165 g.height = bounds.height
166 x = x + width
167 else
168 g.x = 0
169 g.y = 0
170 g.width = 0
171 g.height = 0
174 table.insert(geometries, g)
178 return geometries
181 function leftright(...)
182 return horizontal("leftright", ...)
185 function rightleft(...)
186 return horizontal("rightleft", ...)
189 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80