Package diva.canvas.interactor

Source Code of diva.canvas.interactor.DragInteractor

/*
Copyright (c) 1998-2005 The Regents of the University of California
All rights reserved.
Permission is hereby granted, without written agreement and without
license or royalty fees, to use, copy, modify, and distribute this
software and its documentation for any purpose, provided that the above
copyright notice and the following two paragraphs appear in all copies
of this software.

IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
PROVIDED HEREUNDER IS ON AN  BASIS, AND THE UNIVERSITY OF
CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.

PT_COPYRIGHT_VERSION_2
COPYRIGHTENDKEY
*
*/
package diva.canvas.interactor;

import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Iterator;

import diva.canvas.Figure;
import diva.canvas.event.LayerEvent;
import diva.canvas.event.LayerEventMulticaster;
import diva.canvas.event.LayerListener;
import diva.util.ArrayIterator;

/**
* An interactor that responds to mouse drag events. It adds
* the notion of constraints, so that dragging can be limited
* to certain coordinates or "snapped" to suitable locations,
* and a "target" array, which contain the figure or figures
* that are dragged.
*
* @version $Id: DragInteractor.java,v 1.14 2005/12/14 04:12:39 cxh Exp $
* @author John Reekie
*/
public class DragInteractor extends AbstractInteractor {
    /** The set of constraints
     */
    private ArrayList _constraints;

    /** The target array. This is an array of objects to make it
     * easier to use with SelectionModel.
     */
    private transient Object[] _targetArray;

    /** Layer listeners
     */
    private transient LayerListener _layerListener;

    /* The most recent coordinates
     */
    private double _prevX = 0.0;

    private double _prevY = 0.0;

    /* Enable only if the figure in the event is in the selection
     */
    private boolean _selectiveEnabled;

    ///////////////////////////////////////////////////////////////////
    //// public methods

    /** Add the given layer listener to this interactor.  Any event that is
     * received by this interactor will be passed on to the listener after
     * it is handled by this interactor.
     */
    public void addLayerListener(LayerListener l) {
        _layerListener = LayerEventMulticaster.add(_layerListener, l);
    }

    /** Append a constraint to the list of constraints on
     * this interactor.
     */
    public void appendConstraint(PointConstraint constraint) {
        if (_constraints == null) {
            _constraints = new ArrayList();
        }

        _constraints.add(constraint);
    }

    /** Constrain a point using the current constraints.  The given
     * point will be modified according to the current
     * constraints. This method <i>does not</i> trigger constraint
     * events. The caller must be careful to make a copy of the passed
     * point if it is not guaranteed that changing the point will not
     * affect other objects with a reference to it.
     */
    public void constrainPoint(Point2D p) {
        if (_constraints != null) {
            Iterator i = _constraints.iterator();

            while (i.hasNext()) {
                PointConstraint c = (PointConstraint) i.next();
                c.constrain(p);
            }
        }
    }

    /** Fire a layer event.
     */
    public void fireLayerEvent(LayerEvent event) {
        if (_layerListener != null) {
            int id = event.getID();

            switch (id) {
            case MouseEvent.MOUSE_PRESSED:
                _layerListener.mousePressed(event);
                break;

            case MouseEvent.MOUSE_DRAGGED:
                _layerListener.mouseDragged(event);
                break;

            case MouseEvent.MOUSE_RELEASED:
                _layerListener.mouseReleased(event);
                break;
            }
        }
    }

    /** Get the flag that says that the interactor responds only
     * if the figure being moused on is selected. By default, this
     * flag is false.
     */
    public boolean getSelectiveEnabled() {
        return _selectiveEnabled;
    }

    /** Get the target array.
     */
    public Object[] getTargetArray() {
        return _targetArray;
    }

    /** Get the current value of the X coordinate
     */
    public double getX() {
        return _prevX;
    }

    /** Get the current value of the Y coordinate
     */
    public double getY() {
        return _prevY;
    }

