00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011 #include "vgui_listmanager2D_tableau.h"
00012
00013 #include <vcl_iostream.h>
00014 #include <vcl_vector.h>
00015 #include <vcl_algorithm.h>
00016
00017 #include <vgui/vgui_gl.h>
00018 #include <vgui/vgui_parent_child_link.h>
00019 #include <vgui/vgui_event.h>
00020 #include <vgui/vgui_matrix_state.h>
00021 #include <vgui/vgui_projection_inspector.h>
00022 #include <vgui/vgui_utils.h>
00023 #include <vgui/vgui_soview.h>
00024 #include <vgui/vgui_soview2D.h>
00025 #include <vgui/vgui_displaylist2D_tableau.h>
00026 #include <vgui/vgui_style.h>
00027
00028
00029 vgui_listmanager2D_tableau::vgui_listmanager2D_tableau():
00030 #if 0
00031 highlight_list(0),
00032 #endif
00033 highlight_so(0)
00034 {
00035 }
00036
00037 vgui_listmanager2D_tableau::~vgui_listmanager2D_tableau()
00038 {
00039 }
00040
00041 vcl_string vgui_listmanager2D_tableau::type_name() const
00042 {
00043 return "vgui_listmanager2D_tableau";
00044 }
00045
00046
00047 void vgui_listmanager2D_tableau::add(vgui_displaylist2D_tableau_sptr const& dl)
00048 {
00049 children.push_back( vgui_parent_child_link(this,dl) );
00050 active.push_back(true);
00051 visible.push_back(true);
00052 observers.notify();
00053 }
00054
00055
00056 void vgui_listmanager2D_tableau::remove(vgui_displaylist2D_tableau_sptr const& t)
00057 {
00058 vcl_vector<bool>::iterator ia = active.begin();
00059 vcl_vector<bool>::iterator iv = visible.begin();
00060 for (vcl_vector<vgui_parent_child_link>::iterator i=children.begin() ; i!=children.end() ; ++i, ++ia, ++iv)
00061 if ( *i == t )
00062 {
00063 children.erase(i);
00064 active.erase(ia);
00065 visible.erase(iv);
00066 observers.notify();
00067 return;
00068 }
00069 }
00070
00071 void vgui_listmanager2D_tableau::set_active(int v, bool b)
00072 {
00073 if (!index_ok(v)) return;
00074 active[v] = b;
00075 }
00076
00077 bool vgui_listmanager2D_tableau::is_active(int v)
00078 {
00079 if (!index_ok(v)) return false;
00080 return active[v];
00081 }
00082
00083 void vgui_listmanager2D_tableau::set_visible(int v, bool b)
00084 {
00085 if (!index_ok(v)) return;
00086 visible[v] = b;
00087 }
00088
00089 bool vgui_listmanager2D_tableau::is_visible(int v)
00090 {
00091 if (!index_ok(v)) return false;
00092 return visible[v];
00093 }
00094
00095 bool vgui_listmanager2D_tableau::index_ok(int v)
00096 {
00097 return v >= 0 && v < int(children.size());
00098 }
00099
00100 bool vgui_listmanager2D_tableau::help()
00101 {
00102 vcl_cerr << '\n'
00103 << "+- vgui_listmanager2D_tableau keys -+\n"
00104 << "| |\n"
00105 << "| `1' to `9' toggle child `n' |\n"
00106 << "+-----------------------------------+\n\n";
00107 return false;
00108 }
00109
00110 vgui_displaylist2D_tableau_sptr vgui_listmanager2D_tableau::contains_hit(vcl_vector<unsigned> const& names)
00111 {
00112 for (vcl_vector<vgui_parent_child_link>::iterator i=this->children.begin() ;
00113 i!=this->children.end() ; ++i)
00114 {
00115
00116 vgui_displaylist2D_tableau_sptr list;
00117 list.vgui_tableau_sptr::operator=(i->child());
00118 unsigned list_id = list->get_id();
00119
00120 vcl_vector<unsigned>::const_iterator ni = vcl_find(names.begin(), names.end(), list_id);
00121 if (ni != names.end())
00122 return list;
00123 }
00124
00125 return vgui_displaylist2D_tableau_sptr();
00126 }
00127
00128 void vgui_listmanager2D_tableau::get_hits(float x, float y, vcl_vector<vcl_vector<unsigned> >* hits)
00129 {
00130 GLuint *ptr = vgui_utils::enter_pick_mode(x,y,100);
00131
00132 int count=0;
00133 for (vcl_vector<vgui_parent_child_link>::iterator i=this->children.begin() ;
00134 i!=this->children.end() ; ++i, ++count)
00135 {
00136 vgui_displaylist2D_tableau_sptr display;
00137 display.vgui_tableau_sptr::operator=(i->child());
00138
00139 if (this->active[count] && this->visible[count])
00140 {
00141 display->gl_mode = GL_SELECT;
00142 display->handle(vgui_event(vgui_DRAW));
00143 display->gl_mode = GL_RENDER;
00144 }
00145 }
00146
00147 int num_hits = vgui_utils::leave_pick_mode();
00148
00149
00150 vgui_utils::process_hits(num_hits, ptr, *hits);
00151 }
00152
00153 void vgui_listmanager2D_tableau::find_closest(float x, float y, vcl_vector<vcl_vector<unsigned> >* hits,
00154 vgui_soview2D** closest_so, vgui_displaylist2D_tableau_sptr* closest_display)
00155 {
00156 float closest_dist = -1;
00157 vcl_vector<unsigned> closest_hit;
00158 vgui_displaylist2D_tableau_sptr display;
00159 closest_display = 0;
00160 closest_so = 0;
00161
00162 #ifdef DEBUG
00163 vcl_cerr << "vgui_listmanager2D_tableau::find_closest: hits->size() = " << hits->size() << '\n';
00164 #endif
00165 for (vcl_vector<vcl_vector<unsigned> >::iterator h_iter = hits->begin();
00166 h_iter != hits->end(); ++h_iter)
00167 {
00168 vcl_vector<unsigned> names = *h_iter;
00169 #ifdef DEBUG
00170 vcl_cerr << "vgui_listmanager2D_tableau::find_closest: names.size() " << names.size() << '\n';
00171 #endif
00172
00173
00174 display = contains_hit(names);
00175 if (display)
00176 {
00177 #ifdef DEBUG
00178 vcl_cerr << "vgui_listmanager2D_tableau::find_closest: hit in display " << display->get_id() << '\n';
00179 #endif
00180 vgui_soview2D *so = static_cast<vgui_soview2D*>(display->contains_hit(names));
00181 if (so)
00182 {
00183 float dist = so->distance_squared(x,y);
00184 if (closest_dist<0 || dist<closest_dist)
00185 {
00186 closest_dist = dist;
00187 *closest_display = display;
00188 closest_hit = *h_iter;
00189 }
00190 }
00191 }
00192 }
00193
00194 if (*closest_display)
00195 {
00196
00197 *closest_so = static_cast<vgui_soview2D*>((*closest_display)->contains_hit(closest_hit));
00198 }
00199 }
00200
00201
00202
00203 bool vgui_listmanager2D_tableau::handle(const vgui_event& event)
00204 {
00205
00206 vgui_matrix_state PM;
00207
00208
00209 if (event.type==vgui_DRAW || event.type==vgui_DRAW_OVERLAY)
00210 {
00211 bool retv = true;
00212
00213 int ia = 0;
00214 for ( vcl_vector<vgui_parent_child_link>::iterator i = children.begin(); i != children.end(); ++i, ++ia)
00215 {
00216 PM.restore();
00217
00218 if (visible[ia])
00219 if ( !(*i)->handle(event) )
00220 retv=false;
00221 }
00222 return retv;
00223 }
00224
00225
00226
00227 this->saved_event_ = event;
00228 return vgui_tableau::handle(event);
00229 }
00230
00231 bool vgui_listmanager2D_tableau::motion(int x, int y)
00232 {
00233 vgui_projection_inspector pi;
00234 float ix, iy;
00235 pi.window_to_image_coordinates(int(x),int(y), ix,iy);
00236
00237 vcl_vector<vcl_vector<unsigned> > hits;
00238 get_hits(x,y,&hits);
00239
00240 vgui_soview2D* closest_so;
00241 vgui_displaylist2D_tableau_sptr closest_display;
00242 find_closest(ix, iy, &hits, &closest_so, &closest_display);
00243
00244 #ifdef DEBUG
00245 if (closest_so && closest_display)
00246 vcl_cerr << "vgui_listmanager2D_tableau::motion: hit " << closest_so->get_id()
00247 << " in vcl_list " << closest_display->get_id() << vcl_endl;
00248 #endif
00249
00250 vgui_utils::begin_sw_overlay();
00251
00252 if (highlight_so)
00253 {
00254 vgui_soview* so = highlight_so;
00255 vgui_style_sptr style = so->get_style();
00256 style->apply_point_size();
00257 style->apply_line_width();
00258
00259 if (highlight_list->is_selected(so->get_id()))
00260 glColor3f(1.0f, 0.0f, 0.0f);
00261 else
00262 {
00263 style->apply_color();
00264 }
00265 so->draw();
00266 }
00267
00268 if (closest_so)
00269 {
00270 #ifdef DEBUG
00271 vcl_cerr << "vgui_listmanager2D_tableau::motion highlighting : " << closest_id << '\n';
00272 #endif
00273 vgui_soview* so = closest_so;
00274 vgui_style_sptr style = so->get_style();
00275 style->apply_point_size();
00276 style->apply_line_width();
00277 glColor3f(0.0f,1.0f,1.0f);
00278 so->draw();
00279 }
00280
00281 vgui_utils::end_sw_overlay();
00282
00283 highlight_list = closest_display;
00284 highlight_so = closest_so;
00285
00286 return true;
00287 }
00288
00289
00290 bool vgui_listmanager2D_tableau::mouse_down(int x, int y, vgui_button button, vgui_modifier modifier)
00291 {
00292 if (button == vgui_MIDDLE && (modifier & vgui_SHIFT))
00293 {
00294 int count=0;
00295 for (vcl_vector<vgui_parent_child_link>::iterator i=this->children.begin() ;
00296 i!=this->children.end() ; ++i, ++count)
00297 {
00298 vgui_displaylist2D_tableau_sptr display;
00299 display.vgui_tableau_sptr::operator=(i->child());
00300 if (this->active[count] && this->visible[count])
00301 display->handle(this->saved_event_);
00302 }
00303 return true;
00304 }
00305
00306
00307 vgui_projection_inspector pi;
00308 float ix, iy;
00309 pi.window_to_image_coordinates(int(x),int(y), ix,iy);
00310
00311 vcl_vector<vcl_vector<unsigned> > hits;
00312 get_hits(x,y,&hits);
00313
00314 vgui_soview2D* closest_so;
00315 vgui_displaylist2D_tableau_sptr closest_display;
00316 find_closest(ix, iy, &hits, &closest_so, &closest_display);
00317
00318 return closest_display && closest_display->handle(this->saved_event_);
00319 }
00320
00321 bool vgui_listmanager2D_tableau::key_press(int , int , vgui_key key, vgui_modifier)
00322 {
00323 #ifdef DEBUG
00324 vcl_cerr << "vgui_listmanager2D_tableau_handler::key_press " << key << '\n';
00325 #endif
00326
00327 if (key >= '1' && key <= '9')
00328 {
00329 char text[1];
00330 text[0] = key;
00331 int num = atoi(text);
00332
00333 bool isactive = this->is_active(num-1);
00334 bool isvisible = this->is_visible(num-1);
00335
00336 if (isactive)
00337 {
00338 this->set_active(num-1, false);
00339 this->set_visible(num-1, false);
00340 vgui_displaylist2D_tableau_sptr list;
00341 list.vgui_tableau_sptr::operator=(this->children[num-1].child());
00342 if (highlight_list == list)
00343 {
00344 highlight_list = vgui_displaylist2D_tableau_sptr();
00345 highlight_so = 0;
00346 }
00347 }
00348 else if (isvisible)
00349 {
00350 this->set_active(num-1, true);
00351 this->set_visible(num-1, true);
00352 }
00353 else
00354 {
00355 this->set_active(num-1, false);
00356 this->set_visible(num-1, true);
00357
00358 vgui_displaylist2D_tableau_sptr list;
00359 list.vgui_tableau_sptr::operator=(this->children[num-1].child());
00360 if (highlight_list == list)
00361 {
00362 highlight_list = vgui_displaylist2D_tableau_sptr();
00363 highlight_so = 0;
00364 }
00365 }
00366
00367 this->post_redraw();
00368 return true;
00369 }
00370 return false;
00371 }