Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/sg/infos_box 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_infos_box
0005 #define tools_sg_infos_box
0006 
0007 //
0008 // In z the scene is within [0,0.5]
0009 //
0010 
0011 #include "back_area"
0012 #include "matrix"
0013 #include "text_hershey"
0014 #include "base_freetype"
0015 #include "enums"
0016 
0017 #include "../colorf"
0018 
0019 namespace tools {
0020 namespace sg {
0021 
0022 class infos_box : public back_area {
0023   TOOLS_NODE(infos_box,tools::sg::infos_box,back_area)
0024 public:
0025   mf_string lstrings;
0026   mf_string rstrings;
0027   sf<unsigned int> num_spaces; //in "number of one line height" unit.
0028 
0029   sf_vec<colorf,float> color;
0030   sf_string font;
0031   sf_enum<sg::font_modeling> font_modeling;
0032   sf_string encoding;
0033   sf<float> line_width; // for text_hershey.
0034   sf_enum<winding_type> front_face; //no more used.
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 public:
0043   virtual const desc_fields& node_desc_fields() const {
0044     TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::infos_box)
0045     static const desc_fields s_v(parent::node_desc_fields(),15, //WARNING : take care of count.
0046       TOOLS_ARG_FIELD_DESC(lstrings),
0047       TOOLS_ARG_FIELD_DESC(rstrings),
0048       TOOLS_ARG_FIELD_DESC(num_spaces),
0049       TOOLS_ARG_FIELD_DESC(color),
0050 
0051       TOOLS_ARG_FIELD_DESC_OPTS_BEG(font,10)
0052         font_hershey().c_str(),
0053         font_lato_regular_ttf().c_str(),
0054         font_roboto_bold_ttf().c_str(),
0055         font_arial_ttf().c_str(),
0056         font_arialbd_ttf().c_str(),
0057         font_timesbd_ttf().c_str(),
0058         font_symbol_ttf().c_str(),
0059         font_stixgeneral_otf().c_str(),
0060         font_helvetica_ttf().c_str(),
0061         font_times_roman_ttf().c_str()
0062       TOOLS_ARG_FIELD_DESC_OPTS_END,
0063 
0064       TOOLS_ARG_FIELD_DESC_ENUMS_BEG(font_modeling,3)
0065         TOOLS_ARG_ENUM(font_outline),
0066         TOOLS_ARG_ENUM(font_filled),
0067         TOOLS_ARG_ENUM(font_pixmap)
0068       TOOLS_ARG_FIELD_DESC_ENUMS_END,
0069 
0070       TOOLS_ARG_FIELD_DESC(encoding),
0071       TOOLS_ARG_FIELD_DESC(line_width),
0072       TOOLS_ARG_FIELD_DESC(front_face),
0073 
0074       TOOLS_ARG_FIELD_DESC(back_visible), //10
0075       TOOLS_ARG_FIELD_DESC(wmargin_factor),
0076       TOOLS_ARG_FIELD_DESC(hmargin_factor),
0077       TOOLS_ARG_FIELD_DESC(lhjust),
0078       TOOLS_ARG_FIELD_DESC(rhjust),
0079       TOOLS_ARG_FIELD_DESC(confine)
0080     );
0081     return s_v;
0082   }
0083 private:
0084   void add_fields(){
0085     add_field(&lstrings);
0086     add_field(&rstrings);
0087     add_field(&num_spaces);
0088 
0089     add_field(&color);
0090     add_field(&font);
0091     add_field(&font_modeling);
0092     add_field(&encoding);
0093     add_field(&line_width);
0094     add_field(&front_face);
0095 
0096     add_field(&back_visible);
0097     add_field(&wmargin_factor);
0098     add_field(&hmargin_factor);
0099     add_field(&lhjust);
0100     add_field(&rhjust);
0101     add_field(&confine);
0102   }
0103 public:
0104   virtual void render(render_action& a_action) {
0105     if(touched()) {
0106       update_sg();
0107       reset_touched();
0108     }
0109     if(back_visible.value()) m_back_sep.render(a_action);
0110     m_sep.render(a_action);
0111   }
0112   virtual void pick(pick_action& a_action) {
0113     if(touched()) {
0114       update_sg();
0115       reset_touched();
0116     }
0117     if(back_visible.value()) {
0118       m_back_sep.pick(a_action);
0119       if(a_action.done()) return;
0120     }
0121   }
0122   virtual void search(search_action& a_action) {
0123     if(touched()) {
0124       update_sg();
0125       reset_touched();
0126     }
0127     node::search(a_action);
0128     if(a_action.done()) return;
0129     if(back_visible.value()) {
0130       m_back_sep.search(a_action);
0131       if(a_action.done()) return;
0132     }
0133     m_sep.search(a_action);
0134     if(a_action.done()) return;
0135   }
0136   virtual bool write(write_action& a_action) {
0137     if(touched()) {
0138       update_sg();
0139       reset_touched();
0140     }
0141     if(back_visible.value()) if(!m_back_sep.write(a_action)) return false;
0142     return m_sep.write(a_action);
0143   }
0144   virtual void bbox(bbox_action& a_action) {
0145     if(touched()) {
0146       update_sg();
0147       reset_touched();
0148     }
0149     if(back_visible.value()) m_back_sep.bbox(a_action);
0150     m_sep.bbox(a_action);
0151   }
0152 public:
0153   infos_box(const base_freetype& a_ttf)
0154   :parent()
0155   ,lstrings()
0156   ,rstrings()
0157   ,num_spaces(4)
0158 
0159   ,color(colorf_black())
0160   ,font(font_hershey())
0161   ,font_modeling(font_filled)
0162   ,encoding(encoding_PAW())
0163   ,line_width(1)
0164   ,front_face(winding_ccw)
0165 
0166   ,back_visible(true)
0167   ,wmargin_factor(0.9f)
0168   ,hmargin_factor(0.9f)
0169   ,lhjust(left)
0170   ,rhjust(right)
0171 
0172   ,confine(false)
0173 
0174   ,m_ttf(a_ttf)
0175   {
0176     add_fields();
0177   }
0178   virtual ~infos_box(){}
0179 public:
0180   infos_box(const infos_box& a_from)
0181   :parent(a_from)
0182   ,lstrings(a_from.lstrings)
0183   ,rstrings(a_from.rstrings)
0184   ,num_spaces(a_from.num_spaces)
0185 
0186   ,color(a_from.color)
0187   ,font(a_from.font)
0188   ,font_modeling(a_from.font_modeling)
0189   ,encoding(a_from.encoding)
0190   ,line_width(a_from.line_width)
0191   ,front_face(a_from.front_face)
0192 
0193   ,back_visible(a_from.back_visible)
0194   ,wmargin_factor(a_from.wmargin_factor)
0195   ,hmargin_factor(a_from.hmargin_factor)
0196   ,lhjust(a_from.lhjust)
0197   ,rhjust(a_from.rhjust)
0198 
0199   ,confine(a_from.confine)
0200 
0201   ,m_ttf(a_from.m_ttf)
0202   {
0203     add_fields();
0204   }
0205   infos_box& operator=(const infos_box& a_from){
0206     parent::operator=(a_from);
0207     lstrings = a_from.lstrings;
0208     rstrings = a_from.rstrings;
0209     num_spaces = a_from.num_spaces;
0210 
0211     color = a_from.color;
0212     font = a_from.font;
0213     font_modeling = a_from.font_modeling;
0214     encoding = a_from.encoding;
0215     line_width = a_from.line_width;
0216     front_face = a_from.front_face;
0217 
0218     back_visible = a_from.back_visible;
0219     wmargin_factor = a_from.wmargin_factor;
0220     hmargin_factor = a_from.hmargin_factor;
0221     lhjust = a_from.lhjust;
0222     rhjust = a_from.rhjust;
0223 
0224     confine = a_from.confine;
0225 
0226     return *this;
0227   }
0228 public:
0229   void update_sg() {
0230     // have this method public in order to use it in plotter.
0231     // This is so because infos_box::height is an output field
0232     // needed in plotter to place the box.
0233 
0234     m_back_sep.clear(); //back_area::update_sg done last.
0235 
0236     m_sep.clear();
0237 
0238     if(width.value()<=0) return;
0239     if(confine) {
0240       if(height.value()<=0) return;
0241     }
0242 
0243    {bool empty = true;
0244     std::vector<std::string>::const_iterator it;
0245     for(it=lstrings.values().begin();it!=lstrings.values().end();++it) {
0246       if((*it).size()) {empty = false;break;}
0247     }
0248     if(empty){
0249       for(it=rstrings.values().begin();it!=rstrings.values().end();++it) {
0250         if((*it).size()) {empty = false;break;}
0251       }
0252     }
0253     if(empty) {
0254       return;
0255     }}
0256 
0257     rgba* mat = new rgba();
0258     mat->color = color;
0259     m_sep.add(mat);
0260 
0261     if(font==font_hershey()) {
0262       draw_style* ds = new draw_style;
0263       ds->style.value(draw_lines);
0264       ds->line_width = line_width;
0265       m_sep.add(ds);
0266     }
0267 
0268     ////////////////////////////////////////////////////////////
0269     /// left text //////////////////////////////////////////////
0270     ////////////////////////////////////////////////////////////
0271     base_text* ltext = 0;
0272     matrix* ltsf = 0;
0273 
0274    {separator* sep = new separator;
0275     m_sep.add(sep);
0276     ltsf = new matrix;
0277     sep->add(ltsf);
0278     if(font==font_hershey()) {
0279       text_hershey* text = new text_hershey;
0280       ltext = text;
0281       text->encoding = encoding;
0282       sep->add(text);
0283     } else {
0284       base_freetype* text = base_freetype::create(m_ttf);
0285       ltext = text;
0286       text->font = font;
0287       text->modeling = font_modeling;
0288       sep->add(text);
0289     }
0290     ltext->strings = lstrings;
0291     ltext->hjust = lhjust;}
0292 
0293     ////////////////////////////////////////////////////////////
0294     /// right text /////////////////////////////////////////////
0295     ////////////////////////////////////////////////////////////
0296     base_text* rtext = 0;
0297     matrix* rtsf = 0;
0298 
0299    {separator* sep = new separator;
0300     m_sep.add(sep);
0301     rtsf = new matrix;
0302     sep->add(rtsf);
0303     if(font==font_hershey()) {
0304       text_hershey* text = new text_hershey;
0305       rtext = text;
0306       text->encoding = encoding;
0307       sep->add(text);
0308     } else {
0309       base_freetype* text = base_freetype::create(m_ttf);
0310       rtext = text;
0311       text->font = font;
0312       text->modeling = font_modeling;
0313       sep->add(text);
0314     }
0315     rtext->strings = rstrings;
0316     rtext->hjust = rhjust;}
0317 
0318     ////////////////////////////////////////////////////////////
0319     /// middle spaces //////////////////////////////////////////
0320     ////////////////////////////////////////////////////////////
0321     base_text* mtext = 0;
0322    {std::string _s(num_spaces,' ');
0323     if(font==font_hershey()) {
0324       text_hershey* text = new text_hershey;
0325       mtext = text;
0326       text->strings.add(_s);
0327       text->hjust = left;
0328     } else {
0329       base_freetype* text = base_freetype::create(m_ttf);
0330       mtext = text;
0331       text->strings.add(_s);
0332       text->hjust = left;
0333       text->font = font;
0334       text->modeling = font_modeling;
0335     }}
0336 
0337     float zz = back_visible.value()?0.01f:0;
0338 
0339     float fw = width * wmargin_factor;
0340 
0341     if(confine) {
0342       // left right texts may overlap.
0343 
0344       // adjust height :
0345       float fh = height * hmargin_factor;
0346       float th = fh;
0347      {float mn_x,mn_y,mn_z;
0348       float mx_x,mx_y,mx_z;
0349       ltext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0350       float bxh = mx_y-mn_y;
0351       // adjust box height :
0352       // fh -> bxh then to have fh :
0353       if(!bxh) {
0354         m_sep.clear();
0355         parent::update_sg();
0356         delete mtext;
0357         return;
0358       }
0359       th = fh*fh/bxh;}
0360 
0361       ltext->height = th;
0362       rtext->height = th;
0363 
0364      {float mn_x,mn_y,mn_z;
0365       float mx_x,mx_y,mx_z;
0366       ltext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0367       float lw = mx_x-mn_x;
0368       float xtrans = (fw-lw)*0.5f; //left justified
0369       float xx = -(mn_x+mx_x)*0.5F-xtrans;
0370       float yy = -(mn_y+mx_y)*0.5F;
0371       ltsf->set_translate(xx,yy,zz);}
0372 
0373      {float mn_x,mn_y,mn_z;
0374       float mx_x,mx_y,mx_z;
0375       rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0376       rtext->hjust = right;
0377       float xx = fw*0.5f;
0378       float yy = -(mn_y+mx_y)*0.5F;
0379       rtsf->set_translate(xx,yy,zz);}
0380 
0381       parent::update_sg();
0382 
0383     } else {
0384       // height of the info box is an output of the below.
0385       // The input to compute the geometry is the width of the infos
0386       // box, the left/right texts and the space between
0387       // left/right texts.
0388 
0389       // from a text height of th=1, and a left/right sep
0390       // of num_spaces*th, get width of the box :
0391 
0392       float th = 1;
0393 
0394       float lmn_x,lmn_y,lmn_z;
0395       float lmx_x,lmx_y,lmx_z;
0396       ltext->get_bounds(th,lmn_x,lmn_y,lmn_z,lmx_x,lmx_y,lmx_z);
0397       float lw = (lmx_x<lmn_x)?0:lmx_x-lmn_x;
0398 
0399       float rmn_x,rmn_y,rmn_z;
0400       float rmx_x,rmx_y,rmx_z;
0401       rtext->get_bounds(th,rmn_x,rmn_y,rmn_z,rmx_x,rmx_y,rmx_z);
0402       float rw = (rmx_x<rmn_x)?0:rmx_x-rmn_x;
0403 
0404       float mmn_x,mmn_y,mmn_z;
0405       float mmx_x,mmx_y,mmx_z;
0406       mtext->get_bounds(th,mmn_x,mmn_y,mmn_z,mmx_x,mmx_y,mmx_z);
0407       float mw = (mmx_x<mmn_x)?0:mmx_x-mmn_x;
0408 
0409       float winfos = lw+mw+rw;
0410       if(!winfos) {
0411         m_sep.clear();
0412         height = 1;
0413         parent::update_sg();
0414         delete mtext;
0415         return;
0416       }
0417 
0418       // assuming that text size is linear relative
0419       // to th, we get the th needed to match infos_box.width :
0420       // th -> winfos then to have fw :
0421       th = fw*th/winfos;
0422 
0423       // place the left/right texts by rescaling them to
0424       // the new th :
0425       ltext->height = th;
0426       ltext->get_bounds(th,lmn_x,lmn_y,lmn_z,lmx_x,lmx_y,lmx_z);
0427       float hinfos = (lmx_x<lmn_x)?0:lmx_y-lmn_y;
0428 
0429       float xx = -fw*0.5F; //left justified.
0430       float ty = -ltext->ascent(th)+hinfos*0.5f;
0431       ltsf->set_translate(xx,ty,zz);
0432 
0433       rtext->height = th;
0434       if(rtext->hjust==right) {
0435         xx = fw*0.5F;
0436       } else if(rtext->hjust==left) {
0437         rtext->get_bounds(th,rmn_x,rmn_y,rmn_z,rmx_x,rmx_y,rmx_z);
0438         rw = (rmx_x<rmn_x)?0:rmx_x-rmn_x;
0439         xx = fw*0.5F-rw;
0440       } else { //center
0441         rtext->get_bounds(th,rmn_x,rmn_y,rmn_z,rmx_x,rmx_y,rmx_z);
0442         rw = (rmx_x<rmn_x)?0:rmx_x-rmn_x;
0443         xx = fw*0.5F-rw*0.5F;
0444       }
0445       rtsf->set_translate(xx,ty,zz);
0446 
0447       // set infos_box.height :
0448       height = hinfos/hmargin_factor;
0449 
0450       //done last because of the upper height setup.
0451       parent::update_sg();
0452 
0453     }
0454 
0455     delete mtext;
0456 
0457   }
0458 protected:
0459   const base_freetype& m_ttf;
0460 
0461   separator m_sep;
0462 };
0463 
0464 }}
0465 
0466 #endif