| /****************************************************************************** |
| * 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); |
| } |
| |
| } |