Add function to easily create yes/no user question
This commit is contained in:
parent
bf4f532643
commit
362b5d1bfd
2 changed files with 171 additions and 1 deletions
|
|
@ -45,6 +45,8 @@
|
||||||
- Add `evennia/utils/verb_conjugation` for automatic verb conjugation (English only). This
|
- Add `evennia/utils/verb_conjugation` for automatic verb conjugation (English only). This
|
||||||
is useful for implementing actor-stance emoting for sending a string to different targets.
|
is useful for implementing actor-stance emoting for sending a string to different targets.
|
||||||
- New version of Italian translation (rpolve)
|
- New version of Italian translation (rpolve)
|
||||||
|
- `utils.evmenu.ask_yes_no` is a helper function that makes it easy to ask a yes/no question
|
||||||
|
to the user and respond to their input. This complements the existing `get_input` helper.
|
||||||
|
|
||||||
### Evennia 0.9.5 (2019-2020)
|
### Evennia 0.9.5 (2019-2020)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1554,7 +1554,7 @@ class InputCmdSet(CmdSet):
|
||||||
self.add(CmdGetInput())
|
self.add(CmdGetInput())
|
||||||
|
|
||||||
|
|
||||||
class _Prompt(object):
|
class _Prompt:
|
||||||
"""Dummy holder"""
|
"""Dummy holder"""
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
@ -1621,6 +1621,174 @@ def get_input(caller, prompt, callback, session=None, *args, **kwargs):
|
||||||
caller.msg(prompt, session=session)
|
caller.msg(prompt, session=session)
|
||||||
|
|
||||||
|
|
||||||
|
class CmdYesNoQuestion(Command):
|
||||||
|
"""
|
||||||
|
Handle a prompt for yes or no. Press [return] for the default choice.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
key = _CMD_NOINPUT
|
||||||
|
aliases = [_CMD_NOMATCH, "yes", "no", 'y', 'n', 'a', 'abort']
|
||||||
|
arg_regex = r"^$"
|
||||||
|
|
||||||
|
def _clean(self):
|
||||||
|
del self.caller.ndb._yes_no_question
|
||||||
|
self.caller.cmdset.remove(YesNoQuestionCmdSet)
|
||||||
|
|
||||||
|
|
||||||
|
def func(self):
|
||||||
|
"""This is called when user enters anything."""
|
||||||
|
caller = self.caller
|
||||||
|
try:
|
||||||
|
yes_no_question = caller.ndb._yes_no_question
|
||||||
|
if not yes_no_question and hasattr(caller, "account"):
|
||||||
|
yes_no_question = caller.account.ndb._yes_no_question
|
||||||
|
caller = caller.account
|
||||||
|
|
||||||
|
inp = self.cmdname
|
||||||
|
|
||||||
|
if inp == _CMD_NOINPUT:
|
||||||
|
raw = self.raw_cmdname.strip()
|
||||||
|
if not raw:
|
||||||
|
# use default
|
||||||
|
inp = yes_no_question.default
|
||||||
|
else:
|
||||||
|
inp = raw
|
||||||
|
|
||||||
|
if inp in ('a', 'abort') and yes_no_question.allow_abort:
|
||||||
|
caller.msg("Aborted.")
|
||||||
|
self._clean()
|
||||||
|
return
|
||||||
|
|
||||||
|
caller.ndb._yes_no_question.session = self.session
|
||||||
|
|
||||||
|
args = yes_no_question.args
|
||||||
|
kwargs = yes_no_question.kwargs
|
||||||
|
kwargs['caller_session'] = self.session
|
||||||
|
|
||||||
|
ok = False
|
||||||
|
if inp in ('yes', 'y'):
|
||||||
|
yes_no_question.yes_callable(caller, *args, **kwargs)
|
||||||
|
elif inp in ('no', 'n'):
|
||||||
|
yes_no_question.no_callable(caller, *args, **kwargs)
|
||||||
|
else:
|
||||||
|
# invalid input. Resend prompt without cleaning
|
||||||
|
caller.msg(yes_no_question.prompt, session=self.session)
|
||||||
|
return
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
self._clean()
|
||||||
|
except Exception:
|
||||||
|
# make sure to clean up cmdset if something goes wrong
|
||||||
|
caller.msg("|rError in ask_yes_no. Choice not confirmed (report to admin)|n")
|
||||||
|
logger.log_trace("Error in ask_yes_no")
|
||||||
|
self._clean()
|
||||||
|
|
||||||
|
|
||||||
|
class YesNoQuestionCmdSet(CmdSet):
|
||||||
|
"""
|
||||||
|
This stores the input command
|
||||||
|
"""
|
||||||
|
|
||||||
|
key = "yes_no_question_cmdset"
|
||||||
|
priority = 1
|
||||||
|
mergetype = "Replace"
|
||||||
|
no_objs = True
|
||||||
|
no_exits = True
|
||||||
|
no_channels = False
|
||||||
|
|
||||||
|
def at_cmdset_creation(self):
|
||||||
|
"""called once at creation"""
|
||||||
|
self.add(CmdYesNoQuestion())
|
||||||
|
|
||||||
|
|
||||||
|
def ask_yes_no(caller, prompt, yes_action, no_action, default=None,
|
||||||
|
allow_abort=False, session=None, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
A helper question for asking a simple yes/no question. This will cause
|
||||||
|
the system to pause and wait for input from the player.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
prompt (str): The yes/no question to ask. This takes an optional formatting
|
||||||
|
marker `{suffix}` which will be filled with 'Y/N', [Y]/N or Y/[N]
|
||||||
|
depending on the setting of `default`. If `allow_abort`, then the
|
||||||
|
`A(bort)` will also be available.
|
||||||
|
yes_action (callable or str): If a callable, this will be called
|
||||||
|
with `(caller, *args, **kwargs) when the yes-choice is made.
|
||||||
|
If a string, this string will be echoed back to the caller.
|
||||||
|
no_action (callable or str): If a callable, this will be called
|
||||||
|
with `(caller, *args, **kwargs)` when the no-choice is made.
|
||||||
|
If a string, this string will be echoed back to the caller.
|
||||||
|
default (str optional): One of "N", "Y", "A" or None for no default.
|
||||||
|
If "A" is given, `allow_abort` is assumed set. The user can choose
|
||||||
|
the default option just by pressing return.
|
||||||
|
allow_abort (bool, optional): If set, the Q(uit) option is available,
|
||||||
|
which is neither yes or no.
|
||||||
|
session (Session, optional): This allows to specify the
|
||||||
|
session to send the prompt to. It's usually only needed if `caller`
|
||||||
|
is an Account in multisession modes greater than 2. The session is
|
||||||
|
then updated by the command and is available (for example in
|
||||||
|
callbacks) through `caller.ndb._yes_no_question.session`.
|
||||||
|
*args, **kwargs: These are passed into the callables, if any.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
RuntimeError: If default and allow_abort clashes.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
ask_yes_no(caller, "Are you happy {suffix}?",
|
||||||
|
"you answered yes", "you answered no")
|
||||||
|
ask_yes_no(caller, "Are you sad {suffix}?",
|
||||||
|
_callable_yes, _callable_no, allow_abort=True)
|
||||||
|
|
||||||
|
"""
|
||||||
|
def _callable_yes_txt(caller, *args, **kwargs):
|
||||||
|
yes_txt = kwargs['yes_txt']
|
||||||
|
session = kwargs['caller_session']
|
||||||
|
caller.msg(yes_txt, session=session)
|
||||||
|
|
||||||
|
def _callable_no_txt(caller, *args, **kwargs):
|
||||||
|
no_txt = kwargs['no_txt']
|
||||||
|
session = kwargs['caller_session']
|
||||||
|
caller.msg(no_txt, session=session)
|
||||||
|
|
||||||
|
if not callable(yes_action):
|
||||||
|
kwargs['yes_txt'] = str(yes_action)
|
||||||
|
yes_action = _callable_yes_txt
|
||||||
|
|
||||||
|
if not callable(no_action):
|
||||||
|
kwargs['no_txt'] = str(no_action)
|
||||||
|
no_action = _callable_no_txt
|
||||||
|
|
||||||
|
# prepare the prompt with suffix
|
||||||
|
suffix = "Y/N"
|
||||||
|
abort_txt = "/Abort" if allow_abort else ""
|
||||||
|
if default:
|
||||||
|
default = default.lower()
|
||||||
|
if default == "y":
|
||||||
|
suffix = "[Y]/N"
|
||||||
|
elif default == "n":
|
||||||
|
suffix = "Y/[N]"
|
||||||
|
elif default == "a":
|
||||||
|
allow_abort = True
|
||||||
|
abort_txt = "/[A]bort"
|
||||||
|
suffix += abort_txt
|
||||||
|
prompt = prompt.format(suffix=suffix)
|
||||||
|
|
||||||
|
caller.ndb._yes_no_question = _Prompt()
|
||||||
|
caller.ndb._yes_no_question.session = session
|
||||||
|
caller.ndb._yes_no_question.prompt = prompt
|
||||||
|
caller.ndb._yes_no_question.default = default
|
||||||
|
caller.ndb._yes_no_question.allow_abort = allow_abort
|
||||||
|
caller.ndb._yes_no_question.yes_callable = yes_action
|
||||||
|
caller.ndb._yes_no_question.no_callable = no_action
|
||||||
|
caller.ndb._yes_no_question.args = args
|
||||||
|
caller.ndb._yes_no_question.kwargs = kwargs
|
||||||
|
|
||||||
|
caller.cmdset.add(YesNoQuestionCmdSet)
|
||||||
|
caller.msg(prompt, session=session)
|
||||||
|
|
||||||
|
|
||||||
# -------------------------------------------------------------
|
# -------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Menu generation from menu template string
|
# Menu generation from menu template string
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue