comparison dwtx/jface/layout/LayoutGenerator.d @ 13:6886832e1ed8

ErrorDialog
author Frank Benoit <benoit@tionex.de>
date Mon, 31 Mar 2008 01:41:52 +0200
parents
children 7ab2f0b11096
comparison
equal deleted inserted replaced
12:8ec40848221b 13:6886832e1ed8
1 /*******************************************************************************
2 * Copyright (c) 2005, 2006 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 dwtx.jface.layout.LayoutGenerator;
14
15 import dwtx.jface.layout.GridDataFactory;
16 import dwtx.jface.layout.LayoutConstants;
17
18 import dwt.DWT;
19 import dwt.events.ModifyListener;
20 import dwt.graphics.Point;
21 import dwt.layout.GridData;
22 import dwt.layout.GridLayout;
23 import dwt.widgets.Button;
24 import dwt.widgets.Composite;
25 import dwt.widgets.Control;
26 import dwt.widgets.Layout;
27 import dwt.widgets.Scrollable;
28 import dwtx.jface.util.Geometry;
29
30 import dwt.dwthelper.utils;
31
32 /* package */class LayoutGenerator {
33
34 /**
35 * Default size for controls with varying contents
36 */
37 private static const Point defaultSize;
38
39 /**
40 * Default wrapping size for wrapped labels
41 */
42 private static const int wrapSize = 350;
43
44 private static const GridDataFactory nonWrappingLabelData;
45
46 static this(){
47 defaultSize = new Point(150, 150);
48 nonWrappingLabelData = GridDataFactory.fillDefaults().align_(DWT.BEGINNING, DWT.CENTER).grab(false, false);
49 }
50
51 private static bool hasStyle(Control c, int style) {
52 return (c.getStyle() & style) !is 0;
53 }
54
55 /**
56 * Generates a GridLayout for the given composite by examining its child
57 * controls and attaching layout data to any immediate children that do not
58 * already have layout data.
59 *
60 * @param toGenerate
61 * composite to generate a layout for
62 */
63 public static void generateLayout(Composite toGenerate) {
64 Control[] children = toGenerate.getChildren();
65
66 for (int i = 0; i < children.length; i++) {
67 Control control = children[i];
68
69 // Skip any children that already have layout data
70 if (control.getLayoutData() !is null) {
71 continue;
72 }
73
74 applyLayoutDataTo(control);
75 }
76 }
77
78 private static void applyLayoutDataTo(Control control) {
79 defaultsFor(control).applyTo(control);
80 }
81
82 /**
83 * Creates default factory for this control types:
84 * <ul>
85 * <li>{@link Button} with {@link DWT#CHECK}</li>
86 * <li>{@link Button}</li>
87 * <li>{@link Composite}</li>
88 * </ul>
89 * @param control the control the factory is search for
90 * @return a default factory for the control
91 */
92 public static GridDataFactory defaultsFor(Control control) {
93 if ( auto button = cast(Button) control ) {
94
95 if (hasStyle(button, DWT.CHECK)) {
96 return nonWrappingLabelData.copy();
97 } else {
98 return GridDataFactory.fillDefaults().align_(DWT.FILL, DWT.CENTER).hint(Geometry.max(button.computeSize(DWT.DEFAULT, DWT.DEFAULT, true), LayoutConstants.getMinButtonSize()));
99 }
100 }
101
102 if (auto scrollable = cast(Scrollable) control ) {
103
104 if ( auto composite = cast(Composite) scrollable ) {
105
106 Layout theLayout = composite.getLayout();
107 if ( cast(GridLayout) theLayout ) {
108 bool growsHorizontally = false;
109 bool growsVertically = false;
110
111 Control[] children = composite.getChildren();
112 for (int i = 0; i < children.length; i++) {
113 Control child = children[i];
114
115 GridData data = cast(GridData) child.getLayoutData();
116
117 if (data !is null) {
118 if (data.grabExcessHorizontalSpace) {
119 growsHorizontally = true;
120 }
121 if (data.grabExcessVerticalSpace) {
122 growsVertically = true;
123 }
124 }
125 }
126
127 return GridDataFactory.fillDefaults().grab(growsHorizontally, growsVertically);
128 }
129 }
130 }
131
132 bool wrapping = hasStyle(control, DWT.WRAP);
133
134 // Assume any control with the H_SCROLL or V_SCROLL flags are
135 // horizontally or vertically
136 // scrollable, respectively.
137 bool hScroll = hasStyle(control, DWT.H_SCROLL);
138 bool vScroll = hasStyle(control, DWT.V_SCROLL);
139
140 bool containsText = hasMethod(control, "setText", [ ArrayWrapperString.classinfo ] ); //$NON-NLS-1$
141
142 // If the control has a setText method, an addModifyListener method, and
143 // does not have
144 // the DWT.READ_ONLY flag, assume it contains user-editable text.
145 bool userEditable = !hasStyle(control, DWT.READ_ONLY) && containsText && hasMethod(control, "addModifyListener", [ ModifyListener.classinfo ]); //$NON-NLS-1$
146
147 // For controls containing user-editable text...
148 if (userEditable) {
149 if (hasStyle(control, DWT.MULTI)) {
150 vScroll = true;
151 }
152
153 if (!wrapping) {
154 hScroll = true;
155 }
156 }
157
158 // Compute the horizontal hint
159 int hHint = DWT.DEFAULT;
160 bool grabHorizontal = hScroll;
161
162 // For horizontally-scrollable controls, override their horizontal
163 // preferred size
164 // with a constant
165 if (hScroll) {
166 hHint = defaultSize.x;
167 } else {
168 // For wrapping controls, there are two cases.
169 // 1. For controls that contain text (like wrapping labels,
170 // read-only text boxes,
171 // etc.) override their preferred size with the preferred wrapping
172 // point and
173 // make them grab horizontal space.
174 // 2. For non-text controls (like wrapping toolbars), assume that
175 // their non-wrapped
176 // size is best.
177
178 if (wrapping) {
179 if (containsText) {
180 hHint = wrapSize;
181 grabHorizontal = true;
182 }
183 }
184 }
185
186 int vAlign = DWT.FILL;
187
188 // Heuristic for labels: Controls that contain non-wrapping read-only
189 // text should be
190 // center-aligned rather than fill-aligned
191 if (!vScroll && !wrapping && !userEditable && containsText) {
192 vAlign = DWT.CENTER;
193 }
194
195 return GridDataFactory.fillDefaults().grab(grabHorizontal, vScroll).align_(DWT.FILL, vAlign).hint(hHint, vScroll ? defaultSize.y : DWT.DEFAULT);
196 }
197
198 private static bool hasMethod(Control control, String name, ClassInfo[] parameterTypes) {
199 ClassInfo c = control.classinfo;
200 implMissing(__FILE__,__LINE__);
201 pragma(msg, "FIXME dwtx.jface.layout.LayoutGenerator hasMethod reflection" );
202 return true;
203 /+ try {
204 return c.getMethod(name, parameterTypes) !is null;
205 } catch (SecurityException e) {
206 return false;
207 } catch (NoSuchMethodException e) {
208 return false;
209 }+/
210 }
211 }