blob: 3b14edb89f12ebe36b54858c464703db28a6d83d [file] [log] [blame]
/*******************************************************************************
* 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);
}
}
}