Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDpk3062 <dpk3062@rit.edu>2009-07-06 03:48:30 (GMT)
committer Dpk3062 <dpk3062@rit.edu>2009-07-06 03:48:30 (GMT)
commit3d58f3f0ffc9041ad6f87364e0b209c0b0a8cdb3 (patch)
tree17c374c77f627dde11ec1636c438758e253a1e79
parentbe5f99eca2a2d42552605a1e9fb34063734903ba (diff)
* Now using Curses for text display
* 'Main Menu' working * 'Change Player' menu working * Putting constants and strings in utils.strs.py * Added class 'Profile' * Renamed class 'LevelInfo' to 'Level' Note: paths still hard coded for main developer's machine
-rw-r--r--src/setup/__init__.py1
-rw-r--r--src/setup/config.py122
-rw-r--r--src/setup/level.py17
-rw-r--r--src/setup/main.py62
-rw-r--r--src/setup/menus.py191
-rw-r--r--src/setup/profile.py30
-rw-r--r--src/setup/profiles.py31
-rw-r--r--src/utils/__init__.py1
-rw-r--r--src/utils/strs.py35
9 files changed, 435 insertions, 55 deletions
diff --git a/src/setup/__init__.py b/src/setup/__init__.py
index e69de29..a003759 100644
--- a/src/setup/__init__.py
+++ b/src/setup/__init__.py
@@ -0,0 +1 @@
+# this is a package
diff --git a/src/setup/config.py b/src/setup/config.py
new file mode 100644
index 0000000..696c039
--- /dev/null
+++ b/src/setup/config.py
@@ -0,0 +1,122 @@
+'''
+
+'''
+
+import os
+from lxml import etree # using lxml for XML processing
+from utils import strs # string constants
+from utils import utils # some XML utilities
+from profile import Profile
+from level import Level
+
+# setup logging
+import logging
+logging.basicConfig(filename=strs.LoggingFile,level=logging.DEBUG)
+log = logging.getLogger('setup.config')
+
+
+# -----------------------------------------------------------------------------
+# Some Getters
+# -----------------------------------------------------------------------------
+
+# TODO refactor to remove duplicated code logic: should have the two getXXX() going to findFiles() -> findFolders() -> find()
+
+def getLevelDescriptors():
+ '''Returns a list of Levels representing all known levels'''
+ # get all the level descriptor files
+ files = findLevelFiles()
+
+ # convert them all into objects
+ levels = []
+ for file in files:
+ level = Level(path)
+ levels.append(level)
+ return files
+
+def getProfiles():
+ '''Returns a list of Profiles representing all known profiles'''
+ # get all the profile files
+ files = findProfileFiles()
+
+ # convert the files into Profile objects
+ profiles = []
+ for file in files:
+ profile = Profile(file)
+ profiles.append(profile)
+ return profiles
+
+# -----------------------------------------------------------------------------
+# File related methods
+# -----------------------------------------------------------------------------
+
+def getLastProfileName():
+ '''Returns the name of the last loaded profile'''
+ name = find(strs.XP_LastProfileName)[0]
+ return name
+
+def findLevelFiles():
+ '''Returns the list of found level descriptor files'''
+ folders = findLevelFolders()
+ files = findFiles(folders, strs.Ext_Level)
+ log.debug('Found ' + str(len(files)) + ' level files')
+ return files
+
+def findProfileFiles():
+ '''Returns the list of found profile files'''
+ folders = findProfileFolders()
+ files = findFiles(folders, strs.Ext_Profile)
+ log.debug('Found ' + str(len(files)) + ' profile files')
+ return files
+
+def findFiles(folders, extension):
+ '''Returns a list of all files with the given extension directly inside the given folders'''
+ files = []
+
+ for dir in folders:
+ contents = os.listdir(dir)
+ for item in contents:
+ item = dir + '/' + item # must convert the file/folder name into its complete path
+
+ # only want files with the given extension
+ if not os.path.isfile(item):
+ continue
+ if not item.endswith(extension):
+ continue
+
+ files.append(item)
+ return files
+
+# -----------------------------------------------------------------------------
+# Folder related methods
+# -----------------------------------------------------------------------------
+
+def findLevelFolders():
+ '''Returns the list of known level folders'''
+ folders = find(strs.XP_LevelFolderLocation)
+ log.debug('Found ' + str(len(folders)) + ' level folders')
+ return folders
+ pass
+
+def findProfileFolders():
+ '''Returns the list of known profile folders'''
+ folders = find(strs.XP_ProfileFolderLocation)
+ log.debug('Found ' + str(len(folders)) + ' profile folders')
+ return folders
+
+# -----------------------------------------------------------------------------
+# General methods
+# -----------------------------------------------------------------------------
+
+def find(xpath):
+ ''' Returns the result of applying the given xpath onto the config file'''
+ config = utils.getXMLRoot(strs.ConfigFile)
+ return config.xpath(xpath)
+
+# -----------------------------------------------------------------------------
+# Some Setters
+# -----------------------------------------------------------------------------
+
+def setLastProfileName(name):
+ ''' '''
+ # TODO fill in this stub
+ pass
diff --git a/src/setup/level.py b/src/setup/level.py
index 907d8bd..193e8f7 100644
--- a/src/setup/level.py
+++ b/src/setup/level.py
@@ -1,10 +1,12 @@
'''
'''
-from lxml import etree
-from utils import utils
+from lxml import etree # using lxml for XML processing
+from utils import strs # string constants
+from utils import utils # some XML utilities
-class LevelInfo(object):
+
+class Level(object):
'''
'''
@@ -15,16 +17,17 @@ class LevelInfo(object):
#open up the mlvl file and read in its basic properties
root = utils.getXMLRoot(path)
- self.name = root.xpath('//level-info/@name')[0]
- self.description = root.xpath('//level-info/@description')[0]
+ self.name = root.xpath(strs.XP_LevelName)[0]
+ self.description = root.xpath(strs.XP_LevelName)[0]
+ self.path = path
pass
def getName(self):
- '''Gets the name of this level'''
+ '''Returns the name of this level'''
return self.name
def getDescription(self):
- '''Gets the description of this level'''
+ '''Returns the description of this level'''
return self.description
diff --git a/src/setup/main.py b/src/setup/main.py
index 1f05f10..c88cb46 100644
--- a/src/setup/main.py
+++ b/src/setup/main.py
@@ -2,60 +2,26 @@
'''
+#why?
if __name__ == '__main__':
pass
-import os
-
-# using lxml for XML processing
-from lxml import etree
-from level import LevelInfo
-from utils import utils
-
-# constants
-ConfigFile = '/home/doug/workspace/Muthris/docs/examples/config.xml'
-LevelExt = '.mlvl'
-
-# load the configuration file
-config = utils.getXMLRoot(ConfigFile)
-
-#for each level folder, scan for and process any Muthris level files (.mlvl)
-levels = []
-folders = config.xpath('//level-folders/folder/@location')
-for folder in folders:
- #search for files in the level folder
- list = os.listdir(folder)
- print(list)
- for path in list:
- #make sure path is not just the filename, as isfile() would fail if it was
- path = folder + '/' + path
-
- #only want level files
- if not os.path.isfile(path):
- continue
- if not path.endswith(LevelExt):
- continue
-
- #create a level object for this level file
- level = LevelInfo( path )
- levels.append( level )
-
-print( config )
-print( folders )
-
-
-
-# find all the level folders
-
-# load all the level folders
-# start the menus
+import sys
+sys.path.append('/home/doug/workspace/Muthris/src/')
-print( 'done' )
+import menus
+from utils import strs
+# setup logging
+import logging
+logging.basicConfig(filename=strs.LoggingFile,level=logging.DEBUG)
+log = logging.getLogger('setup.main')
-def processLevelFile( file ):
- ''' '''
- pass
+# start the menus
+
+menus.begin()
+
+print( 'done' )
diff --git a/src/setup/menus.py b/src/setup/menus.py
new file mode 100644
index 0000000..e229277
--- /dev/null
+++ b/src/setup/menus.py
@@ -0,0 +1,191 @@
+'''
+
+'''
+
+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 = []
+ self.profiles = []
+ self.profile = None
+ self.screen = None
+
+
+# -----------------------------------------------------------------------------
+# 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()
+
+ # 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()
+
+ # 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):
+ ''' '''
+
+ # check for required vars
+ # clear the screen and display the title
+ # display the menu
+ # refresh the screen
+ # wait for input
+ # process input
+
+ pass
+
+def levelOptionsMenu(data):
+ ''' '''
+ pass
+
+def skillLevelMenu(data):
+ ''' '''
+ 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)
+
diff --git a/src/setup/profile.py b/src/setup/profile.py
new file mode 100644
index 0000000..0aceea3
--- /dev/null
+++ b/src/setup/profile.py
@@ -0,0 +1,30 @@
+'''
+
+'''
+
+from lxml import etree # using lxml for XML processing
+from utils import strs # string constants
+from utils import utils # some XML utilities
+
+
+
+class Profile(object):
+ '''
+ '''
+
+ def __init__(self, path):
+ '''
+ Constructor
+ '''
+
+ #open up the mpro file and read in its basic properties
+ root = utils.getXMLRoot(path)
+ self.name = root.xpath(strs.XP_ProfileName)[0]
+ self.path = path
+ pass
+
+ def getName(self):
+ '''Returns the name of the profile's user'''
+ return self.name
+
+
diff --git a/src/setup/profiles.py b/src/setup/profiles.py
new file mode 100644
index 0000000..3282a62
--- /dev/null
+++ b/src/setup/profiles.py
@@ -0,0 +1,31 @@
+'''
+
+'''
+
+import os # file path support
+from lxml import etree # using lxml for XML processing
+from utils import utils # some XML utilities
+from utils import strs # string constants
+
+# setup logging
+import logging # logging support
+logging.basicConfig(level=logging.DEBUG)
+log = logging.getLogger('setup.profiles')
+
+
+
+def findAllProfiles():
+ ''' '''
+ pass
+
+def getLastUsedProfile():
+ ''' '''
+ pass
+
+def createNewProfile():
+ ''' '''
+ pass
+
+
+
+
diff --git a/src/utils/__init__.py b/src/utils/__init__.py
index e69de29..a003759 100644
--- a/src/utils/__init__.py
+++ b/src/utils/__init__.py
@@ -0,0 +1 @@
+# this is a package
diff --git a/src/utils/strs.py b/src/utils/strs.py
new file mode 100644
index 0000000..4059bbf
--- /dev/null
+++ b/src/utils/strs.py
@@ -0,0 +1,35 @@
+'''
+Created on Jul 5, 2009
+
+@author: doug
+'''
+
+# files
+ConfigFile = '/home/doug/workspace/Muthris/docs/examples/config.xml'
+LoggingFile = '/tmp/muthris-dev.log'
+
+# file extensions
+Ext_Level = '.mlvl'
+Ext_Profile = '.mpro'
+
+# XML locations
+XP_LevelFolderLocation = '/muthris/config/level-folders/folder/@location'
+XP_ProfileFolderLocation = '/muthris/config/profile-folders/folder/@location'
+XP_LastProfileName = '/muthris/config/last/profile/@name'
+XP_LevelName = '/muthris/level/@name'
+XP_LevelDescription = '/muthris/level/@description'
+XP_ProfileName = '/muthris/profile/@name'
+
+# menu titles
+Title_Main = 'Main Menu'
+Title_ChangePlayer = 'Change Player'
+Title_PlayGame = 'Play Game'
+# Title_LevelOptions = '' # title uses the name of the level
+Title_SkillLevel = 'Skill Level'
+Title_NumberOfPlayers = 'Number of Players'
+Title_Seperator = ' - '
+
+# indent spacing for curses
+Indent_Title = 25
+Indent_Options = 10
+Indent_Prompt = 5 \ No newline at end of file