mirror of
https://github.com/evennia/evennia.git
synced 2026-03-23 08:16:30 +01:00
Gave EvMenu a 'persistent' option (False by default). This makes the menu survive a server reboot, including remembering its last node. Use with caution during debugging. Changed the EvMenu API so allow_exit is now auto_exit, which better describes its functionality. Also added auto_look and auto_help flags for turning off the respective automatic options (Resolves #949)."
This commit is contained in:
parent
3b8142201d
commit
74a339574a
1 changed files with 66 additions and 23 deletions
|
|
@ -14,7 +14,7 @@ To start the menu, just import the EvMenu class from this module,
|
|||
EvMenu(caller, menu_module_path,
|
||||
startnode="node1",
|
||||
cmdset_mergetype="Replace", cmdset_priority=1,
|
||||
allow_quit=True, cmd_on_quit="look")
|
||||
auto_quit=True, cmd_on_exit="look")
|
||||
```
|
||||
|
||||
Where `caller` is the Object to use the menu on - it will get a new
|
||||
|
|
@ -195,6 +195,17 @@ class CmdEvMenuNode(Command):
|
|||
"""
|
||||
caller = self.caller
|
||||
menu = caller.ndb._menutree or self.session.ndb._menutree
|
||||
if not menu:
|
||||
# check if there is a saved menu available
|
||||
saved_options = caller.attributes.get("_menutree_saved")
|
||||
if saved_options:
|
||||
startnode = caller.attributes.get("_menutree_saved_startnode")
|
||||
if startnode:
|
||||
saved_options[1]["startnode"] = startnode
|
||||
# this will create a completely new menu call
|
||||
EvMenu(caller, *saved_options[0], **saved_options[1])
|
||||
|
||||
return
|
||||
|
||||
if not menu:
|
||||
err = "Menu object not found as %s.ndb._menutree!" % (caller)
|
||||
|
|
@ -326,18 +337,17 @@ def evtable_parse_input(menuobject, raw_string, caller):
|
|||
the menu.
|
||||
"""
|
||||
cmd = raw_string.strip().lower()
|
||||
allow_quit = menuobject.allow_quit
|
||||
|
||||
if cmd in menuobject.options:
|
||||
# this will take precedence over the default commands
|
||||
# below
|
||||
goto, callback = menuobject.options[cmd]
|
||||
menuobject.callback_goto(callback, goto, raw_string)
|
||||
elif cmd in ("look", "l"):
|
||||
elif menuobject.auto_look and cmd in ("look", "l"):
|
||||
menuobject.display_nodetext()
|
||||
elif cmd in ("help", "h"):
|
||||
elif menuobject.auto_help and cmd in ("help", "h"):
|
||||
menuobject.display_helptext()
|
||||
elif allow_quit and cmd in ("quit", "q", "exit"):
|
||||
elif menuobject.auto_quit and cmd in ("quit", "q", "exit"):
|
||||
menuobject.close_menu()
|
||||
elif menuobject.default:
|
||||
goto, callback = menuobject.default
|
||||
|
|
@ -363,7 +373,8 @@ class EvMenu(object):
|
|||
"""
|
||||
def __init__(self, caller, menudata, startnode="start",
|
||||
cmdset_mergetype="Replace", cmdset_priority=1,
|
||||
allow_quit=True, cmd_on_quit="look",
|
||||
auto_quit=True, auto_look=True, auto_help=True,
|
||||
cmd_on_exit="look", persistent=False,
|
||||
nodetext_formatter=dedent_strip_nodetext_formatter,
|
||||
options_formatter=evtable_options_formatter,
|
||||
node_formatter=underline_node_formatter,
|
||||
|
|
@ -394,16 +405,28 @@ class EvMenu(object):
|
|||
cmdset_priority (int, optional): The merge priority for the
|
||||
menu command set. The default (1) is usually enough for most
|
||||
types of menus.
|
||||
allow_quit (bool, optional): Allow user to use quit or
|
||||
exit to leave the menu at any point. Recommended during
|
||||
auto_quit (bool, optional): Allow user to use "q", "quit" or
|
||||
"exit" to leave the menu at any point. Recommended during
|
||||
development!
|
||||
cmd_on_quit (callable, str or None, optional): When exiting the menu
|
||||
auto_look (bool, optional): Automatically make "looK" or "l" to
|
||||
re-show the last node. Turning this off means you have to handle
|
||||
re-showing nodes yourself, but may be useful if you need to
|
||||
use "l" for some other purpose.
|
||||
auto_help (bool, optional): Automatically make "help" or "h" show
|
||||
the current help entry for the node. If turned off, eventual
|
||||
help must be handled manually, but it may be useful if you
|
||||
need 'h' for some other purpose, for example.
|
||||
cmd_on_exit (callable, str or None, optional): When exiting the menu
|
||||
(either by reaching a node with no options or by using the
|
||||
in-built quit command (activated with `allow_quit`), this
|
||||
callback function or command string will be executed.
|
||||
The callback function takes two parameters, the caller then the
|
||||
EvMenu object. This is called after cleanup is complete.
|
||||
Set to None to not call any command.
|
||||
persistent (bool, optional): Make the Menu persistent (i.e. it will
|
||||
survive a reload. This will make the Menu cmdset persistent. Use
|
||||
with caution - if your menu is buggy you may end up in a state
|
||||
you can't get out of!
|
||||
nodetext_formatter (callable, optional): This callable should be on
|
||||
the form `function(nodetext, has_options, caller=None)`, where `nodetext` is the
|
||||
node text string and `has_options` a boolean specifying if there
|
||||
|
|
@ -448,6 +471,7 @@ class EvMenu(object):
|
|||
self._options_formatter = options_formatter
|
||||
self._node_formatter = node_formatter
|
||||
self._input_parser = input_parser
|
||||
self._persistent = persistent
|
||||
|
||||
if startnode not in self._menutree:
|
||||
raise EvMenuError("Start node '%s' not in menu tree!" % startnode)
|
||||
|
|
@ -455,19 +479,20 @@ class EvMenu(object):
|
|||
# public variables made available to the command
|
||||
|
||||
self.caller = caller
|
||||
self.allow_quit = allow_quit
|
||||
if isinstance(cmd_on_quit, str):
|
||||
self.cmd_on_quit = lambda caller, menu: caller.execute_cmd(cmd_on_quit)
|
||||
elif callable(cmd_on_quit):
|
||||
self.cmd_on_quit = cmd_on_quit
|
||||
self.auto_quit = auto_quit
|
||||
self.auto_look = auto_look
|
||||
self.auto_help = auto_help
|
||||
if isinstance(cmd_on_exit, str):
|
||||
self.cmd_on_exit = lambda caller, menu: caller.execute_cmd(cmd_on_exit)
|
||||
elif callable(cmd_on_exit):
|
||||
self.cmd_on_exit = cmd_on_exit
|
||||
else:
|
||||
self.cmd_on_quit = None
|
||||
self.cmd_on_exit = None
|
||||
self.default = None
|
||||
self.nodetext = None
|
||||
self.helptext = None
|
||||
self.options = None
|
||||
|
||||
|
||||
# store ourself on the object
|
||||
self.caller.ndb._menutree = self
|
||||
|
||||
|
|
@ -475,7 +500,19 @@ class EvMenu(object):
|
|||
menu_cmdset = EvMenuCmdSet()
|
||||
menu_cmdset.mergetype = str(cmdset_mergetype).lower().capitalize() or "Replace"
|
||||
menu_cmdset.priority = int(cmdset_priority)
|
||||
self.caller.cmdset.add(menu_cmdset)
|
||||
self.caller.cmdset.add(menu_cmdset, permanent=persistent)
|
||||
if persistent:
|
||||
caller.attributes.add("_menutree_saved",
|
||||
((menudata, ),
|
||||
{"startnode": startnode,
|
||||
"cmdset_mergetype": cmdset_mergetype,
|
||||
"cmdset_priority": cmdset_priority,
|
||||
"auto_quit": auto_quit, "auto_look": auto_look, "auto_help": auto_help,
|
||||
"cmd_on_exit": cmd_on_exit, "persistent": persistent,
|
||||
"nodetext_formatter": nodetext_formatter, "options_formatter": options_formatter,
|
||||
"node_formatter": node_formatter, "input_parser": input_parser}))
|
||||
caller.attributes.add("_menutree_saved_startnode", startnode)
|
||||
|
||||
# start the menu
|
||||
self.goto(self._startnode, "")
|
||||
|
||||
|
|
@ -633,6 +670,9 @@ class EvMenu(object):
|
|||
except EvMenuError:
|
||||
return
|
||||
|
||||
if self._persistent:
|
||||
self.caller.attributes.add("_menutree_saved_startnode", nodename)
|
||||
|
||||
# validation of the node return values
|
||||
helptext = ""
|
||||
if hasattr(nodetext, "__iter__"):
|
||||
|
|
@ -674,20 +714,23 @@ class EvMenu(object):
|
|||
if helptext:
|
||||
self.helptext = helptext
|
||||
elif options:
|
||||
self.helptext = _HELP_FULL if self.allow_quit else _HELP_NO_QUIT
|
||||
self.helptext = _HELP_FULL if self.auto_quit else _HELP_NO_QUIT
|
||||
else:
|
||||
self.helptext = _HELP_NO_OPTIONS if self.allow_quit else _HELP_NO_OPTIONS_NO_QUIT
|
||||
self.helptext = _HELP_NO_OPTIONS if self.auto_quit else _HELP_NO_OPTIONS_NO_QUIT
|
||||
|
||||
self.display_nodetext()
|
||||
|
||||
def close_menu(self):
|
||||
"""
|
||||
Shutdown menu; occurs when reaching the end node.
|
||||
Shutdown menu; occurs when reaching the end node or using the quit command.
|
||||
"""
|
||||
self.caller.cmdset.remove(EvMenuCmdSet)
|
||||
del self.caller.ndb._menutree
|
||||
if self.cmd_on_quit is not None:
|
||||
self.cmd_on_quit(self.caller, self)
|
||||
if self._persistent:
|
||||
self.caller.attributes.remove("_menutree_saved")
|
||||
self.caller.attributes.remove("_menutree_saved_startnode")
|
||||
if self.cmd_on_exit is not None:
|
||||
self.cmd_on_exit(self.caller, self)
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------------------------------
|
||||
|
|
@ -894,4 +937,4 @@ class CmdTestMenu(Command):
|
|||
self.caller.msg("Usage: testmenu menumodule")
|
||||
return
|
||||
# start menu
|
||||
EvMenu(self.caller, self.args.strip(), startnode="test_start_node", cmdset_mergetype="Replace")
|
||||
EvMenu(self.caller, self.args.strip(), startnode="test_start_node", persistent=True, cmdset_mergetype="Replace")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue