#include "menuDefs.h" using namespace Menu; void panelsList::reset(idx_t from) {for(int n=from;nuseAccel&&strchr(numericChars,ch)) { return navCmd(idxCmd,ch-'1'); } if ((escaped == 0) && (ch == '\e')) {escaped = 1; return noCmd;} else if ((escaped == 1) && (ch == '[')) {escaped = 2; return noCmd;} else if (escaped == 1) {escaped = 0; return noCmd;} else if (escaped == 2) { escaped = 0; switch (ch) { case 'A': return(downCmd); break; case 'B': return(upCmd); break; case 'C': return(enterCmd); break; case 'D': return(escCmd); break; default: return(noCmd); break; } } for(uint8_t i=0;inavCodes)/sizeof(navCode);i++) if (options->navCodes[i].ch==ch) return options->navCodes[i].cmd; return noCmd; } // generic navigation (aux function) navCmd navNode::doNavigation(navCmd cmd) { trace(MENU_DEBUG_OUT<<"navNode::doNavigation"<isVariant()) root->out.doNav(cmd,*this);*/ case upCmd: // trace(MENU_DEBUG_OUT<<"up"<=sz()) {if(wrap()) nsel=0; else nsel=sz()-1;} // trace(MENU_DEBUG_OUT<<"new sel:"<isVariant()) root->out.doNav(cmd,*this);*/ case downCmd: trace(MENU_DEBUG_OUT<<"down"<is(_asPad)) { if(sz()) { nsel--; if (nsel<0) {if(wrap()) nsel=sz()-1; else nsel=0;} } break; } case escCmd: assert(root); rCmd=root->exit(); break; case enterCmd: assert(root); rCmd=root->enter(); break; case selCmd: case idxCmd: { idx_t at=(idx_t)cmd.param;//-'1';send us numeric index pls! if (at>=0&&atsysStyles()&(_parentDraw|_isVariant)) { trace(MENU_DEBUG_OUT<<"setting dirty"<dirty=true; //this works but might be too much, we dont want to invaludate all the menu! // if (_parentDraw/*&&root->level*/) root->path[root->level-1].target->dirty=true; } else { operator[](osel).dirty=true; operator[](nsel).dirty=true; } //send focus In/Out events if (selBlurEvent&target->events()) target->operator()(selBlurEvent,*this,*target); event(blurEvent,osel); sel=nsel; if (cmd.cmd==selCmd||cmd.cmd==idxCmd) {//do accelerator and enter the option assert(root); rCmd=root->enter(); }//other commands up/down just receive focus events event(focusEvent,nsel); if (selFocusEvent&target->events()) target->operator()(selFocusEvent,*this,*target); } //else its an enter/esc or a non-changing index! //MENU_DEBUG_OUT<<"doNavigation returning "<getCmdChar(enterCmd)==c || options->getCmdChar(escCmd)==c) idleOff(); } else { idx_t inputBurstCnt=inputBurst+1; //if (in.available()) while ((!sleepTask)&&in.available()&&(--inputBurstCnt)) {//if not doing something else and there is input //MENU_DEBUG_OUT.print("."); navFocus->parseInput(node(),in);//deliver navigation input task to target... } } trace(MENU_DEBUG_OUT<<"navRoot::doInput ended!"<doNav(node(),cmd); } } navCmd navRoot::enter() { _trace(MENU_DEBUG_OUT<<"navRoot::enter"<dirty=true; if (!isMenu) in.fieldOn(); } //node().event(activateEvent);//item is active.. not here, root info is not set yet return rCmd; } return noCmd; } navCmd navRoot::exit() { trace(MENU_DEBUG_OUT<<"navRoot::exit"<dirty=true; if (navFocus->isMenu()) { if (level) { level--; node().event(exitEvent,node().sel); } else if (canExit) { node().event(exitEvent,node().sel); idleOn(idleTask); } } else { node().event(exitEvent,node().sel); in.fieldOff(); } active().dirty=true; navFocus=&active(); if (navFocus->asPad()) exit(); return escCmd; } void navRoot::idleOn(idleFunc task) { out.clear(); sleepTask=task; idleChanged=true; active().dirty=true; out.idle(sleepTask,idleStart); #ifdef MENU_IDLE_BKGND if (idleTask!=sleepTask) out.idle(idleTask,idleStart); #endif } void navRoot::idleOff() { out.idle(sleepTask,idleEnd); #ifdef MENU_IDLE_BKGND if (idleTask!=sleepTask) out.idle(idleTask,idleEnd); #endif sleepTask=NULL; active().dirty=true; out.clear(); } bool navNode::changed(const menuOut& out) const { trace("navNode::changed"); if (out.drawn==NULL||target->changed(*this,out)) { root->lastChanged=millis(); return true; } else if (root->canExit&&root->timeOut&&(millis()-root->lastChanged)/1000>root->timeOut) root->idleOn(root->idleTask); return false; } bool navRoot::changed(const menuOut& out) { trace(MENU_DEBUG_OUT.println("DEBUG: changed")); if (sleepTask) return idleChanged; return node().changed(out); } #ifdef MENU_ASYNC // prompt* navRoot::seek(char* uri) { // StringStream s(uri); // size_t len = std::count(s.begin(), s.end(), '/'); // if (uri[0]=='/') s>>'/'; else len++; // assert(len<(1<<(sizeof(idx_t)<<3))); // idx_t sel[len]; // for(int n=0;n>sel[n]; // s>>'/'; // } // return seek(sel,len); // } // prompt* navRoot::seek(idx_t* uri,idx_t len) { // trace(MENU_DEBUG_OUT<<"menuNode::seek"<=0&&uri[0]=0); // if (lvl<0) return; idx_t cnt=0; while(level>lvl) { trace(MENU_DEBUG_OUT<<"escaping "<async(at, *this, 0); else return active().async(at, *this, level+1);//TODO: check max_depth here! } menuOut& navRoot::printPath(menuOut& o,menuNode* to) const { trace(MENU_DEBUG_OUT<<"printPath:"); for(idx_t n=0;n