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 "text_valop"
0018
0019 namespace tools {
0020 namespace sg {
0021
0022 class legend : public back_area {
0023 TOOLS_NODE(legend,tools::sg::legend,back_area)
0024 public:
0025 mf_string strings;
0026
0027 sf_vec<colorf,float> color; //color of the "rep"
0028 // text atbs :
0029 sf_string font;
0030 sf_enum<sg::font_modeling> font_modeling;
0031 sf_string encoding;
0032
0033 sf<bool> back_visible;
0034 sf<float> wmargin_factor;
0035 sf<float> hmargin_factor;
0036 sf_enum<hjust> lhjust;
0037 sf_enum<hjust> rhjust;
0038
0039 sf_enum<sg::marker_style> marker_style;
0040 sf<float> marker_size;
0041 public:
0042 virtual const desc_fields& node_desc_fields() const {
0043 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::legend)
0044 static const desc_fields s_v(parent::node_desc_fields(),12, //WARNING : take care of count.
0045 TOOLS_ARG_FIELD_DESC(strings),
0046 TOOLS_ARG_FIELD_DESC(color),
0047 TOOLS_ARG_FIELD_DESC(font),
0048
0049 TOOLS_ARG_FIELD_DESC_ENUMS_BEG(font_modeling,3)
0050 TOOLS_ARG_ENUM(font_outline),
0051 TOOLS_ARG_ENUM(font_filled),
0052 TOOLS_ARG_ENUM(font_pixmap)
0053 TOOLS_ARG_FIELD_DESC_ENUMS_END,
0054
0055 TOOLS_ARG_FIELD_DESC(encoding),
0056 TOOLS_ARG_FIELD_DESC(back_visible),
0057 TOOLS_ARG_FIELD_DESC(wmargin_factor),
0058 TOOLS_ARG_FIELD_DESC(hmargin_factor),
0059 TOOLS_ARG_FIELD_DESC(lhjust),
0060 TOOLS_ARG_FIELD_DESC(rhjust),
0061 TOOLS_ARG_FIELD_DESC(marker_style),
0062 TOOLS_ARG_FIELD_DESC(marker_size)
0063 );
0064 return s_v;
0065 }
0066 private:
0067 void add_fields(){
0068 add_field(&strings);
0069
0070 add_field(&color);
0071 add_field(&font);
0072 add_field(&font_modeling);
0073 add_field(&encoding);
0074
0075 add_field(&back_visible);
0076 add_field(&wmargin_factor);
0077 add_field(&hmargin_factor);
0078 add_field(&lhjust);
0079 add_field(&rhjust);
0080 add_field(&marker_style);
0081 add_field(&marker_size);
0082 }
0083 public:
0084 virtual void render(render_action& a_action) {
0085 if(touched()) {
0086 update_sg();
0087 reset_touched();
0088 }
0089 if(back_visible.value()) m_back_sep.render(a_action);
0090 m_sep.render(a_action);
0091 }
0092 virtual void pick(pick_action& a_action) {
0093 if(touched()) {
0094 update_sg();
0095 reset_touched();
0096 }
0097 if(back_visible.value()) {
0098 m_back_sep.pick(a_action);
0099 if(a_action.done()) return;
0100 }
0101 }
0102 virtual void search(search_action& a_action) {
0103 if(touched()) {
0104 update_sg();
0105 reset_touched();
0106 }
0107 node::search(a_action);
0108 if(a_action.done()) return;
0109 if(back_visible.value()) {
0110 m_back_sep.search(a_action);
0111 if(a_action.done()) return;
0112 }
0113 m_sep.search(a_action);
0114 if(a_action.done()) return;
0115 }
0116 virtual void bbox(bbox_action& a_action) {
0117 if(touched()) {
0118 update_sg();
0119 reset_touched();
0120 }
0121 if(back_visible.value()) m_back_sep.bbox(a_action);
0122 m_sep.bbox(a_action);
0123 }
0124 public:
0125 legend(const base_freetype& a_ttf)
0126 :parent()
0127 ,strings()
0128 ,color(colorf_black())
0129 ,font(font_hershey())
0130 ,font_modeling(font_filled)
0131 ,encoding(encoding_PAW())
0132 ,back_visible(true)
0133 ,wmargin_factor(0.9f)
0134 ,hmargin_factor(0.9f)
0135 ,lhjust(left)
0136 ,rhjust(right)
0137 ,marker_style(marker_dot)
0138 ,marker_size(10)
0139 ,m_ttf(a_ttf)
0140 {
0141 add_fields();
0142 }
0143 virtual ~legend(){}
0144 public:
0145 legend(const legend& a_from)
0146 :parent(a_from)
0147 ,strings(a_from.strings)
0148 ,color(a_from.color)
0149 ,font(a_from.font)
0150 ,font_modeling(a_from.font_modeling)
0151 ,encoding(a_from.encoding)
0152 ,back_visible(a_from.back_visible)
0153 ,wmargin_factor(a_from.wmargin_factor)
0154 ,hmargin_factor(a_from.hmargin_factor)
0155 ,lhjust(a_from.lhjust)
0156 ,rhjust(a_from.rhjust)
0157 ,marker_style(a_from.marker_style)
0158 ,marker_size(a_from.marker_size)
0159 ,m_ttf(a_from.m_ttf)
0160 {
0161 add_fields();
0162 }
0163 legend& operator=(const legend& a_from){
0164 parent::operator=(a_from);
0165 strings = a_from.strings;
0166
0167 color = a_from.color;
0168 font = a_from.font;
0169 font_modeling = a_from.font_modeling;
0170 encoding = a_from.encoding;
0171
0172 back_visible = a_from.back_visible;
0173 wmargin_factor = a_from.wmargin_factor;
0174 hmargin_factor = a_from.hmargin_factor;
0175 lhjust = a_from.lhjust;
0176 rhjust = a_from.rhjust;
0177
0178 marker_style = a_from.marker_style;
0179 marker_size = a_from.marker_size;
0180
0181 return *this;
0182 }
0183 public:
0184 void update_sg() {
0185 // have this method public in order to use it in plotter.
0186 // This is so because legend::height is an output field
0187 // needed in plotter to place the box.
0188
0189 m_back_sep.clear(); //back_area::update_sg done last.
0190
0191 m_sep.clear();
0192
0193 if(width.value()<=0) return;
0194
0195 {bool empty = true;
0196 std::vector<std::string>::const_iterator it;
0197 for(it=strings.values().begin();it!=strings.values().end();++it) {
0198 if((*it).size()) {empty = false;break;}
0199 }
0200 if(empty) return;}
0201
0202 //sf<float> zfront ?
0203 float zz = back_visible.value()?0.01f:0;
0204
0205 {separator* _sep = new separator;
0206 m_sep.add(_sep);
0207
0208 rgba* mat = new rgba();
0209 mat->color = color;
0210 _sep->add(mat);
0211
0212 { // rep marker :
0213 if(marker_style.value()==marker_dot) {
0214 draw_style* ds = new draw_style;
0215 ds->style = draw_points;
0216 ds->point_size = marker_size;
0217 _sep->add(ds);
0218 vertices* vtxs = new vertices;
0219 vtxs->mode = gl::points();
0220 vtxs->add(-width*0.5f+height*0.5f,0,zz);
0221 _sep->add(vtxs);
0222 } else {
0223 markers* vtxs = new markers;
0224 vtxs->size = marker_size;
0225 vtxs->style = marker_style;
0226 vtxs->add(-width*0.5f+height*0.5f,0,zz);
0227 _sep->add(vtxs);
0228 }
0229 }
0230
0231 }
0232
0233 ////////////////////////////////////////////////////////////
0234 /// right text /////////////////////////////////////////////
0235 ////////////////////////////////////////////////////////////
0236 base_text* rtext = 0;
0237 matrix* rtsf = 0;
0238
0239 {separator* _sep = new separator;
0240 m_sep.add(_sep);
0241
0242 rgba* mat = new rgba();
0243 mat->color = colorf_black();
0244 _sep->add(mat);
0245
0246 if(font==font_hershey()) {
0247 draw_style* ds = new draw_style;
0248 ds->style.value(draw_lines);
0249 _sep->add(ds);
0250 }
0251
0252 rtsf = new matrix;
0253 _sep->add(rtsf);
0254 if(font==font_hershey()) {
0255 text_hershey* text = new text_hershey;
0256 text->encoding = encoding;
0257 text->strings = strings;
0258 _sep->add(text);
0259 rtext = text;
0260 } else {
0261 if(encoding==encoding_PAW()) {
0262 text_valop* text = new text_valop(m_ttf);
0263 text->font = font;
0264 text->font_modeling = font_modeling;
0265 text->strings = strings;
0266 _sep->add(text);
0267 rtext = text;
0268 } else {
0269 base_freetype* text = base_freetype::create(m_ttf);
0270 text->font = font;
0271 text->modeling = font_modeling;
0272 text->strings = strings;
0273 _sep->add(text);
0274 rtext = text;
0275 }
0276 }
0277 rtext->hjust = rhjust;}
0278 { //rep mark :
0279
0280 // adjust width :
0281 float th = height;
0282 {float mn_x,mn_y,mn_z;
0283 float mx_x,mx_y,mx_z;
0284 rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0285 float bxw = mx_x-mn_x;
0286 if(!bxw) {
0287 m_sep.clear();
0288 parent::update_sg();
0289 return;
0290 }
0291 // adjust box width :
0292 // height -> bxw then to have a wanted width :
0293 float max_width = (width-height)*wmargin_factor;
0294 if(bxw>max_width) th = max_width*height/bxw;
0295 if(th<0) {
0296 m_sep.clear();
0297 parent::update_sg();
0298 return;
0299 }}
0300
0301 rtext->height = th;
0302 {float mn_x,mn_y,mn_z;
0303 float mx_x,mx_y,mx_z;
0304 rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0305 rtext->hjust = left;
0306 float yy = -(mn_y+mx_y)*0.5F;
0307 rtsf->set_translate(-width*0.5f+height,yy,zz);}
0308
0309 }
0310
0311 parent::update_sg();
0312
0313 }
0314 protected:
0315 separator m_sep;
0316 const base_freetype& m_ttf;
0317 };
0318
0319 }}
0320
0321 #endif