Skip to content

Instantly share code, notes, and snippets.

@lukassup
Created June 11, 2016 23:36
Show Gist options
  • Save lukassup/bd556a6a38732fbd6a3ce1436c317d44 to your computer and use it in GitHub Desktop.
Save lukassup/bd556a6a38732fbd6a3ce1436c317d44 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import curses
import sys
def curses_wrapper(func, *args, **kwds):
"""Wrapper decorator that initializes curses and calls another function,
restoring normal keyboard/screen behavior on error or exit.
See curses.wrapper() for more info.
"""
def decorated(*args, **kwds):
try:
screen = curses.initscr()
curses.noecho()
curses.cbreak()
screen.keypad(1)
try:
curses.start_color()
except:
pass
return func(screen, *args, **kwds)
finally:
if 'screen' in locals():
screen.keypad(0)
curses.echo()
curses.nocbreak()
curses.endwin()
return decorated
def make_win(*args, width=2, height=2, pos_x=0, pos_y=0):
"""Wrapper to fix coordinate order in curses.newwin()"""
# Enable "WxH" shortcut string
if len(args) == 1 and "x" in args[0].lower():
width, height = map(int, args[0].split("x"))
return curses.newwin(height, width, pos_y, pos_x)
def dialog(screen, *args, title=None, message=None, shadow=True, **kwargs):
"""Build dialog boxes centered on screen
:screen: base screen on which to center dialog
:title: dialog title text
:message: dialog message text
"""
# Set up window dimensions
height = kwargs.get("height", 8)
width = kwargs.get("width", 32)
max_h, max_w = screen.getmaxyx()
x_offset = (max_w - width) // 2
y_offset = (max_h - height) // 2
# Draw shadow
if shadow:
shadow = make_win(
*args,
width=width,
height=height,
pos_x=x_offset+1,
pos_y=y_offset+1,
**kwargs
)
shadow.bkgd(" ", curses.color_pair(1))
window = make_win(
*args,
width=width,
height=height,
pos_x=x_offset,
pos_y=y_offset,
**kwargs
)
window.bkgd(" ", curses.color_pair(3))
window.box()
# Place message in a subwindow for proper text wrap
sub_win = window.derwin(height - 2, width - 2, 1, 1)
if title:
# Center title
title_x_offset = (width - len(title)) // 2
window.addstr(0, title_x_offset, title)
if message:
sub_win.addstr(0, 0, message)
return window, ( shadow if shadow else None )
@curses_wrapper
def main(screen):
"""Main curses function
:screen: screen provided by the wrapper decorator
"""
# Setup some colors
curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_BLUE)
curses.init_pair(3, curses.COLOR_BLACK, curses.COLOR_MAGENTA)
# Initialize screen
screen.bkgd(" ", curses.color_pair(2))
screen.clear()
screen.refresh()
win, wsh = dialog(
screen,
title="MS-DOS",
message="Microsoft MS-DOS 7.10 Setup\n\nPlease wait...")
wsh.refresh()
win.refresh()
screen.getkey()
sys.exit(0)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment