Allow fields to choose whether they close on enter press
authorrubenwardy <rubenwardy@gmail.com>
Sun, 7 Aug 2016 15:22:50 +0000 (16:22 +0100)
committerrubenwardy <rubenwardy@gmail.com>
Sat, 27 Aug 2016 12:05:01 +0000 (13:05 +0100)
doc/lua_api.txt
src/guiFormSpecMenu.cpp
src/guiFormSpecMenu.h

index 440edd963f3b298177e2465c3c848481781823f0..579fe796e18f30a68657f48ec6df91ffb029626c 100644 (file)
@@ -1503,17 +1503,23 @@ examples.
 * If `true` the background is clipped to formspec size
   (`x` and `y` are used as offset values, `w` and `h` are ignored)
 
-#### `pwdfield[<X>,<Y>;<W>,<H>;<name>;<label>]`
+#### `pwdfield[<X>,<Y>;<W>,<H>;<name>;<label>;<close_on_enter>]`
 * Textual password style field; will be sent to server when a button is clicked
+* When enter is pressed in field, fields.key_enter_field will be sent with the name
+  of this field.
 * `x` and `y` position the field relative to the top left of the menu
 * `w` and `h` are the size of the field
 * Fields are a set height, but will be vertically centred on `h`
 * Position and size units are inventory slots
 * `name` is the name of the field as returned in fields to `on_receive_fields`
 * `label`, if not blank, will be text printed on the top left above the field
+* `close_on_enter` (optional) is whether the form should accept and close when enter is
+  pressed in this field. Defaults to true.
 
-#### `field[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]`
+#### `field[<X>,<Y>;<W>,<H>;<name>;<label>;<default>;<close_on_enter>]`
 * Textual field; will be sent to server when a button is clicked
+* When enter is pressed in field, fields.key_enter_field will be sent with the name
+  of this field.
 * `x` and `y` position the field relative to the top left of the menu
 * `w` and `h` are the size of the field
 * Fields are a set height, but will be vertically centred on `h`
@@ -1524,12 +1530,18 @@ examples.
     * `default` may contain variable references such as `${text}'` which
       will fill the value from the metadata value `text`
     * **Note**: no extra text or more than a single variable is supported ATM.
+* `close_on_enter` (optional) is whether the form should accept and close when enter is
+  pressed in this field. Defaults to true.
 
-#### `field[<name>;<label>;<default>]`
+#### `field[<name>;<label>;<default>;<close_on_enter>]`
 * As above, but without position/size units
+* When enter is pressed in field, fields.key_enter_field will be sent with the name
+  of this field.
 * Special field for creating simple forms, such as sign text input
 * Must be used without a `size[]` element
 * A "Proceed" button will be added automatically
+* `close_on_enter` (optional) is whether the form should accept and close when enter is
+  pressed in this field. Defaults to true.
 
 #### `textarea[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]`
 * Same as fields above, but with multi-line input
index dd96da5a99a9524279cdd07010d1c11318a84ad8..2564671a327c9595a1caf9429faf107e924ced3b 100644 (file)
@@ -894,8 +894,8 @@ void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element)
 {
        std::vector<std::string> parts = split(element,';');
 
-       if ((parts.size() == 4) ||
-               ((parts.size() > 4) && (m_formspec_version > FORMSPEC_API_VERSION)))
+       if ((parts.size() == 4) || (parts.size() == 5) ||
+               ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
        {
                std::vector<std::string> v_pos = split(parts[0],',');
                std::vector<std::string> v_geom = split(parts[1],',');
@@ -952,6 +952,11 @@ void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element)
                evt.KeyInput.Shift       = 0;
                evt.KeyInput.PressedDown = true;
                e->OnEvent(evt);
+
+               if (parts.size() >= 5 && !is_yes(parts[4])) {
+                       spec.close_on_enter = false;
+               }
+
                m_fields.push_back(spec);
                return;
        }
@@ -1033,6 +1038,10 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data,
                }
        }
 
+       if (parts.size() >= 4 && !is_yes(parts[3])) {
+               spec.close_on_enter = false;
+       }
+
        m_fields.push_back(spec);
 }
 
@@ -1137,6 +1146,11 @@ void GUIFormSpecMenu::parseTextArea(parserData* data,
                        addStaticText(Environment, spec.flabel.c_str(), rect, false, true, this, 0);
                }
        }
+
+       if (parts.size() >= 6 && !is_yes(parts[5])) {
+               spec.close_on_enter = false;
+       }
+
        m_fields.push_back(spec);
 }
 
@@ -1150,8 +1164,8 @@ void GUIFormSpecMenu::parseField(parserData* data,std::string element,
                return;
        }
 
-       if ((parts.size() == 5) ||
-               ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
+       if ((parts.size() == 5) || (parts.size() == 6) ||
+               ((parts.size() > 6) && (m_formspec_version > FORMSPEC_API_VERSION)))
        {
                parseTextArea(data,parts,type);
                return;
@@ -2698,6 +2712,7 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode=quit_mode_no)
 
                if (!current_field_enter_pending.empty()) {
                        fields["key_enter_field"] = current_field_enter_pending;
+                       current_field_enter_pending = "";
                }
 
                if (current_keys_pending.key_escape) {
@@ -3630,15 +3645,18 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 
                if (event.GUIEvent.EventType == gui::EGET_EDITBOX_ENTER) {
                        if (event.GUIEvent.Caller->getID() > 257) {
+                               bool close_on_enter = true;
                                for (u32 i = 0; i < m_fields.size(); i++) {
                                        FieldSpec &s = m_fields[i];
                                        if (s.ftype == f_Unknown &&
                                                        s.fid == event.GUIEvent.Caller->getID()) {
                                                current_field_enter_pending = s.fname;
+                                               close_on_enter = s.close_on_enter;
+                                               break;
                                        }
                                }
 
-                               if (m_allowclose) {
+                               if (m_allowclose && close_on_enter) {
                                        current_keys_pending.key_enter = true;
                                        acceptInput(quit_mode_accept);
                                        quitMenu();
index 7b809df7128b1c14ac18d8e7f7d881eb40732562..d06aa6cf5c319d468a12f0322d5458d7fd501ff3 100644 (file)
@@ -202,20 +202,22 @@ class GUIFormSpecMenu : public GUIModalMenu
                FieldSpec(const std::string &name, const std::wstring &label,
                                const std::wstring &default_text, int id) :
                        fname(name),
-                       fid(id)
+                       flabel(label),
+                       fid(id),
+                       send(false),
+                       close_on_enter(false),
+                       ftype(f_Unknown),
+                       is_exit(false)
                {
                        //flabel = unescape_enriched(label);
-                       flabel = label;
                        fdefault = unescape_enriched(default_text);
-                       send = false;
-                       ftype = f_Unknown;
-                       is_exit = false;
                }
                std::string fname;
                std::wstring flabel;
                std::wstring fdefault;
                int fid;
                bool send;
+               bool close_on_enter; // used by text fields
                FormspecFieldType ftype;
                bool is_exit;
                core::rect<s32> rect;