Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/sg/legend

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_sg_legend
  5 #define tools_sg_legend
  6 
  7 // To handle a colored "rep" (line or marker) with a text at right.
  8 
  9 #include "back_area"
 10 #include "matrix"
 11 #include "text_hershey"
 12 #include "base_freetype"
 13 #include "markers"
 14 #include "enums"
 15 
 16 #include "../colorf"
 17 //#include "../paw2stix"
 18 #include "text_valop"
 19 
 20 namespace tools {
 21 namespace sg {
 22 
 23 class legend : public back_area {
 24   TOOLS_NODE(legend,tools::sg::legend,back_area)
 25 public:
 26   mf_string strings;
 27 
 28   sf_vec<colorf,float> color; //color of the "rep"
 29   // text atbs :
 30   //sf<float> transparency;
 31   sf_string font;
 32   sf_enum<sg::font_modeling> font_modeling;
 33   sf_string encoding;
 34   //sf<float> line_width;          // for text_hershey.
 35 
 36   sf<bool> back_visible;
 37   sf<float> wmargin_factor;
 38   sf<float> hmargin_factor;
 39   sf_enum<hjust> lhjust;
 40   sf_enum<hjust> rhjust;
 41   //sf<bool> confine;
 42 
 43   sf_enum<sg::marker_style> marker_style;
 44   sf<float> marker_size;
 45 public:
 46   virtual const desc_fields& node_desc_fields() const {
 47     TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::legend)
 48     static const desc_fields s_v(parent::node_desc_fields(),12, //WARNING : take care of count.
 49       TOOLS_ARG_FIELD_DESC(strings),
 50       TOOLS_ARG_FIELD_DESC(color),
 51       TOOLS_ARG_FIELD_DESC(font),
 52 
 53       TOOLS_ARG_FIELD_DESC_ENUMS_BEG(font_modeling,3)
 54         TOOLS_ARG_ENUM(font_outline),
 55         TOOLS_ARG_ENUM(font_filled),
 56         TOOLS_ARG_ENUM(font_pixmap)
 57       TOOLS_ARG_FIELD_DESC_ENUMS_END,
 58 
 59       TOOLS_ARG_FIELD_DESC(encoding),
 60       TOOLS_ARG_FIELD_DESC(back_visible),
 61       TOOLS_ARG_FIELD_DESC(wmargin_factor),
 62       TOOLS_ARG_FIELD_DESC(hmargin_factor),
 63       TOOLS_ARG_FIELD_DESC(lhjust),
 64       TOOLS_ARG_FIELD_DESC(rhjust),
 65       TOOLS_ARG_FIELD_DESC(marker_style),
 66       TOOLS_ARG_FIELD_DESC(marker_size)
 67     );
 68     return s_v;
 69   }
 70 private:
 71   void add_fields(){
 72     add_field(&strings);
 73 
 74     add_field(&color);
 75     add_field(&font);
 76     add_field(&font_modeling);
 77     add_field(&encoding);
 78 
 79     add_field(&back_visible);
 80     add_field(&wmargin_factor);
 81     add_field(&hmargin_factor);
 82     add_field(&lhjust);
 83     add_field(&rhjust);
 84     add_field(&marker_style);
 85     add_field(&marker_size);
 86   }
 87 public:
 88   virtual void render(render_action& a_action) {
 89     if(touched()) {
 90       update_sg();
 91       reset_touched();
 92     }
 93     if(back_visible.value()) m_back_sep.render(a_action);
 94     m_sep.render(a_action);
 95   }
 96   virtual void pick(pick_action& a_action) {
 97     if(touched()) {
 98       update_sg();
 99       reset_touched();
100     }
101     if(back_visible.value()) {
102       m_back_sep.pick(a_action);
103       if(a_action.done()) return;
104     }
105   }
106   virtual void search(search_action& a_action) {
107     if(touched()) {
108       update_sg();
109       reset_touched();
110     }
111     node::search(a_action);
112     if(a_action.done()) return;
113     if(back_visible.value()) {
114       m_back_sep.search(a_action);
115       if(a_action.done()) return;
116     }
117     m_sep.search(a_action);
118     if(a_action.done()) return;
119   }
120   virtual void bbox(bbox_action& a_action) {
121     if(touched()) {
122       update_sg();
123       reset_touched();
124     }
125     if(back_visible.value()) m_back_sep.bbox(a_action);
126     m_sep.bbox(a_action);
127   }
128 public:
129   legend(const base_freetype& a_ttf)
130   :parent()
131   ,strings()
132 
133   ,color(colorf_black())
134   //,transparency(0)
135   ,font(font_hershey())
136   ,font_modeling(font_filled)
137   ,encoding(encoding_PAW())
138   //,line_width(1)
139 
140   ,back_visible(true)
141   ,wmargin_factor(0.9f)
142   ,hmargin_factor(0.9f)
143   ,lhjust(left)
144   ,rhjust(right)
145 
146   ,marker_style(marker_dot)
147   ,marker_size(10)
148 
149   //,confine(false)
150 
151   ,m_ttf(a_ttf)
152   {
153     add_fields();
154   }
155   virtual ~legend(){}
156 public:
157   legend(const legend& a_from)
158   :parent(a_from)
159   ,strings(a_from.strings)
160 
161   ,color(a_from.color)
162   //,transparency(a_from.transparency)
163   ,font(a_from.font)
164   ,font_modeling(a_from.font_modeling)
165   ,encoding(a_from.encoding)
166   //,line_width(a_from.line_width)
167 
168   ,back_visible(a_from.back_visible)
169   ,wmargin_factor(a_from.wmargin_factor)
170   ,hmargin_factor(a_from.hmargin_factor)
171   ,lhjust(a_from.lhjust)
172   ,rhjust(a_from.rhjust)
173 
174   ,marker_style(a_from.marker_style)
175   ,marker_size(a_from.marker_size)
176 
177   //,confine(a_from.confine)
178 
179   ,m_ttf(a_from.m_ttf)
180   {
181     add_fields();
182   }
183   legend& operator=(const legend& a_from){
184     parent::operator=(a_from);
185     strings = a_from.strings;
186 
187     color = a_from.color;
188     //transparency = a_from.transparency;
189     font = a_from.font;
190     font_modeling = a_from.font_modeling;
191     encoding = a_from.encoding;
192     //line_width = a_from.line_width;
193 
194     back_visible = a_from.back_visible;
195     wmargin_factor = a_from.wmargin_factor;
196     hmargin_factor = a_from.hmargin_factor;
197     lhjust = a_from.lhjust;
198     rhjust = a_from.rhjust;
199 
200     marker_style = a_from.marker_style;
201     marker_size = a_from.marker_size;
202 
203     //confine = a_from.confine;
204 
205     return *this;
206   }
207 public:
208   void update_sg() {
209     // have this method public in order to use it in plotter.
210     // This is so because legend::height is an output field
211     // needed in plotter to place the box.
212 
213     m_back_sep.clear(); //back_area::update_sg done last.
214 
215     m_sep.clear();
216 
217     if(width.value()<=0) return;
218     //if(confine) {
219     //  if(height.value()<=0) return;
220     //}
221 
222    {bool empty = true;
223     std::vector<std::string>::const_iterator it;
224     for(it=strings.values().begin();it!=strings.values().end();++it) {
225       if((*it).size()) {empty = false;break;}
226     }
227     if(empty) return;}
228 
229     //sf<float> zfront ?
230     float zz = back_visible.value()?0.01f:0;
231 
232   //bool rep_line = false;
233 
234     /*
235     float fw = 0;
236     float fh = 0;
237     float lw = 0;
238     float rw = 0;
239     if(rep_line) {
240       fw = width * wmargin_factor;
241       fh = height * hmargin_factor;
242 
243       lw = fw*0.5f*0.95f;
244       rw = fw*0.5f;
245     }*/
246     ////////////////////////////////////////////////////////////
247     /// rep at left ////////////////////////////////////////////
248     ////////////////////////////////////////////////////////////
249 
250    {separator* _sep = new separator;
251     m_sep.add(_sep);
252 
253     rgba* mat = new rgba();
254     mat->color = color;
255     _sep->add(mat);
256 
257 /*  if(rep_line) {
258       matrix* ltsf = new matrix;
259       float xx = -fw*0.5F; //left justified.
260       ltsf->set_translate(xx,0,zz);
261       _sep->add(ltsf);
262 
263       draw_style* ds = new draw_style;
264       ds->style = draw_lines;
265       _sep->add(ds);
266 
267       vertices* vtxs = new vertices;
268       vtxs->mode = gl::line_strip();
269       vtxs->add( 0,0,zz);
270       vtxs->add(lw,0,zz);
271       _sep->add(vtxs);
272 
273     } else*/ { // rep marker :
274       if(marker_style.value()==marker_dot) {
275         draw_style* ds = new draw_style;
276         ds->style = draw_points;
277         ds->point_size = marker_size;
278         _sep->add(ds);
279         vertices* vtxs = new vertices;
280         vtxs->mode = gl::points();
281         vtxs->add(-width*0.5f+height*0.5f,0,zz);
282         _sep->add(vtxs);
283       } else {
284         markers* vtxs = new markers;
285         vtxs->size = marker_size;
286         vtxs->style = marker_style;
287         vtxs->add(-width*0.5f+height*0.5f,0,zz);
288         _sep->add(vtxs);
289       }
290     }
291 
292     }
293 
294     ////////////////////////////////////////////////////////////
295     /// right text /////////////////////////////////////////////
296     ////////////////////////////////////////////////////////////
297     base_text* rtext = 0;
298     matrix* rtsf = 0;
299 
300    {separator* _sep = new separator;
301     m_sep.add(_sep);
302 
303     rgba* mat = new rgba();
304     mat->color = colorf_black();
305     _sep->add(mat);
306 
307     if(font==font_hershey()) {
308       draw_style* ds = new draw_style;
309       ds->style.value(draw_lines);
310       _sep->add(ds);
311     }
312 
313     rtsf = new matrix;
314     _sep->add(rtsf);
315     if(font==font_hershey()) {
316       text_hershey* text = new text_hershey;
317       text->encoding = encoding;
318       text->strings = strings;
319       _sep->add(text);
320       rtext = text;
321     } else {
322       if(encoding==encoding_PAW()) {
323         text_valop* text = new text_valop(m_ttf);
324         text->font = font;
325         text->font_modeling = font_modeling;
326         text->strings = strings;
327         _sep->add(text);
328         rtext = text;
329       } else {
330         base_freetype* text = base_freetype::create(m_ttf);
331         text->font = font;
332         text->modeling = font_modeling;
333         text->strings = strings;
334         _sep->add(text);
335         rtext = text;
336       }
337     }
338     rtext->hjust = rhjust;}
339 
340     ////////////////////////////////////////////////////////////
341     ////////////////////////////////////////////////////////////
342     ////////////////////////////////////////////////////////////
343 
344 /*  if(rep_line) {
345 
346       // adjust width :
347       float th = fh;
348      {float mn_x,mn_y,mn_z;
349       float mx_x,mx_y,mx_z;
350       rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
351       float bxw = mx_x-mn_x;
352       if(!bxw) {
353         m_sep.clear();
354         parent::update_sg();
355         return;
356       }
357       // adjust box width :
358       // fh -> bxw then to have rw :
359       float max_width = rw;
360       if(bxw>max_width) th = max_width*fh/bxw;}
361 
362       rtext->height = th;
363 
364      {float mn_x,mn_y,mn_z;
365       float mx_x,mx_y,mx_z;
366       rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
367       rtext->hjust = right;
368       float xx = fw*0.5f;
369       float yy = -(mn_y+mx_y)*0.5F;
370       rtsf->set_translate(xx,yy,zz);}
371 
372     } else*/ { //rep mark :
373 
374       // adjust width :
375       float th = height;
376      {float mn_x,mn_y,mn_z;
377       float mx_x,mx_y,mx_z;
378       rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
379       float bxw = mx_x-mn_x;
380       if(!bxw) {
381         m_sep.clear();
382         parent::update_sg();
383         return;
384       }
385       // adjust box width :
386       // height -> bxw then to have a wanted width :
387       float max_width = (width-height)*wmargin_factor;
388       if(bxw>max_width) th = max_width*height/bxw;
389       if(th<0) {
390         m_sep.clear();
391         parent::update_sg();
392         return;
393       }}
394 
395       rtext->height = th;
396      {float mn_x,mn_y,mn_z;
397       float mx_x,mx_y,mx_z;
398       rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
399       rtext->hjust = left;
400       float yy = -(mn_y+mx_y)*0.5F;
401       rtsf->set_translate(-width*0.5f+height,yy,zz);}
402 
403     }
404 
405     parent::update_sg();
406 
407   }
408 protected:
409   separator m_sep;
410   const base_freetype& m_ttf;
411 };
412 
413 }}
414 
415 #endif