big refactoring; advanced grid mode; readme
This commit is contained in:
parent
820dcc98f6
commit
c8d2b5fd45
127
README.md
127
README.md
|
@ -23,7 +23,7 @@ Please let me know if it does not work in other versions.
|
||||||
|
|
||||||
Suppose this git is checked out at `~/.config/awesome/layout-machi`
|
Suppose this git is checked out at `~/.config/awesome/layout-machi`
|
||||||
|
|
||||||
`machi = require("layout-machi")`
|
Use `local machi = require("layout-machi")` to load the module.
|
||||||
|
|
||||||
The package provide a default layout `machi.default_layout` and editor `machi.default_editor`, which can be added into the layout list.
|
The package provide a default layout `machi.default_layout` and editor `machi.default_editor`, which can be added into the layout list.
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ The package comes with the icon for `layoutbox`, which can be set with the follo
|
||||||
|
|
||||||
## Use the layout
|
## Use the layout
|
||||||
|
|
||||||
Use `layout = machi.layout.create(name, editor)` to instantiate the layout with an editor object.
|
Use `local layout = machi.layout.create(name, editor)` to instantiate the layout with an editor object.
|
||||||
|
|
||||||
`name` can be a string or a function returning a string (see `init.lua` and "Advanced" below).
|
`name` can be a string or a function returning a string (see `init.lua` and "Advanced" below).
|
||||||
This is used for having different actual layout dependent on tags.
|
This is used for having different actual layout dependent on tags.
|
||||||
|
@ -42,25 +42,46 @@ This is used for having different actual layout dependent on tags.
|
||||||
`machi.default_editor` can be used, or see below on creating editors.
|
`machi.default_editor` can be used, or see below on creating editors.
|
||||||
You can create multiple layouts with different names and share the same editor.
|
You can create multiple layouts with different names and share the same editor.
|
||||||
|
|
||||||
## Editor
|
## The layout editor and commands
|
||||||
|
|
||||||
Call `editor = machi.editor.create()` to create an editor.
|
### Starting editor in lua
|
||||||
|
|
||||||
|
Call `local editor = machi.editor.create()` to create an editor.
|
||||||
To edit the layout `l` on screen `s`, call `editor.start_interactive(s = awful.screen.focused(), l = awful.layout.get(s))`.
|
To edit the layout `l` on screen `s`, call `editor.start_interactive(s = awful.screen.focused(), l = awful.layout.get(s))`.
|
||||||
|
|
||||||
### The layout editing command
|
### Basic usage
|
||||||
|
|
||||||
The editing starts with the open area of the entire workarea, takes commands to split the current area into multiple sub-areas, then recursively edits each of them.
|
The editing command starts with the open region of the entire workarea, perform "operations" to split the current region into multiple sub-regions, then recursively edits each of them.
|
||||||
The editor is keyboard driven, each command is a key with optional digits (namely `D`) before it as parameter (or multiple parameters depending on the command).
|
The layout is defined by a sequence of operations as a layout command.
|
||||||
|
The layout editor allows users to interactively input their commands and shows the resulting layouts on screen, with the following auxiliary functions:
|
||||||
|
|
||||||
1. `Up`/`Down`: restore to the history command sequence
|
1. `Up`/`Down`: restore to the history command
|
||||||
2. `h`/`v`: split the current region horizontally/vertically into `#D` regions. The split will respect the ratio of digits in `D`.
|
2. `Backspace`: undo the last command.
|
||||||
3. `w`: Take the last two digits from `D` as `D = ...AB` (1 if `D` is shorter than 2 digits), and split the current region equally into A rows and B columns. If no digits are provided at all, behave the same as `Space`.
|
3. `Escape`: exit the editor without saving the layout.
|
||||||
4. `d`: Take the argument in the format of `A0B`, where `A` and `B` do not contain any `0`, apply `h` with argument `A` unless `A` is shorter than 2 digits. On each splitted region, apply `v` with argument `B` unless `B` is shorter than 2 digit. Does nothing if the argument is ill-formed.
|
4. `Enter`: when all regions are defined, hit enter will save the layout.
|
||||||
5. `s`: shift the current editing region with other open regions. If digits are provided, shift for that many times.
|
|
||||||
6. `Space` or `-`: Without parameters, close the current region and move to the next open region. With digits, set the maximum depth of splitting (the default depth is 2).
|
### Layout command
|
||||||
7. `Enter`/`.`: close all open regions. When all regions are closed, press `Enter` will save the layout and exit the editor.
|
|
||||||
8. `Backspace`: undo the last command.
|
As aforementioned, command a sequence of operations.
|
||||||
9. `Escape`: exit the editor without saving the layout.
|
There are three kinds of operations:
|
||||||
|
|
||||||
|
1. Operations taking argument string and parsed as multiple numbers.
|
||||||
|
|
||||||
|
`h` (horizontally split), `v` (vertically split), `w` (grid split), `d` (draft split)
|
||||||
|
|
||||||
|
2. Operations taking argument string as a single number.
|
||||||
|
|
||||||
|
`s` (shifting active region)
|
||||||
|
|
||||||
|
3. Operation not taking argument.
|
||||||
|
|
||||||
|
`.` (Finish all regions), `-` (Finish the current region), `;` (No-op)
|
||||||
|
|
||||||
|
Argument string are composed of numbers and `,`. If the string contains `,`, it will be used to split argument into multiple numbers.
|
||||||
|
Otherwise, each digit in the string will be treated as a separated number in type 1 ops.
|
||||||
|
|
||||||
|
Each operation may take argument string either from before (such as `22w`) or after (such as `w22`).
|
||||||
|
When any ambiguity arises, operation before always take the argument after. So `h11v` is interpreted as `h11` and `v`.
|
||||||
|
|
||||||
For examples:
|
For examples:
|
||||||
|
|
||||||
|
@ -125,6 +146,76 @@ Tada!
|
||||||
99 AAAA BBBB CC
|
99 AAAA BBBB CC
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Advanced grid layout
|
||||||
|
|
||||||
|
__More document coming soon. For now there is only a running example.__
|
||||||
|
|
||||||
|
Simple grid, `w44`:
|
||||||
|
```
|
||||||
|
0 1 2 3
|
||||||
|
|
||||||
|
4 5 6 7
|
||||||
|
|
||||||
|
8 9 A B
|
||||||
|
|
||||||
|
C D E F
|
||||||
|
```
|
||||||
|
|
||||||
|
Merge grid from the top-left corner, size 3x1, `w4431`:
|
||||||
|
```
|
||||||
|
0-0-0 1
|
||||||
|
|
||||||
|
2 3 4 5
|
||||||
|
|
||||||
|
6 7 8 9
|
||||||
|
|
||||||
|
A B C D
|
||||||
|
```
|
||||||
|
|
||||||
|
Another merge, size 1x3, `w443113`:
|
||||||
|
```
|
||||||
|
0-0-0 1
|
||||||
|
|
|
||||||
|
2 3 4 1
|
||||||
|
|
|
||||||
|
5 6 7 1
|
||||||
|
|
||||||
|
8 9 A B
|
||||||
|
```
|
||||||
|
|
||||||
|
Another merge, size 1x3, `w44311313`:
|
||||||
|
```
|
||||||
|
0-0-0 1
|
||||||
|
|
|
||||||
|
2 3 4 1
|
||||||
|
| |
|
||||||
|
2 5 6 1
|
||||||
|
|
|
||||||
|
2 7 8 9
|
||||||
|
```
|
||||||
|
|
||||||
|
Another merge, size 2x2, `w4431131322`:
|
||||||
|
```
|
||||||
|
0-0-0 1
|
||||||
|
|
|
||||||
|
2 3-3 1
|
||||||
|
| | | |
|
||||||
|
2 3-3 1
|
||||||
|
|
|
||||||
|
2 4 5 6
|
||||||
|
```
|
||||||
|
|
||||||
|
Final merge, size 3x1, `w443113132231`:
|
||||||
|
```
|
||||||
|
0-0-0 1
|
||||||
|
|
|
||||||
|
2 3-3 1
|
||||||
|
| | | |
|
||||||
|
2 3-3 1
|
||||||
|
|
|
||||||
|
2 4-4-4
|
||||||
|
```
|
||||||
|
|
||||||
### Draft mode
|
### Draft mode
|
||||||
|
|
||||||
__This mode is experimental. Its usage may change fast.__
|
__This mode is experimental. Its usage may change fast.__
|
||||||
|
@ -133,8 +224,8 @@ Unlike the original machi layout, where a window fits in a single region, draft
|
||||||
Each tiled window is associated with a upper-left region (ULR) and a bottom-right region (BRR).
|
Each tiled window is associated with a upper-left region (ULR) and a bottom-right region (BRR).
|
||||||
The geometry of the window is from the upper-left corner of the ULR to the bottom-right corner of the BRR.
|
The geometry of the window is from the upper-left corner of the ULR to the bottom-right corner of the BRR.
|
||||||
|
|
||||||
This is suppose to work with regions produced with `d` command.
|
This is suppose to work with regions produced with `d` or `w` operation.
|
||||||
To enable draft mode in a layout, configure the layout with a command with a leading `d`, for example, `d12210121d`.
|
To enable draft mode in a layout, configure the layout with a command with a leading `d`, for example, `d12210121`, or `dw66`.
|
||||||
|
|
||||||
### Persistent history
|
### Persistent history
|
||||||
|
|
||||||
|
|
313
editor.lua
313
editor.lua
|
@ -201,20 +201,23 @@ local function create(data)
|
||||||
max_depth = init_max_depth
|
max_depth = init_max_depth
|
||||||
current_info = ""
|
current_info = ""
|
||||||
current_cmd = ""
|
current_cmd = ""
|
||||||
|
pending_op = nil
|
||||||
to_exit = false
|
to_exit = false
|
||||||
to_apply = false
|
to_apply = false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function push_history()
|
local function push_history()
|
||||||
history[#history + 1] = {#closed_areas, #open_areas, {}, current_info, current_cmd, max_depth, arg_str}
|
if history == nil then return end
|
||||||
|
history[#history + 1] = {#closed_areas, #open_areas, {}, current_info, current_cmd, pending_op, max_depth, arg_str}
|
||||||
end
|
end
|
||||||
|
|
||||||
local function discard_history()
|
local function discard_history()
|
||||||
|
if history == nil then return end
|
||||||
table.remove(history, #history)
|
table.remove(history, #history)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function pop_history()
|
local function pop_history()
|
||||||
if #history == 0 then return end
|
if history == nil or #history == 0 then return end
|
||||||
for i = history[#history][1] + 1, #closed_areas do
|
for i = history[#history][1] + 1, #closed_areas do
|
||||||
table.remove(closed_areas, #closed_areas)
|
table.remove(closed_areas, #closed_areas)
|
||||||
end
|
end
|
||||||
|
@ -229,8 +232,9 @@ local function create(data)
|
||||||
|
|
||||||
current_info = history[#history][4]
|
current_info = history[#history][4]
|
||||||
current_cmd = history[#history][5]
|
current_cmd = history[#history][5]
|
||||||
max_depth = history[#history][6]
|
pending_op = history[#history][6]
|
||||||
arg_str = history[#history][7]
|
max_depth = history[#history][7]
|
||||||
|
arg_str = history[#history][8]
|
||||||
|
|
||||||
table.remove(history, #history)
|
table.remove(history, #history)
|
||||||
end
|
end
|
||||||
|
@ -238,6 +242,8 @@ local function create(data)
|
||||||
local function pop_open_area()
|
local function pop_open_area()
|
||||||
local a = open_areas[#open_areas]
|
local a = open_areas[#open_areas]
|
||||||
table.remove(open_areas, #open_areas)
|
table.remove(open_areas, #open_areas)
|
||||||
|
if history == nil or #history == 0 then return a end
|
||||||
|
|
||||||
local idx = history[#history][2] - #open_areas
|
local idx = history[#history][2] - #open_areas
|
||||||
-- only save when the position has been firstly poped
|
-- only save when the position has been firstly poped
|
||||||
if idx > #history[#history][3] then
|
if idx > #history[#history][3] then
|
||||||
|
@ -246,17 +252,38 @@ local function create(data)
|
||||||
return a
|
return a
|
||||||
end
|
end
|
||||||
|
|
||||||
local split_count = 0
|
local function push_area()
|
||||||
|
closed_areas[#closed_areas + 1] = pop_open_area()
|
||||||
|
end
|
||||||
|
|
||||||
local function handle_split(method, alt)
|
local function push_children(c)
|
||||||
split_count = split_count + 1
|
for i = #c, 1, -1 do
|
||||||
|
if c[i] ~= false then
|
||||||
|
if c[i].x ~= math.floor(c[i].x)
|
||||||
|
or c[i].y ~= math.floor(c[i].y)
|
||||||
|
or c[i].width ~= math.floor(c[i].width)
|
||||||
|
or c[i].height ~= math.floor(c[i].height)
|
||||||
|
then
|
||||||
|
print("warning, splitting yields floating area " .. _area_tostring(c[i]))
|
||||||
|
end
|
||||||
|
open_areas[#open_areas + 1] = c[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local a = pop_open_area()
|
local op_count = 0
|
||||||
|
|
||||||
print("split " .. method .. " " .. tostring(alt) .. " " .. arg_str .. " " .. _area_tostring(a))
|
local function handle_op(method)
|
||||||
|
op_count = op_count + 1
|
||||||
|
|
||||||
|
local l = method:lower()
|
||||||
|
local alt = method ~= l
|
||||||
|
method = l
|
||||||
|
|
||||||
|
print("op " .. method .. " " .. tostring(alt) .. " " .. arg_str)
|
||||||
if method == "h" or method == "v" then
|
if method == "h" or method == "v" then
|
||||||
|
|
||||||
|
local a = pop_open_area()
|
||||||
local args = parse_arg_string(arg_str, 0)
|
local args = parse_arg_string(arg_str, 0)
|
||||||
if #args == 0 then
|
if #args == 0 then
|
||||||
args = {1, 1}
|
args = {1, 1}
|
||||||
|
@ -288,7 +315,7 @@ local function create(data)
|
||||||
width = shares[i],
|
width = shares[i],
|
||||||
height = a.height,
|
height = a.height,
|
||||||
depth = a.depth + 1,
|
depth = a.depth + 1,
|
||||||
group_id = split_count,
|
group_id = op_count,
|
||||||
bl = i == 1 and a.bl or false,
|
bl = i == 1 and a.bl or false,
|
||||||
br = i == #shares and a.br or false,
|
br = i == #shares and a.br or false,
|
||||||
bu = a.bu,
|
bu = a.bu,
|
||||||
|
@ -305,7 +332,7 @@ local function create(data)
|
||||||
width = a.width,
|
width = a.width,
|
||||||
height = shares[i],
|
height = shares[i],
|
||||||
depth = a.depth + 1,
|
depth = a.depth + 1,
|
||||||
group_id = split_count,
|
group_id = op_count,
|
||||||
bl = a.bl,
|
bl = a.bl,
|
||||||
br = a.br,
|
br = a.br,
|
||||||
bu = i == 1 and a.bu or false,
|
bu = i == 1 and a.bu or false,
|
||||||
|
@ -315,19 +342,11 @@ local function create(data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for i = #children, 1, -1 do
|
push_children(children)
|
||||||
if children[i].x ~= math.floor(children[i].x)
|
|
||||||
or children[i].y ~= math.floor(children[i].y)
|
|
||||||
or children[i].width ~= math.floor(children[i].width)
|
|
||||||
or children[i].height ~= math.floor(children[i].height)
|
|
||||||
then
|
|
||||||
print("warning, splitting yields floating area " .. _area_tostring(children[i]))
|
|
||||||
end
|
|
||||||
open_areas[#open_areas + 1] = children[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif method == "w" then
|
elseif method == "w" then
|
||||||
|
|
||||||
|
local a = pop_open_area()
|
||||||
local args = parse_arg_string(arg_str, 0)
|
local args = parse_arg_string(arg_str, 0)
|
||||||
if #args == 0 then
|
if #args == 0 then
|
||||||
args = {1, 1}
|
args = {1, 1}
|
||||||
|
@ -335,15 +354,13 @@ local function create(data)
|
||||||
args[2] = 1
|
args[2] = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if alt then arg_str = table.reverse(arg_str) end
|
|
||||||
|
|
||||||
local h_split, v_split
|
local h_split, v_split
|
||||||
if alt then
|
if alt then
|
||||||
h_split = args[#args]
|
h_split = args[2]
|
||||||
v_split = args[#args - 1]
|
v_split = args[1]
|
||||||
else
|
else
|
||||||
h_split = args[#args - 1]
|
h_split = args[1]
|
||||||
v_split = args[#args]
|
v_split = args[2]
|
||||||
end
|
end
|
||||||
if h_split < 1 then h_split = 1 end
|
if h_split < 1 then h_split = 1 end
|
||||||
if v_split < 1 then v_split = 1 end
|
if v_split < 1 then v_split = 1 end
|
||||||
|
@ -365,7 +382,7 @@ local function create(data)
|
||||||
width = x_shares[x_index],
|
width = x_shares[x_index],
|
||||||
height = y_shares[y_index],
|
height = y_shares[y_index],
|
||||||
depth = a.depth + 1,
|
depth = a.depth + 1,
|
||||||
group_id = split_count,
|
group_id = op_count,
|
||||||
}
|
}
|
||||||
if x_index == 1 then r.bl = a.bl else r.bl = false end
|
if x_index == 1 then r.bl = a.bl else r.bl = false end
|
||||||
if x_index == h_split then r.br = a.br else r.br = false end
|
if x_index == h_split then r.br = a.br else r.br = false end
|
||||||
|
@ -375,19 +392,78 @@ local function create(data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for i = #children, 1, -1 do
|
local merged_children = {}
|
||||||
if children[i].x ~= math.floor(children[i].x)
|
local start_index = 1
|
||||||
or children[i].y ~= math.floor(children[i].y)
|
for i = 3, #args, 2 do
|
||||||
or children[i].width ~= math.floor(children[i].width)
|
-- find the first index that is not merged
|
||||||
or children[i].height ~= math.floor(children[i].height)
|
while start_index <= #children and children[start_index] == false do
|
||||||
then
|
start_index = start_index + 1
|
||||||
print("warning, splitting yields floating area " .. _area_tostring(children[i]))
|
end
|
||||||
|
if start_index > #children or children[start_index] == false then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
local x = (start_index - 1) % h_split
|
||||||
|
local y = math.floor((start_index - 1) / h_split)
|
||||||
|
local w = args[i]
|
||||||
|
local h = args[i + 1]
|
||||||
|
if w < 1 then w = 1 end
|
||||||
|
if h == nil or h < 1 then h = 1 end
|
||||||
|
if alt then
|
||||||
|
local tmp = w
|
||||||
|
w = h
|
||||||
|
h = tmp
|
||||||
|
end
|
||||||
|
if x + w > h_split then w = h_split - x end
|
||||||
|
if y + h > v_split then h = v_split - y end
|
||||||
|
local end_index = start_index
|
||||||
|
for ty = y, y + h - 1 do
|
||||||
|
local succ = true
|
||||||
|
for tx = x, x + w - 1 do
|
||||||
|
if children[ty * h_split + tx + 1] == false then
|
||||||
|
succ = false
|
||||||
|
break
|
||||||
|
elseif ty == y then
|
||||||
|
end_index = ty * h_split + tx + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not succ then
|
||||||
|
break
|
||||||
|
elseif ty > y then
|
||||||
|
end_index = ty * h_split + x + w
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local r = {
|
||||||
|
x = children[start_index].x, y = children[start_index].y,
|
||||||
|
width = children[end_index].x + children[end_index].width - children[start_index].x,
|
||||||
|
height = children[end_index].y + children[end_index].height - children[start_index].y,
|
||||||
|
bu = children[start_index].bu, bl = children[start_index].bl,
|
||||||
|
bd = children[end_index].bd, br = children[end_index].br,
|
||||||
|
depth = a.depth + 1,
|
||||||
|
group_id = op_count
|
||||||
|
}
|
||||||
|
merged_children[#merged_children + 1] = r
|
||||||
|
|
||||||
|
for ty = y, y + h - 1 do
|
||||||
|
local succ = true
|
||||||
|
for tx = x, x + w - 1 do
|
||||||
|
local index = ty * h_split + tx + 1
|
||||||
|
if index <= end_index then
|
||||||
|
children[index] = false
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
open_areas[#open_areas + 1] = children[i]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
push_children(merged_children)
|
||||||
|
push_children(children)
|
||||||
|
|
||||||
elseif method == "d" then
|
elseif method == "d" then
|
||||||
|
|
||||||
|
local a = pop_open_area()
|
||||||
local shares = parse_arg_string(arg_str, 0)
|
local shares = parse_arg_string(arg_str, 0)
|
||||||
local x_shares = {}
|
local x_shares = {}
|
||||||
local y_shares = {}
|
local y_shares = {}
|
||||||
|
@ -406,9 +482,11 @@ local function create(data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if #x_shares == 0 or #y_shares == 0 then
|
if #x_shares == 0 then
|
||||||
open_areas[#open_areas + 1] = a
|
open_areas[#open_areas + 1] = a
|
||||||
return
|
return
|
||||||
|
elseif #y_shares == 0 then
|
||||||
|
y_shares = {1}
|
||||||
end
|
end
|
||||||
|
|
||||||
x_shares = fair_split(a.width, x_shares)
|
x_shares = fair_split(a.width, x_shares)
|
||||||
|
@ -423,7 +501,7 @@ local function create(data)
|
||||||
width = x_shares[x_index],
|
width = x_shares[x_index],
|
||||||
height = y_shares[y_index],
|
height = y_shares[y_index],
|
||||||
depth = a.depth + 1,
|
depth = a.depth + 1,
|
||||||
group_id = split_count,
|
group_id = op_count,
|
||||||
}
|
}
|
||||||
if x_index == 1 then r.bl = a.bl else r.bl = false end
|
if x_index == 1 then r.bl = a.bl else r.bl = false end
|
||||||
if x_index == #x_shares then r.br = a.br else r.br = false end
|
if x_index == #x_shares then r.br = a.br else r.br = false end
|
||||||
|
@ -433,46 +511,11 @@ local function create(data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for i = #children, 1, -1 do
|
push_children(children)
|
||||||
if children[i].x ~= math.floor(children[i].x)
|
|
||||||
or children[i].y ~= math.floor(children[i].y)
|
|
||||||
or children[i].width ~= math.floor(children[i].width)
|
|
||||||
or children[i].height ~= math.floor(children[i].height)
|
|
||||||
then
|
|
||||||
print("warning, splitting yields floating area " .. _area_tostring(children[i]))
|
|
||||||
end
|
|
||||||
open_areas[#open_areas + 1] = children[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif method == "p" then
|
elseif method == "s" then
|
||||||
-- XXX
|
|
||||||
end
|
|
||||||
|
|
||||||
arg_str = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
local function push_area()
|
|
||||||
closed_areas[#closed_areas + 1] = pop_open_area()
|
|
||||||
end
|
|
||||||
|
|
||||||
local function handle_command(key)
|
|
||||||
if key == "h" or key == "H" then
|
|
||||||
handle_split("h", key == "H")
|
|
||||||
elseif key == "v" or key == "V" then
|
|
||||||
handle_split("v", key == "V")
|
|
||||||
elseif key == "w" or key == "W" then
|
|
||||||
if arg_str == "" then
|
|
||||||
push_area()
|
|
||||||
else
|
|
||||||
handle_split("w", key == "W")
|
|
||||||
end
|
|
||||||
elseif key == "d" or key == "D" then
|
|
||||||
handle_split("d", key == "D")
|
|
||||||
elseif key == "p" or key == "P" then
|
|
||||||
handle_split("p", key == "P")
|
|
||||||
elseif key == "s" or key == "S" then
|
|
||||||
if #open_areas > 0 then
|
if #open_areas > 0 then
|
||||||
key = "s"
|
|
||||||
local times = arg_str == "" and 1 or tonumber(arg_str)
|
local times = arg_str == "" and 1 or tonumber(arg_str)
|
||||||
local t = {}
|
local t = {}
|
||||||
while #open_areas > 0 do
|
while #open_areas > 0 do
|
||||||
|
@ -481,34 +524,76 @@ local function create(data)
|
||||||
for i = #t, 1, -1 do
|
for i = #t, 1, -1 do
|
||||||
open_areas[#open_areas + 1] = t[(i + times - 1) % #t + 1]
|
open_areas[#open_areas + 1] = t[(i + times - 1) % #t + 1]
|
||||||
end
|
end
|
||||||
arg_str = ""
|
|
||||||
else
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
elseif key == " " or key == "-" then
|
|
||||||
key = "-"
|
elseif method == "-" then
|
||||||
if arg_str == "" then
|
|
||||||
push_area()
|
push_area()
|
||||||
else
|
|
||||||
max_depth = tonumber(arg_str)
|
elseif method == "." then
|
||||||
arg_str = ""
|
|
||||||
end
|
|
||||||
elseif key == "Return" or key == "." then
|
|
||||||
key = "."
|
|
||||||
while #open_areas > 0 do
|
while #open_areas > 0 do
|
||||||
push_area()
|
push_area()
|
||||||
end
|
end
|
||||||
arg_str = ""
|
|
||||||
elseif key == "," or tonumber(key) ~= nil then
|
elseif method == ";" then
|
||||||
arg_str = arg_str .. key
|
|
||||||
else
|
-- nothing
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
while #open_areas > 0 and open_areas[#open_areas].depth >= max_depth do
|
while #open_areas > 0 and open_areas[#open_areas].depth >= max_depth do
|
||||||
push_area()
|
push_area()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
arg_str = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
local key_translate_tab = {
|
||||||
|
["Return"] = ".",
|
||||||
|
[" "] = "-",
|
||||||
|
}
|
||||||
|
|
||||||
|
local ch_info = {
|
||||||
|
["h"] = 2, ["H"] = 2,
|
||||||
|
["v"] = 2, ["V"] = 2,
|
||||||
|
["w"] = 2, ["W"] = 2,
|
||||||
|
["d"] = 2, ["D"] = 2,
|
||||||
|
["s"] = 2, ["S"] = 2,
|
||||||
|
["-"] = 1,
|
||||||
|
["."] = 1,
|
||||||
|
[";"] = 1,
|
||||||
|
["0"] = 0, ["1"] = 0, ["2"] = 0, ["3"] = 0, ["4"] = 0,
|
||||||
|
["5"] = 0, ["6"] = 0, ["7"] = 0, ["8"] = 0, ["9"] = 0,
|
||||||
|
[","] = 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
local function handle_ch(key)
|
||||||
|
if key_translate_tab[key] ~= nil then
|
||||||
|
key = key_translate_tab[key]
|
||||||
|
end
|
||||||
|
local t = ch_info[key]
|
||||||
|
if t == nil then
|
||||||
|
return nil
|
||||||
|
elseif t == 2 then
|
||||||
|
if pending_op ~= nil then
|
||||||
|
handle_op(pending_op)
|
||||||
|
pending_op = key
|
||||||
|
elseif arg_str == "" then
|
||||||
|
pending_op = key
|
||||||
|
else
|
||||||
|
handle_op(key)
|
||||||
|
end
|
||||||
|
elseif t == 1 then
|
||||||
|
if pending_op ~= nil then
|
||||||
|
handle_op(pending_op)
|
||||||
|
pending_op = nil
|
||||||
|
end
|
||||||
|
handle_op(key)
|
||||||
|
elseif t == 0 then
|
||||||
|
arg_str = arg_str .. key
|
||||||
|
end
|
||||||
|
|
||||||
return key
|
return key
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -575,9 +660,17 @@ local function create(data)
|
||||||
|
|
||||||
for i, a in ipairs(closed_areas) do
|
for i, a in ipairs(closed_areas) do
|
||||||
local sa = shrink_area_with_gap(a, inner_gap, outer_gap)
|
local sa = shrink_area_with_gap(a, inner_gap, outer_gap)
|
||||||
|
local to_highlight = false
|
||||||
|
if pending_op ~= nil then
|
||||||
|
to_highlight = a.group_id == op_count
|
||||||
|
end
|
||||||
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
||||||
cr:clip()
|
cr:clip()
|
||||||
cr:set_source(closed_color)
|
if to_highlight then
|
||||||
|
cr:set_source(active_color)
|
||||||
|
else
|
||||||
|
cr:set_source(closed_color)
|
||||||
|
end
|
||||||
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
||||||
cr:fill()
|
cr:fill()
|
||||||
cr:set_source(border_color)
|
cr:set_source(border_color)
|
||||||
|
@ -589,12 +682,18 @@ local function create(data)
|
||||||
|
|
||||||
for i, a in ipairs(open_areas) do
|
for i, a in ipairs(open_areas) do
|
||||||
local sa = shrink_area_with_gap(a, inner_gap, outer_gap)
|
local sa = shrink_area_with_gap(a, inner_gap, outer_gap)
|
||||||
|
local to_highlight = false
|
||||||
|
if pending_op == nil then
|
||||||
|
to_highlight = i == #open_areas
|
||||||
|
else
|
||||||
|
to_highlight = a.group_id == op_count
|
||||||
|
end
|
||||||
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
||||||
cr:clip()
|
cr:clip()
|
||||||
if i == #open_areas then
|
if i == #open_areas then
|
||||||
cr:set_source(api.gears.color(active_color))
|
cr:set_source(active_color)
|
||||||
else
|
else
|
||||||
cr:set_source(api.gears.color(open_color))
|
cr:set_source(open_color)
|
||||||
end
|
end
|
||||||
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
||||||
cr:fill()
|
cr:fill()
|
||||||
|
@ -602,12 +701,12 @@ local function create(data)
|
||||||
cr:set_source(border_color)
|
cr:set_source(border_color)
|
||||||
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
cr:rectangle(sa.x - start_x, sa.y - start_y, sa.width, sa.height)
|
||||||
cr:set_line_width(10.0)
|
cr:set_line_width(10.0)
|
||||||
if i ~= #open_areas then
|
if to_highlight then
|
||||||
|
cr:stroke()
|
||||||
|
else
|
||||||
cr:set_dash({5, 5}, 0)
|
cr:set_dash({5, 5}, 0)
|
||||||
cr:stroke()
|
cr:stroke()
|
||||||
cr:set_dash({}, 0)
|
cr:set_dash({}, 0)
|
||||||
else
|
|
||||||
cr:stroke()
|
|
||||||
end
|
end
|
||||||
cr:reset_clip()
|
cr:reset_clip()
|
||||||
end
|
end
|
||||||
|
@ -653,6 +752,10 @@ local function create(data)
|
||||||
|
|
||||||
local ok, err = pcall(
|
local ok, err = pcall(
|
||||||
function ()
|
function ()
|
||||||
|
if pending_op ~= nil then
|
||||||
|
pop_history()
|
||||||
|
end
|
||||||
|
|
||||||
if key == "BackSpace" then
|
if key == "BackSpace" then
|
||||||
pop_history()
|
pop_history()
|
||||||
elseif key == "Escape" then
|
elseif key == "Escape" then
|
||||||
|
@ -675,7 +778,7 @@ local function create(data)
|
||||||
local cmd = data.cmds[cmd_index]:sub(i, i)
|
local cmd = data.cmds[cmd_index]:sub(i, i)
|
||||||
|
|
||||||
push_history()
|
push_history()
|
||||||
local ret = handle_command(cmd)
|
local ret = handle_ch(cmd)
|
||||||
|
|
||||||
if ret == nil then
|
if ret == nil then
|
||||||
print("warning: ret is nil")
|
print("warning: ret is nil")
|
||||||
|
@ -690,7 +793,7 @@ local function create(data)
|
||||||
end
|
end
|
||||||
elseif #open_areas > 0 then
|
elseif #open_areas > 0 then
|
||||||
push_history()
|
push_history()
|
||||||
local ret = handle_command(key)
|
local ret = handle_ch(key)
|
||||||
if ret ~= nil then
|
if ret ~= nil then
|
||||||
current_info = current_info .. ret
|
current_info = current_info .. ret
|
||||||
current_cmd = current_cmd .. ret
|
current_cmd = current_cmd .. ret
|
||||||
|
@ -745,6 +848,11 @@ local function create(data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not to_exit and pending_op ~= nil then
|
||||||
|
push_history()
|
||||||
|
handle_op(pending_op)
|
||||||
|
end
|
||||||
|
|
||||||
refresh()
|
refresh()
|
||||||
|
|
||||||
if to_exit then
|
if to_exit then
|
||||||
|
@ -781,10 +889,9 @@ local function create(data)
|
||||||
local outer_gap = data.outer_gap or data.gap or api.beautiful.useless_gap * 2 or 0
|
local outer_gap = data.outer_gap or data.gap or api.beautiful.useless_gap * 2 or 0
|
||||||
local inner_gap = data.inner_gap or data.gap or api.beautiful.useless_gap * 2 or 0
|
local inner_gap = data.inner_gap or data.gap or api.beautiful.useless_gap * 2 or 0
|
||||||
init(init_area)
|
init(init_area)
|
||||||
push_history()
|
|
||||||
|
|
||||||
for i = 1, #cmd do
|
for i = 1, #cmd do
|
||||||
local key = handle_command(cmd:sub(i, i))
|
handle_ch(cmd:sub(i, i))
|
||||||
end
|
end
|
||||||
|
|
||||||
local areas_with_gap = {}
|
local areas_with_gap = {}
|
||||||
|
|
|
@ -29,7 +29,6 @@ local function with_alpha(col, alpha)
|
||||||
return api.lgi.cairo.SolidPattern.create_rgba(r, g, b, alpha)
|
return api.lgi.cairo.SolidPattern.create_rgba(r, g, b, alpha)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function start(c)
|
local function start(c)
|
||||||
local tablist_font_desc = api.beautiful.get_merged_font(
|
local tablist_font_desc = api.beautiful.get_merged_font(
|
||||||
api.beautiful.mono_font or api.beautiful.font, api.dpi(10))
|
api.beautiful.mono_font or api.beautiful.font, api.dpi(10))
|
||||||
|
|
Loading…
Reference in New Issue