1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  * Port to the D programming language:
11  *     Frank Benoit <benoit@tionex.de>
12  *******************************************************************************/
13 module org.eclipse.swt.custom.ViewFormLayout;
14 
15 import java.lang.all;
16 
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.graphics.Point;
19 import org.eclipse.swt.graphics.Rectangle;
20 import org.eclipse.swt.widgets.Composite;
21 import org.eclipse.swt.widgets.Control;
22 import org.eclipse.swt.widgets.Layout;
23 import org.eclipse.swt.widgets.Scrollable;
24 import org.eclipse.swt.custom.ViewForm;
25 import org.eclipse.swt.custom.CLayoutData;
26 
27 /**
28  * This class provides the layout for ViewForm
29  *
30  * @see ViewForm
31  */
32 class ViewFormLayout : Layout {
33 
34 protected override Point computeSize(Composite composite, int wHint, int hHint, bool flushCache) {
35     ViewForm form = cast(ViewForm)composite;
36     Control left = form.topLeft;
37     Control center = form.topCenter;
38     Control right = form.topRight;
39     Control content = form.content;
40 
41     Point leftSize = new Point(0, 0);
42     if (left !is null) {
43         leftSize = computeChildSize(left, SWT.DEFAULT, SWT.DEFAULT, flushCache);
44     }
45     Point centerSize = new Point(0, 0);
46     if (center !is null) {
47          centerSize = computeChildSize(center, SWT.DEFAULT, SWT.DEFAULT, flushCache);
48     }
49     Point rightSize = new Point(0, 0);
50     if (right !is null) {
51          rightSize = computeChildSize(right, SWT.DEFAULT, SWT.DEFAULT, flushCache);
52     }
53     Point size = new Point(0, 0);
54     // calculate width of title bar
55     if (form.separateTopCenter ||
56         (wHint !is SWT.DEFAULT &&  leftSize.x + centerSize.x + rightSize.x > wHint)) {
57         size.x = leftSize.x + rightSize.x;
58         if (leftSize.x > 0 && rightSize.x > 0) size.x += form.horizontalSpacing;
59         size.x = Math.max(centerSize.x, size.x);
60         size.y = Math.max(leftSize.y, rightSize.y);
61         if (center !is null){
62             size.y += centerSize.y;
63             if (left !is null ||right !is null)size.y += form.verticalSpacing;
64         }
65     } else {
66         size.x = leftSize.x + centerSize.x + rightSize.x;
67         int count = -1;
68         if (leftSize.x > 0) count++;
69         if (centerSize.x > 0) count++;
70         if (rightSize.x > 0) count++;
71         if (count > 0) size.x += count * form.horizontalSpacing;
72         size.y = Math.max(leftSize.y, Math.max(centerSize.y, rightSize.y));
73     }
74 
75     if (content !is null) {
76         if (left !is null || right !is null || center !is null) size.y += 1; // allow space for a vertical separator
77         Point contentSize = new Point(0, 0);
78         contentSize = computeChildSize(content, SWT.DEFAULT, SWT.DEFAULT, flushCache);
79         size.x = Math.max (size.x, contentSize.x);
80         size.y += contentSize.y;
81         if (size.y > contentSize.y) size.y += form.verticalSpacing;
82     }
83 
84     size.x += 2*form.marginWidth;
85     size.y += 2*form.marginHeight;
86 
87     if (wHint !is SWT.DEFAULT) size.x  = wHint;
88     if (hHint !is SWT.DEFAULT) size.y = hHint;
89 
90     return size;
91 }
92 
93 Point computeChildSize(Control control, int wHint, int hHint, bool flushCache) {
94     Object data = control.getLayoutData();
95     if (data is null || !( null !is cast(CLayoutData)data )) {
96         data = new CLayoutData();
97         control.setLayoutData(data);
98     }
99     return (cast(CLayoutData)data).computeSize(control, wHint, hHint, flushCache);
100 }
101 
102 int computeTrim(Control c) {
103     if ( auto sa = cast(Scrollable)c) {
104         Rectangle rect = sa.computeTrim (0, 0, 0, 0);
105         return rect.width;
106     }
107     return c.getBorderWidth () * 2;
108 }
109 
110 protected override bool flushCache(Control control) {
111     Object data = control.getLayoutData();
112     if ( auto ld = cast(CLayoutData)data ) ld.flushCache();
113     return true;
114 }
115 
116 protected override void layout(Composite composite, bool flushCache) {
117     ViewForm form = cast(ViewForm)composite;
118     Control left = form.topLeft;
119     Control center = form.topCenter;
120     Control right = form.topRight;
121     Control content = form.content;
122 
123     Rectangle rect = composite.getClientArea();
124 
125     Point leftSize = new Point(0, 0);
126     if (left !is null && !left.isDisposed()) {
127         leftSize = computeChildSize(left, SWT.DEFAULT, SWT.DEFAULT, flushCache);
128     }
129     Point centerSize = new Point(0, 0);
130     if (center !is null && !center.isDisposed()) {
131          centerSize = computeChildSize(center, SWT.DEFAULT, SWT.DEFAULT, flushCache);
132     }
133     Point rightSize = new Point(0, 0);
134     if (right !is null && !right.isDisposed()) {
135          rightSize = computeChildSize(right, SWT.DEFAULT, SWT.DEFAULT, flushCache);
136     }
137 
138     int minTopWidth = leftSize.x + centerSize.x + rightSize.x + 2*form.marginWidth + 2*form.highlight;
139     int count = -1;
140     if (leftSize.x > 0) count++;
141     if (centerSize.x > 0) count++;
142     if (rightSize.x > 0) count++;
143     if (count > 0) minTopWidth += count * form.horizontalSpacing;
144 
145     int x = rect.x + rect.width - form.marginWidth - form.highlight;
146     int y = rect.y + form.marginHeight + form.highlight;
147 
148     bool top = false;
149     if (form.separateTopCenter || minTopWidth > rect.width) {
150         int topHeight = Math.max(rightSize.y, leftSize.y);
151         if (right !is null && !right.isDisposed()) {
152             top = true;
153             x -= rightSize.x;
154             right.setBounds(x, y, rightSize.x, topHeight);
155             x -= form.horizontalSpacing;
156         }
157         if (left !is null && !left.isDisposed()) {
158             top = true;
159             int trim = computeTrim(left);
160             int leftW = x - rect.x - form.marginWidth - form.highlight - trim;
161             leftSize = computeChildSize(left, leftW, SWT.DEFAULT, false);
162             left.setBounds(rect.x + form.marginWidth + form.highlight, y, leftSize.x, topHeight);
163         }
164         if (top) y += topHeight + form.verticalSpacing;
165         if (center !is null && !center.isDisposed()) {
166             top = true;
167             int trim = computeTrim(center);
168             int w = rect.width - 2*form.marginWidth - 2*form.highlight - trim;
169             centerSize = computeChildSize(center, w, SWT.DEFAULT, false);
170             center.setBounds(rect.x + rect.width - form.marginWidth - form.highlight - centerSize.x, y, centerSize.x, centerSize.y);
171             y += centerSize.y + form.verticalSpacing;
172         }
173     } else {
174         int topHeight = Math.max(rightSize.y, Math.max(centerSize.y, leftSize.y));
175         if (right !is null && !right.isDisposed()) {
176             top = true;
177             x -= rightSize.x;
178             right.setBounds(x, y, rightSize.x, topHeight);
179             x -= form.horizontalSpacing;
180         }
181         if (center !is null && !center.isDisposed()) {
182             top = true;
183             x -= centerSize.x;
184             center.setBounds(x, y, centerSize.x, topHeight);
185             x -= form.horizontalSpacing;
186         }
187         if (left !is null && !left.isDisposed()) {
188             top = true;
189             Rectangle trim = ( null !is cast(Composite)left ) ? (cast(Composite)left).computeTrim(0, 0, 0, 0) : new Rectangle(0, 0, 0, 0);
190             int w = x - rect.x - form.marginWidth - form.highlight - trim.width;
191             int h = topHeight - trim.height;
192             leftSize = computeChildSize(left, w, h, false);
193             left.setBounds(rect.x + form.marginWidth + form.highlight, y, leftSize.x, topHeight);
194         }
195         if (top)y += topHeight + form.verticalSpacing;
196     }
197     int oldSeperator = form.separator;
198     form.separator = -1;
199     if (content !is null && !content.isDisposed()) {
200         if (left !is null || right !is null || center !is null){
201             form.separator = y;
202             y++;
203         }
204          content.setBounds(rect.x + form.marginWidth + form.highlight, y, rect.width - 2 * form.marginWidth - 2*form.highlight, rect.y + rect.height - y - form.marginHeight - form.highlight);
205     }
206     if (oldSeperator !is -1 && form.separator !is -1) {
207         int t = Math.min(form.separator, oldSeperator);
208         int b = Math.max(form.separator, oldSeperator);
209         form.redraw(form.borderLeft, t, form.getSize().x - form.borderLeft - form.borderRight, b - t, false);
210     }
211 }
212 }