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       //parent::update_sg();
0255       return;
0256     }}
0257 
0258     rgba* mat = new rgba();
0259     mat->color = color;
0260     m_sep.add(mat);
0261 
0262     if(font==font_hershey()) {
0263       draw_style* ds = new draw_style;
0264       ds->style.value(draw_lines);
0265       //ds->line_pattern = line_pattern;
0266       ds->line_width = line_width;
0267       m_sep.add(ds);
0268     }
0269 
0270     ////////////////////////////////////////////////////////////
0271     /// left text //////////////////////////////////////////////
0272     ////////////////////////////////////////////////////////////
0273     base_text* ltext = 0;
0274     matrix* ltsf = 0;
0275 
0276    {separator* sep = new separator;
0277     m_sep.add(sep);
0278     ltsf = new matrix;
0279     sep->add(ltsf);
0280     if(font==font_hershey()) {
0281       text_hershey* text = new text_hershey;
0282       ltext = text;
0283       text->encoding = encoding;
0284       sep->add(text);
0285     } else {
0286       base_freetype* text = base_freetype::create(m_ttf);
0287       //TTNODE* text = new TTNODE;
0288       ltext = text;
0289       text->font = font;
0290       text->modeling = font_modeling;
0291       sep->add(text);
0292     }
0293     ltext->strings = lstrings;
0294     ltext->hjust = lhjust;}
0295 
0296     ////////////////////////////////////////////////////////////
0297     /// right text /////////////////////////////////////////////
0298     ////////////////////////////////////////////////////////////
0299     base_text* rtext = 0;
0300     matrix* rtsf = 0;
0301 
0302    {separator* sep = new separator;
0303     m_sep.add(sep);
0304     rtsf = new matrix;
0305     sep->add(rtsf);
0306     if(font==font_hershey()) {
0307       text_hershey* text = new text_hershey;
0308       rtext = text;
0309       text->encoding = encoding;
0310       sep->add(text);
0311     } else {
0312       base_freetype* text = base_freetype::create(m_ttf);
0313       //TTNODE* text = new TTNODE;
0314       rtext = text;
0315       text->font = font;
0316       text->modeling = font_modeling;
0317       sep->add(text);
0318     }
0319     rtext->strings = rstrings;
0320     rtext->hjust = rhjust;}
0321 
0322     ////////////////////////////////////////////////////////////
0323     /// middle spaces //////////////////////////////////////////
0324     ////////////////////////////////////////////////////////////
0325     base_text* mtext = 0;
0326    {std::string _s(num_spaces,' ');
0327     if(font==font_hershey()) {
0328       text_hershey* text = new text_hershey;
0329       mtext = text;
0330       text->strings.add(_s);
0331       text->hjust = left;
0332     } else {
0333       base_freetype* text = base_freetype::create(m_ttf);
0334       //TTNODE* text = new TTNODE;
0335       mtext = text;
0336       text->strings.add(_s);
0337       text->hjust = left;
0338       text->font = font;
0339       text->modeling = font_modeling;
0340     }}
0341 
0342     //sf<float> zfront ?
0343     float zz = back_visible.value()?0.01f:0;
0344 
0345     float fw = width * wmargin_factor;
0346 
0347     if(confine) {
0348       // left right texts may overlap.
0349 
0350       // adjust height :
0351       float fh = height * hmargin_factor;
0352       float th = fh;
0353      {float mn_x,mn_y,mn_z;
0354       float mx_x,mx_y,mx_z;
0355       ltext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0356       float bxh = mx_y-mn_y;
0357       // adjust box height :
0358       // fh -> bxh then to have fh :
0359       if(!bxh) {
0360         m_sep.clear();
0361         parent::update_sg();
0362         delete mtext;
0363         return;
0364       }
0365       th = fh*fh/bxh;}
0366 
0367       ltext->height = th;
0368       rtext->height = th;
0369 
0370      {float mn_x,mn_y,mn_z;
0371       float mx_x,mx_y,mx_z;
0372       ltext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0373       float lw = mx_x-mn_x;
0374       float xtrans = (fw-lw)*0.5f; //left justified
0375       float xx = -(mn_x+mx_x)*0.5F-xtrans;
0376       float yy = -(mn_y+mx_y)*0.5F;
0377       ltsf->set_translate(xx,yy,zz);}
0378 
0379      {float mn_x,mn_y,mn_z;
0380       float mx_x,mx_y,mx_z;
0381       rtext->get_bounds(th,mn_x,mn_y,mn_z,mx_x,mx_y,mx_z);
0382       rtext->hjust = right;
0383       float xx = fw*0.5f;
0384       float yy = -(mn_y+mx_y)*0.5F;
0385       rtsf->set_translate(xx,yy,zz);}
0386 
0387       parent::update_sg();
0388 
0389     } else {
0390       // height of the info box is an output of the below.
0391       // The input to compute the geometry is the width of the infos
0392       // box, the left/right texts and the space between
0393       // left/right texts.
0394 
0395       // from a text height of th=1, and a left/right sep
0396       // of num_spaces*th, get width of the box :
0397 
0398       float th = 1;
0399 
0400       float lmn_x,lmn_y,lmn_z;
0401       float lmx_x,lmx_y,lmx_z;
0402       ltext->get_bounds(th,lmn_x,lmn_y,lmn_z,lmx_x,lmx_y,lmx_z);
0403       float lw = (lmx_x<lmn_x)?0:lmx_x-lmn_x;
0404 
0405       float rmn_x,rmn_y,rmn_z;
0406       float rmx_x,rmx_y,rmx_z;
0407       rtext->get_bounds(th,rmn_x,rmn_y,rmn_z,rmx_x,rmx_y,rmx_z);
0408       float rw = (rmx_x<rmn_x)?0:rmx_x-rmn_x;
0409 
0410       float mmn_x,mmn_y,mmn_z;
0411       float mmx_x,mmx_y,mmx_z;
0412       mtext->get_bounds(th,mmn_x,mmn_y,mmn_z,mmx_x,mmx_y,mmx_z);
0413       float mw = (mmx_x<mmn_x)?0:mmx_x-mmn_x;
0414 
0415       float winfos = lw+mw+rw;
0416       if(!winfos) {
0417         m_sep.clear();
0418         height = 1;
0419         parent::update_sg();
0420         delete mtext;
0421         return;
0422       }
0423 
0424       // assuming that text size is linear relative
0425       // to th, we get the th needed to match infos_box.width :
0426       // th -> winfos then to have fw :
0427       th = fw*th/winfos;
0428 
0429       // place the left/right texts by rescaling them to
0430       // the new th :
0431       ltext->height = th;
0432       ltext->get_bounds(th,lmn_x,lmn_y,lmn_z,lmx_x,lmx_y,lmx_z);
0433       float hinfos = (lmx_x<lmn_x)?0:lmx_y-lmn_y;
0434 
0435       float xx = -fw*0.5F; //left justified.
0436       float ty = -ltext->ascent(th)+hinfos*0.5f;
0437       ltsf->set_translate(xx,ty,zz);
0438 
0439       rtext->height = th;
0440       if(rtext->hjust==right) {
0441         xx = fw*0.5F;
0442       } else if(rtext->hjust==left) {
0443         rtext->get_bounds(th,rmn_x,rmn_y,rmn_z,rmx_x,rmx_y,rmx_z);
0444         rw = (rmx_x<rmn_x)?0:rmx_x-rmn_x;
0445         xx = fw*0.5F-rw;
0446       } else { //center
0447         rtext->get_bounds(th,rmn_x,rmn_y,rmn_z,rmx_x,rmx_y,rmx_z);
0448         rw = (rmx_x<rmn_x)?0:rmx_x-rmn_x;
0449         xx = fw*0.5F-rw*0.5F;
0450       }
0451       rtsf->set_translate(xx,ty,zz);
0452 
0453       // set infos_box.height :
0454       height = hinfos/hmargin_factor;
0455 
0456       //done last because of the upper height setup.
0457       parent::update_sg();
0458 
0459     }
0460 
0461     delete mtext;
0462 
0463   }
0464 protected:
0465   const base_freetype& m_ttf;
0466 
0467   separator m_sep;
0468 };
0469 
0470 }}
0471 
0472 #endif