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