forked from itsapi/pycraft
/
ui.py
172 lines (129 loc) · 4.13 KB
/
ui.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import sys
import json
from nbinput import BlockingInput, escape_code, UP, DOWN, RIGHT, LEFT
from console import CLS, REDRAW, WIDTH, HEIGHT
from colours import *
import saves
from data import help_data
back = ('Back...', lambda: None)
def menu(name, options):
"""
Executes the users selection from the menu, and returns the result.
Parameters:
- name: menu title
- options: a tuple of option name and option function
"""
STAR = colour_str('*', YELLOW)
selection = 0
char = None
with BlockingInput() as bi:
while not str(char) in ' \n':
# Print menu
out = ''
for i, option in enumerate(options):
if i == selection:
out += STAR + colour_str(option[0], style=BOLD) + STAR
else:
out += ' ' + option[0] + ' '
out += '\n'
print(REDRAW + title(name) + out)
# Wait for useful input
while True:
char = str(escape_code(bi))
if char in ' \n':
break
if char in 'Ww'+UP:
selection -= 1
break
if char in 'Ss'+DOWN:
selection += 1
break
selection %= len(options)
print(CLS)
# Execute function of selection
return options[selection][1]()
def main():
""" Loops the main menu until the user loads a save. """
save = None
while not save:
save = menu('Main menu', (
('New Save', new),
('Load Save', load),
('Delete Save', delete),
('Help', help_),
('Exit', sys.exit)
))
return save
def lambda_gen(func, var):
""" Creates a lambda for to call a function with a parameter. """
return lambda: func(var)
def title(name):
""" Returns a padded coloured string containing the title. """
return ' {title}\n\n'.format(
title = colour_str('{name}\n {_}'.format(
name = name,
_ = ('=' * len(name))
), style=BOLD)
)
def load():
""" A menu for selectng a save to load. """
saves_list = saves.list_saves()
return menu(
'Load save',
([(save[1]['name'], lambda_gen(saves.load_save, save[0]))
for save in saves_list] + [back])
)
def delete():
""" A menu for selectng a save to delete. """
saves_list = saves.list_saves()
return menu(
'Delete save',
([(save[1]['name'], lambda_gen(saves.delete_save, save[0]))
for save in saves_list] + [back])
)
def new():
""" Lets the user enter a save name, then it creates and loads the save. """
print(REDRAW + title('New save'), end='')
meta = {}
meta['name'] = input(colour_str(' Save name', style=BOLD)
+ ' (leave blank to cancel): ')
if not meta['name']:
print(CLS)
return None
meta['seed'] = input(colour_str(' Map seed', style=BOLD)
+ ' (leave blank to randomise): ')
save = saves.new_save(meta)
if save is None:
error('Error creating save')
else:
return saves.load_save(save)
def pause():
print(CLS)
return menu('Paused', (
('Resume', lambda: None),
('Help', help_),
('Main Menu', lambda: 'exit')
))
def help_():
""" Displays the help stored in the help_data list. """
out = REDRAW + title('Help')
max_len = max(len(item[0]) for section in help_data.values() for item in section)
for label, section in help_data.items():
out += label + '\n'
for name, key in section:
out += ' {name:{max_len}} - {key}\n'.format(
name = name, key = key, max_len = max_len
)
out += 'Back...\n'
print(out)
wait_for_input()
print(CLS)
return None
def error(message):
print(CLS + REDRAW + '\n' + colour_str(message, fg=RED) + '\n\nBack...\n')
wait_for_input()
print(CLS, end='')
def wait_for_input():
with BlockingInput() as bi:
while not str(bi.char()) in ' \n':
pass