1 12 package org.eclipse.ui.forms.widgets; 13 import org.eclipse.swt.SWT; 14 import org.eclipse.swt.graphics.Point; 15 import org.eclipse.swt.graphics.Rectangle; 16 import org.eclipse.swt.widgets.Composite; 17 import org.eclipse.swt.widgets.Control; 18 import org.eclipse.swt.widgets.Layout; 19 38 public final class ColumnLayout extends Layout implements ILayoutExtension { 39 42 public int minNumColumns = 1; 43 46 public int maxNumColumns = 3; 47 50 public int horizontalSpacing = 5; 51 54 public int verticalSpacing = 5; 55 58 public int topMargin = 5; 59 62 public int leftMargin = 5; 63 66 public int bottomMargin = 5; 67 70 public int rightMargin = 5; 71 72 75 public ColumnLayout() { 76 } 77 78 protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { 79 if (wHint == 0) 80 return computeSize(composite, wHint, hHint, minNumColumns); 81 else if (wHint == SWT.DEFAULT) 82 return computeSize(composite, wHint, hHint, maxNumColumns); 83 else 84 return computeSize(composite, wHint, hHint, -1); 85 } 86 87 private Point computeSize(Composite parent, int wHint, int hHint, int ncolumns) { 88 Control[] children = parent.getChildren(); 89 int cwidth = 0; 90 int cheight = 0; 91 Point[] sizes = new Point[children.length]; 92 93 int cwHint = SWT.DEFAULT; 94 if (ncolumns != -1) { 95 cwHint = wHint - leftMargin - rightMargin - (ncolumns - 1) * horizontalSpacing; 96 if (cwHint <= 0) 97 cwHint = 0; 98 else 99 cwHint /= ncolumns; 100 } 101 102 for (int i = 0; i < children.length; i++) { 103 sizes[i] = computeControlSize(children[i], cwHint); 104 cwidth = Math.max(cwidth, sizes[i].x); 105 cheight += sizes[i].y; 106 } 107 if (ncolumns == -1) { 108 ncolumns = (wHint - leftMargin - rightMargin - horizontalSpacing) / (cwidth + horizontalSpacing); 110 ncolumns = Math.min(ncolumns, children.length); 111 ncolumns = Math.max(ncolumns, minNumColumns); 112 ncolumns = Math.min(ncolumns, maxNumColumns); 113 } 114 int perColHeight = cheight / ncolumns; 115 if (cheight % ncolumns != 0) 116 perColHeight++; 117 int colHeight = 0; 118 int[] heights = new int[ncolumns]; 119 int ncol = 0; 120 121 boolean fillIn = false; 122 123 for (int i = 0; i < sizes.length; i++) { 124 int childHeight = sizes[i].y; 125 if (i>0 && colHeight + childHeight > perColHeight) { 126 heights[ncol] = colHeight; 127 ncol++; 128 if (ncol == ncolumns || fillIn) { 129 fillIn = true; 131 ncol = findShortestColumn(heights); 132 } 133 colHeight = heights[ncol]; 134 } 135 if (colHeight > 0) 136 colHeight += verticalSpacing; 137 colHeight += childHeight; 138 } 139 heights[ncol] = Math.max(heights[ncol],colHeight); 140 141 Point size = new Point(0, 0); 142 for (int i = 0; i < ncolumns; i++) { 143 size.y = Math.max(size.y, heights[i]); 144 } 145 size.x = cwidth * ncolumns + (ncolumns - 1) * horizontalSpacing; 146 size.x += leftMargin + rightMargin; 147 size.y += topMargin + bottomMargin; 149 return size; 150 } 151 152 private Point computeControlSize(Control c, int wHint) { 153 ColumnLayoutData cd = (ColumnLayoutData) c.getLayoutData(); 154 int widthHint = cd != null ? cd.widthHint : wHint; 155 int heightHint = cd != null ? cd.heightHint : SWT.DEFAULT; 156 return c.computeSize(widthHint, heightHint); 157 } 158 159 private int findShortestColumn(int[] heights) { 160 int result = 0; 161 int height = Integer.MAX_VALUE; 162 for (int i = 0; i < heights.length; i++) { 163 if (height > heights[i]) { 164 height = heights[i]; 165 result = i; 166 } 167 } 168 return result; 169 } 170 171 177 protected void layout(Composite parent, boolean flushCache) { 178 Control[] children = parent.getChildren(); 179 Rectangle carea = parent.getClientArea(); 180 int cwidth = 0; 181 int cheight = 0; 182 Point[] sizes = new Point[children.length]; 183 for (int i = 0; i < children.length; i++) { 184 sizes[i] = computeControlSize(children[i], SWT.DEFAULT); 185 cwidth = Math.max(cwidth, sizes[i].x); 186 cheight += sizes[i].y; 187 } 188 int ncolumns = (carea.width - leftMargin - rightMargin - horizontalSpacing) / (cwidth + horizontalSpacing); 189 ncolumns = Math.min(ncolumns, children.length); 190 ncolumns = Math.max(ncolumns, minNumColumns); 191 ncolumns = Math.min(ncolumns, maxNumColumns); 192 int realWidth = (carea.width - leftMargin - rightMargin + horizontalSpacing) / ncolumns - horizontalSpacing; 193 198 int fillWidth = Math.max(cwidth, realWidth); 199 200 int perColHeight = cheight / ncolumns; 201 if (cheight % ncolumns != 0) 202 perColHeight++; 203 204 int colHeight = 0; 205 int[] heights = new int[ncolumns]; 206 int ncol = 0; 207 int x = leftMargin; 208 boolean fillIn = false; 209 210 for (int i = 0; i < sizes.length; i++) { 211 Control child = children[i]; 212 Point csize = sizes[i]; 213 ColumnLayoutData cd = (ColumnLayoutData) child.getLayoutData(); 214 int align = cd != null ? cd.horizontalAlignment : ColumnLayoutData.FILL; 215 int childWidth = align == ColumnLayoutData.FILL ? fillWidth : csize.x; 216 217 if (i>0 && colHeight + csize.y > perColHeight) { 218 heights[ncol] = colHeight; 219 if (fillIn || ncol == ncolumns-1) { 220 fillIn = true; 222 ncol = findShortestColumn(heights); 223 224 x = leftMargin + ncol * (fillWidth + horizontalSpacing); 225 226 } 227 else { 228 ncol++; 229 x += fillWidth + horizontalSpacing; 230 } 231 colHeight = heights[ncol]; 232 } 233 if (colHeight > 0) 234 colHeight += verticalSpacing; 235 236 237 switch (align) { 238 case ColumnLayoutData.LEFT : 239 case ColumnLayoutData.FILL : 240 child.setBounds(x, topMargin+colHeight, childWidth, csize.y); 241 break; 242 case ColumnLayoutData.RIGHT : 243 child.setBounds(x + fillWidth - childWidth, topMargin+colHeight, childWidth, csize.y); 244 break; 245 case ColumnLayoutData.CENTER : 246 child.setBounds(x + fillWidth / 2 - childWidth / 2, topMargin+colHeight, childWidth, csize.y); 247 break; 248 } 249 250 colHeight += csize.y; 251 } 252 } 253 254 260 public int computeMaximumWidth(Composite parent, boolean changed) { 261 return computeSize(parent, SWT.DEFAULT, SWT.DEFAULT, changed).x; 262 } 263 264 270 public int computeMinimumWidth(Composite parent, boolean changed) { 271 return computeSize(parent, 0, SWT.DEFAULT, changed).x; 272 } 273 } 274 | Popular Tags |