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