diff --git a/nomadnet/NomadNetworkApp.py b/nomadnet/NomadNetworkApp.py index 1a86ec5..060812b 100644 --- a/nomadnet/NomadNetworkApp.py +++ b/nomadnet/NomadNetworkApp.py @@ -244,6 +244,9 @@ class NomadNetworkApp: if not "editor" in self.config["textui"]: self.config["textui"]["editor"] = "editor" + if not "glyphs" in self.config["textui"]: + self.config["textui"]["glyphs"] = "unicode" + if not "mouse_enabled" in self.config["textui"]: self.config["textui"]["mouse_enabled"] = True else: @@ -350,6 +353,16 @@ colormode = 16 # colormode = 256 # colormode = 24bit +# By default, unicode glyphs are used. If +# you have a Nerd Font installed, you can +# enable this for a better user interface. +# You can also enable plain text glyphs if +# your terminal doesn't support unicode. + +# glyphs = plain +glyphs = unicode +# glyphs = nerdfont + # You can specify whether mouse events # should be considered as input to the # application. On by default. diff --git a/nomadnet/ui/TextUI.py b/nomadnet/ui/TextUI.py index c63167a..63b1689 100644 --- a/nomadnet/ui/TextUI.py +++ b/nomadnet/ui/TextUI.py @@ -42,6 +42,29 @@ THEMES = { ] } +GLYPHSETS = { + "plain": 1, + "unicode": 2, + "nerdfont": 3 +} + +GLYPHS = { + # Glyph name # Plain # Unicode # Nerd Font + ("check", "=", "\u2713", "\u2713"), + ("cross", "X", "\u2715", "\u2715"), + ("unknown", "?", "?", "?"), + ("lock", "E", "\U0001f512", "\uf023"), + ("unlock", "!", "\U0001f513", "\uf09c"), + ("arrow_r", "->", "\u2192", "\u2192"), + ("arrow_l", "<-", "\u2190", "\u2190"), + ("arrow_u", "/\\", "\u2191", "\u2191"), + ("arrow_d", "\\/", "\u2193", "\u2193"), + ("warning", "!", "\u26a0", "\uf12a"), + ("info", "i", "\u2139", "\ufb4d"), + ("divider1", "-", "\u2504", "\u2504"), + ("decoration_menu", "", "", " \uf93a"), +} + class TextUI: def __init__(self): @@ -65,6 +88,20 @@ class TextUI: palette = THEMES[theme] + if self.app.config["textui"]["glyphs"] == "plain": + glyphset = "plain" + elif self.app.config["textui"]["glyphs"] == "unicoode": + glyphset = "unicode" + elif self.app.config["textui"]["glyphs"] == "nerdfont": + glyphset = "nerdfont" + else: + glyphset = "unicode" + + self.glyphs = {} + for glyph in GLYPHS: + self.glyphs[glyph[0]] = glyph[GLYPHSETS[glyphset]] + + self.screen = urwid.raw_display.Screen() self.screen.register_palette(palette) diff --git a/nomadnet/ui/textui/Conversations.py b/nomadnet/ui/textui/Conversations.py index 56a98a7..c7192ec 100644 --- a/nomadnet/ui/textui/Conversations.py +++ b/nomadnet/ui/textui/Conversations.py @@ -127,6 +127,7 @@ class ConversationsDisplay(): self.columns_widget.contents[0] = (overlay, options) def edit_selected_in_directory(self): + g = self.app.ui.glyphs self.dialog_open = True source_hash_text = self.ilb.get_selected_item().source_hash display_name = self.ilb.get_selected_item().display_name @@ -195,7 +196,7 @@ class ConversationsDisplay(): source_is_known = self.app.directory.is_known(bytes.fromhex(source_hash_text)) if source_is_known: - known_section = urwid.Divider("\u2504") + known_section = urwid.Divider(g["divider1"]) else: def query_action(sender, user_data): self.close_conversation_by_hash(user_data) @@ -206,12 +207,12 @@ class ConversationsDisplay(): (urwid.Button("OK", on_press=dismiss_dialog), options) ] query_button = urwid.Button("Query network for keys", on_press=query_action, user_data=source_hash_text) - known_section = urwid.Pile([urwid.Divider("\u2504"), urwid.Text("\u2139\n", align="center"), urwid.Text("The identity of this peer is not known, and you cannot currently communicate.\n", align="center"), query_button, urwid.Divider("\u2504")]) + known_section = urwid.Pile([urwid.Divider(g["divider1"]), urwid.Text(g["info"]+"\n", align="center"), urwid.Text("The identity of this peer is not known, and you cannot currently communicate.\n", align="center"), query_button, urwid.Divider(g["divider1"])]) dialog_pile = urwid.Pile([ selected_id_widget, e_name, - urwid.Divider("\u2504"), + urwid.Divider(g["divider1"]), r_untrusted, r_unknown, r_trusted, @@ -364,8 +365,10 @@ class ConversationsDisplay(): display_name = conversation[1] source_hash = conversation[0] + g = self.app.ui.glyphs + if trust_level == DirectoryEntry.UNTRUSTED: - symbol = "\u2715" + symbol = g["cross"] style = "list_untrusted" focus_style = "list_focus_untrusted" elif trust_level == DirectoryEntry.UNKNOWN: @@ -373,15 +376,15 @@ class ConversationsDisplay(): style = "list_unknown" focus_style = "list_focus" elif trust_level == DirectoryEntry.TRUSTED: - symbol = "\u2713" + symbol = g["check"] style = "list_trusted" focus_style = "list_focus_trusted" elif trust_level == DirectoryEntry.WARNING: - symbol = "\u26A0" + symbol = g["warning"] style = "list_warning" focus_style = "list_focus" else: - symbol = "\u26A0" + symbol = g["warning"] style = "list_untrusted" focus_style = "list_focus_untrusted" @@ -471,6 +474,8 @@ class ConversationFrame(urwid.Frame): class ConversationWidget(urwid.WidgetWrap): def __init__(self, source_hash): + self.app = nomadnet.NomadNetworkApp.get_shared_instance() + g = self.app.ui.glyphs if source_hash == None: self.frame = None display_widget = urwid.LineBox(urwid.Filler(urwid.Text("\n No conversation selected"), "top")) @@ -500,7 +505,7 @@ class ConversationWidget(urwid.WidgetWrap): header = None if self.conversation.trust_level == DirectoryEntry.UNTRUSTED: - header = urwid.AttrMap(urwid.Padding(urwid.Text("\u26A0 Warning: Conversation with untrusted peer \u26A0", align="center")), "msg_warning_untrusted") + header = urwid.AttrMap(urwid.Padding(urwid.Text(g["warning"]+" Warning: Conversation with untrusted peer "+g["warning"], align="center")), "msg_warning_untrusted") self.minimal_editor = urwid.AttrMap(msg_editor, "msg_editor") self.minimal_editor.name = "minimal_editor" @@ -548,12 +553,13 @@ class ConversationWidget(urwid.WidgetWrap): self.full_editor_active = True def check_editor_allowed(self): + g = self.app.ui.glyphs if self.frame: allowed = nomadnet.NomadNetworkApp.get_shared_instance().directory.is_known(bytes.fromhex(self.source_hash)) if allowed: self.frame.contents["footer"] = (self.minimal_editor, None) else: - warning = urwid.AttrMap(urwid.Padding(urwid.Text("\u2139 You cannot currently communicate with this peer, since it's identity keys are unknown", align="center")), "msg_header_caution") + warning = urwid.AttrMap(urwid.Padding(urwid.Text(g["info"]+" You cannot currently communicate with this peer, since it's identity keys are unknown", align="center")), "msg_header_caution") self.frame.contents["footer"] = (warning, None) def toggle_focus_area(self): @@ -630,34 +636,35 @@ class ConversationWidget(urwid.WidgetWrap): class LXMessageWidget(urwid.WidgetWrap): def __init__(self, message): app = nomadnet.NomadNetworkApp.get_shared_instance() + g = app.ui.glyphs self.timestamp = message.get_timestamp() time_format = app.time_format message_time = datetime.fromtimestamp(self.timestamp) encryption_string = "" if message.get_transport_encrypted(): - encryption_string = " [\U0001F512"+str(message.get_transport_encryption())+"]" + encryption_string = " ["+g["lock"]+" "+str(message.get_transport_encryption())+"]" else: - encryption_string = " [\U0001F513"+str(message.get_transport_encryption())+"]" + encryption_string = " ["+g["unlock"]+" "+str(message.get_transport_encryption())+"]" title_string = message_time.strftime(time_format)+encryption_string if app.lxmf_destination.hash == message.lxm.source_hash: if message.lxm.state == LXMF.LXMessage.DELIVERED: header_style = "msg_header_delivered" - title_string = "\u2713 " + title_string + title_string = g["check"]+" "+title_string elif message.lxm.state == LXMF.LXMessage.FAILED: header_style = "msg_header_failed" - title_string = "\u2715 " + title_string + title_string = g["cross"]+" "+title_string else: header_style = "msg_header_sent" - title_string = "\u2192 " + title_string + title_string = g["arrow_r"]+" "+title_string else: if message.signature_validated(): header_style = "msg_header_ok" - title_string = "\u2713 " + title_string + title_string = g["check"]+" "+title_string else: header_style = "msg_header_caution" - title_string = "\u26A0 "+message.get_signature_description() + "\n " + title_string + title_string = g["warning"]+" "+message.get_signature_description() + "\n " + title_string if message.get_title() != "": title_string += " | " + message.get_title() diff --git a/nomadnet/ui/textui/Log.py b/nomadnet/ui/textui/Log.py index e9dd8d7..36c88c6 100644 --- a/nomadnet/ui/textui/Log.py +++ b/nomadnet/ui/textui/Log.py @@ -14,11 +14,6 @@ class LogDisplay(): self.app = app self.log_term = LogTerminal(self.app) - pile = urwid.Pile([ - ("weight", 90, self.log_term), - ("fixed", 1, urwid.Text(("body_text", "Log Display \U0001F332"))), - ]) - self.shortcuts_display = LogDisplayShortcuts(self.app) self.widget = urwid.LineBox(self.log_term) diff --git a/nomadnet/ui/textui/Main.py b/nomadnet/ui/textui/Main.py index a95fa0d..de0fff7 100644 --- a/nomadnet/ui/textui/Main.py +++ b/nomadnet/ui/textui/Main.py @@ -140,8 +140,9 @@ class MenuColumns(urwid.Columns): class MenuDisplay(): def __init__(self, app, handler): self.app = app + g = self.app.ui.glyphs - menu_text = ("pack", urwid.Text(" \U00002638")) + menu_text = ("pack", urwid.Text(g["decoration_menu"])) button_network = (11, MenuButton("Network", on_press=handler.show_network)) button_conversations = (17, MenuButton("Conversations", on_press=handler.show_conversations)) button_directory = (13, MenuButton("Directory", on_press=handler.show_directory)) diff --git a/nomadnet/ui/textui/Network.py b/nomadnet/ui/textui/Network.py index a2ef4d4..438b63b 100644 --- a/nomadnet/ui/textui/Network.py +++ b/nomadnet/ui/textui/Network.py @@ -8,8 +8,9 @@ from nomadnet.vendor.additional_urwid_widgets import IndicativeListBox, MODIFIER class NetworkDisplayShortcuts(): def __init__(self, app): self.app = app + g = app.ui.glyphs - self.widget = urwid.AttrMap(urwid.Text("[C-\u2191\u2193] Navigate announces"), "shortcutbar") + self.widget = urwid.AttrMap(urwid.Text("[C-"+g["arrow_u"]+g["arrow_d"]+"] Navigate announces"), "shortcutbar") class DialogLineBox(urwid.LineBox): @@ -49,6 +50,7 @@ class AnnounceInfo(urwid.WidgetWrap): def __init__(self, announce, parent, app): self.app = nomadnet.NomadNetworkApp.get_shared_instance() self.parent = self.app.ui.main_display.sub_displays.network_display + g = self.app.ui.glyphs source_hash = announce[1] time_format = app.time_format @@ -70,23 +72,23 @@ class AnnounceInfo(urwid.WidgetWrap): if trust_level == DirectoryEntry.UNTRUSTED: trust_str = "Untrusted" - symbol = "\u2715" + symbol = g["cross"] style = "list_untrusted" elif trust_level == DirectoryEntry.UNKNOWN: trust_str = "Unknown" - symbol = "?" + symbol = g["unknown"] style = "list_unknown" elif trust_level == DirectoryEntry.TRUSTED: trust_str = "Trusted" - symbol = "\u2713" + symbol = g["check"] style = "list_trusted" elif trust_level == DirectoryEntry.WARNING: trust_str = "Warning" - symbol = "\u26A0" + symbol = g["warning"] style = "list_warning" else: - trust_str = "Untrusted" - symbol = "\u26A0" + trust_str = "Warning" + symbol = g["warning"] style = "list_untrusted" def show_announce_stream(sender): @@ -118,9 +120,9 @@ class AnnounceInfo(urwid.WidgetWrap): urwid.Text("Addr : "+addr_str, align="left"), urwid.Text("Name : "+display_str, align="left"), urwid.Text(["Trust : ", (style, trust_str)], align="left"), - urwid.Divider("\u2504"), + urwid.Divider(g["divider1"]), urwid.Text(["Announce Data: \n", (data_style, data_str)], align="left"), - urwid.Divider("\u2504"), + urwid.Divider(g["divider1"]), urwid.Columns([("weight", 0.45, urwid.Button("Back", on_press=show_announce_stream)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Converse", on_press=converse))]) ]) @@ -138,28 +140,29 @@ class AnnounceStreamEntry(urwid.WidgetWrap): time_format = app.time_format dt = datetime.fromtimestamp(self.timestamp) ts_string = dt.strftime(time_format) + g = self.app.ui.glyphs trust_level = self.app.directory.trust_level(source_hash) display_str = self.app.directory.simplest_display_str(source_hash) if trust_level == DirectoryEntry.UNTRUSTED: - symbol = "\u2715" + symbol = g["cross"] style = "list_untrusted" focus_style = "list_focus_untrusted" elif trust_level == DirectoryEntry.UNKNOWN: - symbol = "?" + symbol = g["unknown"] style = "list_unknown" focus_style = "list_focus" elif trust_level == DirectoryEntry.TRUSTED: - symbol = "\u2713" + symbol = g["check"] style = "list_trusted" focus_style = "list_focus_trusted" elif trust_level == DirectoryEntry.WARNING: - symbol = "\u26A0" + symbol = g["warning"] style = "list_warning" focus_style = "list_focus" else: - symbol = "\u26A0" + symbol = g["warning"] style = "list_untrusted" focus_style = "list_focus_untrusted" @@ -268,6 +271,7 @@ class KnownNodes(urwid.WidgetWrap): def __init__(self, app): self.app = app self.node_list = app.directory.known_nodes() + g = self.app.ui.glyphs self.ilb = IndicativeListBox( self.make_node_widgets(), @@ -283,7 +287,7 @@ class KnownNodes(urwid.WidgetWrap): else: self.no_content = True widget_style = "inactive_text" - self.display_widget = urwid.Pile([urwid.Text(("warning_text", "- i -\n"), align="center"), SelectText(("warning_text", "Currently, no nodes are known\n\n"), align="center")]) + self.display_widget = urwid.Pile([urwid.Text(("warning_text", g["info"]+"\n"), align="center"), SelectText(("warning_text", "Currently, no nodes are known\n\n"), align="center")]) urwid.WidgetWrap.__init__(self, urwid.AttrMap(urwid.LineBox(self.display_widget, title="Known Nodes"), widget_style)) @@ -345,6 +349,7 @@ class LocalPeer(urwid.WidgetWrap): def __init__(self, app, parent): self.app = app self.parent = parent + g = self.app.ui.glyphs self.dialog_open = False display_name = self.app.lxmf_destination.display_name if display_name == None: @@ -364,7 +369,7 @@ class LocalPeer(urwid.WidgetWrap): urwid.Pile([ urwid.Text("\n\n\nSaved\n\n", align="center"), urwid.Button("OK", on_press=dismiss_dialog) - ]), title="i" + ]), title=g["info"] ) dialog.delegate = self bottom = self @@ -387,7 +392,7 @@ class LocalPeer(urwid.WidgetWrap): urwid.Pile([ urwid.Text("\n\n\nAnnounce Sent\n\n", align="center"), urwid.Button("OK", on_press=dismiss_dialog) - ]), title="i" + ]), title=g["info"] ) dialog.delegate = self bottom = self @@ -416,10 +421,10 @@ class LocalPeer(urwid.WidgetWrap): [ t_id, e_name, - urwid.Divider("\u2504"), + urwid.Divider(g["divider1"]), self.t_last_announce, announce_button, - urwid.Divider("\u2504"), + urwid.Divider(g["divider1"]), urwid.Columns([("weight", 0.45, urwid.Button("Save", on_press=save_query)), ("weight", 0.1, urwid.Text("")), ("weight", 0.45, urwid.Button("Node Cfg", on_press=node_settings_query))]) ] ) @@ -434,6 +439,7 @@ class NodeSettings(urwid.WidgetWrap): def __init__(self, app, parent): self.app = app self.parent = parent + g = self.app.ui.glyphs def show_peer_info(sender): options = self.parent.left_pile.options(height_type="pack", height_amount=None) @@ -441,7 +447,7 @@ class NodeSettings(urwid.WidgetWrap): widget_style = "inactive_text" pile = urwid.Pile([ - urwid.Text("- i -\n", align="center"), + urwid.Text("\n"+g["info"], align="center"), urwid.Text("\nNode Hosting currently unavailable\n\n", align="center"), urwid.Padding(urwid.Button("Back", on_press=show_peer_info), "center", "pack") ]) @@ -517,6 +523,7 @@ class NetworkDisplay(): def __init__(self, app): self.app = app + g = self.app.ui.glyphs self.known_nodes_display = KnownNodes(self.app) self.network_stats_display = NetworkStats(self.app, self) @@ -532,7 +539,7 @@ class NetworkDisplay(): ]) self.left_area = self.left_pile - self.right_area = urwid.AttrMap(urwid.LineBox(urwid.Filler(urwid.Text("Disconnected\n\u2190 \u2192", align="center"), "middle"), title="Remote Node"), "inactive_text") + self.right_area = urwid.AttrMap(urwid.LineBox(urwid.Filler(urwid.Text("Disconnected\n"+g["arrow_l"]+" "+g["arrow_r"], align="center"), "middle"), title="Remote Node"), "inactive_text") self.columns = urwid.Columns( [