package org.openflexo.wkf.swleditor.gr;
import java.awt.Cursor;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import org.openflexo.fge.GraphicalRepresentation;
import org.openflexo.fge.ShapeGraphicalRepresentation;
import org.openflexo.fge.ShapeGraphicalRepresentation.DimensionConstraints;
import org.openflexo.fge.controller.DrawingController;
import org.openflexo.fge.cp.ControlArea;
import org.openflexo.fge.cp.ShapeResizingControlPoint;
import org.openflexo.fge.geom.FGEDimension;
import org.openflexo.fge.geom.FGEGeometricObject;
import org.openflexo.fge.geom.FGEGeometricObject.SimplifiedCardinalDirection;
import org.openflexo.fge.geom.FGEPoint;
import org.openflexo.fge.geom.FGERectangle;
import org.openflexo.fge.geom.FGESegment;
import org.openflexo.fge.graphics.FGEGraphics;
import org.openflexo.fge.shapes.Shape;
public class SWLContainerResizeAreas {
private static class LineControlArea extends ControlArea<FGESegment> {
private final SimplifiedCardinalDirection cardinalDirection;
public LineControlArea(ShapeGraphicalRepresentation<?> aGraphicalRepresentation, SimplifiedCardinalDirection cardinalDirection) {
super(aGraphicalRepresentation, getSegment(cardinalDirection));
this.cardinalDirection = cardinalDirection;
}
private static FGESegment getSegment(SimplifiedCardinalDirection cardinalDirection) {
switch (cardinalDirection) {
case EAST:
return new FGESegment(1, 0, 1, 1);
case NORTH:
return new FGESegment(0, 0, 1, 0);
case SOUTH:
return new FGESegment(0, 1, 1, 1);
case WEST:
return new FGESegment(0, 0, 0, 1);
}
return null;
}
@Override
public ShapeGraphicalRepresentation<?> getGraphicalRepresentation() {
return (ShapeGraphicalRepresentation<?>) super.getGraphicalRepresentation();
}
@Override
public Rectangle paint(FGEGraphics graphics) {
return new Rectangle();
}
private FGEPoint initialShapePosition;
private double initialWidth;
private double initialHeight;
private FGEDimension offset;
private FGERectangle initialRequiredBounds;
@Override
public void startDragging(DrawingController<?> controller, FGEPoint startPoint) {
if (!isDraggable()) {
return;
}
initialWidth = getGraphicalRepresentation().getUnscaledViewWidth();
initialHeight = getGraphicalRepresentation().getUnscaledViewHeight();
if (initialWidth < FGEGeometricObject.EPSILON) {
initialWidth = 1;
}
if (initialHeight < FGEGeometricObject.EPSILON) {
initialHeight = 1;
}
offset = new FGEDimension(initialWidth - getGraphicalRepresentation().getWidth(), initialHeight
- getGraphicalRepresentation().getHeight());
initialShapePosition = getGraphicalRepresentation().getLocation();
/*if (controller.getPaintManager().isPaintingCacheEnabled()) {
controller.getPaintManager().addToTemporaryObjects(getGraphicalRepresentation());
controller.getPaintManager().invalidate(getGraphicalRepresentation());
}*/
if (getGraphicalRepresentation().getAdaptBoundsToContents()) {
initialRequiredBounds = getGraphicalRepresentation().getRequiredBoundsForContents();
}
setDraggingAuthorizedArea(getArea().getOrthogonalLine(startPoint));
getGraphicalRepresentation().notifyObjectWillResize();
}
@Override
public boolean dragToPoint(FGEPoint newRelativePoint, FGEPoint pointRelativeToInitialConfiguration, FGEPoint newAbsolutePoint,
FGEPoint initialPoint, MouseEvent event) {
if (!isDraggable()) {
return true;
}
// System.out.println("pointRelativeToInitialConfiguration="+pointRelativeToInitialConfiguration);
FGEPoint nearestPoint = getNearestPointOnAuthorizedArea(pointRelativeToInitialConfiguration);
// System.out.println("nearestPoint="+nearestPoint);
if (cardinalDirection == SimplifiedCardinalDirection.NORTH) {
FGEPoint opposite = Shape.SOUTH;
double newHeight = initialHeight * (opposite.y - nearestPoint.y) / (opposite.y - initialPoint.y);
getGraphicalRepresentation().setSize(new FGEDimension(initialWidth - offset.width, newHeight - offset.height));
getGraphicalRepresentation().setLocation(
new FGEPoint(initialShapePosition.x, initialShapePosition.y - (newHeight - initialHeight)));
} else if (cardinalDirection == SimplifiedCardinalDirection.SOUTH) {
FGEPoint opposite = Shape.NORTH;
double newHeight = initialHeight * (opposite.y - nearestPoint.y) / (opposite.y - initialPoint.y);
getGraphicalRepresentation().setSize(new FGEDimension(initialWidth - offset.width, newHeight - offset.height));
} else if (cardinalDirection == SimplifiedCardinalDirection.WEST) {
FGEPoint opposite = Shape.EAST;
double newWidth = initialWidth * (opposite.x - nearestPoint.x) / (opposite.x - initialPoint.x);
getGraphicalRepresentation().setSize(new FGEDimension(newWidth - offset.width, initialHeight - offset.height));
getGraphicalRepresentation().setLocation(
new FGEPoint(initialShapePosition.x - (newWidth - initialWidth), initialShapePosition.y));
} else if (cardinalDirection == SimplifiedCardinalDirection.EAST) {
FGEPoint opposite = Shape.WEST;
double newWidth = initialWidth * (opposite.x - nearestPoint.x) / (opposite.x - initialPoint.x);
getGraphicalRepresentation().setSize(new FGEDimension(newWidth - offset.width, initialHeight - offset.height));
}
return true;
}
@Override
public void stopDragging(DrawingController<?> controller, GraphicalRepresentation<?> focusedGR) {
if (!isDraggable()) {
return;
}
initialWidth = 0;
initialHeight = 0;
setDraggingAuthorizedArea(null);
getGraphicalRepresentation().notifyObjectHasResized();
}
@Override
public Cursor getDraggingCursor() {
if (!isDraggable()) {
return Cursor.getDefaultCursor();
}
return getResizingCursor(cardinalDirection);
}
@Override
public boolean isDraggable() {
return getGraphicalRepresentation().getDimensionConstraints() != DimensionConstraints.UNRESIZABLE
&& getGraphicalRepresentation().getDimensionConstraints() != DimensionConstraints.CONTAINER;
}
private static Cursor getResizingCursor(SimplifiedCardinalDirection direction) {
if (direction == SimplifiedCardinalDirection.NORTH) {
return Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
} else if (direction == SimplifiedCardinalDirection.SOUTH) {
return Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
} else if (direction == SimplifiedCardinalDirection.EAST) {
return Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
} else if (direction == SimplifiedCardinalDirection.WEST) {
return Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR);
}
return null;
}
}
private List<ControlArea<?>> controlAreas;
public SWLContainerResizeAreas(ShapeGraphicalRepresentation<?> gr) {
super();
controlAreas = new ArrayList<ControlArea<?>>();
controlAreas.add(new ShapeResizingControlPoint(gr, new FGEPoint(1, 1), null));
controlAreas.add(new LineControlArea(gr, SimplifiedCardinalDirection.SOUTH));
controlAreas.add(new LineControlArea(gr, SimplifiedCardinalDirection.EAST));
}
public List<ControlArea<?>> getControlAreas() {
return controlAreas;
}
}