/**
* Copyright (c) 2008, 2009 Borland Software Corp.
*
* 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:
* Alexander Shatalin (Borland) - initial API and implementation
*/
package org.eclipse.gmf.graphdef.editor.edit.policies;
import java.util.Collections;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
import org.eclipse.gmf.gmfgraph.Alignment;
import org.eclipse.gmf.gmfgraph.BorderLayout;
import org.eclipse.gmf.gmfgraph.BorderLayoutData;
import org.eclipse.gmf.gmfgraph.Dimension;
import org.eclipse.gmf.gmfgraph.Figure;
import org.eclipse.gmf.gmfgraph.FlowLayout;
import org.eclipse.gmf.gmfgraph.GMFGraphFactory;
import org.eclipse.gmf.gmfgraph.GridLayout;
import org.eclipse.gmf.gmfgraph.Layout;
import org.eclipse.gmf.gmfgraph.Layoutable;
import org.eclipse.gmf.gmfgraph.StackLayout;
import org.eclipse.gmf.gmfgraph.XYLayout;
import org.eclipse.gmf.gmfgraph.XYLayoutData;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.notation.View;
public class FigureContainerXYLayoutEditPolicy extends AbstractDomainBasedXYLayoutEditPolicy {
public FigureContainerXYLayoutEditPolicy(IMapMode mapMode) {
super(mapMode);
}
@Override
protected ICommand createSetBoundsCommand(TransactionalEditingDomain editingDomain, String label, Resource resource, Rectangle bounds, EObject element) {
if (element instanceof Figure) {
Figure figure = (Figure) element;
return new SetBoundsCommand(editingDomain, label, resource, bounds, figure, getMainFigureLayout());
}
return null;
}
@Override
protected ICommand createSetBoundsCommand(TransactionalEditingDomain editingDomain, String label, Resource resource, ViewDescriptor viewDescriptor, Rectangle rect) {
return new SetBoundsCommand(editingDomain, label, resource, viewDescriptor, rect, getMainFigureLayout());
}
private Layout getMainFigureLayout() {
if (getHost().getModel() instanceof View) {
EObject domainModelElement = ((View) getHost().getModel()).getElement();
if (domainModelElement instanceof Layoutable) {
return ((Layoutable) domainModelElement).getLayout();
}
}
return null;
}
private final class SetBoundsCommand extends AbstractTransactionalCommand {
private Rectangle myBounds;
private Figure myFigure;
private IAdaptable myAdaptable;
private Layout myParentFigureLayout;
protected SetBoundsCommand(TransactionalEditingDomain domain, String label, Resource resource, Rectangle bounds, Figure figure, Layout parentFigureLayout) {
super(domain, label, Collections.singletonList(WorkspaceSynchronizer.getFile(resource)));
myBounds = bounds;
myFigure = figure;
myParentFigureLayout = parentFigureLayout;
}
protected SetBoundsCommand(TransactionalEditingDomain domain, String label, Resource resource, IAdaptable adaptable, Rectangle bounds, Layout parentFigureLayout) {
super(domain, label, Collections.singletonList(WorkspaceSynchronizer.getFile(resource)));
myBounds = bounds;
myAdaptable = adaptable;
myParentFigureLayout = parentFigureLayout;
}
private Figure getFigure() {
if (myFigure != null) {
return myFigure;
}
View view = (View) myAdaptable.getAdapter(View.class);
return (Figure) view.getElement();
}
@Override
protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
int x = getMapMode().LPtoDP(myBounds.x);
int y = getMapMode().LPtoDP(myBounds.y);
int width = getMapMode().LPtoDP(myBounds.width);
int height = getMapMode().LPtoDP(myBounds.height);
if (myParentFigureLayout instanceof XYLayout) {
setXYLayoutBounds(x, y, width, height, getFigure());
} else if (myParentFigureLayout instanceof BorderLayout) {
setBorderLayoutBounds(x, y, width, height, getFigure());
} else if (myParentFigureLayout instanceof FlowLayout) {
setFlowLayoutBounds(x, y, width, height, getFigure());
} else if (myParentFigureLayout instanceof GridLayout) {
setGridLayoutBounds(x, y, width, height, getFigure());
} else if (myParentFigureLayout instanceof StackLayout) {
// Nothing to do here
} else {
setNoLayoutBounds(x, y, width, height, getFigure());
}
return CommandResult.newOKCommandResult();
}
private void setNoLayoutBounds(int x, int y, int width, int height, Figure figure) {
setLocation(x, y, figure);
setPreferredSize(width, height, figure);
}
private void setLocation(int x, int y, Figure figure) {
org.eclipse.gmf.gmfgraph.Point location = figure.getLocation() != null ? figure.getLocation() : GMFGraphFactory.eINSTANCE.createPoint();
location.setX(x);
location.setY(y);
if (figure.getLocation() == null) {
figure.setLocation(location);
}
}
private void setPreferredSize(int width, int height, Figure figure) {
Dimension preferredSize = figure.getPreferredSize() != null ? figure.getPreferredSize() : GMFGraphFactory.eINSTANCE.createDimension();
preferredSize.setDx(width);
preferredSize.setDy(height);
if (figure.getPreferredSize() == null) {
figure.setPreferredSize(preferredSize);
}
}
private void setGridLayoutBounds(int x, int y, int width, int height, Figure figure) {
setPreferredSize(width, height, figure);
}
private void setFlowLayoutBounds(int x, int y, int width, int height, Figure figure) {
setPreferredSize(width, height, figure);
}
private void setBorderLayoutBounds(int x, int y, int width, int height, Figure figure) {
if (false == figure.getLayoutData() instanceof BorderLayoutData) {
BorderLayoutData layoutData = GMFGraphFactory.eINSTANCE.createBorderLayoutData();
layoutData.setAlignment(Alignment.BEGINNING_LITERAL);
figure.setLayoutData(layoutData);
}
BorderLayoutData borderLayoutData = (BorderLayoutData) figure.getLayoutData();
if (borderLayoutData.getAlignment() == Alignment.CENTER_LITERAL) {
return;
}
Dimension preferredSize = figure.getPreferredSize() != null ? figure.getPreferredSize() : GMFGraphFactory.eINSTANCE.createDimension();
if (borderLayoutData.isVertical()) {
preferredSize.setDy(height);
} else {
preferredSize.setDx(width);
}
if (figure.getPreferredSize() == null) {
figure.setPreferredSize(preferredSize);
}
}
private void setXYLayoutBounds(int x, int y, int width, int height, Figure figure) {
// TODO: add -1 as a possible value to XYLayoutData property sheet -
// > then preferred size should be used.
// setPreferredSize(width, height, figure);
XYLayoutData xyLayoutData = figure.getLayoutData() instanceof XYLayoutData ? (XYLayoutData) figure.getLayoutData() : createXYLayoutData();
xyLayoutData.getTopLeft().setX(x);
xyLayoutData.getTopLeft().setY(y);
xyLayoutData.getSize().setDx(width);
xyLayoutData.getSize().setDy(height);
if (false == figure.getLayoutData() instanceof XYLayoutData) {
figure.setLayoutData(xyLayoutData);
}
}
private XYLayoutData createXYLayoutData() {
XYLayoutData layoutData = GMFGraphFactory.eINSTANCE.createXYLayoutData();
layoutData.setTopLeft(GMFGraphFactory.eINSTANCE.createPoint());
layoutData.setSize(GMFGraphFactory.eINSTANCE.createDimension());
return layoutData;
}
}
}