From ee132d30216eba432ea2e745563a8bf30deb2ec7 Mon Sep 17 00:00:00 2001 From: BarsTiger Date: Mon, 22 Nov 2021 21:44:37 +0200 Subject: [PATCH] Created --- README.md | 59 +++++++++++++++++++++++++ __init__.py | 0 ezztui.py | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 14 ++++++ test.py | 56 ++++++++++++++++++++++++ 5 files changed, 251 insertions(+) create mode 100644 README.md create mode 100644 __init__.py create mode 100644 ezztui.py create mode 100644 setup.py create mode 100644 test.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee2aad8 --- /dev/null +++ b/README.md @@ -0,0 +1,59 @@ +## Usage + +```python +import ezztui +ezztui.check_curses() # check and install windows-curses, if on windows +menu = { + 'First menu': + {'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Function 3': 'ezztui_return_value', + 'Function 4': 'ezztui_return_value', + 'Function 5': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + + 'Second menu': + {'Submenu 1': { + 'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Function 3': 'ezztui_return_value', + 'Function 4': 'ezztui_return_value', + 'Function 5': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + 'Submenu 2': { + 'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Function 3': 'ezztui_return_value', + 'Function 4': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + 'Submenu 3': { + 'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Function 3': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + 'Submenu 4': { + 'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + 'Back': 'ezztui_back_value'}, + + 'No submenu function': 'ezztui_return_value', + + 'Third menu': + {'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Function 3': 'ezztui_return_value', + 'Function 4': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + + 'Exit': + {"Exit": 'ezztui_exit_value', + "Back": 'ezztui_back_value'} +} + +``` + +## Returns +``` +['Second menu', 'Submenu 2', 'Function 3'] +``` \ No newline at end of file diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ezztui.py b/ezztui.py new file mode 100644 index 0000000..d87a454 --- /dev/null +++ b/ezztui.py @@ -0,0 +1,122 @@ +import os +def check_curses(): + import subprocess, sys + try: + import curses + except: + subprocess.check_call([sys.executable, "-m", "pip", "install", 'windows-curses']) + import curses + +try: + import curses +except: + check_curses() + +def cls(): + os.system('cls' if os.name == 'nt' else 'clear') + +def softcls(): + print("\n" * (os.get_terminal_size().lines * 2)) + +def print_center(text: str): + def glstdscr(stdscr): + return stdscr + stdscr = curses.wrapper(glstdscr) + stdscr.clear() + h, w = stdscr.getmaxyx() + x = w//2 - len(text)//2 + y = h//2 + stdscr.addstr(y, x, text) + stdscr.refresh() + +def center_message(text: str): + print("\n" * (os.get_terminal_size().lines // 2 - 2)) + print(" " * ((os.get_terminal_size().columns//2 - (len(text)//2)) - 1) + text) + print("\n" * (os.get_terminal_size().lines // 2 - 2)) + input() + cls() + +def center_multiline(text: list): + print("\n" * ((os.get_terminal_size().lines // 2 - (len(text) // 2)) - 1)) + for line in text: + print(" " * ((os.get_terminal_size().columns//2 - (len(line)//2)) - 1) + line) + print("\n" * ((os.get_terminal_size().lines // 2 - (len(text) // 2)) - 2)) + input() + cls() + +def menu(menulist: dict): + def print_menu(stdscr, selected_row_idx, menu): + stdscr.clear() + h, w = stdscr.getmaxyx() + for idx, row in enumerate(menu): + x = w//2 - len(row)//2 + y = h//2 - len(menu)//2 + idx + if idx == selected_row_idx: + stdscr.attron(curses.color_pair(1)) + stdscr.addstr(y, x, row) + stdscr.attroff(curses.color_pair(1)) + else: + stdscr.addstr(y, x, row) + stdscr.refresh() + + global doing + doing = 0 + global menupath + menupath = [] + global currentmenu + currentmenu= menulist + global returning + returning = None + + def mainmenu(stdscr): + global doing + global currentmenu + global menupath + global returning + curses.curs_set(0) + curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE) + current_row = 0 + + print_menu(stdscr, current_row, currentmenu) + + while True: + key = stdscr.getch() + + if key == curses.KEY_UP and current_row > 0: + current_row -= 1 + elif key == curses.KEY_UP and current_row == 0: + current_row = len(currentmenu)-1 + elif key == curses.KEY_DOWN and current_row < len(currentmenu)-1: + current_row += 1 + elif key == curses.KEY_DOWN and current_row == len(currentmenu) - 1: + current_row = 0 + + elif key == curses.KEY_ENTER or key in [10, 13] and isinstance(currentmenu[list(currentmenu.keys())[current_row]], dict): + menupath.append(list(currentmenu)[current_row]) + currentmenu = currentmenu[list(currentmenu.keys())[current_row]] + break + + elif key == curses.KEY_ENTER or key in [10, 13] and currentmenu[list(currentmenu.keys())[current_row]] == 'ezztui_return_value': + menupath.append(list(currentmenu)[current_row]) + returning = menupath + break + + elif key == curses.KEY_BACKSPACE or str(key) in ['KEY_BACKSPACE', '8', '127'] or currentmenu[list(currentmenu.keys())[current_row]] == 'ezztui_back_value': + menupath = menupath[:-1:] + try: + currentmenu = menulist[list(menupath)[0]] + for i in menupath[1:]: + currentmenu = menulist[i] + except: + currentmenu = menulist + mainmenu(stdscr) + break + + elif key == curses.KEY_ENTER or key in [10, 13] and currentmenu[list(currentmenu.keys())[current_row]] == 'ezztui_exit_value': + exit() + + print_menu(stdscr, current_row, currentmenu) + + while returning is None: + curses.wrapper(mainmenu) + return returning diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..ff83895 --- /dev/null +++ b/setup.py @@ -0,0 +1,14 @@ +from setuptools import setup + +with open("README.md", "r") as fh: + long_description = fh.read() + +setup( + name="ezztui", + version="1.0.0", + scripts=["ezztui"], + author="BarsTiger", + description="Easy TextUI creating package", + long_description=long_description, + +) \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000..41b23b6 --- /dev/null +++ b/test.py @@ -0,0 +1,56 @@ +import ezztui +ezztui.check_curses() +# ezztui.center_message("Hello World!") +# ezztui.center_multiline(["Hello", "multiline", "world!"]) + +menu = { + 'First menu': + {'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Function 3': 'ezztui_return_value', + 'Function 4': 'ezztui_return_value', + 'Function 5': 'ezztui_return_value', + 'Function 6': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + + 'Second menu': + {'Submenu 1': { + 'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Function 3': 'ezztui_return_value', + 'Function 4': 'ezztui_return_value', + 'Function 5': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + 'Submenu 2': { + 'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Function 3': 'ezztui_return_value', + 'Function 4': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + 'Submenu 3': { + 'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Function 3': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + 'Submenu 4': { + 'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + 'Back': 'ezztui_back_value'}, + + 'No submenu function': 'ezztui_return_value', + + 'Third menu': + {'Function 1': 'ezztui_return_value', + 'Function 2': 'ezztui_return_value', + 'Function 3': 'ezztui_return_value', + 'Function 4': 'ezztui_return_value', + 'Back': 'ezztui_back_value'}, + + 'Exit': + {"Exit": 'ezztui_exit_value', + "Back": 'ezztui_back_value'} +} + +print(ezztui.menu(menu)) +input()