#include "menuDefs.h" //////////////////////////////////////////////////////////////////////// // template implementation #include "menuIo.h" #include "nav.h" namespace Menu { #ifdef MENU_ASYNC template bool menuValue::async(const char*uri,navRoot& root,idx_t lvl) { trace(MENU_DEBUG_OUT<<(*(prompt*)this)<<" menuValue::async! lvl:"< const char* menuValue::typeName() const {return "menuValue";} #endif template bool menuField::canTune() {return !!tune();} template void menuField::constrainField() {target() = constrain(target(), low(), high());} template void menuField::clearChanged(const navNode &nav,const menuOut& out,bool sub) { fieldBase::clearChanged(nav,out,sub); reflex=target(); } template bool menuField::changed(const navNode &nav,const menuOut& out,bool sub,bool test) { trace(if (test&&dirty) MENU_DEBUG_OUT<<"field dirty"< idx_t menuField::printReflex(menuOut& o) const {return o.print(reflex);} template Used menuField::printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) { trace(print_P(out,getText());MENU_DEBUG_OUT<<" menuField::printTo "< void menuField::parseInput(navNode& nav,menuIn& in) { if (strchr(numericChars,in.peek())) {//a numeric value was entered if (in.numValueInput) { target()=(T)in.parseFloat();//TODO: use template specialization and proper convertion tunning=true; doNav(nav,enterCmd); } else doNav(nav,idxCmd); } else doNav(nav,nav.navKeys(in.read())); } #ifdef MENU_ASYNC template void menuField::printValue(menuOut& o) const {o.print(reflex);} template void menuField::printHigh(menuOut& o) const {o.print(high());} template void menuField::printLow(menuOut& o) const {o.print(low());} template void menuField::printStep(menuOut& o) const {o.print(step());} template void menuField::printTune(menuOut& o) const {o.print(tune());} template const char* menuField::typeName() const {return typeStr();}; #endif template void menuField::stepit(int dir) { dir*=options->invertFieldKeys?-1:1; T thisstep = tunning?tune():step(); dirty=true; //by default they are inverted.. now buttons and joystick have to flip them if (dir > 0) { if ((high()-target()) < thisstep) target() = canWrap()?low():high(); else target() += thisstep; } else { if ((target()-low()) < thisstep) target() = canWrap()?high():low(); else target() -= thisstep; } } template Used choose::printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) { bool ed=this==root.navFocus; return ed? prompt::printTo(root,sel,out,idx,len,panelNr) :menuVariantBase::printTo(root,sel,out,idx,len,panelNr); } template Used toggle::printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t panelNr) { return menuVariantBase::togglePrintTo(root,sel,out,idx,len,panelNr); } #ifdef MENU_ASYNC template const char* toggle::typeName() const {return "toggle";} template bool toggle::async(const char*uri,navRoot& root,idx_t lvl) { _trace(MENU_DEBUG_OUT<<(*(prompt*)this)<<" toggle::async! uri:"<::sync(n);//sync to index n! // root.node().event(root.useUpdateEvent?updateEvent:enterEvent); return true; } //if not by index then do the toggle _trace(Serial<<"toggle proceed..."< result toggle::sysHandler(SYS_FUNC_PARAMS) { _trace(Serial<<"toggle sysHandler!"<::sync(); assert(at!=-1); at++; if (at>=menuNode::sz()) at=0; menuVariant::sync(at); prompt::dirty=true; (menuNode::operator[](at))(FUNC_VALUES); } default: return proceed; } } #ifdef MENU_FMT_WRAPS template classes toggle::type() const {return toggleClass;} #endif template idx_t menuVariant::sync() { for(idx_t i=0;i*)&operator[](i))->target()==target()) return i; #ifdef MENU_DEBUG MENU_DEBUG_OUT.print("value out of range "); MENU_DEBUG_OUT.println(target());MENU_DEBUG_OUT.flush(); assert(false); #endif return -1; } template idx_t menuVariant::sync(idx_t i) { #ifdef MENU_DEBUG if (!(i>=0&&i=0&&i*)&operator[](i))->target(); return i; } template bool menuVariant::changed(const navNode &nav,const menuOut& out,bool sub,bool test) { return dirty||((menuValue*)&operator[](reflex))->target()!=target(); } #ifdef MENU_ASYNC template idx_t menuVariant::selected() const {return reflex;} template const char* menuVariant::typeName() const {return "menuVariant";} #endif template result choose::sysHandler(SYS_FUNC_PARAMS) { switch(event) { case updateEvent: case enterEvent: nav.sel=menuVariant::sync(); default: return proceed; } } template bool choose::changed(const navNode &nav,const menuOut& out,bool sub,bool test) { return menuVariant::changed(nav,out)||menuNode::changed(nav,out); } #ifdef MENU_FMT_WRAPS template classes choose::type() const {return chooseClass;} #endif #ifdef MENU_ASYNC template const char* choose::typeName() const {return "choose";} #endif }//namespace Menu