blob: 59b265015cea45e63304d5d65edde19921158e80 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2005, 2008 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.editparts;
import java.util.Collections;
import java.util.List;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.ExposeHelper;
import org.eclipse.gef.editparts.ViewportExposeHelper;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ResizableCompartmentEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.figures.ResizableCompartmentFigure;
import org.eclipse.gmf.runtime.diagram.ui.internal.figures.NestedResizableCompartmentFigure;
import org.eclipse.gmf.runtime.diagram.ui.internal.properties.Properties;
import org.eclipse.gmf.runtime.draw2d.ui.figures.ConstrainedToolbarLayout;
import org.eclipse.gmf.runtime.draw2d.ui.figures.WrapLabel;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
import org.eclipse.gmf.runtime.notation.DrawerStyle;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.Ratio;
import org.eclipse.gmf.runtime.notation.Style;
import org.eclipse.gmf.runtime.notation.View;
/**
* Extends ListItemEditPart to support nesting of list compartments. This edit
* part supports a TextCompartmentView that contains children. Should be used if
* you have a TextCompartment that contains other children such as a list
* compartment.
*
* @author choang
*
*/
public class NestableListItemEditPart
extends ListItemEditPart
implements IResizableCompartmentEditPart {
final static int IS_RESIZABLE_FLAG = MAX_FLAG << 5;
/**
* @param view
*/
public NestableListItemEditPart(EObject view) {
super(view);
setFlag(IS_RESIZABLE_FLAG, false);
Object model = basicGetModel();
if (model instanceof Node) {
Node node = (Node) model;
Style style = node.getStyle(NotationPackage.Literals
.DRAWER_STYLE);
if (style != null)
setFlag(IS_RESIZABLE_FLAG, true);
}
}
WrapLabel textLabel = null;
/**
* @return Returns the textLabel.
*/
public WrapLabel getLabel() {
if (isResizable()) {
if (textLabel == null) {
textLabel = createWrapLabel();
}
return textLabel;
} else {
return super.getLabel();
}
}
/**
* The main label figure for this editpart (that is, the only label figure
* if this is a regular list item or the header label of the nested list
* items if this is a nestable list item. Clients may override to create
* other label types.
*
* @return the main label figure
*/
protected IFigure getMainLabel() {
return getLabel();
}
/*
* (non-Javadoc)
* @see org.eclipse.gmf.runtime.diagram.ui.editparts.IResizableCompartmentEditPart#getCompartmentName()
*/
public String getCompartmentName() {
return getLabelDelegate().getText();
}
/**
* Override to create a figure that will create a figure that contains a
* text compartment and a pane to store the child figures of the text
* compartment.
*/
protected IFigure createFigure() {
if (isResizable()) {
IMapMode mm = getMapMode();
ResizableCompartmentFigure compartmentFigure = new NestedResizableCompartmentFigure(mm);
ConstrainedToolbarLayout layout = new ConstrainedToolbarLayout();
layout.setStretchMajorAxis(false);
layout.setStretchMinorAxis(false);
layout.setMinorAlignment(ConstrainedToolbarLayout.ALIGN_TOPLEFT);
compartmentFigure.getContentPane().setLayoutManager(layout);
compartmentFigure.getTextPane().add(getMainLabel());
// if the compartment is resizeable then we need to put a border
// around the text compartment so that we have enough room for the
// collpase handle.
int one = mm.DPtoLP(1);
int half_15 = mm.DPtoLP(15) / 2;
// indent to make room for collapse handle for each nested list item
compartmentFigure.getTextPane().setBorder(
new MarginBorder(one, half_15, one, half_15));
// indent for visual appearance
compartmentFigure.getContentPane().setBorder(
new MarginBorder(one, mm.DPtoLP(15), one, half_15));
getMainLabel().setVisible(true);
return compartmentFigure;
} else {
return super.createFigure();
}
}
/**
* Adds additional edit policy EditPolicy.PRIMARY_DRAG_ROLE to provide
* collapsiblity for list compartments
*/
protected void createDefaultEditPolicies() {
super.createDefaultEditPolicies();
if (isResizable()) {
installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE,
new ResizableCompartmentEditPolicy());
}
}
/**
* This edit part can support either being ListItemListCompartmentEditPart
* or ListItemListCompartmentEditPart that is nested with children and hence
* is resizable. This helper method will help us determine which behavior we
* want.
*
* @return true iff the TextCompartment is mean to support children.
*/
final protected boolean isResizable() {
return getFlag(IS_RESIZABLE_FLAG);
}
/*
* @return getView()).getChildren() this editpart supports having children.
*/
protected List getModelChildren() {
if (getModel() instanceof View) {
return ((View) getModel()).getChildren();
}
return Collections.EMPTY_LIST;
}
/**
* This method helps in children navigation by scrolling the compartment
* until the child is visible in the viewport
*/
public Object getAdapter(Class key) {
if (key == ExposeHelper.class) {
ViewportExposeHelper helper = new ViewportExposeHelper(this);
return helper;
}
return super.getAdapter(key);
}
protected void refreshVisuals() {
super.refreshVisuals();
if (isResizable()) {
refreshCollapsed();
refreshRatio();
}
}
/**
* @return The compartment's figure if isResizable() else return null;
*/
private ResizableCompartmentFigure getCompartmentFigure() {
if (isResizable()) {
return (ResizableCompartmentFigure) getFigure();
} else {
return null;
}
}
public IFigure getContentPane() {
if (getCompartmentFigure() != null) {
return getCompartmentFigure().getContentPane();
} else {
return super.getContentPane();
}
}
/**
* Handles the following properties: <BR>
* <UL>
* <LI>{@link Properties#ID_RATIO} calls {@link #refreshRatio()}
* <LI>{@link Properties#ID_COLLAPSED} calls {@link #refreshCollapsed()}
* <UL>
* <BR>
* All other properties are forwarded to the parent class for processing.
*
* @param evt
* a property change event.
* @see org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart#handlePropertyChangeEvent(java.beans.PropertyChangeEvent)
*/
protected void handleNotificationEvent(Notification evt) {
Object feature = evt.getFeature();
if (NotationPackage.Literals.RATIO__VALUE.equals(feature)
|| evt.getOldValue() instanceof Ratio
|| evt.getNewValue() instanceof Ratio)
refreshRatio();
else if (NotationPackage.Literals.DRAWER_STYLE__COLLAPSED.equals(
feature)) {
setCollapsed(((Boolean) evt.getNewValue()).booleanValue(), true);
this.getFigure().revalidate();
} else
super.handleNotificationEvent(evt);
}
/**
* Refreshes the compartment ratio property
*/
protected void refreshRatio() {
if (ViewUtil
.isPropertySupported((View) getModel(), Properties.ID_RATIO))
setRatio((Double) ViewUtil.getStructuralFeatureValue(
(View) getModel(), NotationPackage.Literals.RATIO__VALUE));
else
setRatio(new Double(-1));
}
/**
* Refreshes the compartment collapse state
*/
protected void refreshCollapsed() {
DrawerStyle style = (DrawerStyle) ((View) getModel())
.getStyle(NotationPackage.Literals.DRAWER_STYLE);
if (style != null)
setCollapsed(style.isCollapsed(), false);
}
/**
* Sets the collapse state of the compartment figure, considering the passed
* animate flag while doing so
*
* @param collapsed
* the collapsed state
* @param animate
* the animate flag
*/
protected void setCollapsed(boolean collapsed, boolean animate) {
if (getCompartmentFigure() != null) {
if (collapsed) {
if (animate)
getCompartmentFigure().collapse();
else
getCompartmentFigure().setCollapsed();
} else {
if (animate)
getCompartmentFigure().expand();
else
getCompartmentFigure().setExpanded();
}
}
}
/**
* Sets the ratio of the resizable compartment
*
* @param ratio
*/
protected void setRatio(Double ratio) {
((IGraphicalEditPart) getParent()).setLayoutConstraint(this,
getFigure(), ratio);
}
/**
* Sets the visibility of the compartment title
*
* @param showCompartmentTitle
*/
protected void setShowCompartmentTitle(boolean showCompartmentTitle) {
if (getCompartmentFigure() != null)
getCompartmentFigure().setTitleVisibility(showCompartmentTitle);
}
}