From d5f54aed55d63ce936d2434ea800a62bd325dac4 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 7 Dec 2023 07:34:35 +0000 Subject: [PATCH] Actually show keypresses in menus --- cursesclient.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++-- text.py | 31 ++++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/cursesclient.py b/cursesclient.py index 421957a..58fc2ec 100644 --- a/cursesclient.py +++ b/cursesclient.py @@ -207,10 +207,27 @@ class CursesUI(client.Client): self.curses_shutdown() class Menu: + status_extra_text = None + def __init__(self, cc): self.cc = cc + self.items = [] + self.normalised = False + + def normalise(self): + if self.normalised: + return + + maxw = 0 + for _ in range(2): + for item in self.items: + if isinstance(item, text.MenuKeypressLine): + maxw = item.expand_key_width(maxw) + + self.normalised = True def render(self): + self.normalise() y = 0 header = text.FileHeader(self.title) @@ -218,7 +235,15 @@ class Menu: self.cc.print_at(y, 0, line) y += 1 - sl = text.FileStatusLine() + # FIXME: handle menus too large for the screen, so that you + # have to add > and < keypresses to scroll them + y += 1 + for item in self.items: + for line in item.render(self.cc.scr_w): + self.cc.print_at(y, 0, line) + y += 1 + + sl = text.FileStatusLine(self.status_extra_text) self.add_keys(sl) sl_rendered = util.exactly_one(sl.render(self.cc.scr_w)) self.cc.print_at(self.cc.scr_h - 1, 0, sl_rendered) @@ -238,15 +263,23 @@ class Menu: return 'quit' class MainMenu(Menu): + status_extra_text = text.ColouredString("Select an option") + def __init__(self, cc): super().__init__(cc) self.title = text.ColouredString( "Mastodonochrome Main Menu", 'H') + self.items.append(text.MenuKeypressLine( + 'H', text.ColouredString("Home timeline", + "K "))) + self.items.append(text.BlankLine()) + self.items.append(text.MenuKeypressLine( + 'ESC', text.ColouredString("Utilities and Exit"))) def add_keys(self, sl): # intentionally don't call the base class, because [Q] doesn't # do anything on this menu - sl.keys.append(('ESC', 'Utilities')) + pass def handle_key(self, ch): if ch in {ord('h'), ord('H')}: @@ -260,6 +293,13 @@ class EscMenu(Menu): self.title = text.ColouredString( "Utilities [ESC]", "HHHHHHHHHHHKKKH") + self.items.append(text.MenuKeypressLine( + 'L', text.ColouredString("Logs menu", + "K "))) + self.items.append(text.BlankLine()) + self.items.append(text.MenuKeypressLine( + 'X', text.ColouredString("EXit Mastodonochrome", + " K "))) def handle_key(self, ch): if ch in {ord('r'), ord('R')}: @@ -279,6 +319,9 @@ class LogMenu(Menu): self.title = text.ColouredString( "Client Logs [ESC][L]", "HHHHHHHHHHHHHKKKHHKH") + self.items.append(text.MenuKeypressLine( + 'L', text.ColouredString("Server Logs", + " K "))) def handle_key(self, ch): if ch in {ord('l'), ord('L')}: @@ -292,6 +335,9 @@ class LogMenu2(Menu): self.title = text.ColouredString( "Server Logs [ESC][L][L]", "HHHHHHHHHHHHHKKKHHKHHKH") + self.items.append(text.MenuKeypressLine( + 'E', text.ColouredString("Ego Log (Boosts, Follows and Faves)", + "K "))) def handle_key(self, ch): if ch in {ord('e'), ord('E')}: @@ -305,6 +351,9 @@ class ExitMenu(Menu): self.title = text.ColouredString( "Exit Mastodonochrome [ESC][X]", "HHHHHHHHHHHHHHHHHHHHHHKKKHHKH") + self.items.append(text.MenuKeypressLine( + 'X', text.ColouredString("Confirm eXit", + " K "))) def handle_key(self, ch): if ch in {ord('x'), ord('X')}: diff --git a/text.py b/text.py index f18e30e..91e14c5 100644 --- a/text.py +++ b/text.py @@ -223,14 +223,18 @@ class ExtendableIndicator: yield ColouredString("") class FileStatusLine: - def __init__(self): + def __init__(self, text=None): self.keys = [] self.proportion = None + self.text = text def render(self, width): message = ColouredString('') sep = ColouredString('') sep2 = ColouredString(' ') + if self.text is not None: + message += sep + self.text + sep = sep2 for key, action in self.keys: message += ( sep + ColouredString('[') + ColouredString(key, 'k') + @@ -249,6 +253,31 @@ class FileStatusLine: yield (ColouredString(" " * lspace) + message) +class MenuKeypressLine: + def __init__(self, key, description): + self.key = ColouredString(key) + self.description = ColouredString(description) + self.max_key_width = self.key.width + + def expand_key_width(self, new_max): + self.max_key_width = max(self.max_key_width, new_max) + return self.max_key_width + + def render(self, width): + equalpos = (width - 1) // 2 - 1 + lspace = equalpos - self.max_key_width - 3 + kspace = self.max_key_width - self.key.width + klspace = kspace // 2 + krspace = kspace - klspace + yield (ColouredString(" " * lspace) + + ColouredString(" " * klspace) + + ColouredString("[") + + ColouredString(self.key, 'k') + + ColouredString("]") + + ColouredString(" " * krspace) + + ColouredString(" = ") + + self.description) + class Paragraph: def __init__(self): self.words = [] -- 2.30.2