Added the ability to input a menu dictionary in EvMenu rather than only rely on input modules.

This commit is contained in:
Griatch 2015-09-17 14:12:29 +02:00
parent cb0417fe7f
commit a4e081f11c

View file

@ -266,7 +266,7 @@ class EvMenu(object):
a menufile.py instruction. a menufile.py instruction.
""" """
def __init__(self, caller, menufile, startnode="start", def __init__(self, caller, menudata, startnode="start",
cmdset_mergetype="Replace", cmdset_priority=1, cmdset_mergetype="Replace", cmdset_priority=1,
allow_quit=True, cmd_on_quit="look"): allow_quit=True, cmd_on_quit="look"):
""" """
@ -274,8 +274,15 @@ class EvMenu(object):
Args: Args:
caller (str): The user of the menu. caller (str): The user of the menu.
menufile (str): The full or relative path to the menufile. menudata (str, module or dict): The full or relative path to the module
startnode (str, optional): The starting node in the menufile. holding the menu tree data. All global functions in this module
whose name doesn't start with '_ ' will be parsed as menu nodes.
Also the module itself is accepted as input. Finally, a dictionary
menu tree can be given directly. This must then be a mapping
`{"nodekey":callable,...}` where `callable` must be called as
and return the data expected of a menu node. This allows for
dynamic menu creation.
startnode (str, optional): The starting node name in the menufile.
cmdset_mergetype (str, optional): 'Replace' (default) means the menu cmdset_mergetype (str, optional): 'Replace' (default) means the menu
commands will be exclusive - no other normal commands will commands will be exclusive - no other normal commands will
be usable while the user is in the menu. 'Union' means the be usable while the user is in the menu. 'Union' means the
@ -303,7 +310,7 @@ class EvMenu(object):
""" """
self._caller = caller self._caller = caller
self._startnode = startnode self._startnode = startnode
self._menutree = self._parse_menufile(menufile) self._menutree = self._parse_menudata(menudata)
if startnode not in self._menutree: if startnode not in self._menutree:
raise EvMenuError("Start node '%s' not in menu tree!" % startnode) raise EvMenuError("Start node '%s' not in menu tree!" % startnode)
@ -327,22 +334,30 @@ class EvMenu(object):
# start the menu # start the menu
self.goto(self._startnode, "") self.goto(self._startnode, "")
def _parse_menufile(self, menufile): def _parse_menudata(self, menudata):
""" """
Parse a menufile, split it into #node sections, convert Parse a menufile for node functions and store in dictionary
each to an executable python code and store in a dictionary map. map. Alternatively, accept a pre-made mapping dictionary of
node functions.
Args: Args:
menufile (str or module): The python.path to the menufile, menudata (str, module or dict): The python.path to the menufile,
or the python module itself. or the python module itself. If a dict, this should be a
mapping nodename:callable, where the callable must match
the criteria for a menu node.
Returns: Returns:
menutree (dict): A {nodekey: func} menutree (dict): A {nodekey: func}
""" """
module = mod_import(menufile) if isinstance(menudata, dict):
return dict((key, func) for key, func in module.__dict__.items() # This is assumed to be a pre-loaded menu tree.
if isfunction(func) and not key.startswith("_")) return menudata
else:
# a python path of a module
module = mod_import(menudata)
return dict((key, func) for key, func in module.__dict__.items()
if isfunction(func) and not key.startswith("_"))
def _format_node(self, nodetext, optionlist): def _format_node(self, nodetext, optionlist):
""" """