1 /*******************************************************************************
2  * Copyright (c) 2004, 2015 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 
15 package org.eclipse.ui.internal.layout;
16 
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.graphics.Point;
19 import org.eclipse.swt.layout.GridData;
20 import org.eclipse.swt.widgets.Composite;
21 import org.eclipse.swt.widgets.Control;
22 import org.eclipse.swt.widgets.Shell;
23 
24 /**
25  * Contains helper methods for CellLayout. Many of these methods are workarounds
26  * for known SWT bugs. They should be updated once the original bugs are fixed
27  * in SWT.
28  *
29  * @since 3.0
30  */
31 class CellLayoutUtil {
32 
33 	private static Point zero = new Point(0, 0);
34 
35 	private static Point minimumShellSize;
36 
37 	private static CellData defaultData = new CellData();
38 
39 	/**
40 	 * Returns the minimum size for the given composite. That is, this returns the
41 	 * smallest values that will have any effect when passed into the composite's
42 	 * setSize method. Passing any smaller value is equivalent to passing the
43 	 * minimum size.
44 	 * <p>
45 	 * This method is intended for use by layouts. The layout can use this
46 	 * information when determining its preferred size. Returning a preferred size
47 	 * smaller than the composite's minimum size is pointless since the composite
48 	 * could never be set to that size. The layout may choose a different preferred
49 	 * size in this situation.
50 	 * </p>
51 	 * <p>
52 	 * Note that this method is only concerned with restrictions imposed by the
53 	 * composite; not it's layout. If the only restriction on the composite's size
54 	 * is imposed by the layout, then this method returns (0,0).
55 	 * </p>
56 	 * <p>
57 	 * Currently SWT does not expose this information through API, so this method is
58 	 * developed using trial-and-error. Whenever a composite is discovered that will
59 	 * not accept sizes below a certain threshold on some platform, this method
60 	 * should be updated to reflect that fact.
61 	 * </p>
62 	 * <p>
63 	 * At this time, the only known composite that has a minimum size are Shells.
64 	 * </p>
65 	 *
66 	 * @param toCompute the composite whose minimum size is being computed
67 	 * @return a size, in pixels, which is the smallest value that can be passed
68 	 *         into the composite's setSize(...) method.
69 	 */
computeMinimumSize(Composite toCompute)70 	static Point computeMinimumSize(Composite toCompute) {
71 		if (toCompute instanceof Shell) {
72 			if (minimumShellSize == null) {
73 				Shell testShell = new Shell((Shell) toCompute, SWT.DIALOG_TRIM | SWT.RESIZE);
74 				testShell.setSize(0, 0);
75 				minimumShellSize = testShell.getSize();
76 				testShell.dispose();
77 			}
78 
79 			return minimumShellSize;
80 		}
81 
82 		// If any other composites are discovered to have minimum sizes,
83 		// add heuristics for them here.
84 
85 		// Otherwise, the composite can be reduced to size (0,0)
86 
87 		return zero;
88 	}
89 
90 	/**
91 	 * Returns the CellData associated with the given control. If the control does
92 	 * not have any layout data associated with it, a default object is returned. If
93 	 * the control has a GridData object associated with it, an equivalent CellData
94 	 * object will be returned.
95 	 *
96 	 * @param control
97 	 * @return
98 	 */
getData(Control control)99 	static CellData getData(Control control) {
100 		Object layoutData = control.getLayoutData();
101 		CellData data = null;
102 
103 		if (layoutData instanceof CellData) {
104 			data = (CellData) layoutData;
105 		} else if (layoutData instanceof GridData) {
106 			data = new CellData((GridData) layoutData);
107 		}
108 
109 		if (data == null) {
110 			data = defaultData;
111 		}
112 
113 		return data;
114 	}
115 }
116