/* * Copyright 2010-2015 Institut Pasteur. * * This file is part of Icy. * * Icy 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. * * Icy 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 Icy. If not, see <http://www.gnu.org/licenses/>. */ package plugins.kernel.roi.roi2d; import icy.canvas.IcyCanvas; import icy.painter.Anchor2D; import icy.painter.LineAnchor2D; import icy.resource.ResourceUtil; import icy.roi.ROI; import icy.type.point.Point2DUtil; import icy.type.point.Point5D; import icy.util.XMLUtil; import java.awt.Graphics2D; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.List; import org.w3c.dom.Node; /** * ROI 2D Line. * * @author Stephane */ public class ROI2DLine extends ROI2DShape { protected class ROI2DLineAnchor2D extends LineAnchor2D { public ROI2DLineAnchor2D(Point2D position) { super(position, getOverlay().getColor(), getOverlay().getFocusedColor()); } @Override protected Anchor2D getPreviousPoint() { if (this == pt1) return pt2; return pt1; } } public class ROI2DLinePainter extends ROI2DShapePainter { @Override protected boolean isTiny(Rectangle2D bounds, Graphics2D g, IcyCanvas canvas) { if (isSelected()) return false; return super.isTiny(bounds, g, canvas); } } public static final String ID_PT1 = "pt1"; public static final String ID_PT2 = "pt2"; protected final Anchor2D pt1; protected final Anchor2D pt2; public ROI2DLine(Point2D pt1, Point2D pt2) { super(new Line2D.Double()); this.pt1 = createAnchor(pt1); this.pt2 = createAnchor(pt2); // keep pt2 selected to size the line for "interactive mode" this.pt2.setSelected(true); addPoint(this.pt1); addPoint(this.pt2); // set icon (default name is defined by getDefaultName()) setIcon(ResourceUtil.ICON_ROI_LINE); } public ROI2DLine(Line2D line) { this(line.getP1(), line.getP2()); } /** * @deprecated */ @SuppressWarnings("unused") @Deprecated public ROI2DLine(Point2D pt, boolean cm) { this(pt); } public ROI2DLine(Point2D pt) { this(new Point2D.Double(pt.getX(), pt.getY()), pt); } /** * Generic constructor for interactive mode */ public ROI2DLine(Point5D pt) { this(pt.toPoint2D()); // getOverlay().setMousePos(pt); } public ROI2DLine(double x1, double y1, double x2, double y2) { this(new Point2D.Double(x1, y1), new Point2D.Double(x2, y2)); } public ROI2DLine() { this(new Point2D.Double(), new Point2D.Double()); } @Override public String getDefaultName() { return "Line2D"; } @Override protected ROI2DShapePainter createPainter() { return new ROI2DLinePainter(); } @Override protected Anchor2D createAnchor(Point2D pos) { return new ROI2DLineAnchor2D(pos); } public Line2D getLine() { return (Line2D) shape; } @Override public boolean canSetBounds() { return true; } @Override public void setBounds2D(Rectangle2D bounds) { beginUpdate(); try { pt1.setPosition(bounds.getMinX(), bounds.getMinY()); pt2.setPosition(bounds.getMaxX(), bounds.getMaxY()); } finally { endUpdate(); } } public void setLine(Line2D line) { setBounds2D(line.getBounds2D()); } @Override protected void updateShape() { getLine().setLine(pt1.getPosition(), pt2.getPosition()); // call super method after shape has been updated super.updateShape(); } @Override public boolean canAddPoint() { // this ROI doesn't support point add return false; } @Override public boolean canRemovePoint() { // this ROI doesn't support point remove return false; } @Override protected boolean removePoint(IcyCanvas canvas, Anchor2D pt) { // this ROI doesn't support point remove return false; } @Override protected double getTotalDistance(List<Point2D> points, double factorX, double factorY) { // for ROI2DLine the total length don't need last point connection return Point2DUtil.getTotalDistance(points, factorX, factorY, false); } @Override public double computeNumberOfPoints() { return 0d; } @Override public boolean contains(double x, double y) { return false; } @Override public boolean contains(Point2D p) { return false; } @Override public boolean contains(double x, double y, double w, double h) { return false; } @Override public boolean contains(Rectangle2D r) { return false; } @Override public boolean contains(ROI roi) { return false; } @Override public boolean intersects(ROI r) { // special case of ROI2DLine if (r instanceof ROI2DLine) return onSamePos(((ROI2DLine) r), false) && ((ROI2DLine) r).getLine().intersectsLine(getLine()); // special case of ROI2DRectangle if (r instanceof ROI2DRectangle) return onSamePos(((ROI2DRectangle) r), false) && ((ROI2DRectangle) r).getRectangle().intersectsLine(getLine()); return super.intersects(r); } @Override public boolean loadFromXML(Node node) { beginUpdate(); try { if (!super.loadFromXML(node)) return false; pt1.loadPositionFromXML(XMLUtil.getElement(node, ID_PT1)); pt2.loadPositionFromXML(XMLUtil.getElement(node, ID_PT2)); } finally { endUpdate(); } return true; } @Override public boolean saveToXML(Node node) { if (!super.saveToXML(node)) return false; pt1.savePositionToXML(XMLUtil.setElement(node, ID_PT1)); pt2.savePositionToXML(XMLUtil.setElement(node, ID_PT2)); return true; } }