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