############################################
# 1. how to start curses #
############################################
if False: # some dummy code...
# makes terminal go into curses mode,
# `stdscr` is a curses window.
stdscr = curses.initscr()
# makes text not be echoed in the window
curses.noecho()
# makes curses respond to character input
# immediately (ie. don't have to press ENTER)
curses.cbreak()
curses.nocbreak()
### also there is stuff that has to do with
### restarting the terminal in non-curses mode
### after the program is finished (because the
### terminal will be all messed-up otherwise).
###
### but... we don't have to worry about any of
### that because we are using `curses.wrapper`
############################################
# 2. a curses program #
############################################
# this function definition contains an actual curses program.
def the_program(stdscr):
"""
intended to be used as Callable
argument to curses.wrapper()
"""
curses.noecho()
curses.cbreak()
# making the cursor invisible
CURSOR_VISIBILITY = {
"invisible": 0,
"visibile": 1,
"very_visible": 2
}
curses.curs_set(CURSOR_VISIBILITY["invisible"])
# not that most of the curses attributes are globals:
# when we set them, they will stay that way until
# we change them to something else.
# means that the window will be erased
# and re-drawn the next time that `stdscr.refresh()`
# is called.
stdscr.clear()
# placing a string at the top-left corner of
# the window.
#y #x #the str
stdscr.addstr(0, 0, "hi bud")
# actually printing this screen
stdscr.refresh()
# getting the dimensions of the window.
max_y, max_x = stdscr.getmaxyx()
# adding a string listing the dimensions
# to the center of the window
xy_str = "current window is {} chars wide"\
"and {} chars tall.".format(max_x, max_y)
## printing "#" at the corner of the window OPPOSITE to (0,0)
stdscr.addstr(max_y - 1, max_x - 2, "#")
#################################################################
### interesting fact: i don't know why, but curses will throw an
### error if we tried to print a character at `max_x - 1`
### (probably 79, for a standard 80x24 char terminal).
###
### it does this, even though we made the cursor invisible.
#################################################################
# actually printing the updates
stdscr.refresh()
#################################################################
#
# P ### ### ###
# A ### ### ###
# R ### ### ###
# T ### ### ###
#
#################################################################
# now we will take some user input.
# first, print another message so the user
# knows what to do.
# it will be printed at the bottom of the screen,
# like the message line in GNU emacs.
exit_msg = "press any key to exit"
stdscr.addstr(
max_y - 1, # y
(max_x - len(exit_msg)) // 2, # x
exit_msg # string
)
stdscr.refresh()
# the program will block here, until a button is pressed.
character = stdscr.getch()
# PLAYING A TRICK ON THE USER!!! #
# erasing the screen
stdscr.clear()
# show the user input
curses.echo()
trick_msg = "please enter the name of your operating system"
trick_msg_pos = {
"y": max_y // 2,
"x": (max_x - len(trick_msg)) // 2
}
stdscr.addstr(
trick_msg_pos["y"],
trick_msg_pos["x"],
trick_msg
)
# now we will use `stdscr.getstr` to get a
# "line-delimited" string, and put the
# cursor is a visually pleasing central position
# first we will make the cursor nice and visible again
curses.curs_set(CURSOR_VISIBILITY["very_visible"])
user_os_bytes = stdscr.getstr( # `y` and `x` position cursor
trick_msg_pos["y"] + 2, # 2 lines below the message
trick_msg_pos["x"], # same justification as message
)
#################################################################
### HOW TO BYTES->STRING ########################################
### for some reason, the string is read as bytes.
### we can fix this easily by using utf8 encoding.
#################################################################
stdscr.addstr(
you_said_msg_pos["y"] + 2,
ms_msg_x,
ms_msg_1,
# `addstr` has a fourth, optional parameter that accepts a
# SINGLE attribute.
curses.A_BOLD, # this text will be bold
)
# this part of the message will immediately
# follow the first part, on the same line.
stdscr.addstr(
you_said_msg_pos["y"] + 2,
ms_msg_x + len(ms_msg_1),
ms_msg_2,
curses.A_ITALIC # also italic
)
# make cursor invisible again
curses.curs_set(CURSOR_VISIBILITY["invisible"])
stdscr.refresh()
# more timing
time.sleep(1)
update_msg = "press any key to do windoze updates"
stdscr.addstr(
you_said_msg_pos["y"] + 4,
(max_x - len(update_msg)) // 2,
update_msg
)