10
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2000, 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
|
|
10 * Port to the D programming language:
|
|
11 * Frank Benoit <benoit@tionex.de>
|
|
12 *******************************************************************************/
|
|
13 module dwtx.jface.viewers.TableLayout;
|
|
14
|
|
15 import dwtx.jface.viewers.ColumnLayoutData;
|
|
16 import dwtx.jface.viewers.ColumnPixelData;
|
|
17 import dwtx.jface.viewers.ColumnWeightData;
|
|
18
|
|
19 import tango.util.collection.model.Seq;
|
|
20 import tango.util.collection.ArraySeq;
|
|
21
|
|
22 import dwt.DWT;
|
|
23 import dwt.graphics.Point;
|
|
24 import dwt.widgets.Composite;
|
|
25 import dwt.widgets.Item;
|
|
26 import dwt.widgets.Layout;
|
|
27 import dwt.widgets.Table;
|
|
28 import dwt.widgets.TableColumn;
|
|
29 import dwt.widgets.Tree;
|
|
30 import dwt.widgets.TreeColumn;
|
|
31 import dwtx.core.runtime.Assert;
|
|
32 import dwtx.jface.layout.TableColumnLayout;
|
|
33
|
|
34 import dwt.dwthelper.utils;
|
|
35
|
|
36 /**
|
|
37 * A layout for a table. Call <code>addColumnData</code> to add columns.
|
|
38 * The TableLayout {@link ColumnLayoutData} is only valid until the table
|
|
39 * is resized. To keep the proportions constant when the table is resized
|
|
40 * see {@link TableColumnLayout}
|
|
41 */
|
|
42 public class TableLayout : Layout {
|
|
43
|
|
44 /**
|
|
45 * The number of extra pixels taken as horizontal trim by the table column.
|
|
46 * To ensure there are N pixels available for the content of the column,
|
|
47 * assign N+COLUMN_TRIM for the column width.
|
|
48 *
|
|
49 * @since 3.1
|
|
50 */
|
|
51 private static const int COLUMN_TRIM;
|
|
52 static this(){
|
|
53 COLUMN_TRIM = "carbon".equals(DWT.getPlatform()) ? 24 : 3; //$NON-NLS-1$
|
|
54 }
|
|
55
|
|
56 /**
|
|
57 * The list of column layout data (element type:
|
|
58 * <code>ColumnLayoutData</code>).
|
|
59 */
|
|
60 private Seq!(ColumnLayoutData) columns;
|
|
61
|
|
62 /**
|
|
63 * Indicates whether <code>layout</code> has yet to be called.
|
|
64 */
|
|
65 private bool firstTime = true;
|
|
66
|
|
67 /**
|
|
68 * Creates a new table layout.
|
|
69 */
|
|
70 public this() {
|
|
71 columns = new ArraySeq!(ColumnLayoutData);
|
|
72 }
|
|
73
|
|
74 /**
|
|
75 * Adds a new column of data to this table layout.
|
|
76 *
|
|
77 * @param data
|
|
78 * the column layout data
|
|
79 */
|
|
80 public void addColumnData(ColumnLayoutData data) {
|
|
81 columns.append(data);
|
|
82 }
|
|
83
|
|
84 /*
|
|
85 * (non-Javadoc) Method declared on Layout.
|
|
86 */
|
|
87 public Point computeSize(Composite c, int wHint, int hHint, bool flush) {
|
|
88 if (wHint !is DWT.DEFAULT && hHint !is DWT.DEFAULT) {
|
|
89 return new Point(wHint, hHint);
|
|
90 }
|
|
91
|
|
92 Table table = cast(Table) c;
|
|
93 // To avoid recursions.
|
|
94 table.setLayout(null);
|
|
95 // Use native layout algorithm
|
|
96 Point result = table.computeSize(wHint, hHint, flush);
|
|
97 table.setLayout(this);
|
|
98
|
|
99 int width = 0;
|
|
100 int size = columns.size();
|
|
101 foreach( layoutData; columns ){
|
|
102 if ( auto col = cast(ColumnPixelData) layoutData ) {
|
|
103 width += col.width;
|
|
104 if (col.addTrim) {
|
|
105 width += COLUMN_TRIM;
|
|
106 }
|
|
107 } else if ( auto col = cast(ColumnWeightData) layoutData ) {
|
|
108 width += col.minimumWidth;
|
|
109 } else {
|
|
110 Assert.isTrue(false, "Unknown column layout data");//$NON-NLS-1$
|
|
111 }
|
|
112 }
|
|
113 if (width > result.x) {
|
|
114 result.x = width;
|
|
115 }
|
|
116 return result;
|
|
117 }
|
|
118
|
|
119 /*
|
|
120 * (non-Javadoc) Method declared on Layout.
|
|
121 */
|
|
122 public void layout(Composite c, bool flush) {
|
|
123 // Only do initial layout. Trying to maintain proportions when resizing
|
|
124 // is too hard,
|
|
125 // causes lots of widget flicker, causes scroll bars to appear and
|
|
126 // occasionally stick around (on Windows),
|
|
127 // requires hooking column resizing as well, and may not be what the
|
|
128 // user wants anyway.
|
|
129 if (!firstTime) {
|
|
130 return;
|
|
131 }
|
|
132
|
|
133 int width = c.getClientArea().width;
|
|
134
|
|
135 // XXX: Layout is being called with an invalid value the first time
|
|
136 // it is being called on Linux. This method resets the
|
|
137 // Layout to null so we make sure we run it only when
|
|
138 // the value is OK.
|
|
139 if (width <= 1) {
|
|
140 return;
|
|
141 }
|
|
142
|
|
143 Item[] tableColumns = getColumns(c);
|
|
144 int size = Math.min(columns.size(), tableColumns.length);
|
|
145 int[] widths = new int[size];
|
|
146 int fixedWidth = 0;
|
|
147 int numberOfWeightColumns = 0;
|
|
148 int totalWeight = 0;
|
|
149
|
|
150 // First calc space occupied by fixed columns
|
|
151 for (int i = 0; i < size; i++) {
|
|
152 ColumnLayoutData col = /+cast(ColumnLayoutData)+/ columns.get(i);
|
|
153 if ( auto cpd = cast(ColumnPixelData) col ) {
|
|
154 int pixels = cpd.width;
|
|
155 if (cpd.addTrim) {
|
|
156 pixels += COLUMN_TRIM;
|
|
157 }
|
|
158 widths[i] = pixels;
|
|
159 fixedWidth += pixels;
|
|
160 } else if ( auto cw = cast(ColumnWeightData) col ) {
|
|
161 numberOfWeightColumns++;
|
|
162 // first time, use the weight specified by the column data,
|
|
163 // otherwise use the actual width as the weight
|
|
164 // int weight = firstTime ? cw.weight :
|
|
165 // tableColumns[i].getWidth();
|
|
166 int weight = cw.weight;
|
|
167 totalWeight += weight;
|
|
168 } else {
|
|
169 Assert.isTrue(false, "Unknown column layout data");//$NON-NLS-1$
|
|
170 }
|
|
171 }
|
|
172
|
|
173 // Do we have columns that have a weight
|
|
174 if (numberOfWeightColumns > 0) {
|
|
175 // Now distribute the rest to the columns with weight.
|
|
176 int rest = width - fixedWidth;
|
|
177 int totalDistributed = 0;
|
|
178 for (int i = 0; i < size; ++i) {
|
|
179 ColumnLayoutData col = /+cast(ColumnLayoutData)+/ columns.get(i);
|
|
180 if (auto cw = cast(ColumnWeightData) col ) {
|
|
181 // calculate weight as above
|
|
182 // int weight = firstTime ? cw.weight :
|
|
183 // tableColumns[i].getWidth();
|
|
184 int weight = cw.weight;
|
|
185 int pixels = totalWeight is 0 ? 0 : weight * rest
|
|
186 / totalWeight;
|
|
187 if (pixels < cw.minimumWidth) {
|
|
188 pixels = cw.minimumWidth;
|
|
189 }
|
|
190 totalDistributed += pixels;
|
|
191 widths[i] = pixels;
|
|
192 }
|
|
193 }
|
|
194
|
|
195 // Distribute any remaining pixels to columns with weight.
|
|
196 int diff = rest - totalDistributed;
|
|
197 for (int i = 0; diff > 0; ++i) {
|
|
198 if (i is size) {
|
|
199 i = 0;
|
|
200 }
|
|
201 ColumnLayoutData col = /+cast(ColumnLayoutData)+/ columns.get(i);
|
|
202 if (cast(ColumnWeightData)col ) {
|
|
203 ++widths[i];
|
|
204 --diff;
|
|
205 }
|
|
206 }
|
|
207 }
|
|
208
|
|
209 firstTime = false;
|
|
210
|
|
211 for (int i = 0; i < size; i++) {
|
|
212 setWidth(tableColumns[i], widths[i]);
|
|
213 }
|
|
214 }
|
|
215
|
|
216 /**
|
|
217 * Set the width of the item.
|
|
218 *
|
|
219 * @param item
|
|
220 * @param width
|
|
221 */
|
|
222 private void setWidth(Item item, int width) {
|
|
223 if ( cast(TreeColumn)item ) {
|
|
224 (cast(TreeColumn) item).setWidth(width);
|
|
225 } else {
|
|
226 (cast(TableColumn) item).setWidth(width);
|
|
227 }
|
|
228
|
|
229 }
|
|
230
|
|
231 /**
|
|
232 * Return the columns for the receiver.
|
|
233 *
|
|
234 * @param composite
|
|
235 * @return Item[]
|
|
236 */
|
|
237 private Item[] getColumns(Composite composite) {
|
|
238 if (cast(Tree)composite ) {
|
|
239 return (cast(Tree) composite).getColumns();
|
|
240 }
|
|
241 return (cast(Table) composite).getColumns();
|
|
242 }
|
|
243 }
|