001/* 002 * Copyright 2010-2015 Institut Pasteur. 003 * 004 * This file is part of Icy. 005 * 006 * Icy is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Icy is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Icy. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package plugins.kernel.roi.roi2d; 020 021import icy.canvas.IcyCanvas; 022import icy.painter.Anchor2D; 023import icy.painter.LineAnchor2D; 024import icy.resource.ResourceUtil; 025import icy.roi.ROI; 026import icy.type.point.Point2DUtil; 027import icy.type.point.Point5D; 028import icy.util.XMLUtil; 029 030import java.awt.Graphics2D; 031import java.awt.geom.Line2D; 032import java.awt.geom.Point2D; 033import java.awt.geom.Rectangle2D; 034import java.util.List; 035 036import org.w3c.dom.Node; 037 038/** 039 * ROI 2D Line. 040 * 041 * @author Stephane 042 */ 043public class ROI2DLine extends ROI2DShape 044{ 045 protected class ROI2DLineAnchor2D extends LineAnchor2D 046 { 047 public ROI2DLineAnchor2D(Point2D position) 048 { 049 super(position, getOverlay().getColor(), getOverlay().getFocusedColor()); 050 } 051 052 @Override 053 protected Anchor2D getPreviousPoint() 054 { 055 if (this == pt1) 056 return pt2; 057 return pt1; 058 } 059 } 060 061 public class ROI2DLinePainter extends ROI2DShapePainter 062 { 063 @Override 064 protected boolean isTiny(Rectangle2D bounds, Graphics2D g, IcyCanvas canvas) 065 { 066 if (isSelected()) 067 return false; 068 069 return super.isTiny(bounds, g, canvas); 070 } 071 } 072 073 public static final String ID_PT1 = "pt1"; 074 public static final String ID_PT2 = "pt2"; 075 076 protected final Anchor2D pt1; 077 protected final Anchor2D pt2; 078 079 public ROI2DLine(Point2D pt1, Point2D pt2) 080 { 081 super(new Line2D.Double()); 082 083 this.pt1 = createAnchor(pt1); 084 this.pt2 = createAnchor(pt2); 085 // keep pt2 selected to size the line for "interactive mode" 086 this.pt2.setSelected(true); 087 088 addPoint(this.pt1); 089 addPoint(this.pt2); 090 091 // set icon (default name is defined by getDefaultName()) 092 setIcon(ResourceUtil.ICON_ROI_LINE); 093 } 094 095 public ROI2DLine(Line2D line) 096 { 097 this(line.getP1(), line.getP2()); 098 } 099 100 /** 101 * @deprecated 102 */ 103 @SuppressWarnings("unused") 104 @Deprecated 105 public ROI2DLine(Point2D pt, boolean cm) 106 { 107 this(pt); 108 } 109 110 public ROI2DLine(Point2D pt) 111 { 112 this(new Point2D.Double(pt.getX(), pt.getY()), pt); 113 } 114 115 /** 116 * Generic constructor for interactive mode 117 */ 118 public ROI2DLine(Point5D pt) 119 { 120 this(pt.toPoint2D()); 121 // getOverlay().setMousePos(pt); 122 } 123 124 public ROI2DLine(double x1, double y1, double x2, double y2) 125 { 126 this(new Point2D.Double(x1, y1), new Point2D.Double(x2, y2)); 127 } 128 129 public ROI2DLine() 130 { 131 this(new Point2D.Double(), new Point2D.Double()); 132 } 133 134 @Override 135 public String getDefaultName() 136 { 137 return "Line2D"; 138 } 139 140 @Override 141 protected ROI2DShapePainter createPainter() 142 { 143 return new ROI2DLinePainter(); 144 } 145 146 @Override 147 protected Anchor2D createAnchor(Point2D pos) 148 { 149 return new ROI2DLineAnchor2D(pos); 150 } 151 152 public Line2D getLine() 153 { 154 return (Line2D) shape; 155 } 156 157 @Override 158 public boolean canSetBounds() 159 { 160 return true; 161 } 162 163 @Override 164 public void setBounds2D(Rectangle2D bounds) 165 { 166 beginUpdate(); 167 try 168 { 169 pt1.setPosition(bounds.getMinX(), bounds.getMinY()); 170 pt2.setPosition(bounds.getMaxX(), bounds.getMaxY()); 171 } 172 finally 173 { 174 endUpdate(); 175 } 176 } 177 178 public void setLine(Line2D line) 179 { 180 beginUpdate(); 181 try 182 { 183 pt1.setPosition(line.getP1()); 184 pt2.setPosition(line.getP2()); 185 } 186 finally 187 { 188 endUpdate(); 189 } 190 } 191 192 @Override 193 protected void updateShape() 194 { 195 getLine().setLine(pt1.getPosition(), pt2.getPosition()); 196 197 // call super method after shape has been updated 198 super.updateShape(); 199 } 200 201 @Override 202 public boolean canAddPoint() 203 { 204 // this ROI doesn't support point add 205 return false; 206 } 207 208 @Override 209 public boolean canRemovePoint() 210 { 211 // this ROI doesn't support point remove 212 return false; 213 } 214 215 @Override 216 protected boolean removePoint(IcyCanvas canvas, Anchor2D pt) 217 { 218 // this ROI doesn't support point remove 219 return false; 220 } 221 222 @Override 223 protected double getTotalDistance(List<Point2D> points, double factorX, double factorY) 224 { 225 // for ROI2DLine the total length don't need last point connection 226 return Point2DUtil.getTotalDistance(points, factorX, factorY, false); 227 } 228 229 @Override 230 public double computeNumberOfPoints() 231 { 232 return 0d; 233 } 234 235 @Override 236 public boolean contains(double x, double y) 237 { 238 return false; 239 } 240 241 @Override 242 public boolean contains(Point2D p) 243 { 244 return false; 245 } 246 247 @Override 248 public boolean contains(double x, double y, double w, double h) 249 { 250 return false; 251 } 252 253 @Override 254 public boolean contains(Rectangle2D r) 255 { 256 return false; 257 } 258 259 @Override 260 public boolean contains(ROI roi) 261 { 262 return false; 263 } 264 265 @Override 266 public boolean intersects(ROI r) 267 { 268 // special case of ROI2DLine 269 if (r instanceof ROI2DLine) 270 return onSamePos(((ROI2DLine) r), false) && ((ROI2DLine) r).getLine().intersectsLine(getLine()); 271 // special case of ROI2DRectangle 272 if (r instanceof ROI2DRectangle) 273 return onSamePos(((ROI2DRectangle) r), false) 274 && ((ROI2DRectangle) r).getRectangle().intersectsLine(getLine()); 275 276 return super.intersects(r); 277 } 278 279 @Override 280 public boolean loadFromXML(Node node) 281 { 282 beginUpdate(); 283 try 284 { 285 if (!super.loadFromXML(node)) 286 return false; 287 288 pt1.loadPositionFromXML(XMLUtil.getElement(node, ID_PT1)); 289 pt2.loadPositionFromXML(XMLUtil.getElement(node, ID_PT2)); 290 } 291 finally 292 { 293 endUpdate(); 294 } 295 296 return true; 297 } 298 299 @Override 300 public boolean saveToXML(Node node) 301 { 302 if (!super.saveToXML(node)) 303 return false; 304 305 pt1.savePositionToXML(XMLUtil.setElement(node, ID_PT1)); 306 pt2.savePositionToXML(XMLUtil.setElement(node, ID_PT2)); 307 308 return true; 309 } 310}