]> git.madduck.net Git - etc/awesome.git/blob - layout/centerwork.lua

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Merge pull request #430 from trap000d/weather_widget
[etc/awesome.git] / layout / centerwork.lua
1 --[[
2
3      Licensed under GNU General Public License v2
4       * (c) 2018,      Eugene Pakhomov
5       * (c) 2016,      Henrik Antonsson
6       * (c) 2015,      Joerg Jaspert
7       * (c) 2014,      projektile
8       * (c) 2013,      Luca CPZ
9       * (c) 2010-2012, Peter Hofmann
10
11 --]]
12
13 local floor, max, mouse, mousegrabber, screen = math.floor, math.max, mouse, mousegrabber, screen
14
15 local centerwork = {
16     name       = "centerwork",
17     horizontal = { name = "centerworkh" }
18 }
19
20 local function arrange(p, layout)
21     local t   = p.tag or screen[p.screen].selected_tag
22     local wa  = p.workarea
23     local cls = p.clients
24
25     if #cls == 0 then return end
26
27     local c, g = cls[1], {}
28
29     -- Main column, fixed width and height
30     local mwfact          = t.master_width_factor
31     local mainhei         = floor(wa.height * mwfact)
32     local mainwid         = floor(wa.width * mwfact)
33     local slavewid        = wa.width - mainwid
34     local slaveLwid       = floor(slavewid / 2)
35     local slaveRwid       = slavewid - slaveLwid
36     local slavehei        = wa.height - mainhei
37     local slaveThei       = floor(slavehei / 2)
38     local slaveBhei       = slavehei - slaveThei
39     local nbrFirstSlaves  = floor(#cls / 2)
40     local nbrSecondSlaves = floor((#cls - 1) / 2)
41
42     local slaveFirstDim, slaveSecondDim = 0, 0
43
44     if layout.name == "centerwork" then -- vertical
45         if nbrFirstSlaves  > 0 then slaveFirstDim  = floor(wa.height / nbrFirstSlaves) end
46         if nbrSecondSlaves > 0 then slaveSecondDim = floor(wa.height / nbrSecondSlaves) end
47
48         g.height = wa.height
49         g.width  = mainwid
50
51         g.x = wa.x + slaveLwid
52         g.y = wa.y
53     else -- horizontal
54         if nbrFirstSlaves  > 0 then slaveFirstDim  = floor(wa.width / nbrFirstSlaves) end
55         if nbrSecondSlaves > 0 then slaveSecondDim = floor(wa.width / nbrSecondSlaves) end
56
57         g.height  = mainhei
58         g.width = wa.width
59
60         g.x = wa.x
61         g.y = wa.y + slaveThei
62     end
63
64     g.width  = max(g.width, 1)
65     g.height = max(g.height, 1)
66
67     p.geometries[c] = g
68
69     -- Auxiliary clients
70     if #cls <= 1 then return end
71     for i = 2, #cls do
72         local c, g = cls[i], {}
73         local idxChecker, dimToAssign
74
75         local rowIndex = floor(i/2)
76
77         if layout.name == "centerwork" then
78             if i % 2 == 0 then -- left slave
79                 g.x     = wa.x
80                 g.y     = wa.y + (rowIndex - 1) * slaveFirstDim
81                 g.width = slaveLwid
82
83                 idxChecker, dimToAssign = nbrFirstSlaves, slaveFirstDim
84             else -- right slave
85                 g.x     = wa.x + slaveLwid + mainwid
86                 g.y     = wa.y + (rowIndex - 1) * slaveSecondDim
87                 g.width = slaveRwid
88
89                 idxChecker, dimToAssign = nbrSecondSlaves, slaveSecondDim
90             end
91
92             -- if last slave in row, use remaining space for it
93             if rowIndex == idxChecker then
94                 g.height = wa.y + wa.height - g.y
95             else
96                 g.height = dimToAssign
97             end
98         else
99             if i % 2 == 0 then -- top slave
100                 g.x      = wa.x + (rowIndex - 1) * slaveFirstDim
101                 g.y      = wa.y
102                 g.height = slaveThei
103
104                 idxChecker, dimToAssign = nbrFirstSlaves, slaveFirstDim
105             else -- bottom slave
106                 g.x      = wa.x + (rowIndex - 1) * slaveSecondDim
107                 g.y      = wa.y + slaveThei + mainhei
108                 g.height = slaveBhei
109
110                 idxChecker, dimToAssign = nbrSecondSlaves, slaveSecondDim
111             end
112
113             -- if last slave in row, use remaining space for it
114             if rowIndex == idxChecker then
115                 g.width = wa.x + wa.width - g.x
116             else
117                 g.width = dimToAssign
118             end
119         end
120
121         g.width  = max(g.width, 1)
122         g.height = max(g.height, 1)
123
124         p.geometries[c] = g
125     end
126 end
127
128 local function mouse_resize_handler(c, corner, x, y, orientation)
129     local wa     = c.screen.workarea
130     local mwfact = c.screen.selected_tag.master_width_factor
131     local g      = c:geometry()
132     local offset = 0
133     local cursor = "cross"
134
135     local corner_coords
136
137     if orientation == 'vertical' then
138         if g.height + 15 >= wa.height then
139             offset = g.height * .5
140             cursor = "sb_h_double_arrow"
141         elseif not (g.y + g.height + 15 > wa.y + wa.height) then
142             offset = g.height
143         end
144         corner_coords = { x = wa.x + wa.width * (1 - mwfact) / 2, y = g.y + offset }
145     else
146         if g.width + 15 >= wa.width then
147             offset = g.width * .5
148             cursor = "sb_v_double_arrow"
149         elseif not (g.x + g.width + 15 > wa.x + wa.width) then
150             offset = g.width
151         end
152         corner_coords = { y = wa.y + wa.height * (1 - mwfact) / 2, x = g.x + offset }
153     end
154
155     mouse.coords(corner_coords)
156
157     local prev_coords = {}
158
159     mousegrabber.run(function(_mouse)
160         if not c.valid then return false end
161         for _, v in ipairs(_mouse.buttons) do
162             if v then
163                 prev_coords = { x = _mouse.x, y = _mouse.y }
164                 local new_mwfact
165                 if orientation == 'vertical' then
166                     new_mwfact = 1 - (_mouse.x - wa.x) / wa.width * 2
167                 else
168                     new_mwfact = 1 - (_mouse.y - wa.y) / wa.height * 2
169                 end
170                 c.screen.selected_tag.master_width_factor = math.min(math.max(new_mwfact, 0.01), 0.99)
171                 return true
172             end
173         end
174         return prev_coords.x == _mouse.x and prev_coords.y == _mouse.y
175     end, cursor)
176 end
177
178 function centerwork.arrange(p)
179     return arrange(p, centerwork)
180 end
181
182 function centerwork.horizontal.arrange(p)
183     return arrange(p, centerwork.horizontal)
184 end
185
186 function centerwork.mouse_resize_handler(c, corner, x, y)
187     return mouse_resize_handler(c, corner, x, y, 'vertical')
188 end
189
190 function centerwork.horizontal.mouse_resize_handler(c, corner, x, y)
191     return mouse_resize_handler(c, corner, x, y, 'horizontal')
192 end
193
194 return centerwork