import os from graphics.colors import Colors class Layer: def __init__(self, screen, z_index): self.frame = {} self.z_index = z_index self.x = screen.x self.y = screen.y def clear(self): self.frame = {} def put_char(self, char, x, y, colors=[]): if x > self.x or x < 0 or y > self.y or y < 0: raise ValueError("out of range pixel") self.frame[(x, y)] = "".join(colors) + char + Colors.RESET def put_string(self, string, x, y, colors=[]): if x > self.x or x < 0 or y > self.y or y < 0: raise ValueError("out of range pixel") string = string.split("\n") for string_y in range(len(string)): for string_x in range(len(string[string_y])): self.frame[(x+string_x, y+string_y)] = "".join(colors) + string[string_y][string_x] + Colors.RESET def rect(self, x1, y1, x2, y2, colors=[], template=' '): if (x1 > self.x or x1 < 0 or y1 > self.y or y1 < 0) or (x2 > self.x or x2 < 0 or y2 > self.y or y2 < 0): raise ValueError("out of range pixel") if len(template) > 1: raise ValueError("template should be 1 char long") for x in range(x1, x2+1): for y in range(y1, y2+1): self.frame[(x, y)] = "".join(colors) + template + Colors.RESET class Screen: def __init__(self): size = os.get_terminal_size() self.x = size.columns self.y = size.lines - 2 self.frame = {} self.__layers = {} self.handlers = [] def set_layer(self, name, layer: Layer): self.__layers[name] = layer def __combine_layers(self): self.frame = {} layers = sorted(self.__layers.values(), key=lambda layer: layer.z_index) for layer in layers: self.frame.update(layer.frame) def draw(self): self.__combine_layers() content = "" for y in range(self.y): for x in range(self.x): if (x, y) in self.frame: content += self.frame[(x, y)] else: content += " " content += "\n" print("\033[H\033[J", end="") print(content) def add_key_handler(self, handler): self.handlers.append(handler) def send_key(self, key): for handler in self.handlers: handler(key)