blob: 121376495c3edcf77beaa6a85fb62be920b217ff [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 2006 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
****************************************************************************/
package org.eclipse.gmf.runtime.diagram.ui.editpolicies;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartListener;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ResizableCompartmentEditPart;
import org.eclipse.gmf.runtime.diagram.ui.figures.BorderedNodeFigure;
import org.eclipse.gmf.runtime.diagram.ui.figures.ResizableCompartmentFigure;
import org.eclipse.gmf.runtime.diagram.ui.handles.CompartmentCollapseHandle;
import org.eclipse.gmf.runtime.diagram.ui.internal.handles.CompartmentResizeHandle;
/**
* A resizable editpolicy for resizable compartments. The editpolicy could be
* vertical or horizontal
*
* @author melaasar
*/
public class ResizableCompartmentEditPolicy
extends ResizableEditPolicyEx {
private boolean horizontal;
/**
* Creates a new vertical ResizableCompartmentEditPolicy
*/
public ResizableCompartmentEditPolicy() {
this(false);
}
/**
* creates a new ResizableCompartmentEditPolicy with the given orientation
*
* @param horizontal
*/
public ResizableCompartmentEditPolicy(boolean horizontal) {
this.horizontal = horizontal;
}
/**
* @return Whether the editpolicy is horizontal
*/
protected boolean isHorizontal() {
return horizontal;
}
/**
* This method is used to get the collapse handle(s). Subclasses can
* override to provide different collapse handles
*
* @return a list of collapse handles
*/
protected List createCollapseHandles() {
IGraphicalEditPart part = (IGraphicalEditPart) getHost();
List collapseHandles = new ArrayList();
collapseHandles.add(new CompartmentCollapseHandle(part));
return collapseHandles;
}
/**
* @see org.eclipse.gef.editpolicies.SelectionHandlesEditPolicy#createSelectionHandles()
*/
protected List createSelectionHandles() {
IGraphicalEditPart part = (IGraphicalEditPart) getHost();
int d1 = isHorizontal() ? PositionConstants.WEST
: PositionConstants.NORTH;
int d2 = isHorizontal() ? PositionConstants.EAST
: PositionConstants.SOUTH;
List selectionHandles = new ArrayList();
selectionHandles.addAll(createCollapseHandles());
selectionHandles.add(new CompartmentResizeHandle(part, d1));
selectionHandles.add(new CompartmentResizeHandle(part, d2));
return selectionHandles;
}
/**
* @return the <code>ResizableCompartmentFigure</code> that is the
* corresponding figure for the host edit part.
*/
private ResizableCompartmentFigure getCompartmentFigure() {
ResizableCompartmentFigure compartmentFigure = null;
if (getGraphicalEditPart() instanceof ResizableCompartmentEditPart) {
compartmentFigure = ((ResizableCompartmentEditPart) getGraphicalEditPart())
.getCompartmentFigure();
} else if (getGraphicalEditPart().getFigure() instanceof ResizableCompartmentFigure) {
compartmentFigure = (ResizableCompartmentFigure) getGraphicalEditPart()
.getFigure();
}
// TODO: remove later. this is a temporary fix for defect
// RATLC00522565
// eventually we will put the BorderedNodeFigure inside the resizable
// compartment
else if (getGraphicalEditPart().getFigure() instanceof BorderedNodeFigure) {
BorderedNodeFigure gpf = (BorderedNodeFigure) getGraphicalEditPart()
.getFigure();
IFigure f = gpf.getMainFigure();
if (f instanceof ResizableCompartmentFigure) {
compartmentFigure = (ResizableCompartmentFigure) f;
}
}
return compartmentFigure;
}
/**
* @see org.eclipse.gef.editpolicies.SelectionEditPolicy#showSelection()
*/
protected void showSelection() {
super.showSelection();
if (getHost().getSelected() != EditPart.SELECTED_NONE) {
ResizableCompartmentFigure compartmentFigure = getCompartmentFigure();
if (compartmentFigure != null) {
compartmentFigure.setSelected(true);
}
}
}
/**
* @see org.eclipse.gef.editpolicies.SelectionEditPolicy#hideSelection()
*/
protected void hideSelection() {
super.hideSelection();
if (getHost().getSelected() == EditPart.SELECTED_NONE) {
ResizableCompartmentFigure compartmentFigure = getCompartmentFigure();
if (compartmentFigure != null) {
compartmentFigure.setSelected(false);
}
}
}
/* (non-Javadoc)
* @see org.eclipse.gef.editpolicies.SelectionEditPolicy#activate()
*/
public void activate() {
super.activate();
if (getHost().getParent().getSelected() != EditPart.SELECTED_NONE)
setSelectedState();
}
private EditPartListener hostListener;
private EditPartListener parentListener;
/**
* @see org.eclipse.gef.editpolicies.SelectionEditPolicy#addSelectionListener()
*/
protected void addSelectionListener() {
hostListener = new EditPartListener.Stub() {
public void selectedStateChanged(EditPart part) {
setSelectedState();
setFocus(part.hasFocus());
}
};
getHost().addEditPartListener(hostListener);
parentListener = new EditPartListener.Stub() {
public void selectedStateChanged(EditPart part) {
setSelectedState();
}
};
getParentGraphicEditPart().addEditPartListener(parentListener);
}
/**
* @see org.eclipse.gef.editpolicies.SelectionEditPolicy#removeSelectionListener()
*/
protected void removeSelectionListener() {
getHost().removeEditPartListener(hostListener);
getParentGraphicEditPart().removeEditPartListener(parentListener);
}
/**
* Determine the select state of the policy based on: 1- The select state of
* the compartment editpart 2- The select state of the parent graphic
* editpart 3- The visibility state of the compartment editpart
*/
protected void setSelectedState() {
int hostState = getHost().getSelected();
int topState = EditPart.SELECTED_NONE;
if (getGraphicalEditPart().getTopGraphicEditPart() != null) {
topState = getGraphicalEditPart().getTopGraphicEditPart().getSelected();
}
boolean vis = getGraphicalEditPart().getNotationView().isVisible();
if (vis
&& ((hostState != EditPart.SELECTED_NONE || topState != EditPart.SELECTED_NONE)))
setSelectedState(EditPart.SELECTED);
else
setSelectedState(EditPart.SELECTED_NONE);
}
private IGraphicalEditPart getParentGraphicEditPart() {
return (IGraphicalEditPart) getGraphicalEditPart().getParent();
}
private IGraphicalEditPart getGraphicalEditPart() {
return (IGraphicalEditPart) getHost();
}
/**
* @see org.eclipse.gef.editpolicies.NonResizableEditPolicy#showChangeBoundsFeedback(org.eclipse.gef.requests.ChangeBoundsRequest)
*/
protected void showChangeBoundsFeedback(ChangeBoundsRequest request) {
super.showChangeBoundsFeedback(getResizeChildrenRequest(request));
}
/**
* @see org.eclipse.gef.editpolicies.ResizableEditPolicy#getResizeCommand(org.eclipse.gef.requests.ChangeBoundsRequest)
*/
protected Command getResizeCommand(ChangeBoundsRequest request) {
return getHost().getParent().getCommand(
getResizeChildrenRequest(request));
}
/**
* Creates a new ChangeBoundsRequest that respects the min and max of the
* resize deltas
*/
private ChangeBoundsRequest getResizeChildrenRequest(ChangeBoundsRequest r) {
Dimension delta = r.getSizeDelta();
ResizableCompartmentFigure f = getCompartmentFigure();
Dimension fd = f.getSize().getExpanded(delta);
fd.intersect(f.getMaximumSize()).union(f.getMinimumSize());
delta = fd.shrink(f.getSize().width, f.getSize().height);
boolean moved = (r.getResizeDirection() & PositionConstants.NORTH_WEST) != 0;
IFigure a = f.getAdjacentSibling(moved);
if (a != null) {
Dimension ad = a.getSize().getExpanded(delta.negate());
ad.intersect(a.getMaximumSize()).union(a.getMinimumSize());
delta = ad.shrink(a.getSize().width, a.getSize().height).negate();
} else {
delta.shrink(delta.width, delta.height);
}
ChangeBoundsRequest req = new ChangeBoundsRequest(REQ_RESIZE_CHILDREN);
req.setEditParts(getHost());
req.setLocation(r.getLocation());
req.setResizeDirection(r.getResizeDirection());
req.setSizeDelta(delta);
if (moved)
req.setMoveDelta(new Point(-delta.width, -delta.height));
return req;
}
}