From e3b562e2100c60bc0993490dcf5a423927020800 Mon Sep 17 00:00:00 2001 From: BattleJenkins Date: Wed, 6 Jun 2018 18:05:26 -0700 Subject: [PATCH] Documentation, min/max actually works on numbers now --- evennia/contrib/fieldfill.py | 174 +++++++++++++++++++++++++++++------ 1 file changed, 145 insertions(+), 29 deletions(-) diff --git a/evennia/contrib/fieldfill.py b/evennia/contrib/fieldfill.py index 312ddc658..7a41e5202 100644 --- a/evennia/contrib/fieldfill.py +++ b/evennia/contrib/fieldfill.py @@ -1,30 +1,134 @@ """ -Fyield Fyill +Easy fillable form + +Contrib - Tim Ashley Jenkins 2018 + +This module contains a function that calls an easily customizable EvMenu - this +menu presents the player with a fillable form, with fields that can be filled +out in any order. Each field's value can be verified, with the function +allowing easy checks for text and integer input, minimum and maximum values / +character lengths, or can even be verified by a custom function. Once the form +is submitted, the form's data is submitted as a dictionary to any callable of +your choice. + +Form templates are defined as a list of dictionaries - each dictionary +represents a field in the form, and contains the data for the field's name and +behavior. For example, this basic form template will allow a player to fill out +a brief character profile: + + PROFILE_TEMPLATE = [ + {"fieldname":"Name", "fieldtype":"text"}, + {"fieldname":"Age", "fieldtype":"number"}, + {"fieldname":"History", "fieldtype":"text"} + ] + +This will present the player with an EvMenu showing this basic form: + + Name: + Age: + History: + +While in this menu, the player can assign a new value to any field with the +syntax = , like so: + + > name = Ashley + Field 'Name' set to: Ashley + +Typing 'show' by itself will show the form and its current values. + + > show + + Name: Ashley + Age: + History: + +Number fields require an integer input, and will reject any text that can't +be converted into an integer. + + > age = youthful + Field 'Age' requires a number. + > age = 31 + Field 'Age' set to: 31 + +Form data is presented as an EvTable, so text of any length will wrap cleanly. + + > history = EVERY MORNING I WAKE UP AND OPEN PALM SLAM[...] + Field 'History' set to: EVERY MORNING I WAKE UP AND[...] + > show + + Name: Ashley + Age: 31 + History: EVERY MORNING I WAKE UP AND OPEN PALM SLAM A VHS INTO THE SLOT. + IT'S CHRONICLES OF RIDDICK AND RIGHT THEN AND THERE I START DOING + THE MOVES ALONGSIDE WITH THE MAIN CHARACTER, RIDDICK. I DO EVERY + MOVE AND I DO EVERY MOVE HARD. + +When the player types 'submit' (or your specified submit command), the menu +quits and the form's data is passed to your specified function as a dictionary, +like so: + + formdata = {"Name":"Ashley", "Age":31, "History":"EVERY MORNING I[...]"} + +You can do whatever you like with this data in your function - forms can be used +to set data on a character, to help builders create objects, or for players to +craft items or perform other complicated actions with many variables involved. + +The data that your form will accept can also be specified in your form template - +let's say, for example, that you won't accept ages under 18 or over 100. You can +do this by specifying "min" and "max" values in your field's dictionary: + + PROFILE_TEMPLATE = [ + {"fieldname":"Name", "fieldtype":"text"}, + {"fieldname":"Age", "fieldtype":"number", "min":18, "max":100}, + {"fieldname":"History", "fieldtype":"text"} + ] + +Now if the player tries to enter a value out of range, the form will not acept the +given value. + + > age = 10 + Field 'Age' reqiures a minimum value of 18. + > age = 900 + Field 'Age' has a maximum value of 100. + +Setting 'min' and 'max' for a text field will instead act as a minimum or +maximum character length for the player's input. + +There are lots of ways to present the form to the player - fields can have default +values or show a custom message in place of a blank value, and player input can be +verified by a custom function, allowing for a great deal of flexibility. + +This module contains a simple example form that demonstrates all of the included +functionality - a command that allows a player to compose a message to another +online character and have it send after a custom delay. You can test it by +importing this module in your game's default_cmdsets.py module and adding +CmdTestMenu to your default character's command set. + +FIELD TEMPLATE KEYS: +Required: + fieldname (str): Name of the field, as presented to the player + fieldtype (str):Type of value required, either 'text' or 'number' + +Optional: + max (int): Maximum character length (if text) or value (if number) + min (int): Minimum charater length (if text) or value (if number) + default (str): Initial value (blank if not given) + blankmsg (str): Message to show in place of value when field is blank + cantclear (bool): Field can't be cleared if True + required (bool): If True, form cannot be submitted while field is blank + verifyfunc (callable): Name of a callable used to verify input - takes + (caller, value) as arguments. If the function returns True, + the player's input is considered valid - if it returns False, + the input is rejected. Any other value returned will act as + the field's new value, replacing the player's input. This + allows for values that aren't strings or integers (such as + object dbrefs). """ from evennia.utils import evmenu, evtable, delay, list_to_string from evennia import Command from evennia.server.sessionhandler import SESSIONS -""" -Complete field data is sent to the given callable as a dictionary (field:value pairs) - -FORM LIST/DICTIONARY VALUES: -Required: - fieldname - Name of the field as presented to the player - fieldtype - Type of field, either 'text' or 'number' - -Optional: - max - Maximum character length (if text) or value (if number) - min - Minimum charater length (if text) or value (if number) - default - Initial value (blank if not given) - blankmsg - Message to show when field is blank - cantclear - Field can't be cleared if True - required - If True, form cannot be submitted while field is blank - verifyfunc - Name of a callable used to verify input -""" - - class FieldEvMenu(evmenu.EvMenu): """ Custom EvMenu type with its own node formatter - removes extraneous lines @@ -47,7 +151,8 @@ class FieldEvMenu(evmenu.EvMenu): return nodetext -def init_fill_field(formtemplate, caller, callback, pretext="", posttext="", submitcmd="submit", borderstyle="cells"): +def init_fill_field(formtemplate, caller, callback, pretext="", posttext="", + submitcmd="submit", borderstyle="cells"): """ Presents a player with a fillable form. """ @@ -86,14 +191,14 @@ def menunode_fieldfill(caller, raw_string, **kwargs): # Syntax error syntax_err = "Syntax: = |/Or: clear , help, show, quit|/'%s' to submit form" % submitcmd - # Set help text, including listing the 'submit' command - help_text = """Available commands: -|w = :|n Set given field to new value, replacing the old value -|wclear :|n Clear the value in the given field, making it blank -|wshow|n: Show the form's current values -|whelp|n: Display this help screen -|wquit|n: Quit the form menu without submitting -|w%s|n: Submit this form and quit the menu""" % submitcmd + # Set help text, including listing the given 'submit' command + help_text = ("Available commands:|/" + "|w = :|n Set given field to new value, replacing the old value|/" + "|wclear :|n Clear the value in the given field, making it blank|/" + "|wshow|n: Show the form's current values|/" + "|whelp|n: Display this help screen|/" + "|wquit|n: Quit the form menu without submitting|/" + "|w%s|n: Submit this form and quit the menu" % submitcmd) # Display current form data text = (display_formdata(formtemplate, formdata, pretext=pretext, @@ -225,6 +330,17 @@ def menunode_fieldfill(caller, raw_string, **kwargs): caller.msg("Field '%s' requires a number." % matched_field) text = (None, help_text) return text, options + # Test for max/min + if max_value != None: + if newvalue > max_value: + caller.msg("Field '%s' has a maximum value of %i." % (matched_field, max_value)) + text = (None, help_text) + return text, options + if min_value != None: + if newvalue < min_value: + caller.msg("Field '%s' reqiures a minimum value of %i." % (matched_field, min_value)) + text = (None, help_text) + return text, options # Call verify function if present if verifyfunc: