1 /** DGui project file. 2 3 Copyright: Trogu Antonio Davide 2011-2013 4 5 License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 7 Authors: Trogu Antonio Davide 8 */ 9 module dgui.layout.layoutcontrol; 10 11 import dgui.core.interfaces.ilayoutcontrol; 12 public import dgui.core.controls.containercontrol; 13 14 class ResizeManager: Handle!(HDWP), IDisposable 15 { 16 public this(int c) 17 { 18 if(c > 1) 19 { 20 this._handle = BeginDeferWindowPos(c); 21 } 22 } 23 24 public ~this() 25 { 26 this.dispose(); 27 } 28 29 public void dispose() 30 { 31 if(this._handle) 32 { 33 EndDeferWindowPos(this._handle); 34 } 35 } 36 37 public void setPosition(Control ctrl, Point pt) 38 { 39 this.setPosition(ctrl, pt.x, pt.y); 40 } 41 42 public void setPosition(Control ctrl, int x, int y) 43 { 44 this.resizeControl(ctrl, x, y, 0, 0, PositionSpecified.position); 45 } 46 47 public void setSize(Control ctrl, Size sz) 48 { 49 this.setSize(ctrl, sz.width, sz.height); 50 } 51 52 public void setSize(Control ctrl, int w, int h) 53 { 54 this.resizeControl(ctrl, 0, 0, w, h, PositionSpecified.size); 55 } 56 57 public void resizeControl(Control ctrl, Rect r, PositionSpecified ps = PositionSpecified.all) 58 { 59 this.resizeControl(ctrl, r.x, r.y, r.width, r.height, ps); 60 } 61 62 public void resizeControl(Control ctrl, int x, int y, int w, int h, PositionSpecified ps = PositionSpecified.all) 63 { 64 uint wpf = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE; 65 66 if(ps !is PositionSpecified.all) 67 { 68 if(ps is PositionSpecified.position) 69 { 70 wpf &= ~SWP_NOMOVE; 71 } 72 else //if(ps is PositionSpecified.size) 73 { 74 wpf &= ~SWP_NOSIZE; 75 } 76 } 77 else 78 { 79 wpf &= ~(SWP_NOMOVE | SWP_NOSIZE); 80 } 81 82 if(this._handle) 83 { 84 this._handle = DeferWindowPos(this._handle, ctrl.handle, null, x, y, w, h, wpf); 85 } 86 else 87 { 88 SetWindowPos(ctrl.handle, null, x, y, w, h, wpf); //Bounds updated in WM_WINDOWPOSCHANGED 89 } 90 } 91 } 92 93 abstract class LayoutControl: ContainerControl, ILayoutControl 94 { 95 public override void show() 96 { 97 super.show(); 98 this.updateLayout(); 99 } 100 101 public void updateLayout() 102 { 103 if(this._childControls && this.created && this.visible) 104 { 105 scope ResizeManager rm = new ResizeManager(this._childControls.length); 106 Rect da = Rect(nullPoint, this.clientSize); 107 108 foreach(Control c; this._childControls) 109 { 110 if(da.empty) 111 { 112 rm.dispose(); 113 break; 114 } 115 116 if(c.dock !is DockStyle.none && c.visible && c.created) 117 { 118 switch(c.dock) 119 { 120 case DockStyle.left: 121 //c.bounds = Rect(da.left, da.top, c.width, da.height); 122 rm.resizeControl(c, da.left, da.top, c.width, da.height); 123 da.left += c.width; 124 break; 125 126 case DockStyle.top: 127 //c.bounds = Rect(da.left, da.top, da.width, c.height); 128 rm.resizeControl(c, da.left, da.top, da.width, c.height); 129 da.top += c.height; 130 break; 131 132 case DockStyle.right: 133 //c.bounds = Rect(da.right - c.width, da.top, c.width, da.height); 134 rm.resizeControl(c, da.right - c.width, da.top, c.width, da.height); 135 da.right -= c.width; 136 break; 137 138 case DockStyle.bottom: 139 //c.bounds = Rect(c, da.left, da.bottom - c.height, da.width, c.height); 140 rm.resizeControl(c, da.left, da.bottom - c.height, da.width, c.height); 141 da.bottom -= c.height; 142 break; 143 144 case DockStyle.fill: 145 //c.bounds = da; 146 rm.resizeControl(c, da); 147 da.size = nullSize; 148 break; 149 150 default: 151 rm.dispose(); 152 assert(false, "Unknown DockStyle"); 153 //break; 154 } 155 } 156 } 157 } 158 } 159 160 protected override void onDGuiMessage(ref Message m) 161 { 162 switch(m.msg) 163 { 164 case DGUI_DOLAYOUT: 165 this.updateLayout(); 166 break; 167 168 case DGUI_CHILDCONTROLCREATED: 169 { 170 Control c = winCast!(Control)(m.wParam); 171 172 if(c.dock !is DockStyle.none && c.visible) 173 { 174 this.updateLayout(); 175 } 176 } 177 break; 178 179 default: 180 break; 181 } 182 183 super.onDGuiMessage(m); 184 } 185 186 protected override void onHandleCreated(EventArgs e) 187 { 188 super.onHandleCreated(e); 189 190 this.updateLayout(); 191 } 192 193 protected override void onResize(EventArgs e) 194 { 195 this.updateLayout(); 196 197 InvalidateRect(this._handle, null, true); 198 UpdateWindow(this._handle); 199 super.onResize(e); 200 } 201 }