1 13 package org.eclipse.jface.layout; 14 15 16 import org.eclipse.core.runtime.Assert; 17 import org.eclipse.jface.util.Policy; 18 import org.eclipse.jface.viewers.ColumnLayoutData; 19 import org.eclipse.jface.viewers.ColumnPixelData; 20 import org.eclipse.jface.viewers.ColumnWeightData; 21 import org.eclipse.jface.viewers.TableLayout; 22 import org.eclipse.swt.SWT; 23 import org.eclipse.swt.graphics.Point; 24 import org.eclipse.swt.graphics.Rectangle; 25 import org.eclipse.swt.widgets.Composite; 26 import org.eclipse.swt.widgets.Event; 27 import org.eclipse.swt.widgets.Layout; 28 import org.eclipse.swt.widgets.Listener; 29 import org.eclipse.swt.widgets.Scrollable; 30 import org.eclipse.swt.widgets.Widget; 31 32 43 abstract class AbstractColumnLayout extends Layout { 44 51 private static int COLUMN_TRIM = "carbon".equals(SWT.getPlatform()) ? 24 : 3; 53 static final boolean IS_GTK = "gtk".equals(SWT.getPlatform()); 55 static final String LAYOUT_DATA = Policy.JFACE + ".LAYOUT_DATA"; 57 private boolean inupdateMode = false; 58 59 private boolean relayout = true; 60 61 private Listener resizeListener = new Listener() { 62 63 public void handleEvent(Event event) { 64 if( ! inupdateMode ) { 65 updateColumnData(event.widget); 66 } 67 } 68 69 }; 70 71 80 public void setColumnData(Widget column, ColumnLayoutData data) { 81 82 if( column.getData(LAYOUT_DATA) == null ) { 83 column.addListener(SWT.Resize, resizeListener); 84 } 85 86 column.setData(LAYOUT_DATA, data); 87 } 88 89 101 private Point computeTableTreeSize(Scrollable scrollable, int wHint, 102 int hHint) { 103 Point result = scrollable.computeSize(wHint, hHint); 104 105 int width = 0; 106 int size = getColumnCount(scrollable); 107 for (int i = 0; i < size; ++i) { 108 ColumnLayoutData layoutData = getLayoutData(scrollable,i); 109 if (layoutData instanceof ColumnPixelData) { 110 ColumnPixelData col = (ColumnPixelData) layoutData; 111 width += col.width; 112 if (col.addTrim) { 113 width += COLUMN_TRIM; 114 } 115 } else if (layoutData instanceof ColumnWeightData) { 116 ColumnWeightData col = (ColumnWeightData) layoutData; 117 width += col.minimumWidth; 118 } else { 119 Assert.isTrue(false, "Unknown column layout data"); } 121 } 122 if (width > result.x) 123 result.x = width; 124 125 return result; 126 } 127 128 137 private void layoutTableTree(final Scrollable scrollable, final int width, 138 final Rectangle area, final boolean increase) { 139 final int size = getColumnCount(scrollable); 140 final int[] widths = new int[size]; 141 142 final int[] weightIteration = new int[size]; 143 int numberOfWeightColumns = 0; 144 145 int fixedWidth = 0; 146 int minWeightWidth = 0; 147 int totalWeight = 0; 148 149 for (int i = 0; i < size; i++) { 151 ColumnLayoutData col = getLayoutData(scrollable,i); 152 if (col instanceof ColumnPixelData) { 153 ColumnPixelData cpd = (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 (col instanceof ColumnWeightData) { 161 ColumnWeightData cw = (ColumnWeightData) col; 162 weightIteration[numberOfWeightColumns] = i; 163 numberOfWeightColumns++; 164 totalWeight += cw.weight; 165 minWeightWidth += cw.minimumWidth; 166 widths[i] = cw.minimumWidth; 167 } else { 168 Assert.isTrue(false, "Unknown column layout data"); } 170 } 171 172 final int restIncludingMinWidths = width - fixedWidth; 174 final int rest = restIncludingMinWidths - minWeightWidth; 175 if (numberOfWeightColumns > 0 && rest > 0) { 176 177 int totalWantedPixels = 0; 181 final int[] wantedPixels = new int[numberOfWeightColumns]; 182 for (int i = 0; i < numberOfWeightColumns; i++) { 183 ColumnWeightData cw = (ColumnWeightData) getLayoutData(scrollable,weightIteration[i]); 184 wantedPixels[i] = totalWeight == 0 ? 0 : cw.weight 185 * restIncludingMinWidths / totalWeight; 186 totalWantedPixels += wantedPixels[i]; 187 } 188 189 int totalDistributed = 0; 191 for (int i = 0; i < numberOfWeightColumns; ++i) { 192 int pixels = totalWantedPixels == 0 ? 0 : wantedPixels[i] 193 * rest / totalWantedPixels; 194 totalDistributed += pixels; 195 widths[weightIteration[i]] += pixels; 196 } 197 198 int diff = rest - totalDistributed; 200 for (int i = 0; diff > 0; i = ((i + 1) % numberOfWeightColumns)) { 201 ++widths[weightIteration[i]]; 202 --diff; 203 } 204 } 205 206 if (increase) { 207 scrollable.setSize(area.width, area.height); 208 } 209 210 inupdateMode = true; 211 setColumnWidths(scrollable, widths); 212 scrollable.update(); 213 inupdateMode = false; 214 215 if (!increase) { 216 scrollable.setSize(area.width, area.height); 217 } 218 } 219 220 226 protected Point computeSize(Composite composite, int wHint, int hHint, 227 boolean flushCache) { 228 return computeTableTreeSize(getControl(composite), wHint, hHint); 229 } 230 231 237 protected void layout(Composite composite, boolean flushCache) { 238 Rectangle area = composite.getClientArea(); 239 Scrollable table = getControl(composite); 240 int tableWidth = table.getSize().x; 241 int trim = computeTrim(area, table, tableWidth); 242 int width = Math.max(0, area.width - trim); 243 244 if (width > 1) 245 layoutTableTree(table, width, area, tableWidth < area.width); 246 247 if (relayout) { 250 relayout = false; 251 composite.layout(); 252 } 253 } 254 255 263 private int computeTrim(Rectangle area, Scrollable scrollable, 264 int currentWidth) { 265 int trim; 266 267 if (currentWidth > 1) { 268 trim = currentWidth - scrollable.getClientArea().width; 269 } else { 270 trim = 2 * scrollable.getBorderWidth() + 1; 274 } 275 276 return trim; 277 } 278 279 286 Scrollable getControl(Composite composite) { 287 return (Scrollable) composite.getChildren()[0]; 288 } 289 290 295 abstract int getColumnCount(Scrollable tableTree); 296 297 302 abstract void setColumnWidths(Scrollable tableTree, int[] widths); 303 304 abstract ColumnLayoutData getLayoutData(Scrollable tableTree, int columnIndex); 305 306 abstract void updateColumnData(Widget column); 307 } | Popular Tags |