add color to botany
Add example ANSI-colored ASCII art to "art" directory Add ansi_render() to menu_screen.py to render ANSI-colored ASCII art Fall back on non-colored art if no colored art exists Only single escape codes for setting foreground color are supported. Escape sequences with multiple codes (e.g. "ESC[1;33m") are unsupported. Unsupported escape codes reset colors to normal.pull/44/head
parent
38f7f17b66
commit
fa1837f71f
|
@ -0,0 +1,10 @@
|
||||||
|
[32m&[0m \ [32m&[0m [32m&[0m
|
||||||
|
[32m&[0m\|,/ |/[32m& &&[0m
|
||||||
|
[32m&[0m|/[32m& / [32m& &[0m
|
||||||
|
\ { |___/_[32m&[0m
|
||||||
|
{ {/ / [32m&[0m
|
||||||
|
`, \{______/_[32m&[0m
|
||||||
|
} }{ \_[32m&[0m
|
||||||
|
}{{
|
||||||
|
. , , -=-~{ .-^- _ _ .
|
||||||
|
^ '
|
|
@ -0,0 +1,10 @@
|
||||||
|
[32m&&&[0m\/[32m& &&&[0m
|
||||||
|
[32m&\[0m|,/ |/[32m& &&[0m
|
||||||
|
[32m&&[0m/ / /_[32m&& &&[0m
|
||||||
|
\ { |_____/_[32m&[0m
|
||||||
|
{ / / [32m& & &&&[0m
|
||||||
|
`, \{___________/_[32m&&[0m
|
||||||
|
} }{ [32m&[0m\____[32m&[0m
|
||||||
|
}{{ `[32m&[0m\[32m&&[0m
|
||||||
|
{}{ [32m&&[0m
|
||||||
|
. , , -=-~{ .-^- _ _ .
|
|
@ -0,0 +1,10 @@
|
||||||
|
[32m&[33m*[32m&[0m\/[32m& [33m*[32m&&[0m
|
||||||
|
[32m&[0m\|,/ |/[32m& [33m*[32m&[0m
|
||||||
|
[33m*[32m&[0m/ / /_[32m&& &&[0m
|
||||||
|
\ { |_____/_[33m*[0m
|
||||||
|
{[33m*[0m / / [32m& & [33m*[32m&&[0m
|
||||||
|
`, \{___________/_[33m*[32m&[0m
|
||||||
|
} }{ [33m*[0m\____[32m&[0m
|
||||||
|
}{{ `[32m&[0m\[33m*[32m&[0m
|
||||||
|
{}{ [32m&&[0m
|
||||||
|
. , , -=-~{ .-^- _ _ .
|
|
@ -0,0 +1,10 @@
|
||||||
|
[32m/))[0m HAPPY
|
||||||
|
[33m__[32m((([33m__[0m HALLOWEEN
|
||||||
|
[33m.' [0m_[32m`""`[0m_[33m`'.
|
||||||
|
[33m/ [0m/[33m\[0m\ /[33m\[0m\[33m \
|
||||||
|
[33m| [0m/[33m)[0m_[33m\[0m\/[33m)[0m_[33m\[0m\[33m |
|
||||||
|
[33m| [0m_ _[33m()[0m_ _[33m |
|
||||||
|
[33m| [0m\[33m\/[0m\[33m\/[0m\[33m\/[0m/[33m |
|
||||||
|
[33m\ [0m\/\/\/\/[33m /[0m
|
||||||
|
. , .[33m'.___..___.'[0m _ ., _ .
|
||||||
|
^ ' ` '
|
|
@ -0,0 +1,10 @@
|
||||||
|
______________
|
||||||
|
/ \
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| R.I.P. |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
. |, _[32m\/[0m .. [32m\[0m. [32m\ /[0m,|_ .
|
||||||
|
^ ' ` '
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
. , _ . . _ , _ ., _ .
|
||||||
|
^ ' [33mo[0m ` '
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[32m. ;[0m
|
||||||
|
[32m\|[0m
|
||||||
|
. , _ . ., [32ml[0m, _ ., _ .
|
||||||
|
^ ' ` '
|
|
@ -57,7 +57,6 @@ class CursedMenu(object):
|
||||||
self.show(["water","look","garden","visit", "instructions"], title=' botany ', subtitle='options')
|
self.show(["water","look","garden","visit", "instructions"], title=' botany ', subtitle='options')
|
||||||
|
|
||||||
def define_colors(self):
|
def define_colors(self):
|
||||||
# TODO: implement colors
|
|
||||||
# set curses color pairs manually
|
# set curses color pairs manually
|
||||||
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
|
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
|
||||||
curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK)
|
curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK)
|
||||||
|
@ -68,6 +67,21 @@ class CursedMenu(object):
|
||||||
curses.init_pair(7, curses.COLOR_RED, curses.COLOR_BLACK)
|
curses.init_pair(7, curses.COLOR_RED, curses.COLOR_BLACK)
|
||||||
curses.init_pair(8, curses.COLOR_CYAN, curses.COLOR_BLACK)
|
curses.init_pair(8, curses.COLOR_CYAN, curses.COLOR_BLACK)
|
||||||
|
|
||||||
|
ESC_CODE_TO_PAIR = {
|
||||||
|
'' : 0, # normal
|
||||||
|
'0' : 0, # normal
|
||||||
|
'30' : 1, # black
|
||||||
|
'31' : 7, # red
|
||||||
|
'32' : 3, # green
|
||||||
|
'33' : 6, # yellow
|
||||||
|
'34' : 4, # blue
|
||||||
|
'35' : 5, # magenta
|
||||||
|
'36' : 8, # cyan
|
||||||
|
'37' : 2 # white
|
||||||
|
}
|
||||||
|
def esc_code_to_color(self, esc_code):
|
||||||
|
return curses.color_pair(self.ESC_CODE_TO_PAIR.get(esc_code, 0))
|
||||||
|
|
||||||
def show(self, options, title, subtitle):
|
def show(self, options, title, subtitle):
|
||||||
# Draws a menu with parameters
|
# Draws a menu with parameters
|
||||||
self.set_options(options)
|
self.set_options(options)
|
||||||
|
@ -135,7 +149,7 @@ class CursedMenu(object):
|
||||||
def ascii_render(self, filename, ypos, xpos):
|
def ascii_render(self, filename, ypos, xpos):
|
||||||
# Prints ASCII art from file at given coordinates
|
# Prints ASCII art from file at given coordinates
|
||||||
this_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),"art")
|
this_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),"art")
|
||||||
this_filename = os.path.join(this_dir,filename)
|
this_filename = os.path.join(this_dir,filename + '.txt')
|
||||||
this_file = open(this_filename,"r")
|
this_file = open(this_filename,"r")
|
||||||
this_string = this_file.readlines()
|
this_string = this_file.readlines()
|
||||||
this_file.close()
|
this_file.close()
|
||||||
|
@ -145,6 +159,41 @@ class CursedMenu(object):
|
||||||
# self.screen.refresh()
|
# self.screen.refresh()
|
||||||
self.screen_lock.release()
|
self.screen_lock.release()
|
||||||
|
|
||||||
|
def ansi_render(self, filename, ypos, xpos):
|
||||||
|
# Prints ANSI art from file at given coordinates
|
||||||
|
# Falls back on ASCII if no ANSI version exists
|
||||||
|
# Assumes curses.has_colors()
|
||||||
|
this_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),"art")
|
||||||
|
this_filename = os.path.join(this_dir,filename + '.ansi')
|
||||||
|
if not os.path.exists(this_filename):
|
||||||
|
self.ascii_render(filename, ypos, xpos)
|
||||||
|
return
|
||||||
|
this_file = open(this_filename,"r")
|
||||||
|
this_string = this_file.readlines()
|
||||||
|
this_file.close()
|
||||||
|
self.screen_lock.acquire()
|
||||||
|
color = curses.A_NORMAL
|
||||||
|
for y, line in enumerate(this_string, 2):
|
||||||
|
code_text_pairs = [tuple(token.split('m', 1)) if 'm' in token else (None, token)
|
||||||
|
for token in line.rstrip('\r\n').split('\x1b[') ]
|
||||||
|
color_text_pairs = [(color, text) if code == None else (self.esc_code_to_color(code), text)
|
||||||
|
for (code, text) in code_text_pairs]
|
||||||
|
x = 0
|
||||||
|
for (color, text) in color_text_pairs:
|
||||||
|
# Handle overflowing art gracefully
|
||||||
|
text = text[:max(0, self.maxx-(xpos+x))]
|
||||||
|
if not text:
|
||||||
|
continue
|
||||||
|
self.screen.addstr(ypos+y, xpos+x, text, color)
|
||||||
|
x += len(text)
|
||||||
|
self.screen_lock.release()
|
||||||
|
|
||||||
|
def art_render(self, filename, ypos, xpos):
|
||||||
|
if curses.has_colors():
|
||||||
|
self.ansi_render(filename, ypos, xpos)
|
||||||
|
else:
|
||||||
|
self.ascii_render(filename, ypos, xpos)
|
||||||
|
|
||||||
def draw_plant_ascii(self, this_plant):
|
def draw_plant_ascii(self, this_plant):
|
||||||
ypos = 0
|
ypos = 0
|
||||||
xpos = int((self.maxx-37)/2 + 25)
|
xpos = int((self.maxx-37)/2 + 25)
|
||||||
|
@ -173,22 +222,22 @@ class CursedMenu(object):
|
||||||
'pachypodium',
|
'pachypodium',
|
||||||
]
|
]
|
||||||
if this_plant.dead == True:
|
if this_plant.dead == True:
|
||||||
self.ascii_render('rip.txt', ypos, xpos)
|
self.art_render('rip', ypos, xpos)
|
||||||
elif datetime.date.today().month == 10 and datetime.date.today().day == 31:
|
elif datetime.date.today().month == 10 and datetime.date.today().day == 31:
|
||||||
self.ascii_render('jackolantern.txt', ypos, xpos)
|
self.art_render('jackolantern', ypos, xpos)
|
||||||
elif this_plant.stage == 0:
|
elif this_plant.stage == 0:
|
||||||
self.ascii_render('seed.txt', ypos, xpos)
|
self.art_render('seed', ypos, xpos)
|
||||||
elif this_plant.stage == 1:
|
elif this_plant.stage == 1:
|
||||||
self.ascii_render('seedling.txt', ypos, xpos)
|
self.art_render('seedling', ypos, xpos)
|
||||||
elif this_plant.stage == 2:
|
elif this_plant.stage == 2:
|
||||||
this_filename = plant_art_list[this_plant.species]+'1.txt'
|
this_filename = plant_art_list[this_plant.species]+'1'
|
||||||
self.ascii_render(this_filename, ypos, xpos)
|
self.art_render(this_filename, ypos, xpos)
|
||||||
elif this_plant.stage == 3 or this_plant.stage == 5:
|
elif this_plant.stage == 3 or this_plant.stage == 5:
|
||||||
this_filename = plant_art_list[this_plant.species]+'2.txt'
|
this_filename = plant_art_list[this_plant.species]+'2'
|
||||||
self.ascii_render(this_filename, ypos, xpos)
|
self.art_render(this_filename, ypos, xpos)
|
||||||
elif this_plant.stage == 4:
|
elif this_plant.stage == 4:
|
||||||
this_filename = plant_art_list[this_plant.species]+'3.txt'
|
this_filename = plant_art_list[this_plant.species]+'3'
|
||||||
self.ascii_render(this_filename, ypos, xpos)
|
self.art_render(this_filename, ypos, xpos)
|
||||||
|
|
||||||
def draw_default(self):
|
def draw_default(self):
|
||||||
# draws default menu
|
# draws default menu
|
||||||
|
|
Loading…
Reference in New Issue