Fix awkwardness of Enter key in string picker

Search field starts out hidden. When the button is
clicked, the field and other controls appear, and
the button takes over the enter key. Ctrl+Enter
clicks okay (so if search is not opened, either
Enter OR Ctrl+Enter will click okay)
This commit is contained in:
2025-03-20 20:40:09 -05:00
parent aa029f6bdc
commit f26a9e9c32
5 changed files with 34 additions and 5 deletions

View File

@@ -54,5 +54,5 @@
<button name='left' type='left' def-key='left' relative='pos-in pos-in' anchor='led20' top='19' left='0'/>
<button name='right' type='right' def-key='right' relative='pos-in pos-in' rel-anchor='prev' top='0' left='63'/>
<button name='cancel' type='regular' def-key='esc' relative='pos-in pos-in' rel-anchor='prev' top='0' left='201'>Cancel</button>
<button name='done' type='regular' relative='pos-in pos-in' rel-anchor='prev' top='0' left='66'>OK</button>
<button name='done' type='regular' def-key='ctrl enter' relative='pos-in pos-in' rel-anchor='prev' top='0' left='66'>OK</button>
</dialog>

View File

@@ -158,7 +158,7 @@ void cDialog::loadFromFile(const DialogDefn& file){
Iterator<Attribute> attr;
Iterator<Element> node;
string type, name, val, defaultButton;
string type, name, val, defbtn;
xml.FirstChildElement()->GetValue(&type);
if(type != "dialog") throw xBadNode(type,xml.FirstChildElement()->Row(),xml.FirstChildElement()->Column(),fname);
@@ -182,7 +182,7 @@ void cDialog::loadFromFile(const DialogDefn& file){
}
defTextClr = clr;
} else if(name == "defbtn") {
defaultButton = val;
defbtn = val;
}else if(name != "debug")
throw xBadAttr(type,name,attr->Row(),attr->Column(),fname);
}
@@ -336,8 +336,7 @@ void cDialog::loadFromFile(const DialogDefn& file){
} while(!all_resolved);
// Set the default button.
if(hasControl(defaultButton))
getControl(defaultButton).setDefault(true);
setDefaultButton(defbtn);
// Sort by tab order
// First, fill any gaps that might have been left, using ones that had no specific tab order
@@ -1158,6 +1157,19 @@ bool cDialog::hasControl(std::string id) const {
return false;
}
void cDialog::setDefaultButton(std::string defbtn) {
if(!hasControl(defbtn)){
// this is likely because the dialogxml is malformed. maybe the linter already checks this,
// but the engine might as well also.
throw std::string { "Requested default button does not exist: " } + defbtn;
}
if(!defaultButton.empty()){
getControl(defaultButton).setDefault(false);
}
defaultButton = defbtn;
getControl(defaultButton).setDefault(true);
}
const char*const xBadVal::CONTENT = "$content$";
cDialogIterator::cDialogIterator() : parent(nullptr) {}

View File

@@ -265,6 +265,7 @@ public:
cDialog(cDialog& other) = delete;
inline void setAnimPictFPS(int fps) { if(fps == -1) fps = 2; anim_pict_fps = fps; }
inline void setDoAnimations(bool value) { doAnimations = value; }
void setDefaultButton(std::string defbtn);
private:
void draw();
void handle_events();
@@ -275,6 +276,7 @@ private:
rectangle winRect;
boost::any result;
std::string fname;
std::string defaultButton;
sf::Clock animTimer, paintTimer;
friend class cControl;
friend class cContainer;

View File

@@ -66,6 +66,11 @@ cDialog* cStringChoice::operator->() {
}
size_t cStringChoice::show(size_t selectedIndex) {
// Hide most of the search ui until Ctrl+f or clicking the search button
dlg["search-field"].hide();
dlg["search-label"].hide();
dlg["reverse"].hide();
cur = selectedIndex;
if(cur >= strings.size()) {
if(editable) {
@@ -162,6 +167,15 @@ bool cStringChoice::onOkay(cDialog& me){
}
bool cStringChoice::onSearch(cDialog& me){
if(!search_open){
me["search-field"].show();
me["search-label"].show();
me["reverse"].show();
me.setDefaultButton("search");
search_open = true;
return true;
}
cLed& reverse_led = dynamic_cast<cLed&>(me["reverse"]);
bool reversed = reverse_led.getState() == led_red;
size_t page_delta = reversed ? -1 : 1;

View File

@@ -37,6 +37,7 @@ class cStringChoice {
std::vector<std::string> strings;
size_t page, cur;
std::string search_str;
bool search_open = false;
cLedGroup* leds;
std::function<void(cStringChoice&,int)> select_handler;
cStringChoice(cDialog* parent, bool editable = false);