Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef tools_sg_back_area 5 #define tools_sg_back_area 6 7 #include "node" 8 #include "atb_vertices" 9 #include "rgba" 10 #include "draw_style" 11 #include "../mathf" 12 13 #include "separator" 14 #include "normal" 15 16 namespace tools { 17 namespace sg { 18 19 class back_area : public node { 20 TOOLS_NODE(back_area,tools::sg::back_area,node) 21 public: 22 static unsigned int corner_top_right() {return 1<<0;} 23 static unsigned int corner_top_left() {return 1<<1;} 24 static unsigned int corner_bottom_right() {return 1<<2;} 25 static unsigned int corner_bottom_left() {return 1<<3;} 26 static unsigned int corner_all() { 27 return corner_top_right()|corner_top_left()|corner_bottom_right()|corner_bottom_left(); 28 } 29 public: 30 sf<float> width; 31 sf<float> height; 32 33 sf_vec<colorf,float> color; 34 35 sf<bool> gradient; 36 sf_vec<colorf,float> color_top; 37 38 sf<bool> border_visible; 39 sf_vec<colorf,float> border_color; 40 sf<float> border_line_width; 41 42 sf<float> shadow; //in percent of width. 43 44 sf<float> corner_radius; //percent of height. 45 sf<unsigned int> corner_steps; 46 sf<unsigned int> corner_mask; 47 public: 48 virtual const desc_fields& node_desc_fields() const { 49 TOOLS_FIELD_DESC_NODE_CLASS(tools::sg::back_area) 50 static const desc_fields s_v(parent::node_desc_fields(),12, //WARNING : take care of count. 51 TOOLS_ARG_FIELD_DESC(width), 52 TOOLS_ARG_FIELD_DESC(height), 53 TOOLS_ARG_FIELD_DESC(color), 54 TOOLS_ARG_FIELD_DESC(gradient), 55 TOOLS_ARG_FIELD_DESC(color_top), 56 TOOLS_ARG_FIELD_DESC(border_visible), 57 TOOLS_ARG_FIELD_DESC(border_color), 58 TOOLS_ARG_FIELD_DESC(border_line_width), 59 TOOLS_ARG_FIELD_DESC(shadow), 60 TOOLS_ARG_FIELD_DESC(corner_radius), 61 TOOLS_ARG_FIELD_DESC(corner_steps), 62 TOOLS_ARG_FIELD_DESC(corner_mask) 63 ); 64 return s_v; 65 } 66 private: 67 void add_fields(){ 68 add_field(&width); 69 add_field(&height); 70 71 add_field(&color); 72 add_field(&gradient); 73 add_field(&color_top); 74 add_field(&border_visible); 75 add_field(&border_color); 76 add_field(&border_line_width); 77 78 add_field(&shadow); 79 80 add_field(&corner_radius); 81 add_field(&corner_steps); 82 add_field(&corner_mask); 83 } 84 public: 85 virtual void render(render_action& a_action) { 86 if(touched()) { 87 update_sg(); 88 reset_touched(); 89 } 90 m_back_sep.render(a_action); 91 } 92 virtual void search(search_action& a_action) { 93 if(touched()) { 94 update_sg(); 95 reset_touched(); 96 } 97 parent::search(a_action); 98 if(a_action.done()) return; 99 m_back_sep.search(a_action); 100 if(a_action.done()) return; 101 } 102 virtual void pick(pick_action& a_action) { 103 if(touched()) { 104 update_sg(); 105 reset_touched(); 106 } 107 m_back_sep.pick(a_action); 108 } 109 public: 110 back_area() 111 :parent() 112 ,width(1) 113 ,height(1) 114 ,color(colorf_white()) 115 ,gradient(false) 116 ,color_top(colorf_white()) 117 ,border_visible(true) 118 ,border_color(colorf_black()) 119 ,border_line_width(1) 120 ,shadow(0) 121 ,corner_radius(0) //in percent of the height. 122 ,corner_steps(12) 123 ,corner_mask(corner_all()) 124 { 125 add_fields(); 126 } 127 virtual ~back_area(){} 128 public: 129 back_area(const back_area& a_from) 130 :parent(a_from) 131 ,width(a_from.width) 132 ,height(a_from.height) 133 ,color(a_from.color) 134 ,gradient(a_from.gradient) 135 ,color_top(a_from.color_top) 136 ,border_visible(a_from.border_visible) 137 ,border_color(a_from.border_color) 138 ,border_line_width(a_from.border_line_width) 139 ,shadow(a_from.shadow) 140 ,corner_radius(a_from.corner_radius) 141 ,corner_steps(a_from.corner_steps) 142 ,corner_mask(a_from.corner_mask) 143 { 144 add_fields(); 145 } 146 back_area& operator=(const back_area& a_from){ 147 parent::operator=(a_from); 148 width = a_from.width; 149 height = a_from.height; 150 color = a_from.color; 151 gradient = a_from.gradient; 152 color_top = a_from.color_top; 153 border_visible = a_from.border_visible; 154 border_color = a_from.border_color; 155 border_line_width = a_from.border_line_width; 156 shadow = a_from.shadow; 157 corner_radius = a_from.corner_radius; 158 corner_steps = a_from.corner_steps; 159 corner_mask = a_from.corner_mask; 160 return *this; 161 } 162 protected: 163 void update_sg() { 164 m_back_sep.clear(); 165 166 if(width.value()<=0) return; 167 if(height.value()<=0) return; 168 169 float xb = -width*0.5f; 170 float xe = width*0.5f; 171 float yb = -height*0.5f; 172 173 //float zshadow = -0.05f; 174 float zshadow = -0.005f; //ok with gopaw and ROOT_default. 175 float zback = 0; 176 float zborder = 0.01f; 177 178 if(shadow.value()) { 179 float zz = zback+zshadow; 180 float ye = height*0.5f; 181 182 sg::rgba* mat = new sg::rgba(); 183 mat->color = colorf_black(); 184 m_back_sep.add(mat); 185 186 normal* nm = new normal; 187 //nm->vec.value(); //default is z. ok. 188 m_back_sep.add(nm); 189 190 vertices* vtxs = new vertices; 191 vtxs->mode = gl::triangle_fan(); 192 m_back_sep.add(vtxs); 193 194 float dx = width*shadow; 195 float dy = -dx; 196 vtxs->add(xb+dx,yb+dy,zz); 197 vtxs->add(xe+dx,yb+dy,zz); 198 vtxs->add(xe+dx,ye+dy,zz); 199 vtxs->add(xb+dx,ye+dy,zz); 200 } 201 202 {//background : 203 normal* nm = new normal; 204 //nm->vec.value(); //default is z. ok. 205 m_back_sep.add(nm); 206 207 if(gradient.value()) { 208 // if(true) { 209 //color gradient from (bottom,color) to (top,color_top) 210 211 atb_vertices* vtxs = new atb_vertices; 212 vtxs->mode = gl::triangle_strip(); 213 m_back_sep.add(vtxs); 214 215 float zz = zback; 216 217 unsigned int ncol = 50; 218 float dy = height/ncol; 219 float ye = yb+dy; 220 221 colorf col_beg = color.value(); 222 colorf col_end = color_top.value(); 223 224 float dr = (col_end.r()-col_beg.r())/ncol; 225 float dg = (col_end.g()-col_beg.g())/ncol; 226 float db = (col_end.b()-col_beg.b())/ncol; 227 float da = (col_end.a()-col_beg.a())/ncol; 228 vec4f dcol(dr,dg,db,da); 229 230 colorf col = col_beg; 231 232 vtxs->add(xb,yb,zz); 233 vtxs->add_color(col); 234 235 vtxs->add(xe,yb,zz); 236 vtxs->add_color(col); 237 238 for(unsigned int index=0;index<ncol;index++) { 239 vtxs->add(xb,ye,zz); 240 vtxs->add(xe,ye,zz); 241 242 vtxs->add_color(col); 243 vtxs->add_color(col); 244 245 ye += dy; 246 col += dcol; 247 } 248 249 } else { 250 251 float zz = zback; 252 float ye = height*0.5f; 253 254 sg::rgba* mat = new sg::rgba(); 255 mat->color = color; 256 m_back_sep.add(mat); 257 258 vertices* vtxs = new vertices; 259 vtxs->mode = gl::triangle_fan(); 260 m_back_sep.add(vtxs); 261 262 float r = height*corner_radius; 263 if((r>(0.5f*height.value()))||(r>(0.5f*width.value()))) r = 0; 264 265 if((r>0) && corner_steps.value()) { 266 float dangle = fhalf_pi()/float(corner_steps); 267 unsigned int nslice = corner_steps; 268 269 vtxs->add(0,0,zz); 270 vtxs->add(xe,yb+r,zz); 271 vtxs->add(xe,ye-r,zz); 272 273 // top-right : 274 float angle = dangle; 275 if(corner_mask.value() & corner_top_right()) { 276 float xc = xe-r; 277 float yc = ye-r; 278 for(unsigned int i=0;i<nslice;i++,angle+=dangle) { 279 vtxs->add(r*fcos(angle)+xc,r*fsin(angle)+yc,zz); 280 } 281 } else { 282 angle += fhalf_pi(); 283 vtxs->add(xe,ye,zz); 284 vtxs->add(xe-r,ye,zz); 285 } 286 287 vtxs->add(xb+r,ye,zz); 288 289 // top-left : 290 if(corner_mask.value() & corner_top_left()) { 291 float xc = xb+r; 292 float yc = ye-r; 293 for(unsigned int i=0;i<nslice;i++,angle+=dangle) { 294 vtxs->add(r*fcos(angle)+xc,r*fsin(angle)+yc,zz); 295 } 296 } else { 297 angle += fhalf_pi(); 298 vtxs->add(xb,ye,zz); 299 vtxs->add(xb,ye-r,zz); 300 } 301 302 vtxs->add(xb,yb+r,zz); 303 304 // bottom-left : 305 if(corner_mask.value() & corner_bottom_left()) { 306 float xc = xb+r; 307 float yc = yb+r; 308 for(unsigned int i=0;i<nslice;i++,angle+=dangle) { 309 vtxs->add(r*fcos(angle)+xc,r*fsin(angle)+yc,zz); 310 } 311 } else { 312 angle += fhalf_pi(); 313 vtxs->add(xb,yb,zz); 314 vtxs->add(xb+r,yb,zz); 315 } 316 317 vtxs->add(xe-r,yb,zz); 318 319 // bottom-right : 320 if(corner_mask.value() & corner_bottom_right()) { 321 float xc = xe-r; 322 float yc = yb+r; 323 for(unsigned int i=0;i<nslice;i++,angle+=dangle) { 324 vtxs->add(r*fcos(angle)+xc,r*fsin(angle)+yc,zz); 325 } 326 } else { 327 angle += fhalf_pi(); 328 vtxs->add(xe,yb,zz); 329 vtxs->add(xe,yb+r,zz); 330 } 331 332 } else { 333 vtxs->add(xb,yb,zz); 334 vtxs->add(xe,yb,zz); 335 vtxs->add(xe,ye,zz); 336 vtxs->add(xb,ye,zz); 337 } 338 339 }} 340 341 if(border_visible.value()){ 342 float zz = zborder; 343 float ye = height*0.5f; 344 345 sg::rgba* mat = new sg::rgba(); 346 mat->color = border_color; 347 m_back_sep.add(mat); 348 349 draw_style* ds = new draw_style; 350 ds->style = draw_lines; 351 ds->line_width = border_line_width; 352 m_back_sep.add(ds); 353 354 vertices* vtxs = new vertices; 355 vtxs->mode = gl::line_strip(); 356 m_back_sep.add(vtxs); 357 358 float r = height*corner_radius; 359 if((r>(0.5f*height.value()))||(r>(0.5f*width.value()))) r = 0; 360 361 if((r>0) && corner_steps.value()) { 362 float dangle = fhalf_pi()/float(corner_steps); 363 unsigned int nslice = corner_steps; 364 365 vtxs->add(xe,yb+r,zz); 366 vtxs->add(xe,ye-r,zz); 367 368 // top-right : 369 float angle = dangle; 370 if(corner_mask.value() & corner_top_right()) { 371 float xc = xe-r; 372 float yc = ye-r; 373 for(unsigned int i=0;i<nslice;i++,angle+=dangle) { 374 vtxs->add(r*fcos(angle)+xc,r*fsin(angle)+yc,zz); 375 } 376 } else { 377 angle += fhalf_pi(); 378 vtxs->add(xe,ye,zz); 379 vtxs->add(xe-r,ye,zz); 380 } 381 382 vtxs->add(xb+r,ye,zz); 383 384 // top-left : 385 if(corner_mask.value() & corner_top_left()) { 386 float xc = xb+r; 387 float yc = ye-r; 388 for(unsigned int i=0;i<nslice;i++,angle+=dangle) { 389 vtxs->add(r*fcos(angle)+xc,r*fsin(angle)+yc,zz); 390 } 391 } else { 392 angle += fhalf_pi(); 393 vtxs->add(xb,ye,zz); 394 vtxs->add(xb,ye-r,zz); 395 } 396 397 vtxs->add(xb,yb+r,zz); 398 399 // bottom-left : 400 if(corner_mask.value() & corner_bottom_left()) { 401 float xc = xb+r; 402 float yc = yb+r; 403 for(unsigned int i=0;i<nslice;i++,angle+=dangle) { 404 vtxs->add(r*fcos(angle)+xc,r*fsin(angle)+yc,zz); 405 } 406 } else { 407 angle += fhalf_pi(); 408 vtxs->add(xb,yb,zz); 409 vtxs->add(xb+r,yb,zz); 410 } 411 412 vtxs->add(xe-r,yb,zz); 413 414 // bottom-right : 415 if(corner_mask.value() & corner_bottom_right()) { 416 float xc = xe-r; 417 float yc = yb+r; 418 for(unsigned int i=0;i<nslice;i++,angle+=dangle) { 419 vtxs->add(r*fcos(angle)+xc,r*fsin(angle)+yc,zz); 420 } 421 } else { 422 angle += fhalf_pi(); 423 vtxs->add(xe,yb,zz); 424 vtxs->add(xe,yb+r,zz); 425 } 426 427 } else { 428 vtxs->add(xb,yb,zz); 429 vtxs->add(xe,yb,zz); 430 vtxs->add(xe,ye,zz); 431 vtxs->add(xb,ye,zz); 432 vtxs->add(xb,yb,zz); 433 } 434 } 435 436 } 437 protected: 438 separator m_back_sep; 439 }; 440 441 }} 442 443 #endif