[elbe-devel] [PATCH 06/14] Debianize - Grid widget
Bastian Germann
bage at linutronix.de
Thu Aug 1 15:13:42 CEST 2019
> From: Olivier Dion <dion at linutronix.de>
>
> Urwid is a poor library that offer next to nothing in term of good
offers
> widgets. The grid widget is a recursive abstraction around column and
> pile widgets.
>
> One can nest grid inside of grid .. and so on. Grids also accept the
> emac's keybinding format to move around.
>
> Signed-off-by: Olivier Dion <dion at linutronix.de>
> ---
> elbepack/debianize/widgets/grid.py | 130 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 130 insertions(+)
> create mode 100644 elbepack/debianize/widgets/grid.py
>
> diff --git a/elbepack/debianize/widgets/grid.py b/elbepack/debianize/widgets/grid.py
> new file mode 100644
> index 00000000..1112fcbd
> --- /dev/null
> +++ b/elbepack/debianize/widgets/grid.py
> @@ -0,0 +1,130 @@
> +# ELBE - Debian Based Embedded Rootfilesystem Builder
> +# Copyright (c) 2019 Olivier Dion <dion at linutronix.de>
> +#
> +# SPDX-License-Identifier: GPL-3.0-or-later
> +
> +
> +from urwid import (
> + Columns,
> + Pile as Rows,
> + WidgetWrap
> +)
> +
> +
> +class Grid(WidgetWrap):
> +
> + def __init__(self, rows):
> +
> + m = 1
> + cols = []
> +
> + for row in rows:
> + if len(row) > m:
> + m = len(row)
> +
> + for c in row:
> + if isinstance(c, Grid):
> + c.parent = self
> +
> + cols.append(Columns(row))
> +
> + super().__init__(Rows(cols))
> +
> + self.n = len(rows)
> + self.m = m
> +
> + self.i = 0
> + self.j = 0
> +
> + self.focus(self.i, self.j)
> +
> + self.keybind = {
> + "down" : lambda: self.focus_recursive(forward=True, horizontal=False),
> + "up" : lambda: self.focus_recursive(forward=False, horizontal=False),
> + "tab" : lambda: self.focus_recursive(forward=True, horizontal=True),
> + "shift tab": lambda: self.focus_recursive(forward=False, horizontal=True)
We only have one lambda in the current code base. If you can avoid it
here, please do so.
> + }
> +
> + self.aliases = {
> + "ctrl f": "right",
> + "ctrl b": "left",
> + "ctrl p": "up",
> + "ctrl n": "down"
> + }
> +
> + self.parent = None
> +
> + def focus_direction(self, forward: bool, horizontal: bool):
> +
> + j = self.j
> + i = self.i
> + direction = 1 if forward else -1
> +
> + while True:
> + if horizontal:
> + j += direction
> + i += j // self.m
> + else:
> + i += direction
> + j += i // self.n
> +
> + i %= self.n
> + j %= self.m
> +
> + try:
> + self.focus(i, j)
> + break
> + except IndexError:
> + pass
> +
> + def focus_recursive(self, forward: bool, horizontal: bool):
> + while True:
> + child = self.current_focus()
> +
> + if isinstance(child, Grid):
> + child.focus_recursive(forward, horizontal)
> + elif not forward and self._is_first():
> + if self.parent is not None and not self.parent._is_first():
> + return self.parent.focus_direction(forward, horizontal)
> + else:
> + self.focus_direction(forward, horizontal)
> + elif forward and self._is_last():
> + if self.parent is not None and not self.parent._is_last():
> + return self.parent.focus_direction(forward, horizontal)
> + else:
> + self.focus_direction(forward, horizontal)
> + else:
> + self.focus_direction(forward, horizontal)
> +
> + if self.current_focus().selectable():
> + break
> +
> + def focus_first(self):
> + self.focus(0, 0)
> + self.i = 0
> + self.j = 0
> +
> + def focus(self, i, j):
> + self._w.base_widget.set_focus_path([i, j])
> + self.i = i
> + self.j = j
> +
> + def current_focus(self):
> + return self._w.base_widget.contents[self.i][0].contents[self.j][0].base_widget
> +
> + def _is_last(self):
> + return self.i == self.n - 1 and self.j == self.m - 1
> +
> + def _is_first(self):
> + return self.i == 0 and self.j == 0
> +
> + def keypress(self, size, key):
> +
> + if key in self.aliases:
> + key = self.aliases[key]
> +
> + if key in self.keybind:
> + self.keybind[key]()
> + return None
> +
> + return super().keypress(size, key)
>
with the suggested changes
Reviewed-by: Bastian Germann <bage at linutronix.de>
More information about the elbe-devel
mailing list