/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.gef.service;
import static org.eclipse.draw2d.PositionConstants.EAST;
import static org.eclipse.draw2d.PositionConstants.NORTH;
import static org.eclipse.draw2d.PositionConstants.NORTH_EAST;
import static org.eclipse.draw2d.PositionConstants.NORTH_WEST;
import static org.eclipse.draw2d.PositionConstants.SOUTH;
import static org.eclipse.draw2d.PositionConstants.SOUTH_EAST;
import static org.eclipse.draw2d.PositionConstants.SOUTH_WEST;
import static org.eclipse.draw2d.PositionConstants.WEST;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.xmind.gef.draw2d.IReferencedFigure;
import org.xmind.gef.draw2d.geometry.Geometry;
public abstract class AbstractBendPointsFeedback extends AbstractFeedback
implements IBendPointsFeedback {
public static final int[] ALL_ORIENTATIONS = new int[] { SOUTH_EAST,
SOUTH_WEST, NORTH_WEST, NORTH_EAST, EAST, WEST, SOUTH, NORTH };
private Map<Integer, IReferencedFigure> figures = null;
private Rectangle bounds = null;
private IRectangleProvider boundsProvider = null;
private int hidePointLength = 0;
private int[] orientations = null;
public void addToLayer(IFigure layer) {
if (figures == null) {
figures = createFigures();
}
for (IFigure f : figures.values()) {
layer.add(f);
}
}
private Map<Integer, IReferencedFigure> createFigures() {
HashMap<Integer, IReferencedFigure> map = new HashMap<Integer, IReferencedFigure>(
ALL_ORIENTATIONS.length);
for (int orientation : ALL_ORIENTATIONS) {
map.put(orientation, createPointFigure(orientation));
}
return map;
}
protected abstract IReferencedFigure createPointFigure(int orientation);
public boolean containsPoint(Point point) {
if (figures != null && bounds != null) {
if (getZoomManager() != null)
point = getZoomManager().getScaled(point);
for (IFigure f : figures.values()) {
if (f.containsPoint(point) && f.isVisible()
&& f.getParent() != null)
return true;
}
}
return false;
}
public void removeFromLayer(IFigure layer) {
if (figures != null) {
for (IFigure f : figures.values()) {
layer.remove(f);
}
}
}
public void update() {
if (figures == null)
return;
if (boundsProvider != null) {
Rectangle r = boundsProvider.getRectangle();
if (r != null)
setBounds(r);
}
if (bounds != null) {
Rectangle scaledBounds = bounds;
if (getZoomManager() != null)
scaledBounds = getZoomManager().getScaled(scaledBounds);
for (int orientation : ALL_ORIENTATIONS) {
IReferencedFigure fig = figures.get(orientation);
if (fig != null) {
Point p = calcPointPosition(fig, orientation, scaledBounds);
preUpdatePointFigure(fig, orientation, scaledBounds, p);
fig.setReference(p);
fig.setVisible(isPointVisible(fig, orientation,
scaledBounds));
}
}
updateWithBounds(scaledBounds);
}
for (int orientation : ALL_ORIENTATIONS) {
IReferencedFigure fig = figures.get(orientation);
if (fig != null) {
updatePointFigure(fig, orientation);
}
}
}
protected void updateWithBounds(Rectangle clientBounds) {
}
protected void preUpdatePointFigure(IReferencedFigure figure,
int orientation, Rectangle bounds, Point preferredPosition) {
}
protected abstract void updatePointFigure(IReferencedFigure figure,
int orientation);
protected boolean isPointVisible(IReferencedFigure figure, int orientation,
Rectangle box) {
for (int o : getOrientations()) {
if (o == orientation) {
int length = getLength(orientation, box);
return length < 0 || length >= hidePointLength;
}
}
return false;
}
protected int getLength(int orientation, Rectangle box) {
if (orientation == EAST || orientation == WEST)
return box.height;
if (orientation == NORTH || orientation == SOUTH)
return box.width;
return -1;
}
protected Point calcPointPosition(IReferencedFigure figure,
int orientation, Rectangle box) {
return Geometry.getLocation(orientation, box, true, 1, 0);
}
public int getOrientation(Point point) {
if (figures != null && bounds != null) {
if (getZoomManager() != null)
point = getZoomManager().getScaled(point);
for (int orientation : ALL_ORIENTATIONS) {
IFigure f = figures.get(orientation);
if (f.containsPoint(point) && f.isVisible()
&& f.getParent() != null)
return orientation;
}
}
return PositionConstants.NONE;
}
public int[] getOrientations() {
if (orientations == null)
return ALL_ORIENTATIONS;
return orientations;
}
public void setOrientations(int[] orientations) {
this.orientations = orientations;
}
public Rectangle getBounds() {
return bounds;
}
public void setBounds(Rectangle bounds) {
this.bounds = bounds;
}
public int getHidePointLength() {
return hidePointLength;
}
public void setHidePointLength(int hidePointLength) {
this.hidePointLength = hidePointLength;
}
public IRectangleProvider getBoundsProvider() {
return boundsProvider;
}
public void setBoundsProvider(IRectangleProvider boundsProvider) {
this.boundsProvider = boundsProvider;
}
}