added visual menu and live updates

pull/1/head
Jake Funke 2017-03-08 02:35:04 +00:00
parent a87bc5bae4
commit 180a4fe80f
2 changed files with 140 additions and 9 deletions

View File

@ -8,8 +8,8 @@ import os.path
import random import random
import getpass import getpass
import threading import threading
import errno
from menu_screen import *
# ideas go here # ideas go here
# lifecycle of a plant # lifecycle of a plant
# seed -> seedling -> sprout -> young plant -> mature plant -> flower -> # seed -> seedling -> sprout -> young plant -> mature plant -> flower ->
@ -69,6 +69,7 @@ import threading
# #
# curses.endwin() # curses.endwin()
class Plant(object): class Plant(object):
# This is your plant! # This is your plant!
stage_dict = { stage_dict = {
@ -214,7 +215,8 @@ class Plant(object):
output += self.stage_dict[self.stage] + " " output += self.stage_dict[self.stage] + " "
if self.stage >= 2: if self.stage >= 2:
output += self.species_dict[self.species] + " " output += self.species_dict[self.species] + " "
print output # print output
return output
def start_life(self): def start_life(self):
# runs life on a thread # runs life on a thread
@ -231,13 +233,13 @@ class Plant(object):
while (self.stage < 5) or (self.dead == False): while (self.stage < 5) or (self.dead == False):
time.sleep(1) time.sleep(1)
self.ticks += 1 self.ticks += 1
print self.ticks # print self.ticks
if self.stage < len(self.stage_dict)-1: if self.stage < len(self.stage_dict)-1:
if self.ticks == life_stages[self.stage]: if self.ticks == life_stages[self.stage]:
self.growth() self.growth()
self.parse_plant() print self.parse_plant()
if self.mutate_check(): if self.mutate_check():
self.parse_plant() print self.parse_plant()
# what kills the plant? # what kills the plant?
@ -258,8 +260,13 @@ class DataManager(object):
def __init__(self): def __init__(self):
self.this_user = getpass.getuser() self.this_user = getpass.getuser()
if not os.path.exists(self.botany_dir): # check for .botany dir in home
try:
os.makedirs(self.botany_dir) os.makedirs(self.botany_dir)
except OSError as exception:
if exception.errno != errno.EEXIST:
raise
self.savefile_name = self.this_user + '_plant.dat' self.savefile_name = self.this_user + '_plant.dat'
def check_plant(self): def check_plant(self):
@ -293,7 +300,7 @@ if __name__ == '__main__':
if my_data.check_plant(): if my_data.check_plant():
print "Welcome back, " + getpass.getuser() print "Welcome back, " + getpass.getuser()
my_plant = my_data.load_plant() my_plant = my_data.load_plant()
my_plant.parse_plant() print my_plant.parse_plant()
# otherwise create new plant # otherwise create new plant
else: else:
print "Welcome, " + getpass.getuser() print "Welcome, " + getpass.getuser()
@ -301,7 +308,9 @@ if __name__ == '__main__':
my_plant = Plant(my_data.savefile_path) my_plant = Plant(my_data.savefile_path)
my_plant.start_life() my_plant.start_life()
print "Your plant is living :)" print "Your plant is living :)"
raw_input('Press return to save and exit...\n') botany_menu = CursedMenu(my_plant)
botany_menu.show([1,2,3], title=' botany ', subtitle='Options')
#raw_input('Press return to save and exit...\n')
my_data.save_plant(my_plant) my_data.save_plant(my_plant)
my_data.data_write_json(my_plant) my_data.data_write_json(my_plant)
print "end" print "end"

122
menu_screen.py 100644
View File

@ -0,0 +1,122 @@
import curses, os, traceback, threading, time
class CursedMenu(object):
'''A class which abstracts the horrors of building a curses-based menu system'''
def __init__(self, this_plant):
'''Initialization'''
self.screen = curses.initscr()
curses.noecho()
curses.cbreak()
curses.start_color()
curses.curs_set(0)
self.screen.keypad(1)
self.plant = this_plant
self.exit = False
# Highlighted and Normal line definitions
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
self.highlighted = curses.color_pair(1)
self.normal = curses.A_NORMAL
thread = threading.Thread(target=self.update_plant_live, args=())
thread.daemon = True
thread.start()
def show(self, options, title="Title", subtitle="Subtitle"):
'''Draws a menu with the given parameters'''
self.set_options(options)
self.title = title
self.subtitle = subtitle
self.selected = 0
self.draw_menu()
def set_options(self, options):
'''Validates that the last option is "Exit"'''
if options[-1] is not 'Exit':
options.append('Exit')
self.options = options
def draw_menu(self):
'''Actually draws the menu and handles branching'''
request = ""
try:
while request is not "Exit":
self.draw()
request = self.get_user_input()
self.handle_request(request)
self.__exit__()
# Also calls __exit__, but adds traceback after
except Exception as exception:
self.__exit__()
traceback.print_exc()
def draw(self):
'''Draw the menu and lines'''
self.screen.border(0)
self.screen.addstr(2,2, self.title, curses.A_STANDOUT) # Title for this menu
self.screen.addstr(4,2, self.subtitle, curses.A_BOLD) #Subtitle for this menu
# Display all the menu items, showing the 'pos' item highlighted
for index in range(len(self.options)):
textstyle = self.normal
if index == self.selected:
textstyle = self.highlighted
self.screen.addstr(5+index,4, "%d - %s" % (index+1, self.options[index]), textstyle)
self.screen.refresh()
def update_plant_live(self):
while self.exit is not True:
plant_string = self.plant.parse_plant()
plant_ticks = str(self.plant.ticks)
self.screen.addstr(10,2, plant_string, curses.A_NORMAL)
self.screen.addstr(11,2, plant_ticks, curses.A_NORMAL)
self.screen.refresh()
time.sleep(1)
#curses.endwin()
#os.system('clear')
def get_user_input(self):
'''Gets the user's input and acts appropriately'''
user_in = self.screen.getch() # Gets user input
'''Enter and Exit Keys are special cases'''
if user_in == 10:
return self.options[self.selected]
if user_in == 27:
return self.options[-1]
# This is a number; check to see if we can set it
if user_in >= ord('1') and user_in <= ord(str(min(9,len(self.options)+1))):
self.selected = user_in - ord('0') - 1 # convert keypress back to a number, then subtract 1 to get index
return
# Increment or Decrement
if user_in == curses.KEY_DOWN: # down arrow
self.selected += 1
if user_in == curses.KEY_UP: # up arrow
self.selected -=1
self.selected = self.selected % len(self.options)
return
def handle_request(self, request):
'''This is where you do things with the request'''
if request is None: return
if request == 1:
self.screen.addstr(8,15,str(self.plant.ticks), curses.A_STANDOUT) # Title for this menu
self.screen.refresh()
def __exit__(self):
self.exit = True
curses.curs_set(2)
curses.endwin()
os.system('clear')
'''demo'''
# cm = CursedMenu()
# cm.show([1,2,3], title=' botany ', subtitle='Options')