[Console] Fix and refactor window.add_str code

- Replace usage of single char variable.
- Use max function to prevent negate lengths when calculating trim.
- Remove usage of insstr as the addstr exception when writing offscreen is
excpected behaviour so needs caught and passed. This fixes a similar
error with insstr.
This commit is contained in:
Calum Lind 2018-07-09 17:42:51 +01:00
parent be02be75be
commit 6e81a11d8d
1 changed files with 21 additions and 30 deletions

View File

@ -223,14 +223,14 @@ class BaseMode(CursesStdIO, component.Component):
curses.endwin() curses.endwin()
def add_string(row, string, screen, encoding, col=0, pad=True, pad_char=' ', trim='...', leaveok=0): def add_string(row, fstring, screen, encoding, col=0, pad=True, pad_char=' ', trim='..', leaveok=0):
""" """
Adds a string to the desired `:param:row`. Adds a string to the desired `:param:row`.
Args: Args:
row(int): the row number to write the string row(int): the row number to write the string
row(int): the row number to write the string row(int): the row number to write the string
string(str): the string of text to add fstring(str): the (formatted) string of text to add
scr(curses.window): optional window to add string to instead of self.stdscr scr(curses.window): optional window to add string to instead of self.stdscr
col(int): optional starting column offset col(int): optional starting column offset
pad(bool): optional bool if the string should be padded out to the width of the screen pad(bool): optional bool if the string should be padded out to the width of the screen
@ -258,47 +258,38 @@ def add_string(row, string, screen, encoding, col=0, pad=True, pad_char=' ', tri
""" """
try: try:
parsed = colors.parse_color_string(string, encoding) parsed = colors.parse_color_string(fstring, encoding)
except colors.BadColorString as ex: except colors.BadColorString as ex:
log.error('Cannot add bad color string %s: %s', string, ex) log.error('Cannot add bad color string %s: %s', fstring, ex)
return return
if leaveok: if leaveok:
screen.leaveok(leaveok) screen.leaveok(leaveok)
max_y, max_x = screen.getmaxyx() max_y, max_x = screen.getmaxyx()
for index, (color, s) in enumerate(parsed): for index, (color, string) in enumerate(parsed):
if index + 1 == len(parsed) and pad: # Skip printing chars beyond max_x
# This is the last string so lets append some " " to it if col >= max_x:
s += pad_char * (max_x - (col + len(s)))
# Sometimes the parsed string gives empty elements which may not be printed on max_x
if col == max_x:
break break
if (col + len(s)) > max_x: if index + 1 == len(parsed) and pad:
# This is the last string so lets append some padding to it
string += pad_char * (max_x - (col + len(string)))
if col + len(string) > max_x:
remaining_chrs = max(0, max_x - col)
if trim: if trim:
s = '%s%s' % (s[0:max_x - len(trim) - col], trim) string = string[0:max(0, remaining_chrs - len(trim))] + trim
else: else:
s = s[0:max_x - col] string = string[0:remaining_chrs]
if col + len(s) >= max_x and row == max_y - 1: try:
# Bug in curses when writing to the lower right corner: https://bugs.python.org/issue8243 screen.addstr(row, col, string, color)
# Use insstr instead which avoids scrolling which is the root cause apparently except curses.error as ex:
screen.insstr(row, col, s, color) # Ignore exception for writing offscreen.
else: pass
try:
screen.addstr(row, col, s, color)
except curses.error as ex:
import traceback
log.warn(
'FAILED on call screen.addstr(%s, %s, "%s", %s) - max_y: %s, max_x: %s, '
'curses.LINES: %s, curses.COLS: %s, Error: %s, trace:\n%s',
row, col, s, color, max_y, max_x, curses.LINES, curses.COLS, ex,
''.join(traceback.format_stack(limit=5)),
)
col += len(s) col += len(string)
if leaveok: if leaveok:
screen.leaveok(0) screen.leaveok(0)