blob: 501badb1d981f9c13e5acb19cf7b050dc65318fb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
* Soyatec - initial API and implementation
*******************************************************************************/
package org.eclipse.xwt.tools.ui.designer.policies.layout;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.draw2d.FigureListener;
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.draw2d.geometry.Rectangle;
import org.eclipse.xwt.tools.ui.palette.Entry;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartListener;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gef.editpolicies.LayoutEditPolicy;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gef.requests.DropRequest;
import org.eclipse.gef.requests.ForwardedRequest;
import org.eclipse.gef.requests.GroupRequest;
import org.eclipse.swt.widgets.Display;
import org.eclipse.xwt.tools.ui.designer.commands.GridLayoutCommandsFactory;
import org.eclipse.xwt.tools.ui.designer.commands.NoOpCommand;
import org.eclipse.xwt.tools.ui.designer.editor.palette.CreateReqHelper;
import org.eclipse.xwt.tools.ui.designer.editor.palette.EntryHelper;
import org.eclipse.xwt.tools.ui.designer.layouts.LayoutType;
import org.eclipse.xwt.tools.ui.designer.parts.CompositeEditPart;
import org.eclipse.xwt.tools.ui.designer.parts.MenuBarEditPart;
import org.eclipse.xwt.tools.ui.designer.policies.NewNonResizeEditPolicy;
import org.eclipse.xwt.tools.ui.designer.policies.NewResizableEditPolicy;
import org.eclipse.xwt.tools.ui.designer.policies.feedback.FeedbackHelper;
import org.eclipse.xwt.tools.ui.designer.policies.feedback.FeedbackManager;
import org.eclipse.xwt.tools.ui.designer.policies.layout.grid.GridController;
import org.eclipse.xwt.tools.ui.designer.policies.layout.grid.GridLayoutAddedCellFeedbackFigure;
import org.eclipse.xwt.tools.ui.designer.policies.layout.grid.GridLayoutColumnFigure;
import org.eclipse.xwt.tools.ui.designer.policies.layout.grid.GridLayoutFeedbackFigure;
import org.eclipse.xwt.tools.ui.designer.policies.layout.grid.GridLayoutGridFigure;
import org.eclipse.xwt.tools.ui.designer.policies.layout.grid.GridLayoutPolicyHelper;
import org.eclipse.xwt.tools.ui.designer.policies.layout.grid.GridLayoutRequest;
import org.eclipse.xwt.tools.ui.designer.policies.layout.grid.GridLayoutRowFigure;
import org.eclipse.xwt.tools.ui.designer.policies.layout.grid.GridLayoutSpanFeedbackFigure;
import org.eclipse.xwt.tools.ui.designer.policies.layout.grid.GridSpanHandle;
import org.eclipse.xwt.tools.ui.designer.policies.layout.grid.IGridListener;
import org.eclipse.xwt.tools.ui.xaml.XamlNode;
/**
* @author jliu jin.liu@soyatec.com
*/
public class GridLayoutEditPolicy extends LayoutEditPolicy implements
IGridListener, ILayoutEditPolicy {
public static final String REQ_GRIDLAYOUT_SPAN = "GridLayout span cells"; //$NON-NLS-1$
public static final int DEFAULT_CELL_WIDTH = 40;
public static final int DEFAULT_CELL_HEIGHT = 35;
private static final int ADDEDCELLBORDER = 3; // How much to expand cell for
// added cell to draw the
// new border.
private GridController gridController;
private boolean fShowGrid = false;
private GridLayoutGridFigure fGridLayoutGridFigure;
private GridLayoutSpanFeedbackFigure fGridLayoutSpanFigure;
private GridLayoutFeedbackFigure fGridLayoutCellFigure;
private IFigure fRowColFigure = null;
private EditPartListener editPartListener;
private GridLayoutPolicyHelper helper = new GridLayoutPolicyHelper();
private FeedbackManager fbm = new FeedbackManager(this);
protected FigureListener hostFigureListener = new FigureListener() {
public void figureMoved(IFigure source) {
refresh();
}
};
/*
* (non-Javadoc)
*
* @see org.eclipse.gef.editpolicies.LayoutEditPolicy#activate()
*/
public void activate() {
helper.setHost((CompositeEditPart) getHost());
gridController = new GridController();
GridController.registerEditPart(getHost(), gridController);
gridController.addGridListener(this);
getHostFigure().addFigureListener(hostFigureListener);
if (getHost().getSelected() == EditPart.SELECTED
|| getHost().getSelected() == EditPart.SELECTED_PRIMARY) {
gridController.setGridShowing(true);
}
editPartListener = createEditPartListener();
getHost().addEditPartListener(editPartListener);
List children = getHost().getChildren();
Iterator iterator = children.iterator();
while (iterator.hasNext())
((EditPart) iterator.next()).addEditPartListener(editPartListener);
super.activate();
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.gef.editpolicies.LayoutEditPolicy#createChildEditPolicy(org
* .eclipse.gef.EditPart)
*/
protected EditPolicy createChildEditPolicy(EditPart child) {
if (child instanceof MenuBarEditPart) {
return new NewNonResizeEditPolicy(false);
}
// return new NonResizableSpannableEditPolicy(this);
return new NewResizableEditPolicy(PositionConstants.SOUTH
| PositionConstants.EAST, true);
}
private EditPartListener createEditPartListener() {
return new EditPartListener.Stub() {
public void childAdded(EditPart editpart, int index) {
if (editPartListener != null)
editpart.addEditPartListener(editPartListener);
helper.refresh();
refreshGridFigure();
}
public void removingChild(EditPart editpart, int index) {
if (editPartListener != null)
editpart.removeEditPartListener(editPartListener);
helper.refresh();
refreshGridFigure();
}
public void selectedStateChanged(EditPart editpart) {
if ((editpart == null)
|| (editpart == getHost())
|| (isChildEditPart(editpart))
&& (editpart.getSelected() == EditPart.SELECTED || editpart
.getSelected() == EditPart.SELECTED_PRIMARY)) {
if (gridController != null) {
gridController.setGridShowing(true);
} else {
if (gridController != null)
gridController.setGridShowing(false);
}
} else {
// Hide the grid just in case we were show before and
// changed the prefs
if (gridController != null
&& gridController.isGridShowing())
gridController.setGridShowing(false);
}
}
};
}
private GridLayoutRequest createGridLayoutRequest(Point position) {
return getGridLayoutGridFigure().getGridLayoutRequest(position, helper);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.gef.editpolicies.LayoutEditPolicy#deactivate()
*/
public void deactivate() {
GridController gridController = GridController
.getGridController(getHost());
eraseGridFigure();
if (gridController != null) {
gridController.removeGridListener(this);
GridController.unregisterEditPart(getHost());
}
getHostFigure().removeFigureListener(hostFigureListener);
if (editPartListener != null) {
getHost().removeEditPartListener(editPartListener);
List children = getHost().getChildren();
Iterator iterator = children.iterator();
while (iterator.hasNext())
((EditPart) iterator.next())
.removeEditPartListener(editPartListener);
editPartListener = null;
}
super.deactivate();
}
/**
* erase grid figure.
*/
private void eraseGridFigure() {
if (fGridLayoutGridFigure != null) {
if (fGridLayoutGridFigure.getParent() != null)
removeFeedback(fGridLayoutGridFigure);
fGridLayoutGridFigure = null;
}
fShowGrid = false;
}
public void eraseTargetFeedback(Request request) {
fbm.eraseFeedback(request);
if (!fShowGrid)
if (fGridLayoutGridFigure != null) {
if (fGridLayoutGridFigure.getParent() != null)
removeFeedback(fGridLayoutGridFigure);
fGridLayoutGridFigure = null;
}
if (fGridLayoutSpanFigure != null) {
removeFeedback(fGridLayoutSpanFigure);
fGridLayoutSpanFigure = null;
}
if (fGridLayoutCellFigure != null) {
removeFeedback(fGridLayoutCellFigure);
fGridLayoutCellFigure = null;
}
if (fRowColFigure != null) {
removeFeedback(fRowColFigure);
fRowColFigure = null;
}
super.eraseTargetFeedback(request);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.gef.editpolicies.LayoutEditPolicy#getCommand(org.eclipse.
* gef.Request)
*/
public Command getCommand(Request request) {
// if (REQ_GRIDLAYOUT_SPAN.equals(request.getType())) {
// return getSpanChildrenCommand(request);
// }
if (REQ_RESIZE_CHILDREN.equals(request.getType())) {
return getResizeCommand(request);
}
return super.getCommand(request);
}
private Command getResizeCommand(Request request) {
ChangeBoundsRequest req = (ChangeBoundsRequest) request;
CompoundCommand resize = new CompoundCommand();
Command c;
GraphicalEditPart child;
List children = req.getEditParts();
for (int i = 0; i < children.size(); i++) {
child = (GraphicalEditPart) children.get(i);
c = createResizeChildrenCommand(request, child, req.getSizeDelta());
resize.add(c);
}
return resize.unwrap();
}
protected Command createResizeChildrenCommand(Request request,
EditPart child, Object newSize) {
GridLayoutCommandsFactory factory = new GridLayoutCommandsFactory(
(CompositeEditPart) getHost());
return factory.getResizeChildrenCommand(child,
(ChangeBoundsRequest) request);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.gef.editpolicies.LayoutEditPolicy#getAddCommand(org.eclipse
* .gef.Request)
*/
protected Command getAddCommand(Request request) {
return getMoveChildrenCommand(request);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.gef.editpolicies.LayoutEditPolicy#getCreateCommand(org.eclipse
* .gef.requests.CreateRequest)
*/
protected Command getCreateCommand(CreateRequest request) {
CreateReqHelper reqHelper = new CreateReqHelper(request);
if (!reqHelper.canCreate(getHost())) {
return null;
}
if (fGridLayoutGridFigure == null) {
// TODO: Maybe create layout here.
return UnexecutableCommand.INSTANCE;
}
Point position = getLocationFromRequest(request).getCopy();
GridLayoutRequest gridReq = createGridLayoutRequest(position);
Point cell = new Point(gridReq.column, gridReq.row);
Entry entry = (Entry) request.getNewObject();
XamlNode newObject = EntryHelper.getNode(entry);
if (newObject == null) {
return UnexecutableCommand.INSTANCE;
}
Object requestType = request.getType();
helper.startRequest();
switch (gridReq.type) {
case GridLayoutRequest.REPLACE_FILLER:
helper.replaceFiller(newObject, requestType, cell);
break;
case GridLayoutRequest.INSERT_COLUMN_WITHIN_ROW:
helper.insertColWithinRow(cell);
helper.replaceFillerOrEmpty(newObject, requestType, cell);
break;
case GridLayoutRequest.INSERT_COLUMN:
case GridLayoutRequest.ADD_COLUMN:
helper.createNewCol(cell.x);
helper.replaceFillerOrEmpty(newObject, requestType, cell);
break;
case GridLayoutRequest.INSERT_ROW:
case GridLayoutRequest.ADD_ROW:
helper.createNewRow(cell.y);
helper.replaceFillerOrEmpty(newObject, requestType, cell);
break;
case GridLayoutRequest.ADD_TO_EMPTY_CELL:
helper.replaceEmptyCell(newObject, requestType, cell);
break;
case GridLayoutRequest.ADD_ROW_COL:
cell.setLocation(helper.getNumColumns(), helper.getNumRows());
helper.createNewCol(cell.x);
if (cell.x != 0 || cell.y != 0)
helper.createNewRow(cell.y); // If other than (0,0) for add row
// col, we need a new row. If it
// was (0,0) then we are adding
// the first entry to the grid.
helper.replaceFillerOrEmpty(newObject, requestType, cell);
break;
case GridLayoutRequest.NO_ADD:
return UnexecutableCommand.INSTANCE;
}
Command result = helper.stopRequest();
return result;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.gef.editpolicies.LayoutEditPolicy#getDeleteDependantCommand
* (org.eclipse.gef.Request)
*/
protected Command getDeleteDependantCommand(Request request) {
// Get the commands to insert filler labels into the cells where the
// control used to be
if (request instanceof ForwardedRequest) {
EditPart editPart = ((ForwardedRequest) request).getSender();
if (editPart instanceof CompositeEditPart) {
helper.setHost((CompositeEditPart) editPart);
helper.startRequest();
helper.deleteChild((XamlNode) editPart.getModel());
return helper.stopRequest();
}
}
return UnexecutableCommand.INSTANCE;
}
protected Command getOrphanChildrenCommand(Request request) {
// Get the commands to insert filler labels into the cells where the
// control used to be
if (request instanceof GroupRequest) {
helper.startRequest();
List children = getChildren((GroupRequest) request);
helper.orphanChildren(children);
return helper.stopRequest();
} else
return UnexecutableCommand.INSTANCE;
}
public List getChildren(GroupRequest request) {
List cEP = request.getEditParts();
List children = new ArrayList(cEP.size());
Iterator itr = cEP.iterator();
while (itr.hasNext()) {
Object child = ((EditPart) itr.next()).getModel();
children.add(child);
}
return children;
}
public Rectangle getFullCellBounds(EditPart child) {
if (getGridLayoutGridFigure() == null)
return new Rectangle();
Rectangle dims = helper.getChildDimensions((EObject) child.getModel());
Rectangle bounds;
if (dims != null) {
bounds = getGridLayoutGridFigure()
.getGridBroundsForCellBounds(dims);
} else
bounds = new Rectangle();
return bounds;
}
protected GridLayoutGridFigure getGridLayoutGridFigure() {
if (fGridLayoutGridFigure == null) {
fGridLayoutGridFigure = new GridLayoutGridFigure(helper);
}
return fGridLayoutGridFigure;
}
/**
* @return the helper
*/
public GridLayoutPolicyHelper getHelper() {
return helper;
}
/*
* this gets the location from the request and then makes it absolute
* (relative to the bounds of the host figure). If we didn't do this the
* point is relative to the viewport that is displayed, not absolute wrt to
* the entire canvas.
*/
private Point getLocationFromRequest(Request request) {
Point loc = ((DropRequest) request).getLocation().getCopy();
getHostFigure().translateToRelative(loc);
return loc;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.gef.editpolicies.LayoutEditPolicy#getMoveChildrenCommand(
* org.eclipse.gef.Request)
*/
protected Command getMoveChildrenCommand(Request request) {
if (fGridLayoutGridFigure == null
|| !(request instanceof ChangeBoundsRequest))
return UnexecutableCommand.INSTANCE;
ChangeBoundsRequest req = (ChangeBoundsRequest) request;
List editparts = req.getEditParts();
// Only allow one object to be moved
if (editparts.size() > 1)
return UnexecutableCommand.INSTANCE;
XamlNode trueEObject = (XamlNode) ((EditPart) editparts.get(0))
.getModel();
if (trueEObject == null) {
return UnexecutableCommand.INSTANCE;
}
Point position = getLocationFromRequest(request).getCopy();
GridLayoutRequest gridReq = createGridLayoutRequest(position);
Point cell = new Point(gridReq.column, gridReq.row);
Object requestType = request.getType();
helper.startRequest();
switch (gridReq.type) {
case GridLayoutRequest.REPLACE_FILLER:
helper.replaceFiller(trueEObject, requestType, cell);
break;
case GridLayoutRequest.INSERT_COLUMN_WITHIN_ROW:
helper.insertColWithinRow(cell);
helper.replaceFillerOrEmpty(trueEObject, requestType, cell);
break;
case GridLayoutRequest.INSERT_COLUMN:
case GridLayoutRequest.ADD_COLUMN:
helper.createNewCol(cell.x);
helper.replaceFillerOrEmpty(trueEObject, requestType, cell);
break;
case GridLayoutRequest.INSERT_ROW:
case GridLayoutRequest.ADD_ROW:
helper.createNewRow(cell.y);
helper.replaceFillerOrEmpty(trueEObject, requestType, cell);
break;
case GridLayoutRequest.ADD_TO_EMPTY_CELL:
helper.replaceEmptyCell(trueEObject, requestType, cell);
break;
case GridLayoutRequest.ADD_ROW_COL:
cell.setLocation(helper.getNumColumns(), helper.getNumRows());
helper.createNewCol(cell.x);
if (cell.x != 0 || cell.y != 0)
helper.createNewRow(cell.y); // If other than (0,0) for add row
// col, we need a new row. If it
// was (0,0) then we are adding
// the first entry to the grid.
helper.replaceFillerOrEmpty(trueEObject, requestType, cell);
break;
case GridLayoutRequest.NO_ADD:
return UnexecutableCommand.INSTANCE;
}
Command command = helper.stopRequest();
return command;
}
protected Command getSpanChildrenCommand(Request generic) {
ChangeBoundsRequest request = (ChangeBoundsRequest) generic;
List editParts = request.getEditParts();
if (editParts.isEmpty() || editParts.size() > 1)
return UnexecutableCommand.INSTANCE;
// Get the cell location that the mouse was dragged to
Point spanToPosition = getLocationFromRequest(request).getCopy();
Point spanToCellLocation = getGridLayoutGridFigure().getCellLocation(
spanToPosition.x, spanToPosition.y);
// Get the cell location where we started the drag operation
Dimension dim = request.getSizeDelta();
int handleSizeOffset = GridSpanHandle.HANDLE_SIZE / 2;
Point startPosition = new Point(spanToPosition.x - dim.width
- handleSizeOffset, spanToPosition.y - dim.height
- handleSizeOffset);
// Get the cell location of the child component
GraphicalEditPart ep = (GraphicalEditPart) editParts.get(0);
EObject child = (EObject) ep.getModel();
Point childCellLocation = helper.getChildDimensions(child)
.getLocation();
Point startCellLocation = getGridLayoutGridFigure().getCellLocation(
startPosition);
// If the cell location where the pointer is located is different from
// the original cell location where we started,
// create the commands to change the gridwidth or gridheight
if ((spanToCellLocation.x >= childCellLocation.x && spanToCellLocation.y >= childCellLocation.y)
&& (spanToCellLocation.x != startCellLocation.x || spanToCellLocation.y != startCellLocation.y)) {
// Let the helper get the gridWidth or gridHeight commands based on
// the cell location
// where the pointer is and the span direction (EAST for gridwidth
// or SOUTH for gridheight)
helper.startRequest();
helper.spanChild(child, new Point(spanToCellLocation.x
- childCellLocation.x + 1, spanToCellLocation.y
- childCellLocation.y + 1), request.getResizeDirection(),
null);
return helper.stopRequest();
}
return NoOpCommand.INSTANCE;
}
/*
* (non-Javadoc)
*
* @seeorg.soyatec.xaml.ve.xwt.editpolicies.gridlayout.IGridListener#
* gridHeightChanged(int, int)
*/
public void gridHeightChanged(int gridHeight, int oldGridHeight) {
// do nothing
}
/*
* (non-Javadoc)
*
* @seeorg.soyatec.xaml.ve.xwt.editpolicies.gridlayout.IGridListener#
* gridMarginChanged(int, int)
*/
public void gridMarginChanged(int gridMargin, int oldGridMargin) {
// do nothing
}
/*
* (non-Javadoc)
*
* @seeorg.soyatec.xaml.ve.xwt.editpolicies.gridlayout.IGridListener#
* gridVisibilityChanged(boolean)
*/
public void gridVisibilityChanged(boolean showGrid) {
if (showGrid) {
showGridFigure();
} else {
eraseGridFigure();
}
}
/*
* (non-Javadoc)
*
* @seeorg.soyatec.xaml.ve.xwt.editpolicies.gridlayout.IGridListener#
* gridWidthChanged(int, int)
*/
public void gridWidthChanged(int gridWidth, int oldGridWidth) {
// do nothing
}
/*
* Return true if ep is a child editpart of the host container
*/
private boolean isChildEditPart(EditPart ep) {
if (ep != null) {
List children = getHost().getChildren();
if (!children.isEmpty())
return (children.indexOf(ep) != -1);
}
return false;
}
/**
*
*/
protected void refreshGridFigure() {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (fShowGrid) {
eraseGridFigure();
showGridFigure();
} else {
fGridLayoutGridFigure = null;
}
}
});
}
/**
* Show the adding cell outside figure feedback.
*
* @param cellBounds
*
* @since 1.2.0
*/
protected void showAddedCellFeedback(Rectangle cellBounds) {
cellBounds = cellBounds.getExpanded(cellBounds.width < 10 ? 20 : 0,
cellBounds.height < 10 ? 20 : 0);
fRowColFigure = new GridLayoutAddedCellFeedbackFigure();
fRowColFigure.setBounds(cellBounds);
addFeedback(fRowColFigure);
}
/**
* Show a new yellow column inserted into the grid near the column closest
* to position and only within that row
*/
protected void showColumnFeedBackWithinARow(Rectangle cellBounds) {
cellBounds = cellBounds.getCopy();
cellBounds.x -= 3; // start to the right by three from side of cell.
cellBounds.width = 6; // But only six wide. So it will be centered over
// the right side of the cell.
fRowColFigure = new GridLayoutColumnFigure(cellBounds);
addFeedback(fRowColFigure);
}
/**
* Show grid figure.
*/
private void showGridFigure() {
if (!fShowGrid) {
fShowGrid = true;
addFeedback(getGridLayoutGridFigure());
}
fShowGrid = true;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.gef.editpolicies.LayoutEditPolicy#showTargetFeedback(org.
* eclipse.gef.Request)
*/
public void showTargetFeedback(Request request) {
if (!(REQ_CREATE.equals(request.getType())
&& request instanceof CreateRequest && FeedbackHelper
.showCreationFeedback(fbm, (CreateRequest) request))) {
super.showTargetFeedback(request);
}
}
/**
* Shows an insertion line if there is one or more current children.
*/
protected void showLayoutTargetFeedback(Request request) {
if (!(REQ_CREATE.equals(request.getType()) && FeedbackHelper
.showCreationFeedback(fbm, (CreateRequest) request))) {
super.showLayoutTargetFeedback(request);
}
if (!fShowGrid)
addFeedback(getGridLayoutGridFigure());
if (fRowColFigure != null) {
removeFeedback(fRowColFigure);
fRowColFigure = null;
}
if (fGridLayoutCellFigure != null) {
removeFeedback(fGridLayoutCellFigure);
fGridLayoutCellFigure = null;
}
Point position = getLocationFromRequest(request).getCopy();
GridLayoutRequest gridReq = createGridLayoutRequest(position);
Point cell = new Point(gridReq.column, gridReq.row);
Rectangle cellBounds = getGridLayoutGridFigure().getCellBounds(cell);
// Calculate the bounds of the target cell figure based on whether a
// column is added,
// row is added, or it's inserted before another control.
switch (gridReq.type) {
case GridLayoutRequest.INSERT_COLUMN:
// If a column is added, show the target figure in between the two
// columns
showNewColumnFeedBack(gridReq.column);
Rectangle colFigBounds = fRowColFigure.getBounds();
// mapModelToFigure(cellBounds);
cellBounds.width = DEFAULT_CELL_WIDTH;
if (cellBounds.height < 10)
cellBounds.expand(0, 20);
cellBounds.x = colFigBounds.x + colFigBounds.width / 2
- cellBounds.width / 2;
break;
case GridLayoutRequest.INSERT_ROW:
// If a row is added, show the target figure in between the two rows
showNewRowFeedBack(gridReq.row);
Rectangle rowFigBounds = fRowColFigure.getBounds();
// mapModelToFigure(cellBounds);
cellBounds.height = DEFAULT_CELL_HEIGHT;
if (cellBounds.width < 10)
cellBounds.expand(20, 0);
cellBounds.y = rowFigBounds.y + rowFigBounds.height / 2
- cellBounds.height / 2;
break;
case GridLayoutRequest.INSERT_COLUMN_WITHIN_ROW:
// In case cell is spanned vertically we need to have the complete
// cellbounds.
showColumnFeedBackWithinARow(cellBounds);
// mapModelToFigure(cellBounds);
colFigBounds = fRowColFigure.getBounds();
cellBounds.width = DEFAULT_CELL_WIDTH;
if (cellBounds.height < 10)
cellBounds.expand(0, 20);
cellBounds.x = colFigBounds.x + colFigBounds.width / 2
- cellBounds.width / 2;
break;
case GridLayoutRequest.ADD_COLUMN:
case GridLayoutRequest.ADD_ROW:
case GridLayoutRequest.ADD_ROW_COL:
showAddedCellFeedback(cellBounds);
colFigBounds = fRowColFigure.getBounds();
// Center the cell within these bounds.
cellBounds = colFigBounds.getCopy().shrink(ADDEDCELLBORDER,
ADDEDCELLBORDER);
break;
case GridLayoutRequest.NO_ADD:
return; // No feedback.
default:
// mapModelToFigure(cellBounds.expand(cellBounds.width < 10 ? 20 :
// 0, cellBounds.height < 10 ? 20 : 0));
break;
}
if (fGridLayoutCellFigure == null) {
fGridLayoutCellFigure = new GridLayoutFeedbackFigure();
}
fGridLayoutCellFigure.setBounds(cellBounds);
addFeedback(fGridLayoutCellFigure);
}
/**
* Show a new yellow column inserted into the grid near the column closest
* to position
*/
protected void showNewColumnFeedBack(int col) {
Rectangle rect = fGridLayoutGridFigure.getColumnRectangle(col);
rect.x -= 3;
rect.width = 6;
fRowColFigure = new GridLayoutColumnFigure(rect);
addFeedback(fRowColFigure);
}
/**
* Show a new yellow row inserted into the grid near the row closest to
* position
*/
protected void showNewRowFeedBack(int row) {
Rectangle rect = fGridLayoutGridFigure.getRowRectangle(row);
rect.translate(-2, -3);
rect.width += 4;
rect.height = 6;
fRowColFigure = new GridLayoutRowFigure(rect);
addFeedback(fRowColFigure);
}
/*
* Show target feedback when dragging the span handles of a component.
* Highlight the cells the component will occupy based on the begining cell
* position and end cell position of the pointer.
*/
public void showSpanTargetFeedback(ChangeBoundsRequest request) {
// If the grid is not on, turn it on
if (!fShowGrid)
addFeedback(getGridLayoutGridFigure());
Point spanToPosition = request.getLocation().getCopy();
// Get the cell location of the child component
GraphicalEditPart ep = (GraphicalEditPart) request.getEditParts()
.get(0);
EObject child = (EObject) ep.getModel();
Rectangle childDim = getHelper().getChildDimensions(child);
// Get the start and end cell bounds in order to determine the entire
// bounds of the cell feedback figure.
Rectangle startCellBounds = getGridLayoutGridFigure().getCellBounds(
childDim.getLocation());
Rectangle endCellChildBounds = getGridLayoutGridFigure().getCellBounds(
childDim.getBottomRight().translate(-1, -1)); // This is the
// lower right
// of the child
// itself.
if (request.getResizeDirection() == PositionConstants.EAST
|| request.getResizeDirection() == PositionConstants.WEST) {
spanToPosition.y = endCellChildBounds.y; // This forces us to not
// span north/south when
// going east/west. And
// it will make it tall
// enough that entire
// cell spanned height
// is covered.
} else {
spanToPosition.x = endCellChildBounds.x + endCellChildBounds.width
- 1; // This forces us to not span left/right when going
// north/south. And it will make it wide enough that
// entire cell spanned width is covered.
}
Rectangle endCellBounds = getGridLayoutGridFigure().getCellBounds(
getGridLayoutGridFigure().getCellLocation(spanToPosition));
if (endCellBounds == null || endCellBounds.x < startCellBounds.x
|| endCellBounds.y < startCellBounds.y) {
// End is not within a cell, or the end is before the start cell.
if (fGridLayoutSpanFigure != null) {
removeFeedback(fGridLayoutSpanFigure);
fGridLayoutSpanFigure = null;
}
return;
}
Rectangle spanrect = startCellBounds.union(endCellBounds)
.resize(-1, -1);
if (fGridLayoutSpanFigure == null) {
fGridLayoutSpanFigure = new GridLayoutSpanFeedbackFigure(request
.getResizeDirection());
}
fGridLayoutSpanFigure.setLayoutFigureBounds(spanrect);
addFeedback(fGridLayoutSpanFigure);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.xwt.tools.ui.designer.policies.layout.ILayoutEditPolicy
* #refresh()
*/
public void refresh() {
helper.refresh();
refreshGridFigure();
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.xwt.tools.ui.designer.policies.layout.ILayoutEditPolicy
* #getType()
*/
public LayoutType getType() {
return LayoutType.GridLayout;
}
}