diff options
| author | historia <historiavg@proton.me> | 2026-08-25 21:02:21 -0400 |
|---|---|---|
| committer | historia <historiavg@proton.me> | 2026-08-25 21:02:21 -0400 |
| commit | 4c3e78c39c81d2997e88b84e1b5a25b244e870e4 (patch) | |
| tree | 92c8df5cf5cf240da00d481df1d82105b69feb22 /app/ui | |
| parent | d453d88d1d40c5e54af07ceb89c8c18d09cfdb0e (diff) | |
| download | tts-audiobook-generator-4c3e78c39c81d2997e88b84e1b5a25b244e870e4.tar.gz | |
feat: prompt to save settings when going back from settings menu
Diffstat (limited to 'app/ui')
| -rw-r--r-- | app/ui/hub.py | 32 | ||||
| -rw-r--r-- | app/ui/tui.py | 35 |
2 files changed, 57 insertions, 10 deletions
diff --git a/app/ui/hub.py b/app/ui/hub.py index cad9a9d..de8b861 100644 --- a/app/ui/hub.py +++ b/app/ui/hub.py @@ -405,17 +405,29 @@ class _Hub: # -- settings ------------------------------------------------------- def screen_settings(self): - result = tui.form(self.stdscr, "Settings", _settings_fields(), - back_value=tui.Wizard.BACK) - if result is tui.Wizard.BACK or result is None: - return tui.Wizard.BACK - try: - _apply_settings(result) - except ValueError as exc: - tui.flash(self.stdscr, str(exc), "err") + fields = _settings_fields() + while True: + result = tui.form(self.stdscr, "Settings", fields, + back_value=tui.Wizard.BACK) + if not (result is tui.Wizard.BACK or result is None): + # Save pressed: apply as before, no prompt. + try: + _apply_settings(result) + except ValueError as exc: + tui.flash(self.stdscr, str(exc), "err") + return tui.Wizard.BACK + # q/Esc (or the Cancel button) left the form without saving: + # ask whether the edits should be kept before discarding them. + answer = tui.confirm_yn_cancel(self.stdscr, "Save settings?") + if answer == "cancel": + continue # back into the form, edits intact + if answer == "yes": + values = {field["key"]: field["value"] for field in fields} + try: + _apply_settings(values) + except ValueError as exc: + tui.flash(self.stdscr, str(exc), "err") return tui.Wizard.BACK - tui.flash(self.stdscr, "Settings saved.", "ok") - return tui.Wizard.BACK # -- servers -------------------------------------------------------- diff --git a/app/ui/tui.py b/app/ui/tui.py index b1b18f1..11f5653 100644 --- a/app/ui/tui.py +++ b/app/ui/tui.py @@ -669,6 +669,41 @@ def confirm(scr, question: str, default: bool = False, return index == 0 +def confirm_yn_cancel(scr, question: str) -> str: + """Ask QUESTION with Yes / No / Cancel buttons; return the answer. + + Like ``confirm``, but with a third Cancel button and a string result: + "yes", "no", or "cancel". Tab or the arrow keys cycle all three + buttons (wrapping around), Enter activates the highlighted one (Yes + starts highlighted), y/n answer directly, and Esc (or 'q') counts as + Cancel. + """ + frame = Frame(scr, question, + "Tab/arrows = switch Enter = confirm y/n " + "Esc = cancel") + index = 0 + while True: + frame.rows = [] + frame.cursor = None + frame.buttons = (["Yes", "No", "Cancel"], index) + frame.draw() + curses = frame.curses + key = frame.get_key(cancel_keys=()) + if key in _CANCEL_KEYS: + return "cancel" + if key in (9, curses.KEY_RIGHT, curses.KEY_DOWN, ord("l")): + index = (index + 1) % 3 + elif key in (curses.KEY_BTAB, curses.KEY_LEFT, curses.KEY_UP, + ord("h")): + index = (index - 1) % 3 + elif key in (ord("y"), ord("Y")): + return "yes" + elif key in (ord("n"), ord("N")): + return "no" + elif key in (10, 13): + return ("yes", "no", "cancel")[index] + + # --------------------------------------------------------------------------- # Widget: single-choice menu # --------------------------------------------------------------------------- |
