00001
00002
00003 #include "PTAM/OpenGL.h"
00004 #include "GLWindowMenu.h"
00005 #include <gvars3/instances.h>
00006 #include <gvars3/GStringUtil.h>
00007 #include <sstream>
00008
00009 using namespace GVars3;
00010 using namespace CVD;
00011 using namespace std;
00012
00013 GLWindowMenu::GLWindowMenu(string sName, string sTitle)
00014 {
00015 msName = sName;
00016 msTitle = sTitle;
00017
00018 GUI.RegisterCommand(msName+".AddMenuButton", GUICommandCallBack, this);
00019 GUI.RegisterCommand(msName+".AddMenuToggle", GUICommandCallBack, this);
00020 GUI.RegisterCommand(msName+".AddMenuSlider", GUICommandCallBack, this);
00021 GUI.RegisterCommand(msName+".AddMenuMonitor", GUICommandCallBack, this);
00022 GUI.RegisterCommand(msName+".ShowMenu", GUICommandCallBack, this);
00023 GV2.Register(mgvnMenuItemWidth, msName+".MenuItemWidth", 90, HIDDEN | SILENT);
00024 GV2.Register(mgvnMenuTextOffset, msName+".MenuTextOffset", 20, HIDDEN | SILENT);
00025 GV2.Register(mgvnEnabled, msName+".Enabled", 1, HIDDEN | SILENT);
00026
00027 mmSubMenus.clear();
00028 msCurrentSubMenu="";
00029 }
00030
00031 GLWindowMenu::~GLWindowMenu()
00032 {
00033 GUI.UnRegisterCommand(msName+".AddMenuButton");
00034 GUI.UnRegisterCommand(msName+".AddMenuToggle");
00035 GUI.UnRegisterCommand(msName+".AddMenuSlider");
00036 GUI.UnRegisterCommand(msName+".AddMenuMonitor");
00037 GUI.UnRegisterCommand(msName+".ShowMenu");
00038 };
00039
00040
00041 void GLWindowMenu::GUICommandCallBack(void *ptr, string sCommand, string sParams)
00042 {
00043 ((GLWindowMenu*) ptr)->GUICommandHandler(sCommand, sParams);
00044 }
00045
00046 void GLWindowMenu::GUICommandHandler(string sCommand, string sParams)
00047 {
00048 vector<string> vs = ChopAndUnquoteString(sParams);
00049
00050 if(sCommand==msName+".AddMenuButton")
00051 {
00052 if(vs.size()<3)
00053 {
00054 cout<< "? GLWindowMenu.AddMenuButton: Need 3/4 params: Target Menu, Name, Command , NextMenu=\"\"" << endl;
00055 return;
00056 };
00057 MenuItem m;
00058 m.type = Button;
00059 m.sName = vs[1];
00060 m.sParam = UncommentString(vs[2]);
00061 m.sNextMenu = (vs.size()>3)?(vs[3]):("");
00062 mmSubMenus[vs[0]].mvItems.push_back(m);
00063 return;
00064 }
00065
00066 if(sCommand==msName+".AddMenuToggle")
00067 {
00068 if(vs.size()<3)
00069 {
00070 cout<< "? GLWindowMenu.AddMenuToggle: Need 3/4 params: Target Menu, Name, gvar_int name , NextMenu=\"\"" << endl;
00071 return;
00072 };
00073 MenuItem m;
00074 m.type = Toggle;
00075 m.sName = vs[1];
00076 GV2.Register(m.gvnIntValue, vs[2]);
00077 m.sNextMenu = (vs.size()>3)?(vs[3]):("");
00078 mmSubMenus[vs[0]].mvItems.push_back(m);
00079 return;
00080 }
00081
00082 if(sCommand==msName+".AddMenuMonitor")
00083 {
00084 if(vs.size()<3)
00085 {
00086 cout<< "? GLWindowMenu.AddMenuMonitor: Need 3/4 params: Target Menu, Name, gvar name , NextMenu=\"\"" << endl;
00087 return;
00088 };
00089 MenuItem m;
00090 m.type = Monitor;
00091 m.sName = vs[1];
00092 m.sParam = vs[2];
00093 m.sNextMenu = (vs.size()>3)?(vs[3]):("");
00094 mmSubMenus[vs[0]].mvItems.push_back(m);
00095 return;
00096 }
00097
00098 if(sCommand==msName+".AddMenuSlider")
00099 {
00100 if(vs.size()<5)
00101 {
00102 cout<< "? GLWindowMenu.AddMenuSlider: Need 5/6 params: Target Menu, Name, gvar_int name, min, max, NextMenu=\"\"" << endl;
00103 return;
00104 };
00105 MenuItem m;
00106 m.type = Slider;
00107 m.sName = vs[1];
00108 GV2.Register(m.gvnIntValue, vs[2]);
00109 int *a;
00110 a = ParseAndAllocate<int>(vs[3]);
00111 if(a)
00112 {
00113 m.min = *a;
00114 delete a;
00115 }
00116 a = ParseAndAllocate<int>(vs[4]);
00117 if(a)
00118 {
00119 m.max = *a;
00120 delete a;
00121 }
00122 m.sNextMenu = (vs.size()>5)?(vs[5]):("");
00123 mmSubMenus[vs[0]].mvItems.push_back(m);
00124 return;
00125 }
00126
00127 if(sCommand==msName+".ShowMenu")
00128 {
00129 if(vs.size()==0)
00130 msCurrentSubMenu = "";
00131 else
00132 msCurrentSubMenu = vs[0];
00133 };
00134
00135 };
00136
00137 void GLWindowMenu::LineBox(int l, int r, int t, int b)
00138 {
00139 glBegin(GL_LINE_STRIP);
00140 glVertex2i(l,t);
00141 glVertex2i(l,b);
00142 glVertex2i(r,b);
00143 glVertex2i(r,t);
00144 glVertex2i(l,t);
00145 glEnd();
00146 }
00147
00148 void GLWindowMenu::FillBox(int l, int r, int t, int b)
00149 {
00150 glBegin(GL_QUADS);
00151 glVertex2i(l,t);
00152 glVertex2i(l,b);
00153 glVertex2i(r,b);
00154 glVertex2i(r,t);
00155 glEnd();
00156 }
00157
00158 void GLWindowMenu::Render(int nTop, int nHeight, int nWidth, GLWindow2 &glw)
00159 {
00160 if(!*mgvnEnabled)
00161 return;
00162
00163 mnWidth = nWidth;
00164 mnMenuTop = nTop;
00165 mnMenuHeight = nHeight;
00166
00167 double dAlpha = 0.8;
00168 if(msCurrentSubMenu=="")
00169 {
00170 glColor4d(0,0.5,0,0.5);
00171 FillBox(mnWidth - 30, mnWidth - 1, mnMenuTop, mnMenuTop + mnMenuHeight);
00172 glColor4d(0,1,0,0.5);
00173 LineBox(mnWidth - 30, mnWidth - 1, mnMenuTop, mnMenuTop + mnMenuHeight);
00174 mnLeftMostCoord = mnWidth - 30;
00175 return;
00176 };
00177
00178 SubMenu &m = mmSubMenus[msCurrentSubMenu];
00179
00180 mnLeftMostCoord = mnWidth - (1 + m.mvItems.size()) * *mgvnMenuItemWidth;
00181 int nBase = mnLeftMostCoord;
00182 for(vector<MenuItem>::reverse_iterator i = m.mvItems.rbegin(); i!= m.mvItems.rend(); i++)
00183 {
00184 switch(i->type)
00185 {
00186 case Button:
00187 glColor4d(0,0.5,0,dAlpha);
00188 FillBox(nBase, nBase + *mgvnMenuItemWidth +1, mnMenuTop, mnMenuTop + mnMenuHeight);
00189 glColor4d(0,1,0,dAlpha);
00190 LineBox(nBase, nBase + *mgvnMenuItemWidth +1, mnMenuTop, mnMenuTop + mnMenuHeight);
00191 glw.PrintString(ImageRef( nBase + 3, mnMenuTop + *mgvnMenuTextOffset),
00192 i->sName);
00193 break;
00194
00195 case Toggle:
00196 if(*(i->gvnIntValue))
00197 glColor4d(0,0.5,0.5,dAlpha);
00198 else
00199 glColor4d(0.5,0,0,dAlpha);
00200 FillBox(nBase, nBase + *mgvnMenuItemWidth +1, mnMenuTop, mnMenuTop + mnMenuHeight);
00201 if(*(i->gvnIntValue))
00202 glColor4d(0,1,0.5,dAlpha);
00203 else
00204 glColor4d(1,0,0,dAlpha);
00205 LineBox(nBase, nBase + *mgvnMenuItemWidth +1, mnMenuTop, mnMenuTop + mnMenuHeight);
00206 glw.PrintString(ImageRef( nBase + 3, mnMenuTop + *mgvnMenuTextOffset),
00207 i->sName + " " + ((*(i->gvnIntValue))?("On"):("Off")));
00208 break;
00209
00210 case Monitor:
00211 glColor4d(0,0.5,0.5,dAlpha);
00212 FillBox(nBase, nBase + *mgvnMenuItemWidth +1, mnMenuTop, mnMenuTop + mnMenuHeight);
00213 glColor4d(0,1,1,dAlpha);
00214 LineBox(nBase, nBase + *mgvnMenuItemWidth +1, mnMenuTop, mnMenuTop + mnMenuHeight);
00215 glw.PrintString(ImageRef( nBase + 3, mnMenuTop + *mgvnMenuTextOffset),
00216 i->sName + " " + GV2.StringValue(i->sParam, true));
00217 break;
00218
00219 case Slider:
00220 {
00221 glColor4d(0.0,0.0,0.5,dAlpha);
00222 FillBox(nBase, nBase + *mgvnMenuItemWidth +1, mnMenuTop, mnMenuTop + mnMenuHeight);
00223 glColor4d(0.5,0.0,0.5,dAlpha);
00224 double dFrac = (double) (*(i->gvnIntValue) - i->min) / (i->max - i->min);
00225 if(dFrac<0.0)
00226 dFrac = 0.0;
00227 if(dFrac>1.0)
00228 dFrac = 1.0;
00229 FillBox(nBase, (int) (nBase + dFrac * (*mgvnMenuItemWidth +1)), mnMenuTop, mnMenuTop + mnMenuHeight);
00230 glColor4d(0,1,1,dAlpha);
00231 LineBox(nBase, nBase + *mgvnMenuItemWidth +1, mnMenuTop, mnMenuTop + mnMenuHeight);
00232 ostringstream ost;
00233 ost << i->sName << " " << *(i->gvnIntValue);
00234 glw.PrintString(ImageRef( nBase + 3, mnMenuTop + *mgvnMenuTextOffset),
00235 ost.str());
00236 }
00237 break;
00238 }
00239 nBase += *mgvnMenuItemWidth;
00240 };
00241 glColor4d(0.5, 0.5, 0,dAlpha);
00242 FillBox(mnWidth - *mgvnMenuItemWidth, mnWidth-1, mnMenuTop, mnMenuTop + mnMenuHeight);
00243 glColor4d(1,1,0,dAlpha);
00244 LineBox(mnWidth - *mgvnMenuItemWidth, mnWidth-1, mnMenuTop, mnMenuTop + mnMenuHeight);
00245 ImageRef ir( mnWidth - *mgvnMenuItemWidth + 5, mnMenuTop + *mgvnMenuTextOffset);
00246 if(msCurrentSubMenu == "Root")
00247 glw.PrintString(ir, msTitle+":");
00248 else
00249 glw.PrintString(ir, msCurrentSubMenu+":");
00250 };
00251
00252
00253 bool GLWindowMenu::HandleClick(int nMouseButton, int state, int x, int y)
00254 {
00255 if(!*mgvnEnabled)
00256 return false;
00257
00258 if((y<mnMenuTop)||(y>mnMenuTop + mnMenuHeight))
00259 return false;
00260 if(x<mnLeftMostCoord)
00261 return false;
00262
00263
00264 if(msCurrentSubMenu == "")
00265 {
00266 msCurrentSubMenu = "Root";
00267 return true;
00268 };
00269
00270
00271 int nButtonNumber = (mnWidth - x) / *mgvnMenuItemWidth;
00272 if(nButtonNumber > (int)(mmSubMenus[msCurrentSubMenu].mvItems.size()))
00273 nButtonNumber = 0;
00274
00275 if(nButtonNumber==0)
00276 {
00277 if(msCurrentSubMenu =="Root")
00278 msCurrentSubMenu = "";
00279 else
00280 msCurrentSubMenu = "Root";
00281 return true;
00282 };
00283
00284 MenuItem SelectedItem = mmSubMenus[msCurrentSubMenu].mvItems[nButtonNumber-1];
00285 msCurrentSubMenu=SelectedItem.sNextMenu;
00286 switch(SelectedItem.type)
00287 {
00288 case Button:
00289 GUI.ParseLine(SelectedItem.sParam);
00290 break;
00291 case Toggle:
00292 *(SelectedItem.gvnIntValue)^=1;
00293 break;
00294 case Slider:
00295 {
00296 if(nMouseButton == GLWindow::BUTTON_WHEEL_UP)
00297 {
00298 *(SelectedItem.gvnIntValue)+=1;
00299 if(*(SelectedItem.gvnIntValue) > SelectedItem.max)
00300 *(SelectedItem.gvnIntValue) = SelectedItem.max;
00301 }
00302 else if(nMouseButton == GLWindow::BUTTON_WHEEL_DOWN)
00303 {
00304 *(SelectedItem.gvnIntValue)-=1;
00305 if(*(SelectedItem.gvnIntValue) < SelectedItem.min)
00306 *(SelectedItem.gvnIntValue) = SelectedItem.min;
00307 }
00308 else
00309 {
00310 int nPos = *mgvnMenuItemWidth - ((mnWidth - x) % *mgvnMenuItemWidth);
00311 double dFrac = (double) nPos / *mgvnMenuItemWidth;
00312 *(SelectedItem.gvnIntValue) = (int)(dFrac * (1.0 + SelectedItem.max - SelectedItem.min)) + SelectedItem.min;
00313 };
00314 }
00315 break;
00316 case Monitor:
00317 break;
00318 };
00319 return true;
00320
00321 };
00322
00323
00324
00325
00326
00327