Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/setup/menus.py
blob: 2ac048d32067c850c624c42aa93ecb359c52c9ed (plain)
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
'''

'''

import curses
import config
from utils import strs

# setup logging
import logging
logging.basicConfig(filename=strs.LoggingFile,level=logging.DEBUG)
log = logging.getLogger('setup.menus')

# -----------------------------------------------------------------------------
# 
# -----------------------------------------------------------------------------

class MenuData(object):
    '''Holds data used by the menu system'''
    
    def __init__(self):
        '''
        Constructor
        '''
        self.levels = []    # all the known levels
        self.profiles = []  # all the known profiles
        self.profile = None # the player's current profile
        self.screen = None  # the curses display
        self.level = None   # the level the player wants to play


# -----------------------------------------------------------------------------
# Menu display functions
# -----------------------------------------------------------------------------

# Warning: the menu system uses recursion to move about.  Excessive bad input (tested to crash at 979 bad inputs to the main menu) or moving between menus will case a stack overflow.  When the menu system exits (such as when actually playing a game), we need to make sure all of the menu's function calls unwind
# TODO: improve the menu system so it doesn't use recursion

def mainMenu(data):
    ''' '''
    
    # we use the current profile, so make sure there is one
    if (data.profile == None) | (data.profile == ''):
        changePlayerMenu(data)
        return
    
     # configure the screen for our needs
    data.screen.erase()
    curses.cbreak()
    curses.echo()
    
    # display the title
    title = strs.Title_Main + strs.Title_Seperator + (data.profile or '[No Player]')
    displayTitle(data.screen, title)
    
    # display the menu options
    lines = ('1) Play Game',
             '2) Join Game - Stubbed',
             '3) Options - Stubbed',
             '',
             'c) Change Player',
             'e) Exit')
    displayOptions(data.screen, lines, 1)
    
    # display the input prompt
    lines = ('', 'Pick [1,c,e]: ')
    displayPrompt(data.screen, lines, 7)
    
    # refresh the screen
    data.screen.refresh()
    
    ## No longer matters as we are redrawing the entire screen after every key press
    # store the current cursor location, so we can keep it here when the user types
    #y, x = data.screen.getyx()
    #log.debug('Y,X are at: ' + str(y) + ' ' + str(x))
    
    # wait for user input
    c = data.screen.getch()
    
    ## No longer matters as we are redrawing the entire screen after every key press
    # keep the cursor in the same spot
    #data.screen.move(y, x)
    
    # process input
    if c == ord('1'): playGameMenu(data)
    #elif c == ord('2'): curses.beep()
    #elif c == ord('3'): curses.beep()
    elif c == ord('c'): changePlayerMenu(data)
    elif c == ord('e'): pass
    else:
        mainMenu(data)

def changePlayerMenu(data):
    ''' '''
    
    # create a list of players
    profiles = config.getProfiles()
    players = []
    for profile in profiles:
        players.append(profile.getName())
    
    # configure the screen for our needs
    data.screen.erase()
    curses.nocbreak()
    curses.echo()
    
    # display the title
    title = strs.Title_ChangePlayer + strs.Title_Seperator + (data.profile or '[No Player]')
    displayTitle(data.screen, title)
    
    # display the menu options
    lines = ['', 'Known Players:']
    for player in players:
        lines.append(' * ' + player)
    displayOptions(data.screen, lines, 1)
    
    # display the input prompt
    offset = len(lines) + 1
    lines = ('','Enter your player\'s name: ')
    displayPrompt(data.screen, lines, offset)
    
    # refresh and wait for valid user input
    data.screen.refresh()
    name = data.screen.getstr()
    
    # process input
    # Note: if the player's profile doesn't exist, it will be created whenever the player does something that needs to be saved to a profile
    data.profile = name
    
    # always head back to the main menu after changing the profile
    mainMenu(data)

