""" A module that provides enhanced printing functionality with colored text and optional borders. Supports both traditional terminal output and custom GUI terminal output. """ import threading # Global terminal reference (set by the GUI app) _terminal = None _token_tracker = None _input_result = None _input_event = threading.Event() def _output(text: str, color: str = "white"): """Output text to either the GUI terminal or standard console.""" if _terminal is not None: _terminal.print(text, color) else: # Fallback to standard print with ANSI colors text_color = colors.get(color, colors['reset']) print(f"{text_color}{text}{colors['reset']}") colors = { "red": "\033[91m", "green": "\033[92m", "yellow": "\033[93m", "blue": "\033[94m", "magenta": "\033[95m", "orange": "\033[33m", "black": "\033[90m", "cyan": "\033[96m", "white": "\033[97m", "reset": "\033[0m", } def pr(x, color="red", suround=False, surround_color="red", big_text=False, surround_char="", margin=1): for i in range(margin): _output("", color) if not big_text: if suround: # Handle surround_char if surround_char: # If multiple chars, alternate them if len(surround_char) > 1: chars = list(surround_char) border_top = "" border_bottom = "" for i in range(len(x) + 4): border_top += chars[i % len(chars)] border_bottom += chars[i % len(chars)] left_char = chars[0] right_char = chars[1 % len(chars)] else: # Single char border_top = surround_char * (len(x) + 4) border_bottom = surround_char * (len(x) + 4) left_char = surround_char right_char = surround_char _output(border_top, surround_color) _output(f"{left_char} {x} {right_char}", color) _output(border_bottom, surround_color) else: # Default box drawing characters border_top = "╔" + "═" * (len(x) + 2) + "╗" border_bottom = "╚" + "═" * (len(x) + 2) + "╝" _output(border_top, surround_color) _output(f"║ {x} ║", color) _output(border_bottom, surround_color) else: _output(str(x), color) if big_text: # Unicode block font character definitions block_font = { 'A': [ " █████╗ ", "██╔══██╗", "███████║", "██╔══██║", "██║ ██║", "╚═╝ ╚═╝" ], 'B': [ "██████╗ ", "██╔══██╗", "██████╔╝", "██╔══██╗", "██████╔╝", "╚═════╝ " ], 'C': [ " ██████╗", "██╔════╝", "██║ ", "██║ ", "╚██████╗", " ╚═════╝" ], 'D': [ "██████╗ ", "██╔══██╗", "██║ ██║", "██║ ██║", "██████╔╝", "╚═════╝ " ], 'E': [ "███████╗", "██╔════╝", "█████╗ ", "██╔══╝ ", "███████╗", "╚══════╝" ], 'F': [ "███████╗", "██╔════╝", "█████╗ ", "██╔══╝ ", "██║ ", "╚═╝ " ], 'G': [ " ██████╗ ", "██╔════╝ ", "██║ ███╗", "██║ ██║", "╚██████╔╝", " ╚═════╝ " ], 'H': [ "██╗ ██╗", "██║ ██║", "███████║", "██╔══██║", "██║ ██║", "╚═╝ ╚═╝" ], 'I': [ "██╗", "██║", "██║", "██║", "██║", "╚═╝" ], 'J': [ " ██╗", " ██║", " ██║", "██ ██║", "╚█████╔╝", " ╚════╝ " ], 'K': [ "██╗ ██╗", "██║ ██╔╝", "█████╔╝ ", "██╔═██╗ ", "██║ ██╗", "╚═╝ ╚═╝" ], 'L': [ "██╗ ", "██║ ", "██║ ", "██║ ", "███████╗", "╚══════╝" ], 'M': [ "███╗ ███╗", "████╗ ████║", "██╔████╔██║", "██║╚██╔╝██║", "██║ ╚═╝ ██║", "╚═╝ ╚═╝" ], 'N': [ "███╗ ██╗", "████╗ ██║", "██╔██╗ ██║", "██║╚██╗██║", "██║ ╚████║", "╚═╝ ╚═══╝" ], 'O': [ " ██████╗ ", "██╔═══██╗", "██║ ██║", "██║ ██║", "╚██████╔╝", " ╚═════╝ " ], 'P': [ "██████╗ ", "██╔══██╗", "██████╔╝", "██╔═══╝ ", "██║ ", "╚═╝ " ], 'Q': [ " ██████╗ ", "██╔═══██╗", "██║ ██║", "██║▄▄ ██║", "╚██████╔╝", " ╚══▀▀═╝ " ], 'R': [ "██████╗ ", "██╔══██╗", "██████╔╝", "██╔══██╗", "██║ ██║", "╚═╝ ╚═╝" ], 'S': [ "███████╗", "██╔════╝", "███████╗", "╚════██║", "███████║", "╚══════╝" ], 'T': [ "████████╗", "╚══██╔══╝", " ██║ ", " ██║ ", " ██║ ", " ╚═╝ " ], 'U': [ "██╗ ██╗", "██║ ██║", "██║ ██║", "██║ ██║", "╚██████╔╝", " ╚═════╝ " ], 'V': [ "██╗ ██╗", "██║ ██║", "██║ ██║", "╚██╗ ██╔╝", " ╚████╔╝ ", " ╚═══╝ " ], 'W': [ "██╗ ██╗", "██║ ██║", "██║ █╗ ██║", "██║███╗██║", "╚███╔███╔╝", " ╚══╝╚══╝ " ], 'X': [ "██╗ ██╗", "╚██╗██╔╝", " ╚███╔╝ ", " ██╔██╗ ", "██╔╝ ██╗", "╚═╝ ╚═╝" ], 'Y': [ "██╗ ██╗", "╚██╗ ██╔╝", " ╚████╔╝ ", " ╚██╔╝ ", " ██║ ", " ╚═╝ " ], 'Z': [ "███████╗", "╚══██╔══╝", " ██╔╝ ", " ██╔╝ ", "███████╗", "╚══════╝" ], '0': [ " ██████╗ ", "██╔═████╗", "██║██╔██║", "████╔╝██║", "╚██████╔╝", " ╚═════╝ " ], '1': [ " ██╗", "███║", "╚██║", " ██║", " ██║", " ╚═╝" ], '2': [ "██████╗ ", "╚════██╗", " █████╔╝", "██╔═══╝ ", "███████╗", "╚══════╝" ], '3': [ "██████╗ ", "╚════██╗", " █████╔╝", " ╚═══██╗", "██████╔╝", "╚═════╝ " ], '4': [ "██╗ ██╗", "██║ ██║", "███████║", "╚════██║", " ██║", " ╚═╝" ], '5': [ "███████╗", "██╔════╝", "███████╗", "╚════██║", "███████║", "╚══════╝" ], '6': [ " ██████╗ ", "██╔════╝ ", "███████╗ ", "██╔═══██╗", "╚██████╔╝", " ╚═════╝ " ], '7': [ "███████╗", "╚════██║", " ██╔╝", " ██╔╝ ", " ██║ ", " ╚═╝ " ], '8': [ " ██████╗ ", "██╔═══██╗", "╚█████╔╝ ", "██╔═══██╗", "╚██████╔╝", " ╚═════╝ " ], '9': [ " ██████╗ ", "██╔═══██╗", "╚██████╔╝", " ╚════██║", " █████╔╝ ", " ╚════╝ " ], ' ': [ " ", " ", " ", " ", " ", " " ], '!': [ "██╗", "██║", "██║", "╚═╝", "██╗", "╚═╝" ], '?': [ "██████╗ ", "╚════██╗", " ▄███╔╝", " ▀▀══╝ ", " ██╗ ", " ╚═╝ " ], '.': [ " ", " ", " ", " ", "██╗", "╚═╝" ], ',': [ " ", " ", " ", " ", "▄█╗", "▀═╝" ], '-': [ " ", " ", "█████╗", "╚════╝", " ", " " ], '_': [ " ", " ", " ", " ", "███████╗", "╚══════╝" ], '/': [ " ██╗", " ██╔╝", " ██╔╝ ", " ██╔╝ ", "██╔╝ ", "╚═╝ " ], '\\': [ "██╗ ", "╚██╗ ", " ╚██╗ ", " ╚██╗ ", " ╚██╗", " ╚═╝" ], '(': [ " ██╗", "██╔╝", "██║ ", "██║ ", "╚██╗", " ╚═╝" ], ')': [ "██╗ ", "╚██╗", " ██║", " ██║", "██╔╝", "╚═╝ " ], ':': [ " ", "██╗", "╚═╝", "██╗", "╚═╝", " " ], ';': [ " ", "██╗", "╚═╝", "▄█╗", "▀═╝", " " ], '@': [ " ██████╗ ", "██╔═══██╗", "██║██╗██║", "██║██║██║", "╚█║████╔╝", " ╚╝╚═══╝ " ], '#': [ " ██╗ ██╗ ", "████████╗", "╚██╔═██╔╝", "████████╗", "╚██╔═██╔╝", " ╚═╝ ╚═╝ " ], '$': [ "▄▄███▄▄·", "██╔════╝", "███████╗", "╚════██║", "███████║", "╚═▀▀▀══╝" ], '%': [ "██╗ ██╗", "╚═╝██╔╝", " ██╔╝ ", " ██╔╝ ", "██╔╝██╗", "╚═╝ ╚═╝" ], '&': [ " ██╗ ", "██╔╝ ", "██║█████╗", "╚██╔═══╝ ", " ╚██████╗", " ╚═════╝" ], '*': [ "▄ ██╗▄", " ████╗", "▀╚██╔▀", " ╚═╝ ", " ", " " ], '+': [ " ", " ██╗ ", "██████╗", "╚═██╔═╝", " ╚═╝ ", " " ], '=': [ " ", "█████╗", "╚════╝", "█████╗", "╚════╝", " " ], } # Convert text to uppercase and get characters text = str(x).upper() lines = ["", "", "", "", "", ""] for char in text: if char in block_font: char_lines = block_font[char] for i in range(6): lines[i] += char_lines[i] else: # For unsupported characters, use a placeholder for i in range(6): lines[i] += " " # Apply color text_color = colors.get(color, colors['reset']) # Handle surround for big text if suround: border_color = colors.get(surround_color, colors['reset']) # Calculate max width of the big text max_width = max(len(line) for line in lines) # Handle surround_char if surround_char: # If multiple chars, alternate them if len(surround_char) > 1: chars = list(surround_char) border_top = "" border_bottom = "" for i in range(max_width + 4): border_top += chars[i % len(chars)] border_bottom += chars[i % len(chars)] left_char = chars[0] right_char = chars[1 % len(chars)] else: # Single char border_top = surround_char * (max_width + 4) border_bottom = surround_char * (max_width + 4) left_char = surround_char right_char = surround_char else: # Default box drawing characters border_top = "╔" + "═" * (max_width + 2) + "╗" border_bottom = "╚" + "═" * (max_width + 2) + "╝" left_char = "║" right_char = "║" # Print with border _output(border_top, surround_color) # Join all lines and output as a single block for proper alignment ascii_block = '\n'.join(f"{left_char} {line.ljust(max_width)} {right_char}" for line in lines) _output(ascii_block, color) _output(border_bottom, surround_color) else: # Print without border - join all lines as single block ascii_block = '\n'.join(lines) _output(ascii_block, color) for i in range(margin): _output("", color) def inp(prompt, color="red", margin=1): """Get input from the user, using GUI terminal if available.""" global _input_result for i in range(margin): _output("", color) if _terminal is not None: # Use the GUI terminal's input system _input_event.clear() _input_result = None def on_input(user_input): global _input_result _input_result = user_input _input_event.set() _terminal.set_input_callback(on_input, prompt, color) _input_event.wait() for i in range(margin): _output("", color) return _input_result else: # Fallback to standard input text_color = colors.get(color, colors['reset']) user_input = input(f"{text_color}{prompt}{colors['reset']}") for i in range(margin): print() return user_input