diff --git a/settings.py b/settings.py index b2cab6c..cab2169 100644 --- a/settings.py +++ b/settings.py @@ -5,12 +5,14 @@ from save_to_radio import settings_factory_reset, settings_reboot, settings_rese from ui.menus import generate_menu_from_protobuf from input_handlers import get_bool_selection, get_repeated_input, get_user_input, get_enum_input, get_fixed32_input from save_to_radio import save_changes +from ui.colors import setup_colors import logging def display_menu(current_menu, menu_path, selected_index, show_save_option): global menu_win + # Calculate the dynamic height based on the number of menu items num_items = len(current_menu) + (1 if show_save_option else 0) # Add 1 for the "Save Changes" option if applicable height = min(curses.LINES - 2, num_items + 5) # Ensure the menu fits within the terminal height @@ -34,14 +36,17 @@ def display_menu(current_menu, menu_path, selected_index, show_save_option): for idx, option in enumerate(current_menu): field_info = current_menu[option] current_value = field_info[1] if isinstance(field_info, tuple) else "" - display_option = f"{option}"[:width // 2 - 2] # Truncate option name if too long + display_option = f"{option}"[:width // 2 - 2] # Truncate option name if too long`` display_value = f"{current_value}"[:width // 2 - 4] # Truncate value if too long try: + # Use red color for "Reboot" or "Shutdown" + color = curses.color_pair(5) if option in ["Reboot", "Reset Node DB", "Shutdown", "Factory Reset"] else curses.color_pair(1) + if idx == selected_index: - menu_win.addstr(idx + 3, 4, f"{display_option:<{width // 2 - 2}} {display_value}", curses.A_REVERSE) + menu_win.addstr(idx + 3, 4, f"{display_option:<{width // 2 - 2}} {display_value}", curses.A_REVERSE | color) else: - menu_win.addstr(idx + 3, 4, f"{display_option:<{width // 2 - 2}} {display_value}") + menu_win.addstr(idx + 3, 4, f"{display_option:<{width // 2 - 2}} {display_value}", color) except curses.error: pass @@ -50,9 +55,9 @@ def display_menu(current_menu, menu_path, selected_index, show_save_option): save_option = "Save Changes" save_position = height - 2 if selected_index == len(current_menu): - menu_win.addstr(save_position, (width - len(save_option)) // 2, save_option, curses.A_REVERSE) + menu_win.addstr(save_position, (width - len(save_option)) // 2, save_option, curses.color_pair(2) | curses.A_REVERSE) else: - menu_win.addstr(save_position, (width - len(save_option)) // 2, save_option) + menu_win.addstr(save_position, (width - len(save_option)) // 2, save_option, curses.color_pair(2)) menu_win.refresh() @@ -64,7 +69,6 @@ def settings_menu(sdscr, interface): selected_index = 0 modified_settings = {} - while True: options = list(current_menu.keys()) @@ -229,7 +233,7 @@ def main(stdscr): level=logging.INFO, # DEBUG, INFO, WARNING, ERROR, CRITICAL) format="%(asctime)s - %(levelname)s - %(message)s" ) - + setup_colors() curses.curs_set(0) stdscr.keypad(True) diff --git a/ui/colors.py b/ui/colors.py new file mode 100644 index 0000000..d8ccf74 --- /dev/null +++ b/ui/colors.py @@ -0,0 +1,9 @@ +import curses + +def setup_colors(): + curses.start_color() + curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK) + curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK) + curses.init_pair(3, curses.COLOR_CYAN, curses.COLOR_BLACK) + curses.init_pair(4, curses.COLOR_YELLOW, curses.COLOR_BLACK) + curses.init_pair(5, curses.COLOR_RED, curses.COLOR_BLACK) \ No newline at end of file diff --git a/ui/curses_ui.py b/ui/curses_ui.py index b6f5302..ff30193 100644 --- a/ui/curses_ui.py +++ b/ui/curses_ui.py @@ -5,7 +5,7 @@ from utilities.utils import get_name_from_number, get_channels from settings import settings_menu from message_handlers.tx_handler import send_message, send_traceroute import ui.dialog - +from ui.colors import setup_colors def add_notification(channel_number): handle_notification(channel_number, add=True) @@ -36,8 +36,7 @@ def draw_debug(value): function_win.refresh() def draw_splash(stdscr): - curses.start_color() - curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLACK) # Green text on black background + setup_colors() curses.curs_set(0) stdscr.clear() @@ -50,9 +49,9 @@ def draw_splash(stdscr): start_x = width // 2 - len(message_1) // 2 start_x2 = width // 2 - len(message_4) // 2 start_y = height // 2 - 1 - stdscr.addstr(start_y, start_x, message_1, curses.color_pair(1) | curses.A_BOLD) - stdscr.addstr(start_y+1, start_x-1, message_2, curses.color_pair(1) | curses.A_BOLD) - stdscr.addstr(start_y+2, start_x-2, message_3, curses.color_pair(1) | curses.A_BOLD) + stdscr.addstr(start_y, start_x, message_1, curses.color_pair(2) | curses.A_BOLD) + stdscr.addstr(start_y+1, start_x-1, message_2, curses.color_pair(2) | curses.A_BOLD) + stdscr.addstr(start_y+2, start_x-2, message_3, curses.color_pair(2) | curses.A_BOLD) stdscr.addstr(start_y+4, start_x2, message_4) stdscr.box() stdscr.refresh() @@ -78,10 +77,10 @@ def draw_channel_list(): truncated_channel = channel[:win_width - 5] + '-' if len(channel) > win_width - 5 else channel if i < win_height - 2 : # Check if there is enough space in the window if start_index + i == globals.selected_channel and globals.current_window == 0: - channel_win.addstr(i + 1, 1, truncated_channel + notification, curses.color_pair(3)) + channel_win.addstr(i + 1, 1, truncated_channel + notification, curses.color_pair(1) | curses.A_REVERSE) remove_notification(globals.selected_channel) else: - channel_win.addstr(i + 1, 1, truncated_channel + notification, curses.color_pair(4)) + channel_win.addstr(i + 1, 1, truncated_channel + notification, curses.color_pair(1)) channel_win.box() channel_win.refresh() @@ -133,9 +132,9 @@ def draw_messages_window(): for line in wrapped_lines: # Highlight the row if it's the selected message if index == globals.selected_message and globals.current_window == 1: - color = curses.color_pair(3) # Highlighted row color + color = curses.A_REVERSE # Highlighted row color else: - color = curses.color_pair(1) if prefix.startswith(globals.sent_message_prefix) else curses.color_pair(2) + color = curses.color_pair(4) if prefix.startswith(globals.sent_message_prefix) else curses.color_pair(3) messages_win.addstr(row, 1, line, color) row += 1 @@ -153,9 +152,9 @@ def draw_node_list(): for i, node in enumerate(globals.node_list[start_index:], start=1): if i < win_height - 1 : # Check if there is enough space in the window if globals.selected_node + 1 == start_index + i and globals.current_window == 2: - nodes_win.addstr(i, 1, get_name_from_number(node, "long"), curses.color_pair(3)) + nodes_win.addstr(i, 1, get_name_from_number(node, "long"), curses.color_pair(1) | curses.A_REVERSE) else: - nodes_win.addstr(i, 1, get_name_from_number(node, "long"), curses.color_pair(4)) + nodes_win.addstr(i, 1, get_name_from_number(node, "long"), curses.color_pair(1)) nodes_win.box() nodes_win.refresh() @@ -246,14 +245,6 @@ def main_ui(stdscr): stdscr.keypad(True) get_channels() - # Initialize colors - curses.start_color() - curses.init_pair(1, curses.COLOR_CYAN, curses.COLOR_BLACK) - curses.init_pair(2, curses.COLOR_YELLOW, curses.COLOR_BLACK) - curses.init_pair(3, curses.COLOR_BLACK, curses.COLOR_WHITE) - curses.init_pair(4, curses.COLOR_WHITE, curses.COLOR_BLACK) - curses.init_pair(5, curses.COLOR_RED, curses.COLOR_BLACK) - # Calculate window max dimensions height, width = stdscr.getmaxyx() diff --git a/ui/dialog.py b/ui/dialog.py index b7c215c..7a062d5 100644 --- a/ui/dialog.py +++ b/ui/dialog.py @@ -25,7 +25,7 @@ def dialog(stdscr, title, message): win.addstr(2 + i, 2, l) # Add button - win.addstr(dialog_height - 2, (dialog_width - 4) // 2, " Ok ", curses.color_pair(3)) + win.addstr(dialog_height - 2, (dialog_width - 4) // 2, " Ok ", curses.color_pair(1) | curses.A_REVERSE) # Refresh dialog window win.refresh()