Mercurial > projects > dwt-addons
annotate dwtx/jface/layout/AbstractColumnLayout.d @ 43:ea8ff534f622
Fix override and super aliases
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 11 Apr 2008 01:24:25 +0200 |
parents | b6c35faf97c8 |
children | 46a6e0e6ccd4 |
rev | line source |
---|---|
10 | 1 /******************************************************************************* |
2 * Copyright (c) 2006, 2007 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 (original file dwtx.ui.texteditor.templates.ColumnLayout) | |
10 * Tom Schindl <tom.schindl@bestsolution.at> - refactored to be widget independent (bug 171824) | |
11 * - fix for bug 178280, 184342, 184045 | |
12 * Port to the D programming language: | |
13 * Frank Benoit <benoit@tionex.de> | |
14 *******************************************************************************/ | |
15 module dwtx.jface.layout.AbstractColumnLayout; | |
16 | |
17 | |
18 | |
19 import dwt.DWT; | |
20 import dwt.graphics.Point; | |
21 import dwt.graphics.Rectangle; | |
22 import dwt.widgets.Composite; | |
23 import dwt.widgets.Event; | |
24 import dwt.widgets.Layout; | |
25 import dwt.widgets.Listener; | |
26 import dwt.widgets.Scrollable; | |
27 import dwt.widgets.Widget; | |
28 import dwtx.core.runtime.Assert; | |
29 import dwtx.jface.util.Policy; | |
30 import dwtx.jface.viewers.ColumnLayoutData; | |
31 import dwtx.jface.viewers.ColumnPixelData; | |
32 import dwtx.jface.viewers.ColumnWeightData; | |
33 import dwtx.jface.viewers.TableLayout; | |
34 | |
35 import dwt.dwthelper.utils; | |
36 | |
37 /** | |
38 * The AbstractColumnLayout is a {@link Layout} used to set the size of a table | |
39 * in a consistent way even during a resize unlike a {@link TableLayout} which | |
40 * only sets initial sizes. | |
41 * | |
42 * <p><b>You can only add the layout to a container whose | |
43 * only child is the table/tree control you want the layouts applied to.</b> | |
44 * </p> | |
45 * | |
46 * @since 3.3 | |
47 */ | |
48 abstract class AbstractColumnLayout : Layout { | |
49 /** | |
50 * The number of extra pixels taken as horizontal trim by the table column. | |
51 * To ensure there are N pixels available for the content of the column, | |
52 * assign N+COLUMN_TRIM for the column width. | |
53 * | |
54 * @since 3.1 | |
55 */ | |
56 private static int COLUMN_TRIM; | |
57 | |
58 static const bool IS_GTK; | |
59 | |
60 static const String LAYOUT_DATA; | |
61 | |
62 static this(){ | |
63 COLUMN_TRIM = "carbon".equals(DWT.getPlatform()) ? 24 : 3; //$NON-NLS-1$ | |
64 IS_GTK = "gtk".equals(DWT.getPlatform());//$NON-NLS-1$ | |
65 LAYOUT_DATA = Policy.JFACE ~ ".LAYOUT_DATA"; //$NON-NLS-1$ | |
66 } | |
67 | |
68 private bool inupdateMode = false; | |
69 | |
70 private bool relayout = true; | |
71 | |
72 private Listener resizeListener; | |
73 private void init_resizeListener(){ | |
74 resizeListener = new class Listener { | |
75 | |
76 public void handleEvent(Event event) { | |
77 if( ! inupdateMode ) { | |
78 updateColumnData(event.widget); | |
79 } | |
80 } | |
81 | |
82 }; | |
83 } | |
84 public this(){ | |
85 init_resizeListener(); | |
86 } | |
87 | |
88 /** | |
89 * Adds a new column of data to this table layout. | |
90 * | |
91 * @param column | |
92 * the column | |
93 * | |
94 * @param data | |
95 * the column layout data | |
96 */ | |
97 public void setColumnData(Widget column, ColumnLayoutData data) { | |
98 | |
99 if( column.getData(LAYOUT_DATA) is null ) { | |
100 column.addListener(DWT.Resize, resizeListener); | |
101 } | |
102 | |
103 column.setData(LAYOUT_DATA, data); | |
104 } | |
105 | |
106 /** | |
107 * Compute the size of the table or tree based on the ColumnLayoutData and | |
108 * the width and height hint. | |
109 * | |
110 * @param scrollable | |
111 * the widget to compute | |
112 * @param wHint | |
113 * the width hint | |
114 * @param hHint | |
115 * the height hint | |
116 * @return Point where x is the width and y is the height | |
117 */ | |
118 private Point computeTableTreeSize(Scrollable scrollable, int wHint, | |
119 int hHint) { | |
120 Point result = scrollable.computeSize(wHint, hHint); | |
121 | |
122 int width = 0; | |
123 int size = getColumnCount(scrollable); | |
124 for (int i = 0; i < size; ++i) { | |
125 ColumnLayoutData layoutData = getLayoutData(scrollable,i); | |
126 if ( auto col = cast(ColumnPixelData)layoutData) { | |
127 width += col.width; | |
128 if (col.addTrim) { | |
129 width += COLUMN_TRIM; | |
130 } | |
131 } else if ( auto col = cast(ColumnWeightData)layoutData ) { | |
132 width += col.minimumWidth; | |
133 } else { | |
134 Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$ | |
135 } | |
136 } | |
137 if (width > result.x) | |
138 result.x = width; | |
139 | |
140 return result; | |
141 } | |
142 | |
143 /** | |
144 * Layout the scrollable based on the supplied width and area. Only increase | |
145 * the size of the scrollable if increase is <code>true</code>. | |
146 * | |
147 * @param scrollable | |
148 * @param width | |
149 * @param area | |
150 * @param increase | |
151 */ | |
152 private void layoutTableTree(Scrollable scrollable, int width, | |
153 Rectangle area, bool increase) { | |
154 int size = getColumnCount(scrollable); | |
155 int[] widths = new int[size]; | |
156 | |
157 int[] weightIteration = new int[size]; | |
158 int numberOfWeightColumns = 0; | |
159 | |
160 int fixedWidth = 0; | |
161 int minWeightWidth = 0; | |
162 int totalWeight = 0; | |
163 | |
164 // First calc space occupied by fixed columns | |
165 for (int i = 0; i < size; i++) { | |
166 ColumnLayoutData col = getLayoutData(scrollable,i); | |
167 if ( auto cpd = cast(ColumnPixelData)col ) { | |
168 int pixels = cpd.width; | |
169 if (cpd.addTrim) { | |
170 pixels += COLUMN_TRIM; | |
171 } | |
172 widths[i] = pixels; | |
173 fixedWidth += pixels; | |
174 } else if ( auto cw = cast(ColumnWeightData) col ) { | |
175 weightIteration[numberOfWeightColumns] = i; | |
176 numberOfWeightColumns++; | |
177 totalWeight += cw.weight; | |
178 minWeightWidth += cw.minimumWidth; | |
179 widths[i] = cw.minimumWidth; | |
180 } else { | |
181 Assert.isTrue(false, "Unknown column layout data"); //$NON-NLS-1$ | |
182 } | |
183 } | |
184 | |
185 // Do we have columns that have a weight? | |
186 int restIncludingMinWidths = width - fixedWidth; | |
187 int rest = restIncludingMinWidths - minWeightWidth; | |
188 if (numberOfWeightColumns > 0 && rest > 0) { | |
189 | |
190 // Modify the weights to reflect what each column already | |
191 // has due to its minimum. Otherwise, columns with low | |
192 // minimums get discriminated. | |
193 int totalWantedPixels = 0; | |
194 int[] wantedPixels = new int[numberOfWeightColumns]; | |
195 for (int i = 0; i < numberOfWeightColumns; i++) { | |
196 ColumnWeightData cw = cast(ColumnWeightData) getLayoutData(scrollable,weightIteration[i]); | |
197 wantedPixels[i] = totalWeight is 0 ? 0 : cw.weight | |
198 * restIncludingMinWidths / totalWeight; | |
199 totalWantedPixels += wantedPixels[i]; | |
200 } | |
201 | |
202 // Now distribute the rest to the columns with weight. | |
203 int totalDistributed = 0; | |
204 for (int i = 0; i < numberOfWeightColumns; ++i) { | |
205 int pixels = totalWantedPixels is 0 ? 0 : wantedPixels[i] | |
206 * rest / totalWantedPixels; | |
207 totalDistributed += pixels; | |
208 widths[weightIteration[i]] += pixels; | |
209 } | |
210 | |
211 // Distribute any remaining pixels to columns with weight. | |
212 int diff = rest - totalDistributed; | |
213 for (int i = 0; diff > 0; i = ((i + 1) % numberOfWeightColumns)) { | |
214 ++widths[weightIteration[i]]; | |
215 --diff; | |
216 } | |
217 } | |
218 | |
219 if (increase) { | |
220 scrollable.setSize(area.width, area.height); | |
221 } | |
222 | |
223 inupdateMode = true; | |
224 setColumnWidths(scrollable, widths); | |
225 scrollable.update(); | |
226 inupdateMode = false; | |
227 | |
228 if (!increase) { | |
229 scrollable.setSize(area.width, area.height); | |
230 } | |
231 } | |
232 | |
233 /* | |
234 * (non-Javadoc) | |
235 * | |
236 * @see dwt.widgets.Layout#computeSize(dwt.widgets.Composite, | |
237 * int, int, bool) | |
238 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
10
diff
changeset
|
239 protected override Point computeSize(Composite composite, int wHint, int hHint, |
10 | 240 bool flushCache) { |
241 return computeTableTreeSize(getControl(composite), wHint, hHint); | |
242 } | |
243 | |
244 /* | |
245 * (non-Javadoc) | |
246 * | |
247 * @see dwt.widgets.Layout#layout(dwt.widgets.Composite, | |
248 * bool) | |
249 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
10
diff
changeset
|
250 protected override void layout(Composite composite, bool flushCache) { |
10 | 251 Rectangle area = composite.getClientArea(); |
252 Scrollable table = getControl(composite); | |
253 int tableWidth = table.getSize().x; | |
254 int trim = computeTrim(area, table, tableWidth); | |
255 int width = Math.max(0, area.width - trim); | |
256 | |
257 if (width > 1) | |
258 layoutTableTree(table, width, area, tableWidth < area.width); | |
259 | |
260 // For the first time we need to relayout because Scrollbars are not | |
261 // calculate appropriately | |
262 if (relayout) { | |
263 relayout = false; | |
264 composite.layout(); | |
265 } | |
266 } | |
267 | |
268 /** | |
269 * Compute the area required for trim. | |
270 * | |
271 * @param area | |
272 * @param scrollable | |
273 * @param currentWidth | |
274 * @return int | |
275 */ | |
276 private int computeTrim(Rectangle area, Scrollable scrollable, | |
277 int currentWidth) { | |
278 int trim; | |
279 | |
280 if (currentWidth > 1) { | |
281 trim = currentWidth - scrollable.getClientArea().width; | |
282 } else { | |
283 // initially, the table has no extend and no client area - use the | |
284 // border with | |
285 // plus some padding as educated guess | |
286 trim = 2 * scrollable.getBorderWidth() + 1; | |
287 } | |
288 | |
289 return trim; | |
290 } | |
291 | |
292 /** | |
293 * Get the control being laid out. | |
294 * | |
295 * @param composite | |
296 * the composite with the layout | |
297 * @return {@link Scrollable} | |
298 */ | |
299 Scrollable getControl(Composite composite) { | |
300 return cast(Scrollable) composite.getChildren()[0]; | |
301 } | |
302 | |
303 /** | |
304 * Get the number of columns for the receiver. | |
305 * | |
306 * @return the number of columns | |
307 */ | |
308 abstract int getColumnCount(Scrollable tableTree); | |
309 | |
310 /** | |
311 * Set the widths of the columns. | |
312 * | |
313 * @param widths | |
314 */ | |
315 abstract void setColumnWidths(Scrollable tableTree, int[] widths); | |
316 | |
317 abstract ColumnLayoutData getLayoutData(Scrollable tableTree, int columnIndex); | |
318 | |
319 abstract void updateColumnData(Widget column); | |
320 } |