/* * (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.fge.connectors.rpc; import java.awt.event.MouseEvent; import java.util.Vector; import java.util.logging.Logger; import org.openflexo.fge.GraphicalRepresentation; import org.openflexo.fge.geom.FGEGeometricObject; import org.openflexo.fge.geom.FGEGeometricObject.SimplifiedCardinalDirection; import org.openflexo.fge.geom.FGEPoint; import org.openflexo.fge.geom.FGERectPolylin; import org.openflexo.fge.geom.area.FGEArea; import org.openflexo.fge.geom.area.FGEPlane; public class AdjustableMiddleControlPoint extends RectPolylinAdjustableControlPoint { static final Logger logger = Logger.getLogger(AdjustableMiddleControlPoint.class.getPackage().getName()); public AdjustableMiddleControlPoint(FGEPoint point, RectPolylinConnector connector) { super(point, connector); } @Override public FGEArea getDraggingAuthorizedArea() { return new FGEPlane(); } @Override public boolean dragToPoint(FGEPoint newRelativePoint, FGEPoint pointRelativeToInitialConfiguration, FGEPoint newAbsolutePoint, FGEPoint initialPoint, MouseEvent event) { FGEPoint pt = getNearestPointOnAuthorizedArea(newRelativePoint); if (pt == null) { logger.warning("Cannot nearest point for point " + newRelativePoint + " and area " + getDraggingAuthorizedArea()); return false; } // Following little hack is used here to prevent some equalities that may // lead to inconsistent orientations pt.x += FGEGeometricObject.EPSILON; pt.y += FGEGeometricObject.EPSILON; setPoint(pt); getPolylin().updatePointAt(1, pt); movedMiddleCP(); getConnector()._connectorChanged(true); getGraphicalRepresentation().notifyConnectorChanged(); return true; } private void movedMiddleCP() { FGEArea startArea = getConnector().retrieveAllowedStartArea(false); Vector<SimplifiedCardinalDirection> allowedStartOrientations = getConnector().getPrimitiveAllowedStartOrientations(); Vector<SimplifiedCardinalDirection> allowedEndOrientations = getConnector().getPrimitiveAllowedEndOrientations(); if (getConnector().getIsStartingLocationFixed() && !getConnector().getIsStartingLocationDraggable()) { // If starting location is fixed and not draggable, // Then retrieve start area itself (which is here a single point) startArea = getConnector().retrieveStartArea(); allowedStartOrientations = getConnector().getAllowedStartOrientations(); } FGEArea endArea = getConnector().retrieveAllowedEndArea(false); if (getConnector().getIsEndingLocationFixed() && !getConnector().getIsEndingLocationDraggable()) { // If starting location is fixed and not draggable, // Then retrieve start area itself (which is here a single point) endArea = getConnector().retrieveEndArea(); allowedEndOrientations = getConnector().getAllowedEndOrientations(); } /*System.out.println("startArea="+startArea); System.out.println("endArea="+endArea); System.out.println("allowedStartOrientations="+allowedStartOrientations); System.out.println("allowedEndOrientations="+allowedEndOrientations);*/ FGERectPolylin newPolylin; FGEPoint middleCPLocation = getPoint(); newPolylin = FGERectPolylin.makeRectPolylinCrossingPoint(startArea, endArea, middleCPLocation, true, getConnector() .getOverlapXResultingFromPixelOverlap(), getConnector().getOverlapYResultingFromPixelOverlap(), SimplifiedCardinalDirection .allDirectionsExcept(allowedStartOrientations), SimplifiedCardinalDirection.allDirectionsExcept(allowedEndOrientations)); if (newPolylin == null) { logger.warning("Obtained null polylin allowedStartOrientations=" + allowedStartOrientations); return; } if (getConnector().getIsStartingLocationFixed()) { // Don't forget this !!! getConnector().setFixedStartLocation( GraphicalRepresentation.convertNormalizedPoint(getGraphicalRepresentation(), newPolylin.getFirstPoint(), getGraphicalRepresentation().getStartObject())); } if (getConnector().getIsEndingLocationFixed()) { // Don't forget this !!! getConnector().setFixedEndLocation( GraphicalRepresentation.convertNormalizedPoint(getGraphicalRepresentation(), newPolylin.getLastPoint(), getGraphicalRepresentation().getEndObject())); } if (newPolylin.isNormalized()) { getConnector().updateWithNewPolylin(newPolylin, true, false); } else { logger.warning("Computed layout returned a non-normalized polylin. Please investigate"); getConnector().updateWithNewPolylin(newPolylin, false, false); } } /** * This method is internally called when first control point has been detected to be moved. * */ /*private void movedMiddleCP() { FGEArea startArea = getConnector().retrieveAllowedStartArea(false); if (getConnector().getIsStartingLocationFixed() && !getConnector().getIsStartingLocationDraggable()) { // If starting location is fixed and not draggable, // Then retrieve start area itself (which is here a single point) startArea = getConnector().retrieveStartArea(); } FGEArea endArea = getConnector().retrieveAllowedEndArea(false); if (getConnector().getIsEndingLocationFixed() && !getConnector().getIsEndingLocationDraggable()) { // If starting location is fixed and not draggable, // Then retrieve start area itself (which is here a single point) endArea = getConnector().retrieveEndArea(); } FGEPoint middleCPLocation = getPoint(); //SimplifiedCardinalDirection initialStartOrientation = initialPolylin.getApproximatedOrientationOfSegment(0); //SimplifiedCardinalDirection initialEndOrientation = initialPolylin.getApproximatedOrientationOfSegment(1).getOpposite(); // Try to find a cardinal direction in which it is possible to project // dragged control point SimplifiedCardinalDirection startOrientation = null; SimplifiedCardinalDirection altStartOrientation = null; for (SimplifiedCardinalDirection o : SimplifiedCardinalDirection.values()) { if (startArea.getOrthogonalPerspectiveArea(o).containsPoint(middleCPLocation)) { startOrientation = o; } } if (startOrientation == null) { CardinalQuadrant quadrant = FGEPoint.getCardinalQuadrant(getPolylin().getFirstPoint(),middleCPLocation); startOrientation = quadrant.getHorizonalComponent(); altStartOrientation = quadrant.getVerticalComponent(); } // Try to find a cardinal direction in which it is possible to project // dragged control point SimplifiedCardinalDirection endOrientation = null; SimplifiedCardinalDirection altEndOrientation = null; for (SimplifiedCardinalDirection o : SimplifiedCardinalDirection.values()) { if (endArea.getOrthogonalPerspectiveArea(o).containsPoint(middleCPLocation)) { endOrientation = o; } } if (endOrientation == null) { CardinalQuadrant quadrant = FGEPoint.getCardinalQuadrant(middleCPLocation, getPolylin().getLastPoint()); endOrientation = quadrant.getHorizonalComponent().getOpposite(); altEndOrientation = quadrant.getVerticalComponent().getOpposite(); } if (startArea.getOrthogonalPerspectiveArea(startOrientation).containsPoint(middleCPLocation)) { // OK, the new location will not modify general structure of connector FGEPoint newPoint = new FGEPoint(getPolylin().getFirstPoint()); if (startOrientation.isHorizontal()) { newPoint.setY(middleCPLocation.y); } else if (startOrientation.isVertical()) { newPoint.setX(middleCPLocation.x); } getPolylin().updatePointAt(0, newPoint); getConnector().getStartControlPoint().setPoint(newPoint); if (getConnector().getIsStartingLocationFixed()) { // Don't forget this !!! getConnector().setFixedStartLocation( GraphicalRepresentation.convertNormalizedPoint(getGraphicalRepresentation(), newPoint, getGraphicalRepresentation().getStartObject())); } } if (endArea.getOrthogonalPerspectiveArea(endOrientation).containsPoint(middleCPLocation)) { // OK, the new location will not modify general structure of connector FGEPoint newPoint = new FGEPoint(getPolylin().getLastPoint()); if (endOrientation.isHorizontal()) { newPoint.setY(middleCPLocation.y); } else if (endOrientation.isVertical()) { newPoint.setX(middleCPLocation.x); } getPolylin().updatePointAt(getPolylin().getPointsNb()-1, newPoint); getConnector().getEndControlPoint().setPoint(newPoint); if (getConnector().getIsEndingLocationFixed()) { // Don't forget this !!! getConnector().setFixedEndLocation( GraphicalRepresentation.convertNormalizedPoint(getGraphicalRepresentation(), newPoint, getGraphicalRepresentation().getEndObject())); } } System.out.println("Tiens, je sais pas quoi faire..."); int alternatives = 1; if (altStartOrientation != null) alternatives=alternatives*2; if (altEndOrientation != null) alternatives=alternatives*2; FGERectPolylin[] newPolylins = new FGERectPolylin[alternatives]; int n=0; newPolylins[n++] = FGERectPolylin.makeRectPolylinCrossingPoint( getPolylin().getFirstPoint(), getPolylin().getLastPoint(), middleCPLocation, startOrientation, endOrientation, true, getConnector().getOverlapXResultingFromPixelOverlap(), getConnector().getOverlapYResultingFromPixelOverlap()); if (altStartOrientation != null) { newPolylins[n++] = FGERectPolylin.makeRectPolylinCrossingPoint( getPolylin().getFirstPoint(), getPolylin().getLastPoint(), middleCPLocation, altStartOrientation, endOrientation, true, getConnector().getOverlapXResultingFromPixelOverlap(), getConnector().getOverlapYResultingFromPixelOverlap()); if (altEndOrientation != null) { newPolylins[n++] = FGERectPolylin.makeRectPolylinCrossingPoint( getPolylin().getFirstPoint(), getPolylin().getLastPoint(), middleCPLocation, altStartOrientation, altEndOrientation, true, getConnector().getOverlapXResultingFromPixelOverlap(), getConnector().getOverlapYResultingFromPixelOverlap()); } } if (altEndOrientation != null) { newPolylins[n++] = FGERectPolylin.makeRectPolylinCrossingPoint( getPolylin().getFirstPoint(), getPolylin().getLastPoint(), middleCPLocation, startOrientation, altEndOrientation, true, getConnector().getOverlapXResultingFromPixelOverlap(), getConnector().getOverlapYResultingFromPixelOverlap()); } FGERectPolylin newPolylin = null; for (int i=0; i<alternatives; i++) { if (!newPolylins[i].crossedItSelf() && newPolylin == null) newPolylin = newPolylins[i]; } if (newPolylin == null) newPolylin = newPolylins[0]; getConnector().updateWithNewPolylin(newPolylin,true); } */ }