root/dwt/layout/FillLayout.d

Revision 246:fd9c62a2998e, 8.3 kB (checked in by Frank Benoit <benoit@tionex.de>, 6 months ago)

Updater SWT 3.4M7 to 3.4

Line 
1 /*******************************************************************************
2  * Copyright (c) 2000, 2008 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 dwt.layout.FillLayout;
14
15 import dwt.DWT;
16 import dwt.graphics.Point;
17 import dwt.graphics.Rectangle;
18 import dwt.widgets.Control;
19 import dwt.widgets.Layout;
20 import dwt.widgets.Composite;
21 import dwt.widgets.Scrollable;
22 import dwt.layout.FillData;
23
24 import tango.util.Convert;
25 import dwt.dwthelper.utils;
26
27 /**
28  * <code>FillLayout</code> is the simplest layout class. It lays out
29  * controls in a single row or column, forcing them to be the same size.
30  * <p>
31  * Initially, the controls will all be as tall as the tallest control,
32  * and as wide as the widest. <code>FillLayout</code> does not wrap,
33  * but you can specify margins and spacing. You might use it to
34  * lay out buttons in a task bar or tool bar, or to stack checkboxes
35  * in a <code>Group</code>. <code>FillLayout</code> can also be used
36  * when a <code>Composite</code> only has one child. For example,
37  * if a <code>Shell</code> has a single <code>Group</code> child,
38  * <code>FillLayout</code> will cause the <code>Group</code> to
39  * completely fill the <code>Shell</code> (if margins are 0).
40  * </p>
41  * <p>
42  * Example code: first a <code>FillLayout</code> is created and
43  * its type field is set, and then the layout is set into the
44  * <code>Composite</code>. Note that in a <code>FillLayout</code>,
45  * children are always the same size, and they fill all available space.
46  * <pre>
47  *      FillLayout fillLayout = new FillLayout();
48  *      fillLayout.type = DWT.VERTICAL;
49  *      shell.setLayout(fillLayout);
50  * </pre>
51  * </p>
52  *
53  * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: LayoutExample</a>
54  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
55  */
56 public final class FillLayout : Layout {
57     /**
58      * type specifies how controls will be positioned
59      * within the layout.
60      *
61      * The default value is HORIZONTAL.
62      *
63      * Possible values are: <ul>
64      *    <li>HORIZONTAL: Position the controls horizontally from left to right</li>
65      *    <li>VERTICAL: Position the controls vertically from top to bottom</li>
66      * </ul>
67      */
68     public int type = DWT.HORIZONTAL;
69
70     /**
71      * marginWidth specifies the number of pixels of horizontal margin
72      * that will be placed along the left and right edges of the layout.
73      *
74      * The default value is 0.
75      *
76      * @since 3.0
77      */
78     public int marginWidth = 0;
79
80     /**
81      * marginHeight specifies the number of pixels of vertical margin
82      * that will be placed along the top and bottom edges of the layout.
83      *
84      * The default value is 0.
85      *
86      * @since 3.0
87      */
88     public int marginHeight = 0;
89
90     /**
91      * spacing specifies the number of pixels between the edge of one cell
92      * and the edge of its neighbouring cell.
93      *
94      * The default value is 0.
95      *
96      * @since 3.0
97      */
98     public int spacing = 0;
99
100 /**
101  * Constructs a new instance of this class.
102  */
103 public this () {
104 }
105
106 /**
107  * Constructs a new instance of this class given the type.
108  *
109  * @param type the type of fill layout
110  *
111  * @since 2.0
112  */
113 public this (int type) {
114     this.type = type;
115 }
116
117 override protected Point computeSize (Composite composite, int wHint, int hHint, bool flushCache) {
118     Control [] children = composite.getChildren ();
119     int count = children.length;
120     int maxWidth = 0, maxHeight = 0;
121     for (int i=0; i<count; i++) {
122         Control child = children [i];
123         int w = wHint, h = hHint;
124         if (count > 0) {
125             if (type is DWT.HORIZONTAL && wHint !is DWT.DEFAULT) {
126                 w = Math.max (0, (wHint - (count - 1) * spacing) / count);
127             }
128             if (type is DWT.VERTICAL && hHint !is DWT.DEFAULT) {
129                 h = Math.max (0, (hHint - (count - 1) * spacing) / count);
130             }
131         }
132         Point size = computeChildSize (child, w, h, flushCache);
133         maxWidth = Math.max (maxWidth, size.x);
134         maxHeight = Math.max (maxHeight, size.y);
135     }
136     int width = 0, height = 0;
137     if (type is DWT.HORIZONTAL) {
138         width = count * maxWidth;
139         if (count !is 0) width += (count - 1) * spacing;
140         height = maxHeight;
141     } else {
142         width = maxWidth;
143         height = count * maxHeight;
144         if (count !is 0) height += (count - 1) * spacing;
145     }
146     width += marginWidth * 2;
147     height += marginHeight * 2;
148     if (wHint !is DWT.DEFAULT) width = wHint;
149     if (hHint !is DWT.DEFAULT) height = hHint;
150     return new Point (width, height);
151 }
152
153 Point computeChildSize (Control control, int wHint, int hHint, bool flushCache) {
154     FillData data = cast(FillData)control.getLayoutData ();
155     if (data is null) {
156         data = new FillData ();
157         control.setLayoutData (data);
158     }
159     Point size = null;
160     if (wHint is DWT.DEFAULT && hHint is DWT.DEFAULT) {
161         size = data.computeSize (control, wHint, hHint, flushCache);
162     } else {
163         // TEMPORARY CODE
164         int trimX, trimY;
165         if ( auto sa = cast(Scrollable)control ) {
166             Rectangle rect = sa.computeTrim (0, 0, 0, 0);
167             trimX = rect.width;
168             trimY = rect.height;
169         } else {
170             trimX = trimY = control.getBorderWidth () * 2;
171         }
172         int w = wHint is DWT.DEFAULT ? wHint : Math.max (0, wHint - trimX);
173         int h = hHint is DWT.DEFAULT ? hHint : Math.max (0, hHint - trimY);
174         size = data.computeSize (control, w, h, flushCache);
175     }
176     return size;
177 }
178
179 override protected bool flushCache (Control control) {
180     Object data = control.getLayoutData();
181     if (data !is null) (cast(FillData)data).flushCache();
182     return true;
183 }
184
185 String getName () {
186     String string = this.classinfo.name;
187     int index = string.lastIndexOf( '.');
188     if (index is -1 ) return string;
189     return string[ index + 1 .. string.length ];
190 }
191
192 override protected void layout (Composite composite, bool flushCache) {
193     Rectangle rect = composite.getClientArea ();
194     Control [] children = composite.getChildren ();
195     int count = children.length;
196     if (count is 0) return;
197     int width = rect.width - marginWidth * 2;
198     int height = rect.height - marginHeight * 2;
199     if (type is DWT.HORIZONTAL) {
200         width -= (count - 1) * spacing;
201         int x = rect.x + marginWidth, extra = width % count;
202         int y = rect.y + marginHeight, cellWidth = width / count;
203         for (int i=0; i<count; i++) {
204             Control child = children [i];
205             int childWidth = cellWidth;
206             if (i is 0) {
207                 childWidth += extra / 2;
208             } else {
209                 if (i is count - 1) childWidth += (extra + 1) / 2;
210             }
211             child.setBounds (x, y, childWidth, height);
212             x += childWidth + spacing;
213         }
214     } else {
215         height -= (count - 1) * spacing;
216         int x = rect.x + marginWidth, cellHeight = height / count;
217         int y = rect.y + marginHeight, extra = height % count;
218         for (int i=0; i<count; i++) {
219             Control child = children [i];
220             int childHeight = cellHeight;
221             if (i is 0) {
222                 childHeight += extra / 2;
223             } else {
224                 if (i is count - 1) childHeight += (extra + 1) / 2;
225             }
226             child.setBounds (x, y, width, childHeight);
227             y += childHeight + spacing;
228         }
229     }
230 }
231
232 /**
233  * Returns a string containing a concise, human-readable
234  * description of the receiver.
235  *
236  * @return a string representation of the layout
237  */
238 override public String toString () {
239     String string = getName () ~ " {";
240     string ~= "type="~((type is DWT.VERTICAL) ? "DWT.VERTICAL" : "DWT.HORIZONTAL")~" ";
241     if (marginWidth !is 0) string ~= "marginWidth="~to!(String)(marginWidth)~" ";
242     if (marginHeight !is 0) string ~= "marginHeight="~to!(String)(marginHeight)~" ";
243     if (spacing !is 0) string ~= "spacing="~to!(String)(spacing)~" ";
244     string = string.trim();
245     string ~= "}";
246     return string;
247 }
248 }
Note: See TracBrowser for help on using the browser.