#!/home/sietse/anaconda3/bin/python3.6
import curses
from pprint import pformat
TASKS = [
'Workrave',
'Bril',
'Methylfenidaat',
'Check diary today',
'Check diary 5 days',
'Read todo.txt',
]
def color_pair(id, fg, bg):
"""Combine defining a colour pair and returning its reference"""
curses.init_pair(id, fg, bg)
return curses.color_pair(id)
class TerminalAndStyles:
"""Context manager: initialize terminal for curses and reset on exit"""
def __init__(self):
pass
def __enter__(self):
self.main_t = curses.initscr()
self.t = curses.newwin(curses.LINES - 3, curses.COLS - 8, 3, 8)
curses.start_color()
curses.noecho()
curses.cbreak()
curses.curs_set(False)
self.t.keypad(True)
self.styles = {
'plain': curses.color_pair(0),
'selected': color_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE),
}
return self.t, self.styles
def __exit__(self, type, value, traceback):
curses.endwin()
return False # reraise if needed
def update(state, key):
OS, NS = state, state.copy() # Old state and New State
NS = state.copy()
if key == 'KEY_UP':
NS['current_task_id'] = (OS['current_task_id'] - 1) % len(state['tasks'])
elif key == 'KEY_DOWN':
NS['current_task_id'] = (OS['current_task_id'] + 1) % len(state['tasks'])
elif key == ' ':
checked, desc = OS['tasks'][OS['current_task_id']]
NS['tasks'][OS['current_task_id']] = not checked, desc
elif key == 'q':
NS['running'] = False
return NS
def checkbox(checked):
return '[x]' if checked else '[ ]'
def view(state, t, styles) -> None:
curses.update_lines_cols()
for i, (checked, task) in enumerate(state['tasks']):
if i == state['current_task_id']:
style = styles['selected']
else:
style = styles['plain']
t.addstr(i, 0, f'- {checkbox(checked)} {task}', style)
t.addstr(i + 2, 0, pformat(state), styles['plain'])
def run(t, styles):
state = {
'tasks': [(False, t) for t in TASKS],
'current_task_id': 0,
'running': True,
}
view(state, t, styles)
while True:
key = t.getkey()
state = update(state, key)
view(state, t, styles)
if not state['running']:
break
def main():
with TerminalAndStyles() as (t, styles):
run(t, styles)
if __name__ == '__main__':
main()