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