Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "vgui_soview.h"
00016
00017 #include <vcl_iostream.h>
00018 #include <vcl_map.h>
00019
00020 #include <vgui/vgui_gl.h>
00021 #include <vgui/vgui_observer.h>
00022 #include <vgui/vgui_style.h>
00023
00024 #define VGUI_STATIC_OBJECT(T, var) \
00025 static T& var () { \
00026 static T * t = 0; \
00027 if (t == 0) t = new T(); \
00028 return *t; \
00029 }
00030
00031 #define AWF_USE_MAP 1
00032
00033 unsigned vgui_soview::current_id = 1;
00034
00035 #if AWF_USE_MAP
00036 typedef vcl_map<unsigned, void*, vcl_less<unsigned> > Map_soview;
00037 VGUI_STATIC_OBJECT(Map_soview, object_map);
00038 #else
00039 typedef vcl_vector<void* > Map_soview;
00040 VGUI_STATIC_OBJECT(Map_soview, object_map);
00041 #endif
00042
00043
00044
00045 vgui_soview::~vgui_soview()
00046 {
00047 #if AWF_USE_MAP
00048 object_map().erase(id);
00049 #endif
00050 }
00051
00052 unsigned vgui_soview::create_id()
00053 {
00054 unsigned nid = current_id;
00055 current_id++;
00056 return nid;
00057 }
00058
00059 void vgui_soview::add_id()
00060 {
00061 id = create_id();
00062 #if AWF_USE_MAP
00063 object_map().insert(Map_soview::value_type(id, this));
00064 #else
00065 object_map().resize(id * 2);
00066 object_map()[id] = this;
00067 #endif
00068 }
00069
00070 vgui_soview* vgui_soview::id_to_object(unsigned id)
00071 {
00072 #if AWF_USE_MAP
00073 Map_soview::iterator i = object_map().find(id);
00074 if (i != object_map().end()) {
00075 return static_cast<vgui_soview*>((*i).second);
00076 }
00077 #else
00078 if (id < object_map().size()) {
00079 return static_cast<vgui_soview*>(object_map()[id]);
00080 }
00081 #endif
00082
00083 return 0;
00084 }
00085
00086
00087 vcl_ostream& vgui_soview::print(vcl_ostream& s) const
00088 {
00089 return s << "id " << id;
00090 }
00091
00092
00093 void vgui_soview::draw_select() const
00094 {
00095
00096
00097
00098 this->draw();
00099 }
00100
00101
00102 void vgui_soview::load_name() const
00103 {
00104 glLoadName(id);
00105 }
00106
00107
00108 void vgui_soview::set_colour(float r, float g, float b)
00109 {
00110 vgui_style_sptr newstyle = vgui_style::new_style();
00111
00112 newstyle->rgba[0] = r;
00113 newstyle->rgba[1] = g;
00114 newstyle->rgba[2] = b;
00115
00116 if (style) {
00117 newstyle->point_size = style->point_size;
00118 newstyle->line_width = style->line_width;
00119 }
00120
00121 style = newstyle;
00122 }
00123
00124 void vgui_soview::set_point_size(float s)
00125 {
00126 vgui_style_sptr newstyle = vgui_style::new_style();
00127
00128 newstyle->point_size = s;
00129
00130 if (style) {
00131 newstyle->rgba[0] = style->rgba[0];
00132 newstyle->rgba[1] = style->rgba[1];
00133 newstyle->rgba[2] = style->rgba[2];
00134 newstyle->line_width = style->line_width;
00135 }
00136
00137 style = newstyle;
00138 }
00139
00140 void vgui_soview::set_line_width(float w)
00141 {
00142 vgui_style_sptr newstyle = vgui_style::new_style();
00143
00144 newstyle->line_width = w;
00145
00146 if (style) {
00147 newstyle->rgba[0] = style->rgba[0];
00148 newstyle->rgba[1] = style->rgba[1];
00149 newstyle->rgba[2] = style->rgba[2];
00150 newstyle->point_size = style->point_size;
00151 }
00152
00153 style = newstyle;
00154 }
00155
00156
00157
00158 const void * const vgui_soview::msg_select="select";
00159 const void * const vgui_soview::msg_deselect="deselect";
00160 const void * const vgui_soview::msg_highlight="highlight";
00161 const void * const vgui_soview::msg_unhighlight="unhighlight";
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 typedef vcl_multimap<void *, void *, vcl_less<void *> > mmap_Pv_Pv;
00175 static mmap_Pv_Pv &the_map()
00176 {
00177 static mmap_Pv_Pv *ptr = 0;
00178 if (!ptr)
00179 ptr = new mmap_Pv_Pv;
00180 return *ptr;
00181 }
00182
00183 void vgui_soview::attach(vgui_observer* o)
00184 {
00185 the_map().insert(mmap_Pv_Pv::value_type(this, o));
00186 }
00187
00188 void vgui_soview::detach(vgui_observer* o)
00189 {
00190 mmap_Pv_Pv::iterator lo = the_map().lower_bound(this);
00191 mmap_Pv_Pv::iterator hi = the_map().upper_bound(this);
00192 for (mmap_Pv_Pv::iterator i=lo; i!=hi; ++i)
00193 if (
00194 (*i).second == o
00195 ) {
00196 the_map().erase(i);
00197 return;
00198 }
00199
00200
00201 vcl_cerr << __FILE__ " : no such observer on this soview\n";
00202 }
00203
00204 void vgui_soview::get_observers(vcl_vector<vgui_observer*>& vobs) const
00205 {
00206 mmap_Pv_Pv::const_iterator lo = the_map().lower_bound( const_cast<vgui_soview*>(this) );
00207 mmap_Pv_Pv::const_iterator hi = the_map().upper_bound( const_cast<vgui_soview*>(this) );
00208 for (mmap_Pv_Pv::const_iterator i=lo; i!=hi; ++i)
00209 vobs.push_back( static_cast<vgui_observer*>((*i).second) );
00210 }
00211
00212
00213 void vgui_soview::notify() const
00214 {
00215 vcl_vector<vgui_observer*> vobs;
00216 get_observers(vobs);
00217 for (unsigned i=0; i<vobs.size(); ++i)
00218 vobs[i]->update();
00219 }
00220
00221 void vgui_soview::notify(vgui_message const &msg) const
00222 {
00223 vcl_vector<vgui_observer*> vobs;
00224 get_observers(vobs);
00225 for (unsigned i=0; i<vobs.size(); ++i)
00226 vobs[i]->update(msg);
00227 }