1 // Written in the D programming language. 2 /++ 3 + Authors: KanzakiKino 4 + Copyright: KanzakiKino 2018 5 + License: LGPL-3.0 6 ++/ 7 module w4d.widget.popup.base; 8 import w4d.widget.base, 9 w4d.widget.panel, 10 w4d.widget.root, 11 w4d.exception; 12 import gl3n.linalg; 13 14 /// A base widget of popup. 15 class PopupWidget : RootWidget 16 { 17 /// WindowContext of the popup target. 18 protected WindowContext _objectContext; 19 20 protected vec2 _pos, _size; 21 22 /// 23 override void handlePopup ( bool opened, WindowContext w ) 24 { 25 if ( opened ) { 26 _objectContext = w; 27 } else { 28 _objectContext.requestRedraw(); 29 _objectContext = null; 30 } 31 } 32 33 /// 34 this () 35 { 36 super(); 37 _objectContext = null; 38 39 _pos = vec2(0,0); 40 _size = vec2(0,0); 41 } 42 43 /// Moves the popup to the pos and resize to the size. 44 void move ( vec2 pos, vec2 size ) 45 { 46 _pos = pos; 47 _size = size; 48 requestLayout(); 49 } 50 /// Closes the popup. 51 void close () 52 { 53 enforce( _objectContext, 54 "The popup is not opened yet." ); 55 _objectContext.setPopup( null ); 56 } 57 58 /// 59 override vec2 layout ( vec2 rootlt, vec2 rootsz ) 60 { 61 .Widget.layout( _pos, _size ); 62 63 const rootrb = rootlt + rootsz; 64 65 const lt = style.translate; 66 const rb = lt + style.box.collisionSize; 67 68 auto late = vec2(0,0); 69 if ( lt.x < rootlt.x ) { 70 late.x = rootlt.x - lt.x; 71 } else if ( rb.x > rootrb.x ) { 72 late.x = rootrb.x - rb.x; 73 } 74 if ( lt.y < rootlt.y ) { 75 late.y = rootlt.y - lt.y; 76 } else if ( rb.y > rootrb.y ) { 77 late.y = rootrb.y - rb.y; 78 } 79 80 style.shift( late ); 81 shiftChildren( late ); 82 return vec2(0,0); 83 } 84 }