/*
* org.openmicroscopy.shoola.util.roi.figures.MeasureTextFigure
*
*------------------------------------------------------------------------------
* Copyright (C) 2006-2014 University of Dundee. All rights reserved.
*
*
* This program 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 2 of the License, or
* (at your option) any later version.
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*------------------------------------------------------------------------------
*/
package org.openmicroscopy.shoola.util.roi.figures;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import org.jhotdraw.draw.AbstractAttributedFigure;
import org.jhotdraw.draw.FigureListener;
import org.jhotdraw.draw.TextFigure;
import org.openmicroscopy.shoola.util.roi.model.ROI;
import org.openmicroscopy.shoola.util.roi.model.ROIShape;
import org.openmicroscopy.shoola.util.roi.model.annotation.MeasurementAttributes;
import org.openmicroscopy.shoola.util.roi.model.util.MeasurementUnits;
import org.openmicroscopy.shoola.util.roi.figures.ROIFigure;
import org.openmicroscopy.shoola.util.ui.drawingtools.figures.FigureUtil;
/**
* Text figure with measurement.
*
* @author Jean-Marie Burel
* <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author Donald MacDonald
* <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a>
* @version 3.0
* @since OME3.0
*/
public class MeasureTextFigure
extends TextFigure
implements ROIFigure
{
/** Flag indicating the figure can/cannot be deleted.*/
private boolean deletable;
/** Flag indicating the figure can/cannot be annotated.*/
private boolean annotatable;
/** Flag indicating the figure can/cannot be edited.*/
private boolean editable;
/** Is this figure read only. */
private boolean readOnly;
/** Is this figure a client object. */
private boolean clientObject;
/** has the figure been modified. */
private boolean dirty;
/** This is used to perform faster drawing and hit testing. */
protected Rectangle2D bounds;
/** The ROI containing the ROIFigure which in turn contains this Figure. */
protected ROI roi;
/** The ROIFigure contains this Figure. */
protected ROIShape shape;
/** Flag indicating if the user can move or resize the shape.*/
private boolean interactable;
/**
* The status of the figure i.e. {@link ROIFigure#IDLE} or
* {@link ROIFigure#MOVING}.
*/
private int status;
/** Creates a new instance. Default value <code>(0, 0) </code>.*/
public MeasureTextFigure()
{
this(0, 0);
}
/** Creates a new instance. Default value <code>(0, 0) </code>.
*
* @param readOnly The figure is read only.
* @param clientObject The figure is created client-side.
*/
public MeasureTextFigure(boolean readOnly, boolean clientObject)
{
this(0, 0, readOnly,clientObject, true, true, true);
}
/** Creates a new instance. Default value <code>(0, 0) </code>.
*
* @param readOnly The figure is read only.
* @param clientObject The figure is created client-side.
* @param editable Flag indicating the figure can/cannot be edited.
* @param deletable Flag indicating the figure can/cannot be deleted.
* @param annotatable Flag indicating the figure can/cannot be annotated.
*/
public MeasureTextFigure(boolean readOnly, boolean clientObject,
boolean editable, boolean deletable, boolean annotatable)
{
this(0, 0, readOnly,clientObject, true, true, true);
}
/**
* Creates a new instance.
*
* @param x The x-coordinate of the top-left corner.
* @param y The y-coordinate of the top-left corner.
*/
public MeasureTextFigure(double x, double y)
{
this(x, y, false, true, true, true, true);
}
/**
* Creates a new instance.
*
* @param x The x-coordinate of the top-left corner.
* @param y The y-coordinate of the top-left corner.
* @param readOnly The figure is read only.
* @param clientObject The figure is created client-side.
* @param editable Flag indicating the figure can/cannot be edited.
* @param deletable Flag indicating the figure can/cannot be deleted.
* @param annotatable Flag indicating the figure can/cannot be annotated.
*/
public MeasureTextFigure(double x, double y, boolean readOnly,
boolean clientObject, boolean editable, boolean deletable, boolean
annotatable)
{
super();
setAttribute(MeasurementAttributes.FONT_FACE, ROIFigure.DEFAULT_FONT);
setAttribute(MeasurementAttributes.FONT_SIZE, new Double(FONT_SIZE));
willChange();
changed();
shape = null;
roi = null;
status = IDLE;
setReadOnly(readOnly);
setClientObject(clientObject);
this.deletable = deletable;
this.annotatable = annotatable;
this.editable = editable;
interactable = true;
setBounds(new Point2D.Double(x, y), new Point2D.Double(x, y));
}
/**
* Overridden to stop updating shape if read-only
* @see AbstractAttributedFigure#transform(AffineTransform)
*/
public void transform(AffineTransform tx)
{
if (!readOnly && interactable)
{
super.transform(tx);
this.setObjectDirty(true);
}
}
/**
* Overridden to stop updating shape if read-only.
* @see AbstractAttributedFigure#setBounds(Point2D.Double, Point2D.Double)
*/
public void setBounds(Point2D.Double anchor, Point2D.Double lead)
{
if (!readOnly && interactable)
{
super.setBounds(anchor, lead);
this.setObjectDirty(true);
}
}
/**
* Overridden to return the correct handles.
* @see AbstractAttributedFigure#createHandles(int)
*/
/* cannot do that otherwise enter in an infinite loop
public Collection<Handle> createHandles(int detailLevel)
{
if(!readOnly)
return super.createHandles(detailLevel);
else
{
LinkedList<Handle> handles = new LinkedList<Handle>();
handles.add(new BoundsOutlineHandle(this));
return handles;
}
}
*/
/**
* Implemented as specified by the {@link ROIFigure} interface.
* @see ROIFigure#getROI()
*/
public ROI getROI() { return roi; }
/**
* Implemented as specified by the {@link ROIFigure} interface.
* @see ROIFigure#getROIShape()
*/
public ROIShape getROIShape() { return shape; }
/**
* Implemented as specified by the {@link ROIFigure} interface.
* @see ROIFigure#setROI(ROI)
*/
public void setROI(ROI roi) { this.roi = roi; }
/**
* Implemented as specified by the {@link ROIFigure} interface.
* @see ROIFigure#setROIShape(ROIShape)
*/
public void setROIShape(ROIShape shape) { this.shape = shape; }
/**
* Implemented as specified by the {@link ROIFigure} interface.
* @see ROIFigure#getType()
*/
public String getType() { return FigureUtil.TEXT_TYPE; }
/**
* Implemented as specified by the {@link ROIFigure} interface.
* @see ROIFigure#setMeasurementUnits(MeasurementUnits)
*/
public void setMeasurementUnits(MeasurementUnits units)
{}
/**
* Required by the {@link ROIFigure} interface but no-op implementation
* in our case.
* @see ROIFigure#calculateMeasurements()
*/
public void calculateMeasurements() {}
/**
* Required by the {@link ROIFigure} interface but no-op implementation
* in our case.
* @see ROIFigure#getPoints()
*/
public List<Point> getPoints() { return null; }
/**
* Implemented as specified by the {@link ROIFigure} interface.
* @see ROIFigure#getSize()
*/
public int getSize() { return 0; }
/**
* Implemented as specified by the {@link ROIFigure} interface.
* @see ROIFigure#setStatus(int)
*/
public void setStatus(int status) { this.status = status; }
/**
* Implemented as specified by the {@link ROIFigure} interface.
* @see ROIFigure#getStatus()
*/
public int getStatus() { return status; }
/**
* Implemented as specified by the {@link ROIFigure} interface.
* @see ROIFigure#isReadOnly()
*/
public boolean isReadOnly() { return readOnly;}
/**
* Implemented as specified by the {@link ROIFigure} interface.
* @see ROIFigure#setReadOnly(boolean)
*/
public void setReadOnly(boolean readOnly)
{
this.readOnly = readOnly;
setEditable(!readOnly);
}
/**
* Implemented as specified by the {@link ROIFigure} interface
* @see ROIFigure#isClientObject()
*/
public boolean isClientObject() { return clientObject; }
/**
* Implemented as specified by the {@link ROIFigure} interface
* @see ROIFigure#setClientObject(boolean)
*/
public void setClientObject(boolean clientSide)
{
clientObject = clientSide;
}
/**
* Implemented as specified by the {@link ROIFigure} interface
* @see ROIFigure#isDirty()
*/
public boolean isDirty() { return dirty; }
/**
* Implemented as specified by the {@link ROIFigure} interface
* @see ROIFigure#setObjectDirty(boolean)
*/
public void setObjectDirty(boolean dirty) { this.dirty = dirty; }
/**
* Clones the figure.
* @see MeasureTextFigure#clone()
*/
public MeasureTextFigure clone()
{
MeasureTextFigure that = (MeasureTextFigure) super.clone();
that.setReadOnly(this.isReadOnly());
that.setClientObject(this.isClientObject());
that.setObjectDirty(true);
that.setInteractable(true);
return that;
}
/**
* Marks the figure as dirty.
*
* @see MeasureTextFigure#setText(String)
*/
public void setText(String text)
{
super.setText(text);
this.setObjectDirty(true);
}
@Override
protected void drawText(Graphics2D g) {
if (getText() != null) {
g.setColor(MeasurementAttributes.STROKE_COLOR.get(this));
super.drawText(g);
}
}
/**
* Implemented as specified by the {@link ROIFigure} interface
* @see ROIFigure#getFigureListeners()
*/
public List<FigureListener> getFigureListeners()
{
List<FigureListener> figListeners = new ArrayList<FigureListener>();
Object[] listeners = listenerList.getListenerList();
for (Object listener : listeners)
if (listener instanceof FigureListener)
figListeners.add((FigureListener)listener);
return figListeners;
}
/**
* Implemented as specified by the {@link ROIFigure} interface
* @see ROIFigure#canAnnotate()
*/
public boolean canAnnotate() { return annotatable; }
/**
* Implemented as specified by the {@link ROIFigure} interface
* @see ROIFigure#canDelete()
*/
public boolean canDelete() { return deletable; }
/**
* Implemented as specified by the {@link ROIFigure} interface
* @see ROIFigure#canAnnotate()
*/
public boolean canEdit() { return editable; }
/**
* Implemented as specified by the {@link ROIFigure} interface
* @see ROIFigure#setInteractable(boolean)
*/
public void setInteractable(boolean interactable)
{
this.interactable = interactable;
}
/**
* Implemented as specified by the {@link ROIFigure} interface
* @see ROIFigure#canInteract()
*/
public boolean canInteract() { return interactable; }
}