Input Menus
An Input Menu is the scene an Input command opens, for the player to enter text, such as a name.
Any scene can be an Input Menu: a text field, a name picker, a keypad, a mini-game... It only has to follow a few rules to communicate with the Engine. A template is provided as a starting point. Using Input scenes in Dialogues is covered in Player Input.
- Template script: Input_Text.gd, in Scripts/UI_Elements/Input_UI
- Templates: Scenes/Input_Menus
- Updates: the script is 'unsafe', and so is every template except Default.tscn (see Customizing UI Elements, on the UI page)
- Engine path: input_node_path in ui_elements_paths
Opening
Input Menus aren't placed in your scene in advance. The Input command loads the scene its Line names (looked up in input_menus_folder, in Candy_Properties.gd), and adds it to the node at input_node_path, usually a plain Control covering the screen. A Line can add it to another node instead, with its Parent key, such as a screen in the game world (see Input).
The new node is named after the scene file. If a node of that name is already under the same parent (an Input Menu kept from an earlier Input), it's reused instead of a new one.
Clicking an Input Menu
The z_index only decides what is drawn on top, not what receives the mouse: Godot delivers a click to the last node in the scene tree. An Input Menu opened over a choice menu (from a choice's Lines) must therefore come after the choice menus' node in the scene tree, or the choice menu's shield intercepts its clicks, even though the Input Menu is drawn on top. In Candy_UI.tscn, the input_node_path node follows the choices_path node for this reason. Preserve that order in your own dialogue UI, and when you choose a Parent.
An Input Menu may change the mouse mode freely: the Input command restores the mouse mode it started with once it's done.
Rules for Any Input Menu
Variables
The script attached to the scene's root must declare these two variables, which the Input command sets:
var caller: Node
var depth
- caller: the Engine running the Input command.
- depth: the nesting depth of that Input command, which every event must send back.
Functions the Input command calls
All of them are optional:
| Function | Called |
| setup(save, mode, instructions, default_text, placeholder, custom_data) | Right after the scene is added (or reused). Receives the Input command's values (see Input), and its Custom Data as [[values]]. |
| suspend_on() | When the Dialogue is suspended (see Suspending Dialogues). |
| suspend_off() | When the Dialogue resumes. |
| dialogue_ended() | When the Dialogue ends, for every Input Menu the Engine's Input commands opened that is still open, wherever it was added. |
| refresh_language() | When the Engine's refresh_language() is called while the scene is open. The template displays its texts again in the current language (see Translating UI Texts). |
Events
The Input Menu instructs the Input command by emitting the Engine's input_received signal:
caller.input_received.emit(depth, "finish", null)
The second argument is the event, and the third the data it requires:
| Event | Effect |
"finish" | Leaves the Input command, and the Dialogue carries on. The Input Menu is left as it is: hide it yourself. |
"close" | Leaves the Input command, and deletes the Input Menu. |
"run_lines" | Runs Dialogue Lines, then continues to wait for events. The data is an Array of Lines, written as in a Dialogue file. |
Store whatever the player entered yourself before sending "finish" or "close": the template's store_to_variable() is an example.
Custom events
Each event is a script in Scripts/Input_Events, named after the event (e.g. Run_Lines.gd for "run_lines"). To add an event, add a script there that extends CandyInputEvent and overrides handle(): the base class documents what it receives and what it may return. The scripts you add are 'safe': updates never change them. An event with no script leaves the Input command, with a warning.
The Template
Input_Text.gd is a barebones text input, meant to be expanded: it implements three modes ("Default", "Default_L" and "Default_NS"), with every check turned off. They differ only in how the input is stored (see Sanitization below). Its setup(), config(), submit() and cancel() functions each match on the mode, so new modes can be added as new cases.
Input_Text.gd is an 'unsafe' file: updates overwrite the modes you add to it. To expand it, copy it under a new name, in the same folder, attach the copy to your own Input scene, and add your modes to the copy. Your copy is 'safe'.
A mode the template doesn't implement, including an empty Mode, configures nothing: the scene opens without instructions and doesn't store what the player types. Set Mode to one of the template's modes to use it as it is, or add your own modes to a copy of it.
Nodes
| Variable | Node |
| input_line_path | Required. The LineEdit the player types in. |
| input_instructions_node | Required. A Label or RichTextLabel for the instructions. |
| input_error_node | Required. A Label or RichTextLabel for error messages. |
| input_confirm_button | Required. The confirm button. Connect its pressed signal to submit(). |
| input_cancel_button | Required. The cancel button. Connect its pressed signal to cancel(). |
Checks
config() defines what a valid input is, for each mode: minimum and maximum characters and words, allowed kinds of characters (uppercase, numbers, punctuation, spaces...), a regular expression, and blacklists or whitelists of words. submit() only accepts valid input; the reason for a refusal is displayed in input_error_node while show_errors is on.
Sanitization
Candy Dialogue Engine reads a stored value like any text: if the player types ¤¢globals.gold¤ as their name, a text variable displaying the name evaluates the expression; if the player types •he¦Alice•, a text variable displaying the name substitutes it; [b] formats it; a name identical to a Lexicon keyword is formatted like the keyword; and ¢globals.gold is evaluated wherever the value is read as an expression. sanitize() neutralizes that syntax when the input is stored, according to seven options set in config(); the "Default" mode turns them all on, "Default_L" and "Default_NS" turn them all off, and a mode of your own can turn any of them off.
| Option | What it does to the input |
| sanitize_text_variables | Escapes the text variable symbols, so they are displayed as written and the expression between them is never evaluated. |
| sanitize_substitutions | Escapes the Word Substitution symbols, so they are displayed as written. |
| sanitize_bbcode | Replaces every [ with [lb], so tags are displayed as written. A plain Label, outside Candy Dialogue Engine, displays the [lb] itself. |
| sanitize_expressions | Escapes a leading ¢, so the value is read as text and never evaluated. |
| sanitize_text_events | Escapes the Text Event symbols, so they are displayed as written and run no Event. |
| sanitize_candy_ref_symbols | Removes leading reference symbols (€, °, $, and any registered with CandyRef), so a value read as a reference isn't misinterpreted as a Role or a variable. |
| sanitize_lexicon | Encloses the whole input in the lexicon escape symbols (¬Alice¬), so the Lexicon never formats it. The symbols aren't displayed in spoken text. |
Each option is a function of the CandySanitizer class, which any code can call on a value from elsewhere (see Sanitization).
The symbols these sanitizations add stay in the stored value. Candy Dialogue Engine removes them in spoken text and in the speaker's name; to display the value in your own UI, or compare it with another text, remove the lexicon escape with CandySanitizer.remove_lexicon_escapes(text).
Literal Variables
The "Default_L" mode stores the input as typed, then adds the variable to the literal_variables list, in Literal_Variables.gd (User_Data/Data_Tables). Its record_literal option, set in config(), enables this, and its literal_allowed option names the syntax the value retains (empty in "Default_L": none). The Engine then reads the value as written wherever an expression or a text variable reads it, and the stored value isn't modified. See Sanitization.
Translations
The template translates its texts through Localization Tables, in User_Data/Localization_Tables: input_instructions, input_placeholder_texts, input_default_texts and input_error_messages. The blacklists and whitelists config() picks are read from the input_blacklists and input_whitelists tables, by name. As for choice menus, a text with no entry for the current language is shown as written.
Settings
| Setting | Purpose |
| default_z | The Input Menu's Z-order. |