001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Randy Hudson <hudsonr@us.ibm.com>
011: * - Fix for bug 19524 - Resizing WorkbenchWindow resizes views
012: * Cagatay Kavukcuoglu <cagatayk@acm.org>
013: * - Fix for bug 10025 - Resizing views should not use height ratios
014: *******************************************************************************/package org.eclipse.ui.internal;
015:
016: import org.eclipse.jface.util.Geometry;
017: import org.eclipse.swt.SWT;
018: import org.eclipse.swt.events.SelectionAdapter;
019: import org.eclipse.swt.events.SelectionEvent;
020: import org.eclipse.swt.events.SelectionListener;
021: import org.eclipse.swt.graphics.Rectangle;
022: import org.eclipse.swt.widgets.Composite;
023: import org.eclipse.swt.widgets.Control;
024: import org.eclipse.swt.widgets.Sash;
025:
026: class LayoutPartSash extends LayoutPart {
027:
028: private Sash sash;
029: private boolean enabled = false;
030:
031: private PartSashContainer rootContainer;
032:
033: private int style;
034:
035: private LayoutPartSash preLimit;
036:
037: private LayoutPartSash postLimit;
038:
039: SelectionListener selectionListener;
040:
041: private int left = 300, right = 300;
042:
043: private Rectangle bounds = new Rectangle(0, 0, 0, 0);
044:
045: /**
046: * Stores whether or not the sash is visible. (This is expected to have a meaningful
047: * value even if the underlying control doesn't exist).
048: */
049: private boolean isVisible;
050:
051: LayoutPartSash(PartSashContainer rootContainer, int style) {
052: super (null);
053: this .style = style;
054: this .rootContainer = rootContainer;
055:
056: selectionListener = new SelectionAdapter() {
057: public void widgetSelected(SelectionEvent e) {
058: checkDragLimit(e);
059:
060: if (e.detail != SWT.DRAG) {
061: LayoutPartSash.this .widgetSelected(e.x, e.y,
062: e.width, e.height);
063: }
064: }
065: };
066: }
067:
068: // checkDragLimit contains changes by cagatayk@acm.org
069: private void checkDragLimit(SelectionEvent event) {
070: LayoutTree root = rootContainer.getLayoutTree();
071: LayoutTreeNode node = root.findSash(this );
072: Rectangle nodeBounds = node.getBounds();
073: Rectangle eventRect = new Rectangle(event.x, event.y,
074: event.width, event.height);
075:
076: boolean vertical = (style == SWT.VERTICAL);
077:
078: // If a horizontal sash, flip the coordinate system so that we
079: // can handle horizontal and vertical sashes without special cases
080: if (!vertical) {
081: Geometry.flipXY(nodeBounds);
082: Geometry.flipXY(eventRect);
083: }
084:
085: int eventX = eventRect.x;
086: int left = Math.max(0, eventX - nodeBounds.x);
087: left = Math.min(left, nodeBounds.width
088: - LayoutTreeNode.SASH_WIDTH);
089: int right = nodeBounds.width - left - LayoutTreeNode.SASH_WIDTH;
090:
091: LayoutTreeNode.ChildSizes sizes = node.computeChildSizes(
092: nodeBounds.width, nodeBounds.height, left, right,
093: nodeBounds.width);
094:
095: eventRect.x = nodeBounds.x + sizes.left;
096:
097: // If it's a horizontal sash, restore eventRect to its original coordinate system
098: if (!vertical) {
099: Geometry.flipXY(eventRect);
100: }
101:
102: event.x = eventRect.x;
103: event.y = eventRect.y;
104: }
105:
106: /**
107: * Creates the control. As an optimization, creation of the control is deferred if
108: * the control is invisible.
109: */
110: public void createControl(Composite parent) {
111: // Defer creation of the control until it becomes visible
112: if (isVisible) {
113: doCreateControl();
114: }
115: }
116:
117: /**
118: * Creates the underlying SWT control.
119: *
120: * @since 3.1
121: */
122: private void doCreateControl() {
123: if (sash == null) {
124: sash = new Sash(this .rootContainer.getParent(), style
125: | SWT.SMOOTH);
126: sash.addSelectionListener(selectionListener);
127: sash.setEnabled(enabled);
128: sash.setBounds(bounds);
129: }
130: }
131:
132: public void setBounds(Rectangle r) {
133: super .setBounds(r);
134:
135: bounds = r;
136: }
137:
138: /**
139: * Makes the sash visible or invisible. Note: as an optimization, the actual widget is destroyed when the
140: * sash is invisible.
141: */
142: public void setVisible(boolean visible) {
143: if (visible == isVisible) {
144: return;
145: }
146:
147: if (visible) {
148: doCreateControl();
149: } else {
150: dispose();
151: }
152:
153: super .setVisible(visible);
154:
155: isVisible = visible;
156: }
157:
158: public boolean isVisible() {
159: return isVisible;
160: }
161:
162: /**
163: * See LayoutPart#dispose
164: */
165: public void dispose() {
166:
167: if (sash != null) {
168: bounds = sash.getBounds();
169: sash.dispose();
170: }
171: sash = null;
172: }
173:
174: /**
175: * Gets the presentation bounds.
176: */
177: public Rectangle getBounds() {
178: if (sash == null) {
179: return bounds;
180: }
181:
182: return sash.getBounds();
183: }
184:
185: /**
186: * Returns the part control.
187: */
188: public Control getControl() {
189: return sash;
190: }
191:
192: /**
193: *
194: */
195: public String getID() {
196: return null;
197: }
198:
199: LayoutPartSash getPostLimit() {
200: return postLimit;
201: }
202:
203: LayoutPartSash getPreLimit() {
204: return preLimit;
205: }
206:
207: int getLeft() {
208: return left;
209: }
210:
211: int getRight() {
212: return right;
213: }
214:
215: boolean isHorizontal() {
216: return ((style & SWT.HORIZONTAL) == SWT.HORIZONTAL);
217: }
218:
219: boolean isVertical() {
220: return ((style & SWT.VERTICAL) == SWT.VERTICAL);
221: }
222:
223: void setPostLimit(LayoutPartSash newPostLimit) {
224: postLimit = newPostLimit;
225: }
226:
227: void setPreLimit(LayoutPartSash newPreLimit) {
228: preLimit = newPreLimit;
229: }
230:
231: void setRatio(float newRatio) {
232: int total = left + right;
233: int newLeft = (int) (total * newRatio);
234: setSizes(newLeft, total - newLeft);
235: }
236:
237: void setSizes(int left, int right) {
238: if (left < 0 || right < 0) {
239: return;
240: }
241:
242: if (left == this .left && right == this .right) {
243: return;
244: }
245:
246: this .left = left;
247: this .right = right;
248:
249: flushCache();
250: }
251:
252: private void flushCache() {
253: LayoutTree root = rootContainer.getLayoutTree();
254:
255: if (root != null) {
256: LayoutTreeNode node = root.findSash(this );
257: if (node != null) {
258: node.flushCache();
259: }
260: }
261: }
262:
263: private void widgetSelected(int x, int y, int width, int height) {
264: if (!enabled) {
265: return;
266: }
267:
268: LayoutTree root = rootContainer.getLayoutTree();
269: LayoutTreeNode node = root.findSash(this );
270: Rectangle nodeBounds = node.getBounds();
271: //Recompute ratio
272: x -= nodeBounds.x;
273: y -= nodeBounds.y;
274: if (style == SWT.VERTICAL) {
275: setSizes(x, nodeBounds.width - x
276: - LayoutTreeNode.SASH_WIDTH);
277: } else {
278: setSizes(y, nodeBounds.height - y
279: - LayoutTreeNode.SASH_WIDTH);
280: }
281:
282: node.setBounds(nodeBounds);
283: }
284:
285: /**
286: * @param resizable
287: * @since 3.1
288: */
289: public void setEnabled(boolean resizable) {
290: this.enabled = resizable;
291: if (sash != null) {
292: sash.setEnabled(enabled);
293: }
294: }
295:
296: }
|