How can I create a simple terminal border that can easily be printed in?
Something like this is perfect
┌──────────┐
│ text │
│ text │
├──────────┤
│ input │
└──────────┘
I've seen modules like Npyscreen and a UI like this would be perfect although this is not what my requirements need. It needs to be way easier for my purpose (Text based RPG game). If someone can recommend me a module or give me a simple way on how to replicate this then that'd be great!
Here is a solution using curses :
import curses
screen = curses.initscr()
curses.noecho()
curses.cbreak()
screen.keypad(True)
left_border = '│'
right_border = '│'
top_border = '─'
bottom_border = '─'
separator = '─'
top_left = "┌"
top_right = "┐"
bottom_left = "└"
bottom_right = "┘"
left_junction = "├"
right_junction = '┤'
def refresh_screen(current_text, info):
screen.clear() # clear
rows, cols = screen.getmaxyx() # get screen rows and columns
screen.addstr(0, 0, top_left) # top left corner
screen.addstr(0, 1, top_border * (cols - 3)) # top border
screen.addstr(0, cols - 2, top_right) # top right corner
for i in range(1, rows - 1):
screen.addstr(i, 0, left_border) # left border
for i in range(1, rows - 1):
screen.addstr(i, cols - 2, right_border) # right border
screen.addstr(rows - 1, 0, bottom_left) # bottom left corner
screen.addstr(rows - 1, 1, bottom_border * (cols - 3)) # bottom border
screen.addstr(rows - 1, cols - 2, bottom_right) # bottom right corner
screen.addstr(rows - 3, 0, left_junction) # left junction
screen.addstr(rows - 3, 1, separator * (cols - 3)) # separator
screen.addstr(rows - 3, cols - 2, right_junction) # right junction
cursorx = 1
cursory = 1
# write the info text
for char in info:
if char == '\n': # deal with newlines
cursorx = 1
cursory += 1
else:
screen.addstr(cursory, cursorx, char) # add character
cursorx += 1 # increment cursor position
if cursorx >= cols - 3: # if cursor x is over right border, carriage return
cursorx = 1
cursory += 1
# write the current user input
screen.addstr(rows - 2, 1, " " + current_text)
screen.refresh()
info = "lorem ipsum dolor sit amet " * 10
user_input = ""
refresh_screen(user_input, info)
while True:
key = screen.getkey()
if ord(key) == 127: # backspace
user_input = user_input[:-1]
else:
user_input += key
if key == '\n':
# user entered something
# do_something(user_input)
user_input = ""
refresh_screen(user_input, info)
However, this does not handle the Backspace key or a text overflow (info text larger than the text zone).
EDIT: I added support for deleting with backspace.
info
is the variable containing the text in the top zone (here lorem ipsum ten times) and user_input
contains the current user input. You can change the variable declarations at the top to change the type of the border.
It gives something like this :
┌─────────────────────────────────────────────────────────────────────┐
│lorem ipsum dolor sit amet lorem ipsum dolor sit amet lorem ipsum do │
│lor sit amet lorem ipsum dolor sit amet lorem ipsum dolor sit amet l │
│orem ipsum dolor sit amet lorem ipsum dolor sit amet lorem ipsum dol │
│or sit amet lorem ipsum dolor sit amet lorem ipsum dolor sit amet │
│ │
│ │
│ │
│ │
│ │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ user input here │
└─────────────────────────────────────────────────────────────────────┘