From 96823c8546f86c2aeaa5fb21581e7b70475d5e2b Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Sun, 11 May 2025 20:59:26 +0200 Subject: [PATCH] Added page background and foreground headers to micron --- nomadnet/ui/textui/Browser.py | 93 ++++++++++++++++++++++++++++-- nomadnet/ui/textui/Guide.py | 4 ++ nomadnet/ui/textui/MicronParser.py | 44 ++++++++------ 3 files changed, 119 insertions(+), 22 deletions(-) diff --git a/nomadnet/ui/textui/Browser.py b/nomadnet/ui/textui/Browser.py index 36e01e6..b740023 100644 --- a/nomadnet/ui/textui/Browser.py +++ b/nomadnet/ui/textui/Browser.py @@ -8,7 +8,7 @@ import shutil import nomadnet import subprocess import threading -from .MicronParser import markup_to_attrmaps +from .MicronParser import markup_to_attrmaps, make_style, default_state from nomadnet.Directory import DirectoryEntry from nomadnet.vendor.Scrollable import * @@ -99,6 +99,8 @@ class Browser: self.response_speed = None self.response_size = None self.response_transfer_size = None + self.page_background_color = None + self.page_foreground_color = None self.saved_file_name = None self.page_data = None self.displayed_page_data = None @@ -157,10 +159,16 @@ class Browser: self.browser_footer = self.make_status_widget() self.frame.contents["footer"] = (self.browser_footer, self.frame.options()) self.link_status_showing = False + if self.page_background_color != None or self.page_foreground_color != None: + style_name = make_style(default_state(fg=self.page_foreground_color, bg=self.page_background_color)) + self.browser_footer.set_attr_map({None: style_name}) else: self.link_status_showing = True self.browser_footer = urwid.AttrMap(urwid.Pile([urwid.Divider(self.g["divider1"]), urwid.Text("Link to: "+str(link_target))]), "browser_controls") self.frame.contents["footer"] = (self.browser_footer, self.frame.options()) + if self.page_background_color != None or self.page_foreground_color != None: + style_name = make_style(default_state(fg=self.page_foreground_color, bg=self.page_background_color)) + self.browser_footer.set_attr_map({None: style_name}) def expand_shorthands(self, destination_type): if destination_type == "nnn": @@ -321,7 +329,14 @@ class Browser: def make_status_widget(self): if self.response_progress > 0: - pb = ResponseProgressBar("progress_empty" , "progress_full", current=self.response_progress, done=1.0, satt=None, owner=self) + if self.page_background_color != None or self.page_foreground_color != None: + style_name = make_style(default_state(fg=self.page_foreground_color, bg=self.page_background_color)) + style_name_inverted = make_style(default_state(bg=self.page_foreground_color, fg=self.page_background_color)) + else: + style_name = "progress_empty" + style_name_inverted = "progress_full" + + pb = ResponseProgressBar(style_name , style_name_inverted, current=self.response_progress, done=1.0, satt=None, owner=self) widget = urwid.Pile([urwid.Divider(self.g["divider1"]), pb]) else: widget = urwid.Pile([urwid.Divider(self.g["divider1"]), urwid.Text(self.status_text())]) @@ -368,6 +383,10 @@ class Browser: else: self.display_widget.set_attr_map({None: "body_text"}) self.browser_header = self.make_control_widget() + if self.page_background_color != None or self.page_foreground_color != None: + style_name = make_style(default_state(fg=self.page_foreground_color, bg=self.page_background_color)) + self.browser_header.set_attr_map({None: style_name}) + if self.destination_hash != None: remote_display_string = self.app.directory.simplest_display_str(self.destination_hash) else: @@ -381,6 +400,13 @@ class Browser: if self.status == Browser.DONE: self.browser_footer = self.make_status_widget() self.update_page_display() + + if self.page_background_color != None or self.page_foreground_color != None: + style_name = make_style(default_state(fg=self.page_foreground_color, bg=self.page_background_color)) + self.browser_body.set_attr_map({None: style_name}) + self.browser_footer.set_attr_map({None: style_name}) + self.browser_header.set_attr_map({None: style_name}) + self.display_widget.set_attr_map({None: style_name}) elif self.status == Browser.LINK_TIMEOUT: self.browser_body = self.make_request_failed_widget() @@ -394,6 +420,12 @@ class Browser: ) self.browser_footer = self.make_status_widget() + + if self.page_background_color != None or self.page_foreground_color != None: + style_name = make_style(default_state(fg=self.page_foreground_color, bg=self.page_background_color)) + self.browser_footer.set_attr_map({None: style_name}) + self.browser_header.set_attr_map({None: style_name}) + self.display_widget.set_attr_map({None: style_name}) elif self.status == Browser.REQUEST_FAILED: self.browser_body = self.make_request_failed_widget() @@ -764,7 +796,24 @@ class Browser: self.status = Browser.DONE self.page_data = cached self.markup = self.page_data.decode("utf-8") - self.attr_maps = markup_to_attrmaps(self.markup, url_delegate=self) + + self.page_background_color = None + bgpos = self.markup.find("#!bg=") + if bgpos: + endpos = self.markup.find("\n", bgpos) + if endpos-(bgpos+5) == 3: + bg = self.markup[bgpos+5:endpos] + self.page_background_color = bg + + self.page_foreground_color = None + fgpos = self.markup.find("#!fg=") + if fgpos: + endpos = self.markup.find("\n", fgpos) + if endpos-(fgpos+5) == 3: + fg = self.markup[fgpos+5:endpos] + self.page_foreground_color = fg + + self.attr_maps = markup_to_attrmaps(self.markup, url_delegate=self, fg_color=self.page_foreground_color, bg_color=self.page_background_color) self.response_progress = 0 self.response_speed = None @@ -814,7 +863,24 @@ class Browser: self.status = Browser.DONE self.page_data = page_data self.markup = self.page_data.decode("utf-8") - self.attr_maps = markup_to_attrmaps(self.markup, url_delegate=self) + + self.page_background_color = None + bgpos = self.markup.find("#!bg=") + if bgpos: + endpos = self.markup.find("\n", bgpos) + if endpos-(bgpos+5) == 3: + bg = self.markup[bgpos+5:endpos] + self.page_background_color = bg + + self.page_foreground_color = None + fgpos = self.markup.find("#!fg=") + if fgpos: + endpos = self.markup.find("\n", fgpos) + if endpos-(fgpos+5) == 3: + fg = self.markup[fgpos+5:endpos] + self.page_foreground_color = fg + + self.attr_maps = markup_to_attrmaps(self.markup, url_delegate=self, fg_color=self.page_foreground_color, bg_color=self.page_background_color) self.response_progress = 0 self.response_speed = None @@ -949,7 +1015,24 @@ class Browser: self.status = Browser.DONE self.page_data = request_receipt.response self.markup = self.page_data.decode("utf-8") - self.attr_maps = markup_to_attrmaps(self.markup, url_delegate=self) + + self.page_background_color = None + bgpos = self.markup.find("#!bg=") + if bgpos: + endpos = self.markup.find("\n", bgpos) + if endpos-(bgpos+5) == 3: + bg = self.markup[bgpos+5:endpos] + self.page_background_color = bg + + self.page_foreground_color = None + fgpos = self.markup.find("#!fg=") + if fgpos: + endpos = self.markup.find("\n", fgpos) + if endpos-(fgpos+5) == 3: + fg = self.markup[fgpos+5:endpos] + self.page_foreground_color = fg + + self.attr_maps = markup_to_attrmaps(self.markup, url_delegate=self, fg_color=self.page_foreground_color, bg_color=self.page_background_color) self.response_progress = 0 self.response_speed = None self.progress_updated_at = None diff --git a/nomadnet/ui/textui/Guide.py b/nomadnet/ui/textui/Guide.py index 4b4ca2a..352e71f 100644 --- a/nomadnet/ui/textui/Guide.py +++ b/nomadnet/ui/textui/Guide.py @@ -1268,6 +1268,9 @@ You can use `B5d5`F222 color `f`B333 `Ff00f`Ff80o`Ffd0r`F9f0m`F0f2a`F0fdt`F07ft` `` +>Page Foreground and Background Colors + +To specify a background color for the entire page, place the `!#!bg=X`! header on one of the first lines of your page, where `!X`! is the color you want to use, for example `!444`!. If you're also using the cache control header, the background specifier must come `*after`* the cache control header. Likewise, you can specify the default text color by using the `!#!fg=X`! header. >Links @@ -1385,6 +1388,7 @@ A masked input field: `B444``B333 Full control: `B444``B333 `b + >>> Checkboxes In addition to text fields, Checkboxes are another way of submitting data. They allow the user to make a single selection or select multiple options. diff --git a/nomadnet/ui/textui/MicronParser.py b/nomadnet/ui/textui/MicronParser.py index 9f277ba..70f9f0f 100644 --- a/nomadnet/ui/textui/MicronParser.py +++ b/nomadnet/ui/textui/MicronParser.py @@ -31,20 +31,14 @@ SYNTH_SPECS = {} SECTION_INDENT = 2 INDENT_RIGHT = 1 -def markup_to_attrmaps(markup, url_delegate = None): - global SELECTED_STYLES - if nomadnet.NomadNetworkApp.get_shared_instance().config["textui"]["theme"] == nomadnet.ui.TextUI.THEME_DARK: - SELECTED_STYLES = STYLES_DARK - else: - SELECTED_STYLES = STYLES_LIGHT - - attrmaps = [] - +def default_state(fg=None, bg=None): + if fg == None: fg = SELECTED_STYLES["plain"]["fg"] + if bg == None: bg = DEFAULT_BG state = { "literal": False, "depth": 0, - "fg_color": SELECTED_STYLES["plain"]["fg"], - "bg_color": DEFAULT_BG, + "fg_color": fg, + "bg_color": bg, "formatting": { "bold": False, "underline": False, @@ -54,7 +48,25 @@ def markup_to_attrmaps(markup, url_delegate = None): }, "default_align": "left", "align": "left", + "default_fg": fg, + "default_bg": bg, } + return state + +def markup_to_attrmaps(markup, url_delegate = None, fg_color=None, bg_color=None): + global SELECTED_STYLES + if nomadnet.NomadNetworkApp.get_shared_instance().config["textui"]["theme"] == nomadnet.ui.TextUI.THEME_DARK: + SELECTED_STYLES = STYLES_DARK + else: + SELECTED_STYLES = STYLES_LIGHT + + attrmaps = [] + + fgc = None; bgc = DEFAULT_BG + if bg_color != None: bgc = bg_color + if fg_color != None: fgc = fg_color + + state = default_state(fgc, bgc) # Split entire document into lines for # processing. @@ -73,7 +85,6 @@ def markup_to_attrmaps(markup, url_delegate = None): return attrmaps -import RNS def parse_line(line, state, url_delegate): pre_escape = False if len(line) > 0: @@ -439,7 +450,6 @@ def make_output(state, line, url_delegate, pre_escape=False): escape = pre_escape skip = 0 - RNS.log(f"Line [ESC {escape}] [MODE {mode}: {line}") for i in range(0, len(line)): c = line[i] if skip > 0: @@ -458,20 +468,20 @@ def make_output(state, line, url_delegate, pre_escape=False): state["fg_color"] = color skip = 3 elif c == "f": - state["fg_color"] = SELECTED_STYLES["plain"]["fg"] + state["fg_color"] = state["default_fg"] elif c == "B": if len(line) >= i+4: color = line[i+1:i+4] state["bg_color"] = color skip = 3 elif c == "b": - state["bg_color"] = DEFAULT_BG + state["bg_color"] = state["default_bg"] elif c == "`": state["formatting"]["bold"] = False state["formatting"]["underline"] = False state["formatting"]["italic"] = False - state["fg_color"] = SELECTED_STYLES["plain"]["fg"] - state["bg_color"] = DEFAULT_BG + state["fg_color"] = state["default_fg"] + state["bg_color"] = state["default_bg"] state["align"] = state["default_align"] elif c == "c": if state["align"] != "center":