00001 #include "ControlBase.h"
00002 #include "Motion/MMAccessor.h"
00003 #include "Motion/LedMC.h"
00004 #include "Shared/string_util.h"
00005 #include "Wireless/Wireless.h"
00006 #include <iomanip>
00007 #include <sstream>
00008
00009 ControlBase * ControlBase::activate(MotionManager::MC_ID display, Socket * gui) {
00010 display_id=display;
00011 gui_comm=gui;
00012 hilightFirst();
00013 refresh();
00014 return this;
00015 }
00016
00017 void ControlBase::pause() {
00018 if(doRewrite) {
00019 doRewrite=false;
00020 }
00021 }
00022
00023 void ControlBase::refresh() {
00024
00025 if(display_id!=MotionManager::invalid_MC_ID) {
00026 if(hilights.size()>0) {
00027 MMAccessor<LedMC> display(display_id);
00028 unsigned int cur=hilights.front();
00029 if(options.size()<=10)
00030 display.mc()->displayNumber(cur,LedEngine::onedigit);
00031 else
00032 display.mc()->displayNumber(cur,LedEngine::twodigit);
00033 }
00034 }
00035
00036
00037 if(gui_comm==NULL || !wireless->isConnected(gui_comm->sock)) {
00038
00039 const char * const nosel=" ";
00040 const char * slctd="**";
00041 if(config->main.use_VT100) {
00042 slctd="\33[1m**\33[0m";
00043 if(doRewrite)
00044 clearMenu();
00045 sout->printf("\33[1m%s\33[0m:\n",getName().c_str());
00046 } else
00047 sout->printf("%s:\n",getName().c_str());
00048 unsigned int digits=0;
00049 for(unsigned int i=1; i<options.size(); i*=10)
00050 digits++;
00051 for(unsigned int i=0; i<options.size(); i++) {
00052 if(options[i]==NULL)
00053 for(unsigned int j=0; j<strlen(nosel)+digits+2; j++)
00054 sout->printf(" ");
00055 else
00056 sout->printf("%s%*d%s ",(find(hilights.begin(),hilights.end(),i)!=hilights.end()?slctd:nosel),digits,i,(options[i]->slotsSize()>0?">":"."));
00057
00058 sout->printf("%s\n",getSlotName(i).c_str());
00059 }
00060 if(options.size()==0)
00061 sout->printf(" Empty menu\n");
00062 doRewrite=true;
00063 } else {
00064
00065
00066
00067
00068 std::stringstream ss;
00069 ss << "refresh\n"
00070 << getName() << '\n'
00071 << options.size() << '\n';
00072 for(unsigned int i=0; i<options.size(); i++)
00073 if(options[i]==NULL)
00074 ss << "0\n0\n----------\n\n";
00075 else
00076 ss << options[i]->options.size() << '\n'
00077 << (binary_search(hilights.begin(),hilights.end(),i)?1:0) << '\n'
00078 << options[i]->getName() << '\n'
00079 << options[i]->getDescription().c_str() << '\n';
00080
00081
00082 gui_comm->write((const byte*)ss.str().c_str(),ss.str().size());
00083
00084
00085
00086 }
00087 }
00088
00089 void ControlBase::deactivate() {
00090 hilights.clear();
00091 if(display_id!=MotionManager::invalid_MC_ID) {
00092 MMAccessor<LedMC> display(display_id);
00093 display.mc()->clear();
00094 }
00095 if(doRewrite) {
00096 if(config->main.use_VT100)
00097 clearMenu();
00098 doRewrite=false;
00099 }
00100 display_id=MotionManager::invalid_MC_ID;
00101 }
00102
00103 ControlBase* ControlBase::doSelect() {
00104
00105
00106 if(hilights.size()==0) {
00107 sndman->PlayFile(config->controller.select_snd);
00108 return this;
00109 }
00110 for(unsigned int i=0;i<hilights.size();i++) {
00111 unsigned int cur=hilights[i];
00112 if(cur>=options.size() || options[cur]==NULL) {
00113 if(display_id!=MotionManager::invalid_MC_ID) {
00114 MMAccessor<LedMC> display(display_id);
00115 display.mc()->cflash(FaceLEDMask,.5,100);
00116 }
00117 if(cur>=options.size())
00118 sout->printf("Invalid choice\n");
00119 else
00120 sout->printf("NULL option\n");
00121 continue;
00122 }
00123 if(display_id!=MotionManager::invalid_MC_ID) {
00124 MMAccessor<LedMC> display(display_id);
00125 display.mc()->flash(FaceLEDMask,100);
00126 display.mc()->clear();
00127 }
00128 if(doRewrite) {
00129 if(config->main.use_VT100)
00130 clearMenu();
00131 doRewrite=false;
00132 }
00133 sndman->PlayFile(config->controller.select_snd);
00134 if(hilights.size()>1) {
00135 options[cur]->activate(display_id,gui_comm);
00136 options[cur]->deactivate();
00137 }
00138 }
00139 if(hilights.size()==1)
00140 return options[hilights.front()];
00141 return this;
00142 }
00143
00144 ControlBase* ControlBase::doNextItem() {
00145
00146 if(options.size()==0)
00147 return this;
00148 unsigned int cur=0;
00149 for(unsigned int i=0; i<hilights.size(); i++)
00150 if(hilights[i]>=cur)
00151 cur=(hilights[i]+1)%options.size();
00152 while(options[cur]==NULL)
00153 cur=(cur+1)%options.size();
00154 hilights.clear();
00155 hilights.push_back(cur);
00156 sndman->PlayFile(config->controller.next_snd);
00157 refresh();
00158
00159 return this;
00160 }
00161
00162 ControlBase* ControlBase::doPrevItem() {
00163
00164 if(options.size()==0)
00165 return this;
00166 unsigned int cur=options.size()-1;
00167 for(unsigned int i=hilights.size(); i>0; i--)
00168 if(hilights[i-1]<=cur)
00169 cur=(hilights[i-1]+options.size()-1)%options.size();
00170 while(options[cur]==NULL)
00171 cur=(cur+options.size()-1)%options.size();
00172 hilights.clear();
00173 hilights.push_back(cur);
00174 sndman->PlayFile(config->controller.prev_snd);
00175 refresh();
00176
00177 return this;
00178 }
00179
00180 ControlBase * ControlBase::doCancel() {
00181 sndman->PlayFile(config->controller.cancel_snd);
00182 return NULL;
00183 }
00184
00185
00186 ControlBase* ControlBase::doReadStdIn(const std::string& prompt) {
00187
00188 if(display_id!=MotionManager::invalid_MC_ID) {
00189 MMAccessor<LedMC> display(display_id);
00190 display.mc()->cset(FaceLEDMask,.5);
00191 }
00192 sndman->PlayFile(config->controller.read_snd);
00193
00194
00195 if(gui_comm==NULL || !wireless->isConnected(gui_comm->sock)) {
00196
00197 if(prompt.size()>0)
00198 sout->printf("%s\n",prompt.c_str());
00199 sout->printf("#> ");
00200 if(!wireless->isConnected(sout->sock)) {
00201 std::string choice;
00202 std::cin >> choice;
00203 std::cout << std::endl;
00204 return takeInput(choice);
00205 }
00206 return this;
00207 } else {
00208
00209 if(prompt.size()>0)
00210 gui_comm->printf("status\n%s\n",prompt.c_str());
00211 return this;
00212 }
00213 }
00214
00215 ControlBase* ControlBase::takeInput(const std::string& str) {
00216 std::vector<std::string> args;
00217 std::vector<unsigned int> offsets;
00218 if(!string_util::parseArgs(str,args,offsets)) {
00219 serr->printf("ControlBase::takeInput(\"%s\") was not understood.\n",str.c_str());
00220 refresh();
00221 return this;
00222 } else {
00223
00224 if(args.size()==0) {
00225 refresh();
00226 return this;
00227 }
00228
00229 unsigned int choice=-1U;
00230 bool ambiguous=false;
00231 for(unsigned int i=0; i<options.size(); i++) {
00232 if(options[i]!=NULL && options[i]->name.compare(0,args[0].size(),args[0])==0) {
00233 if(choice==-1U)
00234 choice=i;
00235 else
00236 ambiguous=true;
00237 }
00238 }
00239
00240 if(!ambiguous && choice==-1U) {
00241 std::string argname=string_util::makeLower(args[0]);
00242 for(unsigned int i=0; i<options.size(); i++) {
00243 if(options[i]!=NULL) {
00244 std::string optname=string_util::makeLower(options[i]->name);
00245 if(optname.compare(0,argname.size(),argname)==0) {
00246 if(choice==-1U)
00247 choice=i;
00248 else
00249 ambiguous=true;
00250 }
00251 }
00252 }
00253 }
00254
00255 if(ambiguous || choice==-1U) {
00256 char* endp=NULL;
00257 choice=strtol(args[0].c_str(),&endp,10);
00258 if(endp==NULL || endp==args[0].c_str()) {
00259 if(config->main.use_VT100) {
00260 sout->printf("\r\33[1A");
00261 clearMenu();
00262 doRewrite=false;
00263 }
00264 if(ambiguous)
00265 serr->printf("ControlBase(\"%s\")::takeInput(\"%s\") was ambiguous\n",name.c_str(),args[0].c_str());
00266 else
00267 serr->printf("ControlBase(\"%s\")::takeInput(\"%s\") was not a valid index or option name.\n",name.c_str(),args[0].c_str());
00268 refresh();
00269 return this;
00270 } else if(choice<options.size() && options[choice]!=NULL) {
00271 ambiguous=false;
00272 } else {
00273 if(config->main.use_VT100) {
00274 sout->printf("\r\33[1A");
00275 clearMenu();
00276 doRewrite=false;
00277 }
00278 if(ambiguous)
00279 serr->printf("ControlBase(\"%s\")::takeInput(\"%s\") was ambiguous\n",name.c_str(),args[0].c_str());
00280 else
00281 serr->printf("ControlBase(\"%s\")::takeInput(\"%d\") is not a valid selection\n",name.c_str(),choice);
00282 refresh();
00283 return this;
00284 }
00285 }
00286
00287 if(args.size()>1)
00288 return options[choice]->takeInput(str.substr(offsets[1]));
00289 else {
00290 hilights.clear();
00291 hilights.push_back(choice);
00292 return doSelect();
00293 }
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 }
00334
00335 bool ControlBase::validInput(const std::string& str) {
00336 unsigned int choice=atoi(str.c_str());
00337 return (choice<options.size() && options[choice]!=NULL);
00338 }
00339
00340 std::string ControlBase::getSlotName(unsigned int i) const {
00341 if(options[i]!=NULL)
00342 return options[i]->getName();
00343 else
00344 return "----------";
00345 }
00346
00347
00348 void ControlBase::setSlot(unsigned int i,ControlBase* o) {
00349 while(options.size()<=i)
00350 options.push_back(NULL);
00351 options[i]=o;
00352 }
00353
00354 void ControlBase::pushSlot(ControlBase* o) {
00355 options.push_back(o);
00356 }
00357
00358 void ControlBase::clearSlots() {
00359 for(unsigned int i=0; i<options.size(); i++)
00360 delete options[i];
00361 options.clear();
00362 hilights.clear();
00363 }
00364
00365 void ControlBase::setHilights(const std::vector<unsigned int>& hi) {
00366 float avg=hilightsAvg();
00367 hilights.clear();
00368 for(unsigned int i=0; i<hi.size(); i++)
00369 if(hi[i]<options.size())
00370 hilights.push_back(hi[i]);
00371 float newavg=hilightsAvg();
00372 if(avg!=-1 || newavg!=-1) {
00373 if(avg<=newavg)
00374 sndman->PlayFile(config->controller.next_snd);
00375 else
00376 sndman->PlayFile(config->controller.prev_snd);
00377 }
00378 refresh();
00379 }
00380
00381 void ControlBase::hilightFirst() {
00382 hilights.clear();
00383 for(unsigned int i=0; i<options.size(); i++)
00384 if(options[i]!=NULL) {
00385 hilights.push_back(i);
00386 return;
00387 }
00388 }
00389
00390
00391 void ControlBase::clearMenu() {
00392 if(config->main.use_VT100) {
00393 sout->printf("\r\33[%dA",(options.size()+1));
00394 sout->printf("\33[J");
00395 }
00396 }
00397
00398 float ControlBase::hilightsAvg() const {
00399 if(hilights.size()==0)
00400 return -1;
00401 unsigned int total=0;
00402 for(unsigned int i=0; i<hilights.size(); i++)
00403 total+=hilights[i];
00404 return (float)total/(float)hilights.size();
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418