/**
* $Id: mxInteractiveCanvas.java,v 1.1 2012/11/15 13:26:49 gaudenz Exp $
* Copyright (c) 2007-2010, Gaudenz Alder, David Benson
*/
package com.mxgraph.swing.view;
import com.mxgraph.canvas.mxGraphics2DCanvas;
import com.mxgraph.shape.mxBasicShape;
import com.mxgraph.shape.mxIShape;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxPoint;
import com.mxgraph.util.mxUtils;
import com.mxgraph.view.mxCellState;
import java.awt.*;
import java.awt.image.ImageObserver;
public class mxInteractiveCanvas extends mxGraphics2DCanvas {
/**
*
*/
protected ImageObserver imageObserver = null;
/**
*
*/
public mxInteractiveCanvas() {
this(null);
}
/**
*
*/
public mxInteractiveCanvas(ImageObserver imageObserver) {
setImageObserver(imageObserver);
}
/**
*
*/
public void setImageObserver(ImageObserver value) {
imageObserver = value;
}
/**
*
*/
public ImageObserver getImageObserver() {
return imageObserver;
}
/**
* Overrides graphics call to use image observer.
*/
protected void drawImageImpl(Image image, int x, int y) {
g.drawImage(image, x, y, imageObserver);
}
/**
* Returns the size for the given image.
*/
protected Dimension getImageSize(Image image) {
return new Dimension(image.getWidth(imageObserver), image.getHeight(imageObserver));
}
/**
*
*/
public boolean contains(mxGraphComponent graphComponent, Rectangle rect, mxCellState state) {
return state != null &&
state.getX() >= rect.x &&
state.getY() >= rect.y &&
state.getX() + state.getWidth() <= rect.x + rect.width &&
state.getY() + state.getHeight() <= rect.y + rect.height;
}
/**
*
*/
public boolean intersects(mxGraphComponent graphComponent, Rectangle rect, mxCellState state) {
if (state != null) {
// Checks if the label intersects
if (state.getLabelBounds() != null && state.getLabelBounds().getRectangle().intersects(rect)) {
return true;
}
int pointCount = state.getAbsolutePointCount();
// Checks if the segments of the edge intersect
if (pointCount > 0) {
rect = (Rectangle)rect.clone();
int tolerance = graphComponent.getTolerance();
rect.grow(tolerance, tolerance);
Shape realShape = null;
// FIXME: Check if this should be used for all shapes
if (mxUtils.getString(state.getStyle(), mxConstants.STYLE_SHAPE, "").equals(mxConstants.SHAPE_ARROW)) {
mxIShape shape = getShape(state.getStyle());
if (shape instanceof mxBasicShape) {
realShape = ((mxBasicShape)shape).createShape(this, state);
}
}
if (realShape != null && realShape.intersects(rect)) {
return true;
}
else {
mxPoint p0 = state.getAbsolutePoint(0);
for (int i = 0; i < pointCount; i++) {
mxPoint p1 = state.getAbsolutePoint(i);
if (rect.intersectsLine(p0.getX(), p0.getY(), p1.getX(), p1.getY())) {
return true;
}
p0 = p1;
}
}
}
else {
// Checks if the bounds of the shape intersect
return state.getRectangle().intersects(rect);
}
}
return false;
}
/**
* Returns true if the given point is inside the content area of the given
* swimlane. (The content area of swimlanes is transparent to events.) This
* implementation does not check if the given state is a swimlane, it is
* assumed that the caller has checked this before using this method.
*/
public boolean hitSwimlaneContent(mxGraphComponent graphComponent, mxCellState swimlane, int x, int y) {
if (swimlane != null) {
int start = (int)Math.max(2, Math.round(
mxUtils.getInt(swimlane.getStyle(), mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE) *
graphComponent.getGraph().getView().getScale()));
Rectangle rect = swimlane.getRectangle();
if (mxUtils.isTrue(swimlane.getStyle(), mxConstants.STYLE_HORIZONTAL, true)) {
rect.y += start;
rect.height -= start;
}
else {
rect.x += start;
rect.width -= start;
}
return rect.contains(x, y);
}
return false;
}
}