Allow shift-tab to cycle backwards through tab order

This commit is contained in:
2014-11-29 16:37:26 -05:00
parent 84f53a8a7d
commit b537fabd13
2 changed files with 30 additions and 23 deletions

View File

@@ -1033,29 +1033,10 @@ void cDialog::run(){
where = controls[itemHit]->getBounds().centre();
if(controls[itemHit]->getType() == CTRL_FIELD){
if(key.spec && key.k == key_tab){
// TODO: Tabbing through fields, and trigger focus events.
auto cur = find_if(tabOrder.begin(), tabOrder.end(), [&itemHit](pair<string,cTextField*>& a) {
return a.first == itemHit;
});
if(cur == tabOrder.end()) break; // Unlikely, but let's be safe
if(!cur->second->triggerFocusHandler(*this,itemHit,true)) break;
cTextField* wasFocus = currentFocus;
auto iter = std::next(cur);
if(iter == tabOrder.end()) iter = tabOrder.begin();
while(iter != cur){
// If tab order is explicitly specified for all fields, gaps are possible
if(iter->second == nullptr) continue;
if((currentFocus = dynamic_cast<cTextField*>(iter->second))){
if(currentFocus->triggerFocusHandler(*this,iter->first,false)){
itemHit = "";
break;
}
}
iter++;
if(iter == tabOrder.end()) iter = tabOrder.begin();
}
if(iter == cur) // no focus change occured!
currentFocus = wasFocus; // TODO: Surely something should happen here?
// Could use key.mod, but this is slightly easier.
if(currentEvent.key.shift)
handleTabOrder(itemHit, tabOrder.rbegin(), tabOrder.rend());
else handleTabOrder(itemHit, tabOrder.begin(), tabOrder.end());
} else if(!key.spec || key.k != key_enter || mod_contains(key.mod, mod_alt)) {
dynamic_cast<cTextField*>(controls[itemHit])->handleInput(key);
itemHit = "";
@@ -1097,6 +1078,31 @@ void cDialog::run(){
set_cursor(former_curs);
}
template<typename Iter> void cDialog::handleTabOrder(string itemHit, Iter begin, Iter end) {
auto cur = find_if(begin, end, [&itemHit](pair<string,cTextField*>& a) {
return a.first == itemHit;
});
if(cur == end) return; // Unlikely, but let's be safe
if(!cur->second->triggerFocusHandler(*this,itemHit,true)) return;
cTextField* wasFocus = currentFocus;
auto iter = std::next(cur);
if(iter == end) iter = begin;
while(iter != cur){
// If tab order is explicitly specified for all fields, gaps are possible
if(iter->second == nullptr) continue;
if((currentFocus = dynamic_cast<cTextField*>(iter->second))){
if(currentFocus->triggerFocusHandler(*this,iter->first,false)){
itemHit = "";
break;
}
}
iter++;
if(iter == end) iter = begin;
}
if(iter == cur) // no focus change occured!
currentFocus = wasFocus; // TODO: Surely something should happen here?
}
void cDialog::setBg(short n){
bg = n;
}

View File

@@ -40,6 +40,7 @@ class cDialog {
cTextField* currentFocus;
cDialog* parent;
void loadFromFile(std::string path);
template<typename Iter> void handleTabOrder(std::string itemHit, Iter begin, Iter end);
std::vector<std::pair<std::string,cTextField*>> tabOrder;
public:
static void init();