import sys import shutil class Menu: def __init__(self, items, cursor=0, head={}): self.head = head self.items = items self.cursor = cursor self.marked = [] self.draw() def setHead(self, head): self.head = head self.draw() def setItems(self, items, cursor=0): self.__init__(items, cursor) def toggleMark(self): if self.cursor in self.marked: self.marked.remove(self.cursor) else: self.marked.append(self.cursor) self.draw() def setMarked(self, marked): self.marked = [i for i in range(len(self.items)) if self.items[i] in marked] self.draw() def isCurrentMarked(self): return self.cursor in self.marked def isMarked(self, item): return item in [self.items[i] for i in self.marked] def next(self): self.cursor += 1 if self.cursor >= len(self.items): self.cursor = len(self.items) - 1 self.draw() def prev(self): self.cursor -= 1 if self.cursor < 0: self.cursor = 0 self.draw() def selected(self): return self.items[self.cursor] def draw(self): size = shutil.get_terminal_size((80, 20)) w = size[0] # Heading for i in range(size[1]): sys.stdout.write(f'\x1b[{i + 1};{w//2 + 1}H'+' '*(w//2)) for row, key in enumerate(self.head): sys.stdout.write(f'\x1b[{row + 1};{w//2 + 1}H {key}: {self.head[key][:w//2 - len(key) - 3]}\x1b[0m') offset = len(self.head) + 2 if offset == 2: offset = 1 h = size[1] - offset first = 0 if len(self.items) > h: if self.cursor > (h - offset)/2: first = self.cursor - h//2 - 1 if first < 0: first = 0 elif len(self.items) - first < h + 1: first = len(self.items) - h - 1 for row, item in enumerate(self.items[first:h + first + 1]): mark = '\x1b[44m+' if row + first in self.marked else ' ' text = mark+item[:w//2 - 1]+' '*(w//2 - 1 - len(item)) if self.cursor == row + first: sys.stdout.write(f'\x1b[{row + offset};{w//2 + 1}H\x1b[7m{text}\x1b[0m') else: sys.stdout.write(f'\x1b[{row + offset};{w//2 + 1}H{text}\x1b[0m')