def playGameMenu(data):
    ''' '''
    
    # create a list of levels
    if (data.levels == None) | (data.levels == []):
        data.levels = config.getLevelDescriptors()
    
    # configure the screen for our needs
    data.screen.erase()
    curses.cbreak()
    curses.echo()
    
    # display the title
    title = strs.Title_PlayGame + strs.Title_Seperator + (data.profile or '[No Player]')
    displayTitle(data.screen, title)
    
    # display the menu options
    lines = ['', 'Levels:']
    for index, level in enumerate(data.levels):
        lines.append(' ' + str(index) + ') ' + level.getName() )
    displayOptions(data.screen, lines, 1)
    
    # display the input prompt
    minLevels = 1
    offset = len(lines) + 1
    if len(data.levels) < minLevels:
        lines = ('', 'No known levels.  Press anything to continue...'),
        curses.nocbreak()
    else:
        lines = ('','Enter the number of the level to play: ')
    displayPrompt(data.screen, lines, offset)
    
    # refresh and wait for valid user input
    data.screen.refresh()
    input = data.screen.getstr()
    
    # process input
    if len(data.levels) < minLevels:
        mainMenu(data)
        return
    input = int(input) 
    data.level = data.levels[input]
    
    #move on to configuring the selected level
    levelOptionsMenu(data)

def levelOptionsMenu(data):
    ''' '''
    
    # make sure there is a level
    if (data.level == None) | (data.level == ''):
        log.error('Made it to the levelOptionsMenu() without a selected level!  This should not be possible.')
        return
    
    # get the player's stats for this level
    stats = []
    if data.profile == None:
        pass
    else:
        stats.append('')
        stats.append('Your Stats:')
        
        # get the max score, max duration, and last time played
        profile = config.getProfile(data.profile)
        stats.append('Max Score - ' + str(profile.getMaxScore(data.level)))
        stats.append('Max Duration - ' + str(profile.getMaxDuration(data.level)))
        stats.append('Last Played - ' + profile.getLastTimePlayed(data.level))
        stats.append('')
    
        # configure the screen for our needs
    data.screen.erase()
    curses.cbreak()
    curses.echo()
    
    # display the title
    title = data.level.getName() + strs.Title_Seperator + (data.profile or '[No Player]')
    displayTitle(data.screen, title)
    
    # display the level's description, the player's stats, and the level's options
    lines = ['', data.level.getDescription()]
    lines.extend(stats)
    lines.append('-------------------- -------------------- --------------------')
    lines.extend(['','Options:',
                  '1) Skill level - Easy - Stubbed',
                  '2) Number of players - 1 - Stubbed',
                  '',
                  'p) Play now',
                  's) Spectate - Stubbed',
                  'm) Main Menu'])
    displayOptions(data.screen, lines, 1)
    #displayOptions(data.screen, ['Nothing'], 1)
    
    # display the input prompt
    offset = len(lines) + 1
    lines = ('','Pick [p,m]: ')
    displayPrompt(data.screen, lines, offset)
    
    # refresh and wait for valid user input
    data.screen.refresh()
    c = data.screen.getstr()
    
    # process input
    if c == ord('1'): playGameMenu(data)
    elif c == ord('c'): changePlayerMenu(data)
    elif c == ord('e'): pass
    else:
        levelOptionsMenu(data)

def skillLevelMenu(data):
    ''' '''
    # check for required vars
    
    # clear the screen and display the title
    # display the menu
    # refresh the screen
    # wait for input
    # process  input
    pass

def numberOfPlayersMenu(data):
    ''' '''
    pass

# -----------------------------------------------------------------------------
# Common functions
# -----------------------------------------------------------------------------

def displayTitle(screen, title):
    '''Displays the given title as the title of the given stdscr'''
    screen.addstr(0,strs.Indent_Title, title, curses.A_REVERSE)

def displayOptions(screen, options, offset=0):
    '''Displays the given list of options on the given stdscr with the given vertical offset'''
    for index, line in enumerate(options):
        screen.addstr(index+1+offset,strs.Indent_Options, line)

def displayPrompt(screen, lines, offset=0):
    '''Displays the given list of textual prompt lines on the given stdscr with the given vertical offset'''
    for index, line in enumerate(lines):
        screen.addstr(index+1+offset,strs.Indent_Prompt, line)

# -----------------------------------------------------------------------------
# Menu setup functions
# -----------------------------------------------------------------------------

def init(stdscr):
    ''' '''
    
    # create the menu's data
    data = MenuData()
    data.screen = stdscr
    
    # set the last used values
    data.profile = config.getLastProfileName()
    
    mainMenu(data)

def begin():
    ''' '''
    curses.wrapper(init)