diff options
Diffstat (limited to 'app/ui/tui.py')
| -rw-r--r-- | app/ui/tui.py | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/app/ui/tui.py b/app/ui/tui.py index a647444..933626f 100644 --- a/app/ui/tui.py +++ b/app/ui/tui.py @@ -1492,9 +1492,50 @@ def checkbox_tree(scr, title: str, families: List[dict], if options: checked.add((index, options[0]["key"])) expanded.add(index) + else: + _, index, option_key = node + if (index, option_key) in checked: + checked.discard((index, option_key)) else: - _, index, option_key = node - if (index, option_key) in checked: - checked.discard((index, option_key)) - else: - checked.add((index, option_key)) + checked.add((index, option_key)) + + +# --------------------------------------------------------------------------- +# Widget: scrollable text viewer +# --------------------------------------------------------------------------- + +def text_viewer(scr, title: str, lines: Sequence[str], + back_value: object = None) -> object: + """Show LINES as a read-only dialog; Esc/q/Enter closes it. + + A scrollable pop-up for longer explanatory text (the hub's Help + screen). Rows wrap like body rows and stay centered; none is + selectable, so no cursor bar is drawn — but the (logical) cursor + still scrolls the view into place: Up/Down (or k/j) move one line, + Home/End jump to the top/bottom, PageUp/PageDown page, and the + frame's scroll indicator (``x/y`` in the border) appears whenever + the text overflows the dialog. Closing returns BACK_VALUE when it + is given (not None), so the caller can fall back a screen; without + one, Esc/q raise WizardCancelled as in menu(). + """ + frame = Frame(scr, title, + "Up/Down = scroll PgUp/PgDn = page Enter/Esc = close") + for line in lines: + frame.mark(line) + cursor = 0 + while True: + cursor = max(0, min(cursor, len(frame.rows) - 1)) + frame.cursor = cursor if frame.rows else None + frame.draw() + key = frame.get_key(cancel_keys=()) + if key in _CANCEL_KEYS: + if back_value is not None: + return back_value + raise WizardCancelled() + moved = frame.motion(key, cursor, len(frame.rows)) + if moved is not None: + cursor = moved + elif key in (10, 13): + if back_value is not None: + return back_value + raise WizardCancelled() |
