From e9483c2053c1d66bfa95f40e01fe85d3fb8caf7d Mon Sep 17 00:00:00 2001 From: VikingKong Date: Tue, 15 Nov 2022 19:04:17 +0300 Subject: [PATCH] Switch to urwid. Implement listbox with j/k navigation, adding and removing items --- App.py | 141 ++++++++++++++++++--------------------------------------- 1 file changed, 43 insertions(+), 98 deletions(-) diff --git a/App.py b/App.py index 119e31e..174ebdc 100644 --- a/App.py +++ b/App.py @@ -1,108 +1,53 @@ -from textual.containers import Container, Vertical -from textual.app import ComposeResult, App -from textual.widgets import Static, Header, DataTable -from textual.widget import Widget +import urwid -class FeedPane(Widget): - def __init__(self): - super().__init__() - self.id = "feed-pane" - - def add(self, content): - table = self.query_one(DataTable) - table.add_rows([[item] for item in content]) - - def addColumn(self, title): - table = self.query_one(DataTable) - table.add_column(title, width=60) - - def clear(self): - table = self.query_one(DataTable) - table.data = {} - table.rows = {} - table.row_count = 0 - table._line_no = 0 - table._y_offsets = [] - table._new_rows = set() - table._clear_caches() - table._require_update_dimensions = True - table.check_idle() - - def currentValue(self): - table = self.query_one(DataTable) - row_num = table.cursor_cell.row - column_num = table.cursor_cell.column - return table.data[row_num][column_num] - - def focus(self): - table = self.query_one(DataTable) - table.focus() - - def compose(self): - yield DataTable(id="feeds_table") +class TUI(urwid.Frame): + @classmethod + def create(cls): -class FeedItem(Static): - def __init__(self, content, id): - super().__init__() - self.content = content - self.id = "feed-" + str(id) - if id == 0: - self.set_styles("color: blue;") - - def on_mount(self): - self.update(self.content) - self.on_event - + tui = cls() + palette = [('header', 'white', 'black'), ('reveal focus', 'black', 'dark cyan', 'standout')] + loop = urwid.MainLoop( + tui, + palette, + event_loop=urwid.AsyncioEventLoop(), + ) + tui.loop = loop -class GUI(App): - CSS_PATH = "app.css" + return tui def __init__(self): - super().__init__() - - def on_key(self, event): - if event.key == "j": - pane = self.query_one(DataTable) - pane.key_down(event) - elif event.key == "k": - pane = self.query_one(DataTable) - pane.key_up(event) - elif event.key == "a": - pane = self.query_one(FeedPane) - pane.add(["XXX"]) - elif event.key == "r": - pane = self.query_one(FeedPane) - pane.clear() - elif event.key == "space": - pane = self.query_one(FeedPane) - pane.add([pane.currentValue()]) + self.loop = None + self.items = [urwid.Text("Feed# " + str(i)) for i in range(0, 15)] + walker = urwid.SimpleListWalker([urwid.AttrMap(item, None, 'reveal focus') for item in self.items]) + self.lb = urwid.ListBox(walker) + self.body = self.lb + + super().__init__(self.body) + + def run(self): + self.loop.run() + self.executor.shutdown(wait=False) + + def keypress(self, size, key): + if key in ("j", "down"): + item_size = len(self.lb.body) + focus_widget, idx = self.lb.get_focus() + if idx < item_size - 1: + idx = idx + 1 + self.lb.set_focus(idx) + elif key in ("k", "up"): + focus_widget, idx = self.lb.get_focus() + if idx > 0: + idx = idx - 1 + self.lb.set_focus(idx) + elif key == "a": + self.lb.body.append(urwid.AttrMap(urwid.Text("XXX"), None, 'reveal focus')) else: - pass - - def compose(self) -> ComposeResult: - yield Header() - yield Container( - FeedPane(), - Vertical( - *[Static("Horizontally"), - Static("Positioned"), - Static("Children"), - Static("Here")], - id="right-pane", - ), - id="app-grid", - ) - - def on_mount(self): - fp = self.query_one(FeedPane) - fp.addColumn("Feeds") - fp.add(["Feed#" + str(number) for number in range(15)]) - # fp.add_rows([[FeedItem(f"Feed# {number}", number)] for number in range(15)]) - fp.focus() + self.lb.keypress(size, key) + del self.lb.body[3] -if __name__ == "__main__": - app = GUI() - app.run() +tui = TUI.create() +tui.run()