/*
* (c) Copyright 2010-2011 AgileBirds
*
* This file is part of OpenFlexo.
*
* OpenFlexo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* OpenFlexo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openflexo.wkf.processeditor.gr;
import java.util.List;
import java.util.Vector;
import java.util.logging.Logger;
import org.openflexo.fge.ConnectorGraphicalRepresentation;
import org.openflexo.fge.GraphicalRepresentation;
import org.openflexo.fge.ShapeGraphicalRepresentation;
import org.openflexo.fge.connectors.Connector;
import org.openflexo.fge.connectors.Connector.ConnectorType;
import org.openflexo.fge.cp.ConnectorControlPoint;
import org.openflexo.fge.cp.ControlPoint;
import org.openflexo.fge.geom.FGEGeometricObject.Filling;
import org.openflexo.fge.geom.FGEGeometricObject.SimplifiedCardinalDirection;
import org.openflexo.fge.geom.FGEPoint;
import org.openflexo.fge.geom.FGEPolygon;
import org.openflexo.fge.geom.FGERectangle;
import org.openflexo.fge.graphics.BackgroundStyle;
import org.openflexo.fge.graphics.FGEConnectorGraphics;
import org.openflexo.fge.graphics.ForegroundStyle;
import org.openflexo.foundation.wkf.ActionPetriGraph;
import org.openflexo.foundation.wkf.ActivityPetriGraph;
import org.openflexo.foundation.wkf.FlexoPetriGraph;
import org.openflexo.foundation.wkf.OperationPetriGraph;
import org.openflexo.foundation.wkf.node.AbstractNode;
import org.openflexo.wkf.processeditor.ProcessEditorConstants;
import org.openflexo.wkf.processeditor.ProcessRepresentation;
public class ExpanderGR<O extends AbstractNode> extends ConnectorGraphicalRepresentation<ExpanderGR.Expander<O>> implements
ProcessEditorConstants {
static final Logger logger = Logger.getLogger(Connector.class.getPackage().getName());
public static class Expander<N extends AbstractNode> {
private N node;
private FlexoPetriGraph pg;
public Expander(N aNode, FlexoPetriGraph aPetriGraph) {
node = aNode;
pg = aPetriGraph;
}
public N getFatherNode() {
return node;
}
public FlexoPetriGraph getPetriGraph() {
return pg;
}
}
protected ForegroundStyle foreground;
protected ForegroundStyle noneForeground;
protected BackgroundStyle emptyBackground;
public ExpanderGR(Expander<O> expander, ProcessRepresentation aDrawing) {
super(ConnectorType.CUSTOM, (ShapeGraphicalRepresentation<?>) aDrawing.getGraphicalRepresentation(expander.getFatherNode()),
(ShapeGraphicalRepresentation<?>) aDrawing.getGraphicalRepresentation(expander.getPetriGraph()), expander, aDrawing);
setConnector(new ExpanderConnector());
emptyBackground = BackgroundStyle.makeEmptyBackground();
if (expander.getPetriGraph() instanceof ActivityPetriGraph) {
foreground = ForegroundStyle.makeStyle(ProcessEditorConstants.ACTIVITY_PG_COLOR, 0.3f);
noneForeground = ForegroundStyle.makeNone();
setLayer(ACTIVITY_PG_LAYER);
} else if (expander.getPetriGraph() instanceof OperationPetriGraph) {
foreground = ForegroundStyle.makeStyle(ProcessEditorConstants.OPERATION_PG_COLOR, 0.3f);
noneForeground = ForegroundStyle.makeNone();
setLayer(OPERATION_PG_LAYER);
} else if (expander.getPetriGraph() instanceof ActionPetriGraph) {
foreground = ForegroundStyle.makeStyle(ProcessEditorConstants.ACTION_PG_COLOR, 0.3f);
noneForeground = ForegroundStyle.makeNone();
setLayer(ACTION_PG_LAYER);
}
setIsFocusable(false);
setIsSelectable(false);
}
@Override
public ProcessRepresentation getDrawing() {
return (ProcessRepresentation) super.getDrawing();
}
public Expander<O> getExpander() {
return getDrawable();
}
public AbstractNode getFatherNode() {
return getExpander().getFatherNode();
}
public FlexoPetriGraph getPetriGraph() {
return getExpander().getPetriGraph();
}
@Override
public boolean getIsVisible() {
return getDrawing().isVisible(getPetriGraph());
}
@Override
public String toString() {
return "ExpanderGR of " + getFatherNode();
}
public class ExpanderConnector extends Connector {
private boolean firstUpdated = false;
private Vector<ControlPoint> controlPoints;
public ExpanderConnector() {
super(ExpanderGR.this);
controlPoints = new Vector<ControlPoint>();
}
@Override
public Connector clone() {
return new ExpanderConnector();
}
private void updateControlPoints() {
FGEPoint centerOfStartObject = GraphicalRepresentation.convertNormalizedPoint(getStartObject(), new FGEPoint(0.5, 0.5),
getGraphicalRepresentation());
FGEPoint centerOfEndObject = GraphicalRepresentation.convertNormalizedPoint(getEndObject(), new FGEPoint(0.5, 0.5),
getGraphicalRepresentation());
SimplifiedCardinalDirection orientation = FGEPoint.getSimplifiedOrientation(centerOfStartObject, centerOfEndObject);
FGEPoint newStartP1, newStartP2, newEndP1, newEndP2;
if (orientation == SimplifiedCardinalDirection.NORTH) {
newStartP1 = getStartObject().getShape().getShape().getBoundingBox().getNorthWestPt();
newStartP2 = getStartObject().getShape().getShape().getBoundingBox().getNorthEastPt();
newEndP1 = getEndObject().getShape().getShape().getBoundingBox().getSouthWestPt();
newEndP2 = getEndObject().getShape().getShape().getBoundingBox().getSouthEastPt();
} else if (orientation == SimplifiedCardinalDirection.SOUTH) {
newStartP1 = getStartObject().getShape().getShape().getBoundingBox().getSouthWestPt();
newStartP2 = getStartObject().getShape().getShape().getBoundingBox().getSouthEastPt();
newEndP1 = getEndObject().getShape().getShape().getBoundingBox().getNorthWestPt();
newEndP2 = getEndObject().getShape().getShape().getBoundingBox().getNorthEastPt();
} else if (orientation == SimplifiedCardinalDirection.WEST) {
newStartP1 = getStartObject().getShape().getShape().getBoundingBox().getNorthWestPt();
newStartP2 = getStartObject().getShape().getShape().getBoundingBox().getSouthWestPt();
newEndP1 = getEndObject().getShape().getShape().getBoundingBox().getNorthEastPt();
newEndP2 = getEndObject().getShape().getShape().getBoundingBox().getSouthEastPt();
} else /* if (orientation == SimplifiedCardinalDirection.EAST) */{
newStartP1 = getStartObject().getShape().getShape().getBoundingBox().getNorthEastPt();
newStartP2 = getStartObject().getShape().getShape().getBoundingBox().getSouthEastPt();
newEndP1 = getEndObject().getShape().getShape().getBoundingBox().getNorthWestPt();
newEndP2 = getEndObject().getShape().getShape().getBoundingBox().getSouthWestPt();
}
newStartP1 = getStartObject().getShape().outlineIntersect(newStartP1);
newStartP2 = getStartObject().getShape().outlineIntersect(newStartP2);
newEndP1 = getEndObject().getShape().outlineIntersect(newEndP1);
newEndP2 = getEndObject().getShape().outlineIntersect(newEndP2);
newStartP1 = GraphicalRepresentation.convertNormalizedPoint(getStartObject(), newStartP1, getGraphicalRepresentation());
newStartP2 = GraphicalRepresentation.convertNormalizedPoint(getStartObject(), newStartP2, getGraphicalRepresentation());
newEndP1 = GraphicalRepresentation.convertNormalizedPoint(getEndObject(), newEndP1, getGraphicalRepresentation());
newEndP2 = GraphicalRepresentation.convertNormalizedPoint(getEndObject(), newEndP2, getGraphicalRepresentation());
startP1 = new ConnectorControlPoint(getGraphicalRepresentation(), newStartP1);
startP2 = new ConnectorControlPoint(getGraphicalRepresentation(), newStartP2);
endP1 = new ConnectorControlPoint(getGraphicalRepresentation(), newEndP1);
endP2 = new ConnectorControlPoint(getGraphicalRepresentation(), newEndP2);
controlPoints.clear();
controlPoints.add(startP1);
controlPoints.add(startP2);
controlPoints.add(endP1);
controlPoints.add(endP2);
}
private ConnectorControlPoint startP1;
private ConnectorControlPoint startP2;
private ConnectorControlPoint endP1;
private ConnectorControlPoint endP2;
@Override
public void refreshConnector(boolean force) {
super.refreshConnector(force);
updateControlPoints();
firstUpdated = true;
}
@Override
public double getStartAngle() {
// TODO Auto-generated method stub
return 0;
}
@Override
public double getEndAngle() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void drawConnector(FGEConnectorGraphics g) {
if (!firstUpdated) {
refreshConnector();
}
BackgroundStyle backgroundToUse = emptyBackground;
g.setDefaultBackground(backgroundToUse);
g.setDefaultForeground(noneForeground);
new FGEPolygon(Filling.FILLED, startP1.getPoint(), endP1.getPoint(), endP2.getPoint(), startP2.getPoint()).paint(g);
g.setDefaultForeground(foreground);
g.useDefaultForegroundStyle();
g.drawLine(startP1.getPoint(), endP1.getPoint());
g.drawLine(startP2.getPoint(), endP2.getPoint());
}
@Override
public double distanceToConnector(FGEPoint aPoint, double scale) {
// Never focusable nor inspectable
return Double.POSITIVE_INFINITY;
}
@Override
public ConnectorType getConnectorType() {
return ConnectorType.CUSTOM;
}
@Override
public FGERectangle getConnectorUsedBounds() {
return NORMALIZED_BOUNDS;
}
@Override
public List<ControlPoint> getControlAreas() {
return controlPoints;
}
@Override
public FGEPoint getMiddleSymbolLocation() {
return new FGEPoint(0, 0);
}
// Not relevant here
@Override
public FGEPoint getEndLocation() {
return null;
}
// Not relevant here
@Override
public FGEPoint getStartLocation() {
return null;
}
}
}