fix: len is now based on printable size and not on the nb of chars old: 'bozo\n\n' -> 6 now: -> 4

This commit is contained in:
starnakin 2023-05-29 18:50:23 +02:00
parent 4d85721b8a
commit a546c0ffa4

36
Menu.py
View File

@ -1,4 +1,6 @@
import os; import os;
import re
import colorama
def render(pos: int, min: int, max: int, render_distance: int, elements: list): def render(pos: int, min: int, max: int, render_distance: int, elements: list):
start = pos - render_distance; 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): def preview_formater(title: str, body: str, size_x: int, size_y: int):
out: str = ""; 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"); lines = body.split("\n");
for line in lines[:size_y - 2]: 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) + "" out += "" + "" * (size_x - 2) + ""
return (out); 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(): 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.options = options;
self.title = title; self.title = title;
self.cursor = cursor; self.cursor = cursor;
@ -49,6 +66,7 @@ class Menu():
self.size = len(options) self.size = len(options)
self.preview_ratio = preview_ratio; self.preview_ratio = preview_ratio;
self._nb_printed_lines = 0; self._nb_printed_lines = 0;
self.cursor_size = printable_len(cursor)
def _up(self): def _up(self):
if (self.circular == False): if (self.circular == False):
@ -57,8 +75,7 @@ class Menu():
else: else:
self.cursor_pos = (self.cursor_pos - 1) % self.size; self.cursor_pos = (self.cursor_pos - 1) % self.size;
if (self.skip_empty_option == True): if (self.skip_empty_option == True):
if (self.options[self.cursor_pos] == None if (printable_len(self.options[self.cursor_pos]) == 0):
or self.options[self.cursor_pos] == ""):
self._up() self._up()
self.cursor_pos_x = 0; self.cursor_pos_x = 0;
@ -69,8 +86,7 @@ class Menu():
else: else:
self.cursor_pos = (self.cursor_pos + 1) % self.size; self.cursor_pos = (self.cursor_pos + 1) % self.size;
if (self.skip_empty_option == True): if (self.skip_empty_option == True):
if (self.options[self.cursor_pos] == None if (printable_len(self.options[self.cursor_pos]) == 0):
or self.options[self.cursor_pos] == ""):
self._down() self._down()
self.cursor_pos_x = 0; self.cursor_pos_x = 0;
@ -122,10 +138,10 @@ class Menu():
size_x, size_x,
size_x // 2, size_x // 2,
option) 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: else:
line = " " * len(self.cursor) + element line = " " * self.cursor_size + element[:size_x - self.cursor_size]
line = line[:size_x - len(self.cursor)] + "\n" line = line + colorama.Style.RESET_ALL + "\n"
menu = menu + line; menu = menu + line;
menu = menu[:-1] menu = menu[:-1]
self._display_screen(menu + "\n" + preview) self._display_screen(menu + "\n" + preview)