Warning, /include/Geant4/tools/sg/legend is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_sg_legend
0005 #define tools_sg_legend
0006
0007 // To handle a colored "rep" (line or marker) with a text at right.
0008
0009 #include "back_area"
0010 #include "matrix"
0011 #include "text_hershey"
0012 #include "base_freetype"
0013 #include "markers"
0014 #include "enums"
0015
0016 #include "../colorf"
0017 //#include "../paw2stix"
0018 #include "text_valop"
0019
0020 namespace tools {
0021 namespace sg {
0022
0023 class legend : public back_area {
0024 TOOLS_NODE(legend,tools::sg::legend,back_area)
0025 public:
0026 mf_string strings;
0027
0028 sf_vec<colorf,float> color; //color of the "rep"
0029 // text atbs :
0030 //sf<float> transparency;
0031 sf_string font;
0032 sf_enum<sg::font_modeling> font_modeling;
0033 sf_string encoding;
0034 //sf<float> line_width; // for text_hershey.
0035
0036 sf<bool> back_visible;
0037 sf<float> wmargin_factor;
0038 sf<float> hmargin_factor;
0039 sf_enum<hjust> lhjust;
0040 sf_enum<hjust> rhjust;
0041 //sf<bool> confine;
0042
0043 sf_enum<sg::marker_style> marker_style;
0044 sf<float> marker_size;
0045 public:
0046 virtual const desc_fields& node_desc_fields() const {
0047 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::legend)
0048 static const desc_fields s_v(parent::node_desc_fields(),12, //WARNING : take care of count.
0049 TOOLS_ARG_FIELD_DESC(strings),
0050 TOOLS_ARG_FIELD_DESC(color),
0051 TOOLS_ARG_FIELD_DESC(font),
0052
0053 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(font_modeling,3)
0054 TOOLS_ARG_ENUM(font_outline),
0055 TOOLS_ARG_ENUM(font_filled),
0056 TOOLS_ARG_ENUM(font_pixmap)
0057 TOOLS_ARG_FIELD_DESC_ENUMS_END,
0058
0059 TOOLS_ARG_FIELD_DESC(encoding),
0060 TOOLS_ARG_FIELD_DESC(back_visible),
0061 TOOLS_ARG_FIELD_DESC(wmargin_factor),
0062 TOOLS_ARG_FIELD_DESC(hmargin_factor),
0063 TOOLS_ARG_FIELD_DESC(lhjust),
0064 TOOLS_ARG_FIELD_DESC(rhjust),
0065 TOOLS_ARG_FIELD_DESC(marker_style),
0066 TOOLS_ARG_FIELD_DESC(marker_size)
0067 );
0068 return s_v;
0069 }
0070 private:
0071 void add_fields(){
0072 add_field(&strings);
0073
0074 add_field(&color);
0075 add_field(&font);
0076 add_field(&font_modeling);
0077 add_field(&encoding);
0078
0079 add_field(&back_visible);
0080 add_field(&wmargin_factor);
0081 add_field(&hmargin_factor);
0082 add_field(&lhjust);
0083 add_field(&rhjust);
0084 add_field(&marker_style);
0085 add_field(&marker_size);
0086 }
0087 public:
0088 virtual void render(render_action& a_action) {
0089 if(touched()) {
0090 update_sg();
0091 reset_touched();
0092 }
0093 if(back_visible.value()) m_back_sep.render(a_action);
0094 m_sep.render(a_action);
0095 }
0096 virtual void pick(pick_action& a_action) {
0097 if(touched()) {
0098 update_sg();
0099 reset_touched();
0100 }
0101 if(back_visible.value()) {
0102 m_back_sep.pick(a_action);
0103 if(a_action.done()) return;
0104 }
0105 }
0106 virtual void search(search_action& a_action) {
0107 if(touched()) {
0108 update_sg();
0109 reset_touched();
0110 }
0111 node::search(a_action);
0112 if(a_action.done()) return;
0113 if(back_visible.value()) {
0114 m_back_sep.search(a_action);
0115 if(a_action.done()) return;
0116 }
0117 m_sep.search(a_action);
0118 if(a_action.done()) return;
0119 }
0120 virtual void bbox(bbox_action& a_action) {
0121 if(touched()) {
0122 update_sg();
0123 reset_touched();
0124 }
0125 if(back_visible.value()) m_back_sep.bbox(a_action);
0126 m_sep.bbox(a_action);
0127 }
0128 public:
0129 legend(const base_freetype& a_ttf)
0130 :parent()
0131 ,strings()
0132
0133 ,color(colorf_black())
0134 //,transparency(0)
0135 ,font(font_hershey())
0136 ,font_modeling(font_filled)
0137 ,encoding(encoding_PAW())
0138 //,line_width(1)
0139
0140 ,back_visible(true)
0141 ,wmargin_factor(0.9f)
0142 ,hmargin_factor(0.9f)
0143 ,lhjust(left)
0144 ,rhjust(right)
0145
0146 ,marker_style(marker_dot)
0147 ,marker_size(10)
0148
0149 //,confine(false)
0150
0151 ,m_ttf(a_ttf)
0152 {
0153 add_fields();
0154 }
0155 virtual ~legend(){}
0156 public:
0157 legend(const legend& a_from)
0158 :parent(a_from)
0159 ,strings(a_from.strings)
0160
0161 ,color(a_from.color)
0162 //,transparency(a_from.transparency)
0163 ,font(a_from.font)
0164 ,font_modeling(a_from.font_modeling)
0165 ,encoding(a_from.encoding)
0166 //,line_width(a_from.line_width)
0167
0168 ,back_visible(a_from.back_visible)
0169 ,wmargin_factor(a_from.wmargin_factor)
0170 ,hmargin_factor(a_from.hmargin_factor)
0171 ,lhjust(a_from.lhjust)
0172 ,rhjust(a_from.rhjust)
0173
0174 ,marker_style(a_from.marker_style)
0175 ,marker_size(a_from.marker_size)
0176
0177 //,confine(a_from.confine)
0178
0179 ,m_ttf(a_from.m_ttf)
0180 {
0181 add_fields();
0182 }
0183 legend& operator=(const legend& a_from){
0184 parent::operator=(a_from);
0185 strings = a_from.strings;
0186
0187 color = a_from.color;
0188 //transparency = a_from.transparency;
0189 font = a_from.font;
0190 font_modeling = a_from.font_modeling;
0191 encoding = a_from.encoding;
0192 //line_width = a_from.line_width;
0193
0194 back_visible = a_from.back_visible;
0195 wmargin_factor = a_from.wmargin_factor;
0196 hmargin_factor = a_from.hmargin_factor;
0197 lhjust = a_from.lhjust;
0198 rhjust = a_from.rhjust;
0199
0200 marker_style = a_from.marker_style;
0201 marker_size = a_from.marker_size;
0202
0203 //confine = a_from.confine;
0204
0205 return *this;
0206 }
0207 public:
0208 void update_sg() {
0209 // have this method public in order to use it in plotter.
0210 // This is so because legend::height is an output field
0211 // needed in plotter to place the box.
0212
0213 m_back_sep.clear(); //back_area::update_sg done last.
0214
0215 m_sep.clear();
0216
0217 if(width.value()<=0) return;
0218 //if(confine) {
0219 // if(height.value()<=0) return;
0220 //}
0221
0222 {bool empty = true;
0223 std::vector<std::string>::const_iterator it;
0224 for(it=strings.values().begin();it!=strings.values().end();++it) {
0225 if((*it).size()) {empty = false;break;}
0226 }
0227 if(empty) return;}
0228
0229 //sf<float> zfront ?
0230 float zz = back_visible.value()?0.01f:0;
0231
0232 //bool rep_line = false;
0233
0234 /*
0235 float fw = 0;
0236 float fh = 0;
0237 float lw = 0;
0238 float rw = 0;
0239 if(rep_line) {
0240 fw = width * wmargin_factor;
0241 fh = height * hmargin_factor;
0242
0243 lw = fw*0.5f*0.95f;
0244 rw = fw*0.5f;
0245 }*/
0246 ////////////////////////////////////////////////////////////
0247 /// rep at left ////////////////////////////////////////////
0248 ////////////////////////////////////////////////////////////
0249
0250 {separator* _sep = new separator;
0251 m_sep.add(_sep);
0252
0253 rgba* mat = new rgba();
0254 mat->color = color;
0255 _sep->add(mat);
0256
0257 /* if(rep_line) {
0258 matrix* ltsf = new matrix;
0259 float xx = -fw*0.5F; //left justified.
0260 ltsf->set_translate(xx,0,zz);
0261 _sep->add(ltsf);
0262
0263 draw_style* ds = new draw_style;
0264 ds->style = draw_lines;
0265 _sep->add(ds);
0266
0267 vertices* vtxs = new vertices;
0268 vtxs->mode = gl::line_strip();
0269 vtxs->add( 0,0,zz);
0270 vtxs->add(lw,0,zz);
0271 _sep->add(vtxs);
0272
0273 } else*/ { // rep marker :
0274 if(marker_style.value()==marker_dot) {
0275 draw_style* ds = new draw_style;
0276 ds->style = draw_points;
0277 ds->point_size = marker_size;
0278 _sep->add(ds);
0279 vertices* vtxs = new vertices;
0280 vtxs->mode = gl::points();
0281 vtxs->add(-width*0.5f+height*0.5f,0,zz);
0282 _sep->add(vtxs);
0283 } else {
0284 markers* vtxs = new markers;
0285 vtxs->size = marker_size;
0286 vtxs->style = marker_style;
0287 vtxs->add(-width*0.5f+height*0.5f,0,zz);
0288 _sep->add(vtxs);
0289 }
0290 }
0291
0292 }
0293
0294 ////////////////////////////////////////////////////////////
0295 /// right text /////////////////////////////////////////////
0296 ////////////////////////////////////////////////////////////
0297 base_text* rtext = 0;
0298 matrix* rtsf = 0;
0299
0300 {separator* _sep = new separator;
0301 m_sep.add(_sep);
0302
0303 rgba* mat = new rgba();
0304 mat->color = colorf_black();
0305 _sep->add(mat);
0306
0307 if(font==font_hershey()) {
0308 draw_style* ds = new draw_style;
0309 ds->style.value(draw_lines);
0310 _sep->add(ds);
0311 }
0312
0313 rtsf = new matrix;
0314 _sep->add(rtsf);
0315 if(font==font_hershey()) {
0316 text_hershey* text = new text_hershey;
0317 text->encoding = encoding;
0318 text->strings = strings;
0319 _sep->add(text);
0320 rtext = text;
0321 } else {
0322 if(encoding==encoding_PAW()) {
0323 text_valop* text = new text_valop(m_ttf);
0324 text->font = font;
0325 text->font_modeling = font_modeling;
0326 text->strings = strings;
0327 _sep->add(text);
0328 rtext = text;
0329 } else {
0330 base_freetype* text = base_freetype::create(m_ttf);
0331 text->font = font;
0332 text->modeling = font_modeling;
0333 text->strings = strings;
0334 _sep->add(text);
0335 rtext = text;
0336 }
0337 }
0338 rtext->hjust = rhjust;}
0339
0340 ////////////////////////////////////////////////////////////
0341 ////////////////////////////////////////////////////////////
0342 ////////////////////////////////////////////////////////////
0343
0344 /* if(rep_line) {
0345
0346 // adjust width :
0347 float th = fh;
0348 {float mn_x,mn_y,mn_z;
0349 float mx_x,mx_y,mx_z;
0350 rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0351 float bxw = mx_x-mn_x;
0352 if(!bxw) {
0353 m_sep.clear();
0354 parent::update_sg();
0355 return;
0356 }
0357 // adjust box width :
0358 // fh -> bxw then to have rw :
0359 float max_width = rw;
0360 if(bxw>max_width) th = max_width*fh/bxw;}
0361
0362 rtext->height = th;
0363
0364 {float mn_x,mn_y,mn_z;
0365 float mx_x,mx_y,mx_z;
0366 rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0367 rtext->hjust = right;
0368 float xx = fw*0.5f;
0369 float yy = -(mn_y+mx_y)*0.5F;
0370 rtsf->set_translate(xx,yy,zz);}
0371
0372 } else*/ { //rep mark :
0373
0374 // adjust width :
0375 float th = height;
0376 {float mn_x,mn_y,mn_z;
0377 float mx_x,mx_y,mx_z;
0378 rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0379 float bxw = mx_x-mn_x;
0380 if(!bxw) {
0381 m_sep.clear();
0382 parent::update_sg();
0383 return;
0384 }
0385 // adjust box width :
0386 // height -> bxw then to have a wanted width :
0387 float max_width = (width-height)*wmargin_factor;
0388 if(bxw>max_width) th = max_width*height/bxw;
0389 if(th<0) {
0390 m_sep.clear();
0391 parent::update_sg();
0392 return;
0393 }}
0394
0395 rtext->height = th;
0396 {float mn_x,mn_y,mn_z;
0397 float mx_x,mx_y,mx_z;
0398 rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0399 rtext->hjust = left;
0400 float yy = -(mn_y+mx_y)*0.5F;
0401 rtsf->set_translate(-width*0.5f+height,yy,zz);}
0402
0403 }
0404
0405 parent::update_sg();
0406
0407 }
0408 protected:
0409 separator m_sep;
0410 const base_freetype& m_ttf;
0411 };
0412
0413 }}
0414
0415 #endif