| /******************************************************************************* |
| * Copyright (c) 2000, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Randy Hudson <hudsonr@us.ibm.com> |
| * - Fix for bug 19524 - Resizing WorkbenchWindow resizes views |
| * Cagatay Kavukcuoglu <cagatayk@acm.org> |
| * - Fix for bug 10025 - Resizing views should not use height ratios |
| *******************************************************************************/ |
| package org.eclipse.ui.internal; |
| |
| import org.eclipse.jface.util.Geometry; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Sash; |
| |
| class LayoutPartSash extends LayoutPart { |
| |
| private Sash sash; |
| private boolean enabled = false; |
| |
| private PartSashContainer rootContainer; |
| |
| private int style; |
| |
| private LayoutPartSash preLimit; |
| |
| private LayoutPartSash postLimit; |
| |
| SelectionListener selectionListener; |
| |
| private int left = 300, right = 300; |
| |
| private Rectangle bounds = new Rectangle(0,0,0,0); |
| |
| /** |
| * Stores whether or not the sash is visible. (This is expected to have a meaningful |
| * value even if the underlying control doesn't exist). |
| */ |
| private boolean isVisible; |
| |
| LayoutPartSash(PartSashContainer rootContainer, int style) { |
| super(null); |
| this.style = style; |
| this.rootContainer = rootContainer; |
| |
| selectionListener = new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| checkDragLimit(e); |
| |
| if (e.detail != SWT.DRAG) { |
| LayoutPartSash.this.widgetSelected(e.x, e.y, e.width, |
| e.height); |
| } |
| } |
| }; |
| } |
| |
| // checkDragLimit contains changes by cagatayk@acm.org |
| private void checkDragLimit(SelectionEvent event) { |
| LayoutTree root = rootContainer.getLayoutTree(); |
| LayoutTreeNode node = root.findSash(this); |
| Rectangle nodeBounds = node.getBounds(); |
| Rectangle eventRect = new Rectangle(event.x, event.y, event.width, event.height); |
| |
| boolean vertical = (style == SWT.VERTICAL); |
| |
| // If a horizontal sash, flip the coordinate system so that we |
| // can handle horizontal and vertical sashes without special cases |
| if (!vertical) { |
| Geometry.flipXY(nodeBounds); |
| Geometry.flipXY(eventRect); |
| } |
| |
| int eventX = eventRect.x; |
| int left = Math.max(0, eventX - nodeBounds.x); |
| left = Math.min(left, nodeBounds.width - LayoutTreeNode.SASH_WIDTH); |
| int right = nodeBounds.width - left - LayoutTreeNode.SASH_WIDTH; |
| |
| LayoutTreeNode.ChildSizes sizes = node.computeChildSizes(nodeBounds.width, nodeBounds.height, left, right, nodeBounds.width); |
| |
| eventRect.x = nodeBounds.x + sizes.left; |
| |
| // If it's a horizontal sash, restore eventRect to its original coordinate system |
| if (!vertical) { |
| Geometry.flipXY(eventRect); |
| } |
| |
| event.x = eventRect.x; |
| event.y = eventRect.y; |
| } |
| |
| /** |
| * Creates the control. As an optimization, creation of the control is deferred if |
| * the control is invisible. |
| */ |
| public void createControl(Composite parent) { |
| // Defer creation of the control until it becomes visible |
| if (isVisible) { |
| doCreateControl(); |
| } |
| } |
| |
| /** |
| * Creates the underlying SWT control. |
| * |
| * @since 3.1 |
| */ |
| private void doCreateControl() { |
| if (sash == null) { |
| sash = new Sash(this.rootContainer.getParent(), style | SWT.SMOOTH); |
| sash.addSelectionListener(selectionListener); |
| sash.setEnabled(enabled); |
| sash.setBounds(bounds); |
| } |
| } |
| |
| public void setBounds(Rectangle r) { |
| super.setBounds(r); |
| |
| bounds = r; |
| } |
| |
| /** |
| * Makes the sash visible or invisible. Note: as an optimization, the actual widget is destroyed when the |
| * sash is invisible. |
| */ |
| public void setVisible(boolean visible) { |
| if (visible == isVisible) { |
| return; |
| } |
| |
| if (visible) { |
| doCreateControl(); |
| } else { |
| dispose(); |
| } |
| |
| super.setVisible(visible); |
| |
| isVisible = visible; |
| } |
| |
| public boolean isVisible() { |
| return isVisible; |
| } |
| |
| /** |
| * See LayoutPart#dispose |
| */ |
| public void dispose() { |
| |
| if (sash != null) { |
| bounds = sash.getBounds(); |
| sash.dispose(); |
| } |
| sash = null; |
| } |
| |
| /** |
| * Gets the presentation bounds. |
| */ |
| public Rectangle getBounds() { |
| if (sash == null) { |
| return bounds; |
| } |
| |
| return sash.getBounds(); |
| } |
| |
| /** |
| * Returns the part control. |
| */ |
| public Control getControl() { |
| return sash; |
| } |
| |
| /** |
| * |
| */ |
| public String getID() { |
| return null; |
| } |
| |
| LayoutPartSash getPostLimit() { |
| return postLimit; |
| } |
| |
| LayoutPartSash getPreLimit() { |
| return preLimit; |
| } |
| |
| int getLeft() { |
| return left; |
| } |
| |
| int getRight() { |
| return right; |
| } |
| |
| boolean isHorizontal() { |
| return ((style & SWT.HORIZONTAL) == SWT.HORIZONTAL); |
| } |
| |
| boolean isVertical() { |
| return ((style & SWT.VERTICAL) == SWT.VERTICAL); |
| } |
| |
| void setPostLimit(LayoutPartSash newPostLimit) { |
| postLimit = newPostLimit; |
| } |
| |
| void setPreLimit(LayoutPartSash newPreLimit) { |
| preLimit = newPreLimit; |
| } |
| |
| void setRatio(float newRatio) { |
| int total = left + right; |
| int newLeft = (int) (total * newRatio); |
| setSizes(newLeft, total - newLeft); |
| } |
| |
| void setSizes(int left, int right) { |
| if (left < 0 || right < 0) { |
| return; |
| } |
| |
| if (left == this.left && right == this.right) { |
| return; |
| } |
| |
| this.left = left; |
| this.right = right; |
| |
| flushCache(); |
| } |
| |
| private void flushCache() { |
| LayoutTree root = rootContainer.getLayoutTree(); |
| |
| if (root != null) { |
| LayoutTreeNode node = root.findSash(this); |
| if (node != null) { |
| node.flushCache(); |
| } |
| } |
| } |
| |
| private void widgetSelected(int x, int y, int width, int height) { |
| if (!enabled) { |
| return; |
| } |
| |
| LayoutTree root = rootContainer.getLayoutTree(); |
| LayoutTreeNode node = root.findSash(this); |
| Rectangle nodeBounds = node.getBounds(); |
| //Recompute ratio |
| x -= nodeBounds.x; |
| y -= nodeBounds.y; |
| if (style == SWT.VERTICAL) { |
| setSizes(x, nodeBounds.width - x - LayoutTreeNode.SASH_WIDTH); |
| } else { |
| setSizes(y, nodeBounds.height - y - LayoutTreeNode.SASH_WIDTH); |
| } |
| |
| node.setBounds(nodeBounds); |
| } |
| |
| /** |
| * @param resizable |
| * @since 3.1 |
| */ |
| public void setEnabled(boolean resizable) { |
| this.enabled = resizable; |
| if (sash != null) { |
| sash.setEnabled(enabled); |
| } |
| } |
| |
| } |