/* * 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 icy.canvas; import icy.main.Icy; import icy.painter.Overlay; import icy.painter.Overlay.OverlayPriority; import icy.painter.OverlayEvent; import icy.painter.OverlayEvent.OverlayEventType; import icy.painter.OverlayListener; import icy.painter.OverlayWrapper; import icy.painter.Painter; import icy.painter.WeakOverlayListener; import icy.roi.ROI; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; /** * Layer class.<br> * This class encapsulate {@link Overlay} in a canvas to<br> * add specific display properties (visibility, transparency...). */ public class Layer implements OverlayListener, Comparable<Layer> { public interface LayerListener { public void layerChanged(Layer source, String propertyName); } public final static String PROPERTY_NAME = Overlay.PROPERTY_NAME; public final static String PROPERTY_PRIORITY = Overlay.PROPERTY_PRIORITY; public final static String PROPERTY_READONLY = Overlay.PROPERTY_READONLY; public final static String PROPERTY_CANBEREMOVED = Overlay.PROPERTY_CANBEREMOVED; public final static String PROPERTY_RECEIVEKEYEVENTONHIDDEN = Overlay.PROPERTY_RECEIVEKEYEVENTONHIDDEN; public final static String PROPERTY_RECEIVEMOUSEEVENTONHIDDEN = Overlay.PROPERTY_RECEIVEMOUSEEVENTONHIDDEN; /** * @deprecated Use {@link #PROPERTY_OPACITY} instead */ @Deprecated public final static String PROPERTY_ALPHA = "alpha"; public final static String PROPERTY_OPACITY = "opacity"; public final static String PROPERTY_VISIBLE = "visible"; public final static String DEFAULT_NAME = "layer"; /** * Returns true if the Layer need to be repainted when the specified property has changed. */ public static boolean isPaintProperty(String propertyName) { if (propertyName == null) return false; return propertyName.equals(PROPERTY_OPACITY) || propertyName.equals(PROPERTY_PRIORITY) || propertyName.equals(PROPERTY_VISIBLE); } static Overlay createOverlayWrapper(@SuppressWarnings("deprecation") Painter painter, String name) { if (painter instanceof Overlay) return (Overlay) painter; final Overlay result = new OverlayWrapper(painter, name); if (name == null) result.setName(DEFAULT_NAME); // default priority result.setPriority(OverlayPriority.SHAPE_NORMAL); return result; } private final Overlay overlay; // cache for ROI private WeakReference<ROI> roi; private boolean visible; private float alpha; /** * listeners */ protected final List<LayerListener> listeners; public Layer(Overlay overlay) { this.overlay = overlay; overlay.addOverlayListener(new WeakOverlayListener(this)); visible = true; alpha = 1f; roi = null; listeners = new ArrayList<LayerListener>(); } /** * @deprecated Use {@link #Layer(Overlay)} instead. */ @Deprecated public Layer(Painter painter, String name) { this(createOverlayWrapper(painter, name)); } /** * @deprecated Use {@link #Layer(Overlay)} instead. */ @Deprecated public Layer(Painter painter) { this(painter, null); } /** * Returns the attached {@link Overlay}. */ public Overlay getOverlay() { return overlay; } /** * @deprecated Use {@link #getOverlay()} instead. */ @Deprecated public Painter getPainter() { final Overlay result = getOverlay(); if (result instanceof OverlayWrapper) return ((OverlayWrapper) result).getPainter(); return result; } /** * Returns layer priority (internally use the overlay priority). * * @see Overlay#getPriority() */ public OverlayPriority getPriority() { return overlay.getPriority(); } /** * Set the layer priority (internally set the overlay priority). * * @see Overlay#setPriority(OverlayPriority) */ public void setPriority(OverlayPriority priority) { overlay.setPriority(priority); } /** * Returns layer name (internally use the overlay name). * * @see Overlay#getName() */ public String getName() { return overlay.getName(); } /** * Set the layer name (internally set the overlay name) * * @see Overlay#setName(String) */ public void setName(String name) { overlay.setName(name); } /** * Returns the read only property name (internally use the overlay read only property). * * @see Overlay#isReadOnly() */ public boolean isReadOnly() { return overlay.isReadOnly(); } /** * Set read only property (internally set the overlay read only property). * * @see Overlay#setReadOnly(boolean) */ public void setReadOnly(boolean readOnly) { overlay.setReadOnly(readOnly); } /** * Returns fixed property. * * @deprecated Use {@link #getCanBeRemoved()} instead. */ @Deprecated public boolean isFixed() { return !getCanBeRemoved(); } /** * @deprecated Use {@link #setCanBeRemoved(boolean)} instead. */ @Deprecated public void setFixed(boolean value) { setCanBeRemoved(value); } /** * Returns <code>true</code> if the layer can be freely removed from the Canvas where it * appears and <code>false</code> otherwise.<br/> * * @see Overlay#getCanBeRemoved() */ public boolean getCanBeRemoved() { return overlay.getCanBeRemoved(); } /** * Set the <code>canBeRemoved</code> property.<br/> * Set it to false if you want to prevent the layer to be removed from the Canvas where it * appears. * * @see Overlay#setCanBeRemoved(boolean) */ public void setCanBeRemoved(boolean value) { overlay.setCanBeRemoved(value); } /** * @see Overlay#getReceiveKeyEventOnHidden() */ public boolean getReceiveKeyEventOnHidden() { return overlay.getReceiveKeyEventOnHidden(); } /** * @see Overlay#setReceiveKeyEventOnHidden(boolean) */ public void setReceiveKeyEventOnHidden(boolean value) { overlay.setReceiveKeyEventOnHidden(value); } /** * @see Overlay#getReceiveMouseEventOnHidden() */ public boolean getReceiveMouseEventOnHidden() { return overlay.getReceiveMouseEventOnHidden(); } /** * @see Overlay#setReceiveMouseEventOnHidden(boolean) */ public void setReceiveMouseEventOnHidden(boolean value) { overlay.setReceiveMouseEventOnHidden(value); } /** * @return the attachedROI */ public ROI getAttachedROI() { if (roi == null) // search for attached ROI roi = new WeakReference<ROI>(Icy.getMainInterface().getROI(overlay)); return roi.get(); } /** * @return the visible */ public boolean isVisible() { return visible; } /** * @param visible * the visible to set */ public void setVisible(boolean visible) { if (this.visible != visible) { this.visible = visible; changed(PROPERTY_VISIBLE); } } /** * @return the layer opacity */ public float getOpacity() { return alpha; } /** * Set the layer opacity */ public void setOpacity(float value) { if (alpha != value) { alpha = value; changed(PROPERTY_OPACITY); } } /** * @deprecated Use {@link #getOpacity()} instead */ @Deprecated public float getAlpha() { return getOpacity(); } /** * @deprecated Use {@link #setOpacity(float)} instead. */ @Deprecated public void setAlpha(float value) { setOpacity(value); } /** * Called on layer property change */ protected void changed(String propertyName) { // notify listener fireChangedEvent(propertyName); } /** * fire event */ private void fireChangedEvent(String propertyName) { final List<LayerListener> list; synchronized (listeners) { list = new ArrayList<Layer.LayerListener>(listeners); } for (LayerListener listener : list) listener.layerChanged(this, propertyName); } /** * Add a listener * * @param listener */ public void addListener(LayerListener listener) { synchronized (listeners) { listeners.add(listener); } } /** * Remove a listener * * @param listener */ public void removeListener(LayerListener listener) { synchronized (listeners) { listeners.remove(listener); } } @Override public void overlayChanged(OverlayEvent event) { // only interested by property change here if (event.getType() == OverlayEventType.PROPERTY_CHANGED) changed(event.getPropertyName()); } @Override public int compareTo(Layer layer) { // compare with overlay return getOverlay().compareTo(layer.getOverlay()); } }