00001 #include "fieldmen.h"
00002
00007 #include "registry.h"
00008 #include "fields.h"
00009
00010 #include <glutm/glut.h>
00011
00012 #include <misc/string.h>
00013
00014 #include <cstdio>
00015 #include <fstream>
00016 using namespace std;
00017
00019
00020 GltRegistryMenu::GltRegistryMenu(GltRegistry ®istry)
00021 : _registry(registry),
00022 _active(false),
00023 _position(0),
00024 _current(NULL)
00025 {
00026 }
00027
00028 GltRegistryMenu::~GltRegistryMenu()
00029 {
00030 }
00031
00032 void
00033 GltRegistryMenu::reset()
00034 {
00035 _position = 0;
00036 _stack.clear();
00037 _current = NULL;
00038 }
00039
00040 bool &GltRegistryMenu::active() { return _active; }
00041
00042
00043 bool
00044 GltRegistryMenu::OnKeyboard(unsigned char key, int x, int y)
00045 {
00046 if (!_current)
00047 return false;
00048
00049 vector<GltFieldPtr> &fields = _current->_fields;
00050
00051 switch (key)
00052 {
00053 case 27:
00054 while (_stack.size())
00055 pop();
00056 pop();
00057 return true;
00058
00059 default:
00060 {
00061 if (_position>=(int)fields.size())
00062 return false;
00063
00064 GltField *field = fields[_position].get();
00065
00066 if (!field)
00067 return false;
00068
00069
00070
00071
00072
00073 GltFields::GltFieldBool *fieldBool = dynamic_cast<GltFields::GltFieldBool *>(field);
00074 if (fieldBool)
00075 {
00076 switch (key)
00077 {
00078 case ' ':
00079 case 13:
00080 case '!':
00081 case '+':
00082 case '-':
00083 fieldBool->val() = !fieldBool->val();
00084 break;
00085 case 't':
00086 case 'T':
00087 case '1':
00088 fieldBool->val() = true;
00089 break;
00090 case 'f':
00091 case 'F':
00092 case '0':
00093 fieldBool->val() = false;
00094 break;
00095 case 127:
00096 fieldBool->reset();
00097 break;
00098 default:
00099 return false;
00100 }
00101
00102 return true;
00103 }
00104
00105
00106
00107
00108
00109 GltFields::GltFieldDouble *fieldDouble = dynamic_cast<GltFields::GltFieldDouble *>(field);
00110 if (fieldDouble)
00111 {
00112 switch (key)
00113 {
00114 case '+':
00115 ++(*fieldDouble);
00116 break;
00117 case '-':
00118 --(*fieldDouble);
00119 break;
00120 case '*':
00121 fieldDouble->val() *= 1.25;
00122 break;
00123 case '/':
00124 fieldDouble->val() *= 0.8;
00125 break;
00126 case 'r':
00127 case 'n':
00128 fieldDouble->val() *= -1.0;
00129 break;
00130 case '0':
00131 fieldDouble->val() = 0.0;
00132 break;
00133 case '1':
00134 fieldDouble->val() = 1.0;
00135 break;
00136 case 127:
00137 fieldDouble->reset();
00138 break;
00139 default:
00140 return false;
00141 }
00142
00143 return true;
00144 }
00145
00146
00147
00148
00149
00150 GltFields::GltFieldFloat *fieldFloat = dynamic_cast<GltFields::GltFieldFloat *>(field);
00151 if (fieldFloat)
00152 {
00153 switch (key)
00154 {
00155 case '+':
00156 ++(*fieldFloat);
00157 break;
00158 case '-':
00159 --(*fieldFloat);
00160 break;
00161 case '*':
00162 fieldFloat->val() *= 1.25;
00163 break;
00164 case '/':
00165 fieldFloat->val() *= 0.8;
00166 break;
00167 case 'r':
00168 case 'n':
00169 fieldFloat->val() *= -1.0;
00170 break;
00171 case '0':
00172 fieldFloat->val() = 0.0;
00173 break;
00174 case '1':
00175 fieldFloat->val() = 1.0;
00176 break;
00177 case 127:
00178 fieldFloat->reset();
00179 break;
00180 default:
00181 return false;
00182 }
00183
00184 return true;
00185 }
00186
00187
00188
00189
00190
00191 GltFields::GltFieldInt *fieldInt = dynamic_cast<GltFields::GltFieldInt *>(field);
00192 if (fieldInt)
00193 {
00194 switch (key)
00195 {
00196 case '+':
00197 fieldInt->val()++;
00198 break;
00199 case '-':
00200 fieldInt->val()--;
00201 break;
00202 case '0':
00203 fieldInt->val() = 0;
00204 break;
00205 case '1':
00206 fieldInt->val() = 1;
00207 break;
00208 case 127:
00209 fieldInt->reset();
00210 break;
00211 default:
00212 return false;
00213 }
00214
00215 return true;
00216 }
00217
00218
00219
00220
00221
00222 GltFields::GltFieldEnum *fieldEnum = dynamic_cast<GltFields::GltFieldEnum *>(field);
00223 if (fieldEnum)
00224 {
00225 switch (key)
00226 {
00227 case '+':
00228 ++(*fieldEnum);
00229 break;
00230 case '-':
00231 --(*fieldEnum);
00232 break;
00233 case 127:
00234 fieldEnum->reset();
00235 break;
00236 default:
00237 return false;
00238 }
00239
00240 return true;
00241 }
00242
00243
00244
00245
00246
00247 if (key==' ' || key==13)
00248 return field->set("");
00249
00250 return false;
00251 }
00252 }
00253
00254 return true;
00255 }
00256
00257 bool
00258 GltRegistryMenu::OnSpecial(int key, int x, int y)
00259 {
00260 if (key==GLUT_KEY_RIGHT)
00261 return push();
00262
00263 if (!_current)
00264 return false;
00265
00266 vector<GltFieldPtr> &fields = _current->_fields;
00267
00268 switch (key)
00269 {
00270 case GLUT_KEY_UP: _position = (_position + fields.size() - 1)%fields.size(); break;
00271 case GLUT_KEY_DOWN: _position = (_position + 1)%fields.size(); break;
00272
00273 case GLUT_KEY_LEFT: return pop();
00274
00275 default:
00276 return false;
00277 }
00278
00279 return true;
00280 }
00281
00282 bool GltRegistryMenu::pop()
00283 {
00284 if (_stack.size())
00285 {
00286 _current = _stack.front().first;
00287 _position = _stack.front().second;
00288 _stack.erase(_stack.begin());
00289 return true;
00290 }
00291 else
00292 {
00293 _current = NULL;
00294 _position = 0;
00295 }
00296
00297 if (_active)
00298 {
00299 _active = false;
00300 return true;
00301 }
00302
00303 return false;
00304 }
00305
00306 bool GltRegistryMenu::push()
00307 {
00308 if (!_active)
00309 {
00310 reset();
00311 _active = true;
00312 _current = dynamic_cast<GltFields *>(_registry._root.get());
00313 _position = 0;
00314 return true;
00315 }
00316
00317 vector<GltFieldPtr> &fields = _current->_fields;
00318 GltFields *submenu = dynamic_cast<GltFields *>(fields[_position].get());
00319
00320 if (submenu)
00321 {
00322 _stack.push_front(make_pair(_current,_position));
00323 _current = submenu;
00324 _position = 0;
00325 return true;
00326 }
00327
00328 return false;
00329 }
00330
00331 string
00332 GltRegistryMenu::menu() const
00333 {
00334 if (!_current)
00335 return string();
00336
00337 string tmp;
00338 const vector<GltFieldPtr> &fields = _current->_fields;
00339
00340
00341
00342 for (std::list< std::pair<GltFields *,int> >::const_reverse_iterator j = _stack.rbegin(); j!=_stack.rend(); j++)
00343 {
00344 tmp += j->first->name();
00345 tmp += '.';
00346 }
00347 tmp += _current->name();
00348 tmp += "\n\n";
00349
00350
00351
00352 for (int i=0; i<(int)fields.size(); i++)
00353 {
00354 if (i>0)
00355 tmp += '\n';
00356
00357 const GltFields *submenu = dynamic_cast<const GltFields *>(fields[i].get());
00358
00359 char buffer[1024];
00360 if (submenu)
00361 sprintf(buffer," %-15s %10s ",fields[i]->name().c_str(),">>");
00362 else
00363 sprintf(buffer," %-15s %10s ",fields[i]->name().c_str(),fields[i]->get().c_str());
00364
00365 tmp += (i==_position ? "->" : " ");
00366 tmp += buffer;
00367 }
00368
00369 return tmp;
00370 }
00371