    /** Constrain the point and move the target if the mouse
     * move. The target movement is done by the translate()
     * method, which can be overridden to change the behaviour.
     * Nothing happens if the interactor is not enabled, or if it
     * is "selective enabled" but not in the selection.
     */
    public void mouseDragged(LayerEvent e) {
        if (!isEnabled()
                || (_selectiveEnabled && !SelectionInteractor.isSelected(e))) {
            return;
        }

        if ((getMouseFilter() == null) || getMouseFilter().accept(e)) {
            // Constrain the point
            Point2D p = e.getLayerPoint();
            constrainPoint(p);

            // Translate and consume if the point changed
            double x = p.getX();
            double y = p.getY();
            double deltaX = x - _prevX;
            double deltaY = y - _prevY;

            if ((deltaX != 0) || (deltaY != 0)) {
                translate(e, deltaX, deltaY);
                fireLayerEvent(e);
            }

            _prevX = x;
            _prevY = y;

            // Consume the event
            if (isConsuming()) {
                e.consume();
            }
        }
    }

    /** Handle a mouse press on a figure or layer. Set the target
     * to be the figure contained in the event. Call the setup()
     * method in case there is additional setup to do, then
     * constrain the point and remember it.
     * Nothing happens if the interactor is not enabled, or if it
     * is "selective enabled" but not in the selection.
     */
    public void mousePressed(LayerEvent e) {
        if (!isEnabled()
                || (_selectiveEnabled && !SelectionInteractor.isSelected(e))) {
            return;
        }

        if ((getMouseFilter() == null) || getMouseFilter().accept(e)) {
            // Set up the target array if it hasn't already been
            if (_targetArray == null) {
                _targetArray = new Object[1];
                _targetArray[0] = e.getFigureSource();
            }

            // Set-up
            setup(e);

            // Constrain and remember the point
            Point2D p = e.getLayerPoint();

            // FIXME: no, don't constrain in mouse-pressed!?
            //constrainPoint(p);
            _prevX = p.getX();
            _prevY = p.getY();

            // Inform listeners
            fireLayerEvent(e);

            // Consume the event
            if (isConsuming()) {
                e.consume();
            }
        }
    }

    /** Handle a mouse released event.
     * Nothing happens if the interactor is not enabled, if if it
     * is "selective enabled" but not in the selection.
     */
    public void mouseReleased(LayerEvent e) {
        if (!isEnabled()
                || (_selectiveEnabled && !SelectionInteractor.isSelected(e))) {
            return;
        }

        if ((getMouseFilter() == null) || getMouseFilter().accept(e)) {
            fireLayerEvent(e);
            _targetArray = null;

            // Consume the event
            if (isConsuming()) {
                e.consume();
            }
        }
    }

    /** Prepend a constraint to the list of constraints on
     * this interactor.
     */
    public void prependConstraint(PointConstraint constraint) {
        if (_constraints == null) {
            _constraints = new ArrayList();
        }

        _constraints.add(0, constraint);
    }

    /** Remove the given layer listener from this interactor.
     */
    public void removeLayerListener(LayerListener l) {
        _layerListener = LayerEventMulticaster.remove(_layerListener, l);
    }

    /** Set the flag that says that the interactor responds only
     * if the figure being moused on is selected. By default, this
     * flag is false; if set true, then the mouse methods check that
     * the figure is contained in the selection model of that
     * figure's selection interactor (if it has one).
     */
    public boolean setSelectiveEnabled(boolean s) {
        return _selectiveEnabled = s;
    }

    /** Set the target that the interactor operates on.
     * By default, this will be the figure obtained from
     * the event, but this method can be used to set it to
     * something else.
     */
    public void setTargetArray(Object[] arr) {
        _targetArray = arr;
    }

    /** Initialize the interactor before a mouse-pressed event is
     * processed. This default implementation
     * does nothing, but clients can override to cause it to
     * perform some action, such as setting up constraints.
     */
    public void setup(LayerEvent e) {
        // do nothing
    }

    /** Get an iterator over the target figures.
     */
    public Iterator targets() {
        return new ArrayIterator(_targetArray);
    }

    /** Translate the target by the given distance. The first argument
     * is the figure that was moused one. Any overriding methods should
     * be aware that the interactor may in general be operating on
     * multiple figures, and use the targets() method to get them.
     */
    public void translate(LayerEvent e, double x, double y) {
        Iterator i = targets();

        while (i.hasNext()) {
            Figure t = (Figure) i.next();
            t.translate(x, y);
        }
    }
}
TOP

Related Classes of diva.canvas.interactor.DragInteractor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.