Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 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) 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_are 25 public: 26 mf_string strings; 27 28 sf_vec<colorf,float> color; //color of the " 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 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( 47 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::leg 48 static const desc_fields s_v(parent::node_ 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_mode 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 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 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 210 // This is so because legend::height is an 211 // needed in plotter to place the box. 212 213 m_back_sep.clear(); //back_area::update_sg 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 i 224 for(it=strings.values().begin();it!=string 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_tt 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::c 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 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 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 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 w 387 float max_width = (width-height)*wmargin 388 if(bxw>max_width) th = max_width*height/ 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 399 rtext->hjust = left; 400 float yy = -(mn_y+mx_y)*0.5F; 401 rtsf->set_translate(-width*0.5f+height,y 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