00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011 #include "vgui_tview_tableau.h"
00012
00013 #include <vcl_string.h>
00014 #include <vcl_cmath.h>
00015 #include <vcl_iostream.h>
00016
00017 #include <vgui/vgui_gl.h>
00018 #include <vgui/vgui_event.h>
00019 #include <vgui/vgui_tableau.h>
00020 #include <vgui/vgui_deck_tableau.h>
00021 #include <vgui/vgui_composite_tableau.h>
00022 #include <vgui/vgui_projection_inspector.h>
00023 #include <vgui/vgui_listmanager2D_tableau.h>
00024 #include <vgui/vgui_popup_params.h>
00025 #include <vgui/vgui_menu.h>
00026
00027 vcl_string vgui_tview_tableau::type_name() const {return "vgui_tview_tableau";}
00028
00029
00030 vgui_tview_tableau::vgui_tview_tableau(vgui_tableau_sptr const& t)
00031 : vgui_wrapper_tableau(t)
00032 , spacing(10)
00033 , icon_height(2)
00034 , icon_width(2)
00035 , active_icon(0)
00036 , closest_icon(0)
00037 {
00038 }
00039
00040
00041 vgui_tview_tableau::~vgui_tview_tableau()
00042 {
00043 }
00044
00045
00046 static void draw_rect(float x, float y, float w, float h)
00047 {
00048 glBegin(GL_POLYGON);
00049 glVertex2f(x-w,y-h);
00050 glVertex2f(x+w,y-h);
00051 glVertex2f(x+w,y+h);
00052 glVertex2f(x-w,y+h);
00053 glEnd();
00054 }
00055
00056 static void draw_border(float x, float y, float w, float h, int lt)
00057 {
00058 glLineWidth(lt);
00059
00060 glBegin(GL_LINE_LOOP);
00061 glVertex2f(x-w,y-h);
00062 glVertex2f(x+w,y-h);
00063 glVertex2f(x+w,y+h);
00064 glVertex2f(x-w,y+h);
00065 glEnd();
00066 }
00067
00068
00069 void vgui_tview_tableau::draw_tableau_icon(float x, float y)
00070 {
00071 draw_rect(x,y,icon_width,icon_height);
00072
00073 glColor3f(1,1,1);
00074 glDisable(GL_LINE_STIPPLE);
00075
00076
00077 draw_border(x,y,icon_width, icon_height, 2);
00078 }
00079
00080
00081 void vgui_tview_tableau::draw_tview_icon(float x, float y)
00082 {
00083 glColor3f(1,0,0);
00084 draw_rect(x-icon_width/2.0f, y-icon_height/2.0f, icon_width/2.0f, icon_height/2.0f);
00085
00086 glColor3f(0,1,0);
00087 draw_rect(x-icon_width/2.0f, y+icon_height/2.0f, icon_width/2.0f, icon_height/2.0f);
00088
00089 glColor3f(0,0,1);
00090 draw_rect(x+icon_width/2.0f, y+icon_height/2.0f, icon_width/2.0f, icon_height/2.0f);
00091
00092 glColor3f(1,1,0);
00093 draw_rect(x+icon_width/2.0f, y-icon_height/2.0f, icon_width/2.0f, icon_height/2.0f);
00094
00095 glColor3f(1,1,1);
00096 glDisable(GL_LINE_STIPPLE);
00097
00098
00099 draw_border(x,y,icon_width, icon_height, 2);
00100 }
00101
00102
00103 void vgui_tview_tableau::draw_icons(vgui_tableau_sptr const& parent, float x, float y)
00104 {
00105 vcl_vector<vgui_tableau_sptr> children;
00106 parent->get_children(&children);
00107
00108 if (children.size() > 0)
00109 {
00110 float ny = y + spacing*children.size();
00111 int num = children.size();
00112
00113 float total_x = (num-1)*spacing;
00114 float start_x = x - (int) (total_x/2.0f);
00115 float offset_x = 0;
00116
00117
00118
00119
00120 glLineWidth(1);
00121
00122 int ia = 0;
00123 for (vcl_vector<vgui_tableau_sptr>::iterator i = children.begin();
00124 i != children.end(); ++i, ++ia)
00125 {
00126 glDisable(GL_LINE_STIPPLE);
00127 glColor3f(1,1,1);
00128
00129 if (parent->type_name() == "vgui_deck_tableau") {
00130 vgui_deck_tableau_sptr deck; deck.vertical_cast(parent);
00131 if (deck->current() != *i) {
00132 glLineStipple (1, 0x1C47);
00133 glEnable (GL_LINE_STIPPLE);
00134 }
00135 }
00136 else if (parent->type_name() == "vgui_composite_tableau") {
00137 vgui_composite_tableau_sptr comp; comp.vertical_cast(parent);
00138
00139 if (!comp->is_active(ia)) {
00140 glLineStipple (1, 0x1C47);
00141 glEnable (GL_LINE_STIPPLE);
00142 }
00143 }
00144 else if (parent->type_name() == "vgui_listmanager2D_tableau") {
00145 vgui_listmanager2D_tableau_sptr lman; lman.vertical_cast(parent);
00146 if (!lman->is_active(ia)) {
00147 if (!lman->is_visible(ia))
00148 glLineStipple (1, 0x0101);
00149 else
00150 glLineStipple (1, 0x1C47);
00151 glEnable (GL_LINE_STIPPLE);
00152 }
00153 }
00154
00155 glLineWidth(1);
00156 glBegin(GL_LINES);
00157 glVertex2f(x,y+icon_height);
00158 glVertex2f(start_x+offset_x,ny-(icon_height));
00159 glEnd();
00160
00161 if (*i)
00162 draw_icons(*i, start_x+offset_x, ny);
00163 offset_x+=spacing;
00164 }
00165 }
00166
00167
00168 if (parent->type_name() == "vgui_tview_tableau") {
00169 draw_tview_icon(x,y);
00170 }
00171 else {
00172 if (parent->type_name() == "vgui_deck_tableau")
00173 glColor3f(0,1,0);
00174 else if (parent->type_name() == "vgui_viewer2D_tableau")
00175 glColor3f(1,0,0);
00176 else if (parent->type_name() == "vgui_viewer3D_tableau")
00177 glColor3f(0, 0, 1);
00178 else if (parent->type_name() == "vgui_displaylist2D_tableau")
00179 glColor3f(0.5, 0, 0);
00180 else if (parent->type_name() == "vgui_displaylist3D_tableau")
00181 glColor3f(0, 0, 0.5);
00182 else if (parent->type_name() == "vgui_listmanager2D_tableau")
00183 glColor3f(1, 0, 0.5);
00184 else if (parent->type_name() == "vgui_composite_tableau")
00185 glColor3f(1, 0, 1);
00186 else if (parent->type_name() == "vgui_image_tableau")
00187 glColor3f(1, 0.5, 0);
00188 else if (parent->type_name() == "vgui_vrml_tableau")
00189 glColor3f(0, 1, 1);
00190 else if (parent->type_name() == "vgui_blackbox_tableau")
00191 glColor3f(0, 0, 0);
00192 else
00193 glColor3f(1,1,0);
00194 draw_tableau_icon(x,y);
00195 }
00196
00197 if (parent == active_icon) {
00198 glColor3f(1,1,1);
00199 draw_border(x,y,icon_width,icon_height, 6);
00200
00201 glColor3f(1,0,0);
00202 draw_border(x,y,icon_width,icon_height, 2);
00203 }
00204 }
00205
00206
00207 void vgui_tview_tableau::add_icons(vcl_vector<vgui_tview_tableau::icon>* icons, vgui_tableau_sptr const& parent,
00208 float x, float y)
00209 {
00210 vcl_vector<vgui_tableau_sptr> children;
00211 parent->get_children(&children);
00212
00213 if (children.size() > 0)
00214 {
00215 float ny = y + spacing*children.size();
00216
00217 int num = children.size();
00218
00219 float total_x = (num-1)*spacing;
00220 float start_x = x - (int) (total_x/2.0);
00221 float offset_x = 0;
00222
00223
00224 for (vcl_vector<vgui_tableau_sptr>::iterator i = children.begin();
00225 i != children.end(); ++i)
00226 {
00227 add_icons(icons, *i, start_x+offset_x, ny);
00228 offset_x+=spacing;
00229 }
00230 }
00231
00232
00233 icon this_icon;
00234 this_icon.tableau = parent;
00235 this_icon.x = x;
00236 this_icon.y = y;
00237 icons->push_back(this_icon);
00238 }
00239
00240 vgui_tableau_sptr vgui_tview_tableau::find_closest_icon(vcl_vector<vgui_tview_tableau::icon> const& icons, float ix, float iy)
00241 {
00242 #ifdef DEBUG
00243 vcl_cerr << "vgui_tview_tableau::find_closest_icon() number of icons = " << icons.size() << '\n';
00244 #endif
00245
00246 float closest_dist = -1;
00247 vgui_tableau_sptr closest;
00248
00249 for (vcl_vector<icon>::const_iterator i_iter = icons.begin();
00250 i_iter != icons.end(); ++i_iter) {
00251 icon i = *i_iter;
00252
00253 float dx = i.x - ix;
00254 float dy = i.y - iy;
00255 float dist = vcl_sqrt(dx*dx + dy*dy);
00256 if (!closest || dist < closest_dist) {
00257 closest_dist = dist;
00258 closest = i.tableau;
00259 }
00260 }
00261
00262 return closest;
00263 }
00264
00265
00266 vcl_string strip_preceeding_numerals(const char* name)
00267 {
00268 vcl_string str(name);
00269
00270 vcl_string::iterator s_iter = str.begin();
00271 for (; s_iter != str.end(); ++s_iter) {
00272 if (*s_iter < '0' || *s_iter > '9') {
00273 break;
00274 }
00275 }
00276
00277 if (s_iter != str.end())
00278 str.erase(str.begin(), s_iter);
00279
00280 return str;
00281 }
00282
00283 bool vgui_tview_tableau::handle(const vgui_event& e)
00284 {
00285 #ifdef DEBUG
00286 vcl_cerr << "vgui_tview_tableau::handle\n";
00287 #endif
00288
00289 GLfloat vp[4];
00290 glGetFloatv(GL_VIEWPORT, vp);
00291 float width = vp[2];
00292 float height = vp[3];
00293
00294 float startx = width/2;
00295 float starty = height/3;
00296
00297 if (e.type == vgui_DRAW)
00298 {
00299
00300
00301 glClearColor(0.0, 0.0, 0.0, 1.0);
00302 glClear(GL_COLOR_BUFFER_BIT);
00303
00304
00305 draw_icons(child, startx, starty);
00306 return true;
00307 }
00308 else if (e.type==vgui_MOTION) {
00309 vcl_vector<icon> icons;
00310 add_icons(&icons, child, startx, starty);
00311
00312 vgui_projection_inspector pi;
00313 float ix, iy;
00314 pi.window_to_image_coordinates(e.wx, e.wy, ix, iy);
00315
00316 closest_icon = find_closest_icon(icons, ix, iy);
00317 }
00318 else if (e.type==vgui_BUTTON_DOWN) {
00319 vcl_vector<icon> icons;
00320 add_icons(&icons, child, startx, starty);
00321
00322 vgui_projection_inspector pi;
00323 float ix, iy;
00324 pi.window_to_image_coordinates(e.wx, e.wy, ix, iy);
00325
00326 vgui_tableau_sptr t = find_closest_icon(icons, ix, iy);
00327 active_icon = t;
00328
00329 #ifdef DEBUG
00330 vcl_cerr << "icon is " << (void*) t << '\n';
00331 #endif
00332 if (t) {
00333 vcl_cerr << "---------\n"
00334 #ifdef DEBUG
00335 << "| type : " << strip_preceeding_numerals(typeid(*t).name()) << '\n'
00336 #endif
00337 << "| type_name : " << t->type_name() << vcl_endl
00338 << "| file_name : " << t->file_name() << vcl_endl
00339 << "| pretty_name : " << t->pretty_name() << vcl_endl
00340 << "---------\n\n";
00341 }
00342
00343 post_redraw();
00344 }
00345 else if (e.type==vgui_BUTTON_UP) {
00346 active_icon = 0;
00347 post_redraw();
00348 }
00349 else {
00350 GLint oldbuff;
00351 glGetIntegerv(GL_DRAW_BUFFER, &oldbuff);
00352 glDrawBuffer(GL_NONE);
00353 bool retv = child->handle(e);
00354 glDrawBuffer((GLenum)oldbuff);
00355 return retv;
00356 }
00357
00358 return false;
00359 }
00360
00361
00362 void vgui_tview_tableau::get_popup(const vgui_popup_params& , vgui_menu &menu)
00363 {
00364 if (closest_icon) {
00365 menu.separator();
00366 vgui_popup_params np;
00367 np.recurse = false;
00368 closest_icon->get_popup(np, menu);
00369 }
00370 }