diff --git a/Menu.py b/Menu.py index 337b56f..5c64679 100644 --- a/Menu.py +++ b/Menu.py @@ -1,4 +1,6 @@ import os; +import re +import colorama def render(pos: int, min: int, max: int, render_distance: int, elements: list): start = pos - render_distance; @@ -23,16 +25,31 @@ def render(pos: int, min: int, max: int, render_distance: int, elements: list): def preview_formater(title: str, body: str, size_x: int, size_y: int): out: str = ""; - out += f"┌── {title} " + "─" * (size_x - 6 - len(title)) + "┐\n" + out += f"┌── {title} " + "─" * (size_x - 6 - printable_len(title)) + "┐\n" lines = body.split("\n"); for line in lines[:size_y - 2]: - out += f"│ {line[: size_x - 3]}" + " " * (size_x - 3 - len(line)) + "│\n" + out += f"│ {line[: size_x - 3]}" + " " * (size_x - 3 - printable_len(line)) + "│\n" out += "└" + "─" * (size_x - 2) + "┘" return (out); +strip_ANSI_pat = re.compile(r""" +\x1b # literal ESC +\[ # literal [ +[;\d]* # zero or more digits or semicolons +[A-Za-z] # a letter +""", re.VERBOSE).sub + +def printable_len(string: str): + mid = strip_ANSI_pat("", string) + out = 0; + for char in mid: + if (char.isprintable()): + out += 1; + return (out); + class Menu(): - def __init__(self, options: list, title: str = None, cursor: str = "> ", cursor_pos: int = 0, preview_body_function = None, preview_title_function = None, preview_args: list = None, preview_ratio: float = 0.5, circular: bool = True, skip_empty_option: bool = False, quit_button: bool = False): + def __init__(self, options: list, title: str = None, cursor: str = colorama.Back.WHITE + colorama.Fore.BLACK, cursor_pos: int = 0, preview_body_function = None, preview_title_function = None, preview_args: list = None, preview_ratio: float = 0.5, circular: bool = True, skip_empty_option: bool = False, quit_button: bool = False): self.options = options; self.title = title; self.cursor = cursor; @@ -49,6 +66,7 @@ class Menu(): self.size = len(options) self.preview_ratio = preview_ratio; self._nb_printed_lines = 0; + self.cursor_size = printable_len(cursor) def _up(self): if (self.circular == False): @@ -57,8 +75,7 @@ class Menu(): else: self.cursor_pos = (self.cursor_pos - 1) % self.size; if (self.skip_empty_option == True): - if (self.options[self.cursor_pos] == None - or self.options[self.cursor_pos] == ""): + if (printable_len(self.options[self.cursor_pos]) == 0): self._up() self.cursor_pos_x = 0; @@ -69,8 +86,7 @@ class Menu(): else: self.cursor_pos = (self.cursor_pos + 1) % self.size; if (self.skip_empty_option == True): - if (self.options[self.cursor_pos] == None - or self.options[self.cursor_pos] == ""): + if (printable_len(self.options[self.cursor_pos]) == 0): self._down() self.cursor_pos_x = 0; @@ -122,10 +138,10 @@ class Menu(): size_x, size_x // 2, option) - line = self.cursor + element[min_x:max_x] + line = self.cursor + element[self.cursor_pos_x:size_x - self.cursor_size + self.cursor_pos_x] else: - line = " " * len(self.cursor) + element - line = line[:size_x - len(self.cursor)] + "\n" + line = " " * self.cursor_size + element[:size_x - self.cursor_size] + line = line + colorama.Style.RESET_ALL + "\n" menu = menu + line; menu = menu[:-1] self._display_screen(menu + "\n" + preview)