/* * Copyright 2010-2013 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.sequence; import icy.common.EventHierarchicalChecker; import icy.util.StringUtil; public class SequenceEvent implements EventHierarchicalChecker { public enum SequenceEventSourceType { SEQUENCE_TYPE, SEQUENCE_META, SEQUENCE_COLORMAP, SEQUENCE_COMPONENTBOUNDS, SEQUENCE_DATA, SEQUENCE_ROI, /** * @deprecated **/ @Deprecated SEQUENCE_PAINTER, SEQUENCE_OVERLAY } public enum SequenceEventType { CHANGED, ADDED, REMOVED } private final Sequence sequence; private final SequenceEventSourceType sourceType; private SequenceEventType type; private Object source; private int param; public SequenceEvent(Sequence sequence, SequenceEventSourceType sourceType) { this(sequence, sourceType, null, SequenceEventType.CHANGED, -1); } public SequenceEvent(Sequence sequence, SequenceEventSourceType sourceType, Object source) { this(sequence, sourceType, source, SequenceEventType.CHANGED, -1); } public SequenceEvent(Sequence sequence, SequenceEventSourceType sourceType, Object source, int param) { this(sequence, sourceType, source, SequenceEventType.CHANGED, param); } public SequenceEvent(Sequence sequence, SequenceEventSourceType sourceType, SequenceEventType type) { this(sequence, sourceType, null, type, -1); } public SequenceEvent(Sequence sequence, SequenceEventSourceType sourceType, Object source, SequenceEventType type) { this(sequence, sourceType, source, type, -1); } public SequenceEvent(Sequence sequence, SequenceEventSourceType sourceType, Object source, SequenceEventType type, int param) { super(); this.sequence = sequence; this.sourceType = sourceType; this.source = source; this.type = type; this.param = param; } /** * @return the sequence */ public Sequence getSequence() { return sequence; } /** * SourceType define the object type of <code>source<code><br> * <br> * The following source types are available :<br> * <code>SEQUENCE_TYPE</code> --> source object is null<br> * <code>SEQUENCE_META</code> --> source object define the meta data id (String)<br> * <code>SEQUENCE_COLORMAP</code> --> source object is an instance of IcyColorModel<br> * <code>SEQUENCE_COMPONENTBOUNDS</code> --> source object is an instance of IcyColorModel<br> * <code>SEQUENCE_DATA</code> --> source object is an instance of IcyBufferedImage<br> * source object can be null when severals images has been modified<br> * <code>SEQUENCE_ROI</code> --> source object is an instance of ROI<br> * source object can be null when severals images has been modified<br> * <code>SEQUENCE_OVERLAY</code> --> source object is an instance of Overlay<br> * source object can be null when severals images has been modified<br> * <code>SEQUENCE_PAINTER</code> --> source object is an instance of Painter<br> * source object can be null when severals images has been modified<br> * <br> */ public SequenceEventSourceType getSourceType() { return sourceType; } /** * Source object of the event.<br> * The object type here depend of the <code>sourceType</code> value.<br> */ public Object getSource() { return source; } /** * Type define the type of event.<br> * <br> * When <code>sourceType</code> is one of the following :<br> * <code>SEQUENCE_TYPE, SEQUENCE_META, SEQUENCE_COLORMAP, SEQUENCE_COMPONENTBOUNDS</code><br> * the type can only be <code>SequenceEventType.CHANGED</code><br> * <br> * When <code>sourceType</code> is one of the following :<br> * <code>SEQUENCE_DATA, SEQUENCE_ROI, SEQUENCE_PAINTER, SEQUENCE_OVERLAY</code><br> * the type can also be <code>SequenceEventType.ADDED</code> or * <code>SequenceEventType.REMOVED</code><br> * That mean a specific image, roi or painter (if <code>source != null</code>) has been added or * removed from the sequence.<br> * If <code>source == null</code> that mean we have a global change event and some stuff need to * be recalculated.<br> * Severals ADDED / CHANGED / REMOVE events can be compacted to one CHANGED event with a null * source (global change) for SEQUENCE_DATA source type. */ public SequenceEventType getType() { return type; } /** * Extra parameter of event.<br> * <br> * It's used to specify the component number when <code>sourceType</code> is * <code>SEQUENCE_COLORMAP</code> or <code>SEQUENCE_COMPONENTBOUNDS</code> (in both case source * is instance of <code>IcyColorModel</code>).<br> * Also used internally... */ public int getParam() { return param; } /** * Collapse event */ private boolean collapseWith(SequenceEvent e) { // same source type if (e.getSourceType() == sourceType) { switch (sourceType) { case SEQUENCE_META: if (StringUtil.equals((String) e.getSource(), (String) source)) return true; case SEQUENCE_COLORMAP: case SEQUENCE_COMPONENTBOUNDS: // join events in one global event if (e.getParam() != param) param = -1; return true; case SEQUENCE_DATA: // optimize different type event to a single CHANGED event (for DATA only) if (e.getType() != type) type = SequenceEventType.CHANGED; if (e.getSource() != source) source = null; return true; case SEQUENCE_PAINTER: case SEQUENCE_OVERLAY: case SEQUENCE_ROI: // same type ? if (e.getType() == type) { // join events in one global event if (e.getSource() != source) source = null; return true; } break; case SEQUENCE_TYPE: return true; } } return false; } @Override public boolean isEventRedundantWith(EventHierarchicalChecker event) { if (event instanceof SequenceEvent) return collapseWith((SequenceEvent) event); return false; } }