add max-chars attribute to text field

This commit is contained in:
2025-01-23 20:12:32 -06:00
parent dde250fd25
commit de45b379e3
4 changed files with 21 additions and 11 deletions

View File

@@ -3,8 +3,8 @@
<dialog defbtn='okay'> <dialog defbtn='okay'>
<!-- OK button --> <!-- OK button -->
<field name='who' top='26' left='186' width='64' height='16'/> <field name='who' top='26' left='186' width='64' height='16'/>
<field name='key1' top='54' left='165' width='52' height='16'/> <field name='key1' top='54' left='165' width='52' height='16' max-chars='4'/>
<field name='key2' top='54' left='285' width='52' height='16'/> <field name='key2' top='54' left='285' width='52' height='16' max-chars='4'/>
<text top='6' left='350' width='160' height='48'>The in-game "Buy" button checks for these response keys, in order: purc, sale, heal, iden, trai, ench</text> <text top='6' left='350' width='160' height='48'>The in-game "Buy" button checks for these response keys, in order: purc, sale, heal, iden, trai, ench</text>
<text relative='pos-in pos' rel-anchor='prev' top='0' left='0' width='160' height='50'>The "Sell" button checks for sell.</text> <text relative='pos-in pos' rel-anchor='prev' top='0' left='0' width='160' height='50'>The "Sell" button checks for sell.</text>
<field name='extra1' top='114' left='344' width='64' height='16'/> <field name='extra1' top='114' left='344' width='64' height='16'/>

View File

@@ -150,6 +150,7 @@
</xs:simpleType> </xs:simpleType>
</xs:attribute> </xs:attribute>
<xs:attribute name="tab-order" type="xs:integer"/> <xs:attribute name="tab-order" type="xs:integer"/>
<xs:attribute name="max-chars" type="xs:integer"/>
<xs:attributeGroup ref="rect-size"/> <xs:attributeGroup ref="rect-size"/>
<xs:attributeGroup ref="position"/> <xs:attributeGroup ref="position"/>
</xs:extension> </xs:extension>

View File

@@ -442,16 +442,18 @@ void cTextField::handleInput(cKey key, bool record) {
handleInput(deleteKey); handleInput(deleteKey);
contents = getText(); contents = getText();
} }
if(aTextInsert* ins = dynamic_cast<aTextInsert*>(current_action.get())) if(maxChars < 0 || contents.size() < maxChars){
ins->append(key.c); if(aTextInsert* ins = dynamic_cast<aTextInsert*>(current_action.get()))
else { ins->append(key.c);
if(current_action) history.add(current_action); else {
aTextInsert* new_ins = new aTextInsert(*this, insertionPoint); if(current_action) history.add(current_action);
new_ins->append(key.c); aTextInsert* new_ins = new aTextInsert(*this, insertionPoint);
current_action.reset(new_ins); new_ins->append(key.c);
current_action.reset(new_ins);
}
contents.insert(contents.begin() + insertionPoint, char(key.c));
selectionPoint = ++insertionPoint;
} }
contents.insert(contents.begin() + insertionPoint, char(key.c));
selectionPoint = ++insertionPoint;
} else switch(key.k) { } else switch(key.k) {
case key_enter: break; // Shouldn't be receiving this anyway case key_enter: break; // Shouldn't be receiving this anyway
case key_left: case key_word_left: case key_left: case key_word_left:
@@ -681,6 +683,9 @@ bool cTextField::parseAttribute(ticpp::Attribute& attr, std::string tagName, std
} else if(name == "tab-order"){ } else if(name == "tab-order"){
attr.GetValue(&tabOrder); attr.GetValue(&tabOrder);
return true; return true;
} else if(name == "max-chars"){
attr.GetValue(&maxChars);
return true;
} }
return cControl::parseAttribute(attr, tagName, fname); return cControl::parseAttribute(attr, tagName, fname);
} }

View File

@@ -90,6 +90,10 @@ private:
rectangle text_rect; rectangle text_rect;
std::vector<snippet_t> snippets; std::vector<snippet_t> snippets;
int ip_row, ip_col; int ip_row, ip_col;
/// Setting maxChars AFTER the player has a chance to type in the field would be a bad idea.
/// So would calling setText() with a string longer than maxChars.
/// Really, it should probably only be set in xml, as the attribute "max-chars".
int maxChars = -1;
friend class aTextInsert; friend class aTextInsert;
friend class aTextDelete; friend class aTextDelete;
}; };