50 lines
No EOL
1.7 KiB
Python
50 lines
No EOL
1.7 KiB
Python
import curses
|
|
from typing import List, Tuple, Callable, Any
|
|
|
|
class Application:
|
|
def __init__(self):
|
|
# Initialise curses
|
|
self.__curses = curses.initscr()
|
|
self.__curses.keypad(True)
|
|
|
|
curses.start_color() # todo: check for colour support
|
|
curses.cbreak()
|
|
curses.noecho()
|
|
|
|
# Default colours
|
|
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK) # default
|
|
curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_WHITE) # selected
|
|
|
|
def selectMenu(self, options: List[Tuple[str, Callable[[], Any]]]):
|
|
selectedIndex = 0
|
|
optionCount = len(options)
|
|
screen = self.__curses
|
|
|
|
while True:
|
|
screen.clear()
|
|
screen.addstr("Pick an option:\n\n", curses.A_BOLD)
|
|
|
|
for i in range(optionCount):
|
|
colour = curses.color_pair(2) if i == selectedIndex else curses.color_pair(1)
|
|
screen.addstr(f"{i + 1}. ")
|
|
screen.addstr(f"{options[i][0]}\n", colour)
|
|
|
|
c = screen.getch()
|
|
|
|
if c in [curses.KEY_UP, curses.KEY_LEFT]:
|
|
selectedIndex = (selectedIndex + optionCount - 1) % optionCount
|
|
elif c in [curses.KEY_DOWN, curses.KEY_RIGHT]:
|
|
selectedIndex = (selectedIndex + 1) % optionCount
|
|
elif c == curses.KEY_ENTER or chr(c) in '\n\r':
|
|
break
|
|
|
|
options[selectedIndex][1]()
|
|
|
|
def quit(self):
|
|
curses.nocbreak()
|
|
self.__curses.keypad(False)
|
|
curses.echo()
|
|
curses.endwin()
|
|
|
|
app = Application()
|
|
app.selectMenu([("yes", lambda: (app.quit(),print("i dont think so"))), ("no", lambda: (app.quit(), print("no need to be a cynic")))]) |