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 icy.painter;
020
021import icy.util.EventUtil;
022
023import java.awt.Color;
024import java.awt.event.InputEvent;
025import java.awt.geom.Point2D;
026
027/**
028 * Anchor for line type shape.<br>
029 * Support special line drag operation when shift is maintained.
030 * 
031 * @author Stephane
032 */
033public abstract class LineAnchor2D extends Anchor2D
034{
035    public LineAnchor2D(Point2D position, Color color, Color selectedColor)
036    {
037        super(position.getX(), position.getY(), color, selectedColor);
038    }
039
040    @Override
041    protected boolean updateDrag(InputEvent e, double x, double y)
042    {
043        // not dragging --> exit
044        if (startDragMousePosition == null)
045            return false;
046
047        final Anchor2D anchor = getPreviousPoint();
048
049        // shift action --> special drag
050        if (EventUtil.isShiftDown(e) && (anchor != null))
051        {
052            final Point2D pos = anchor.getPosition();
053
054            double dx = x - pos.getX();
055            double dy = y - pos.getY();
056
057            final double absDx = Math.abs(dx);
058            final double absDy = Math.abs(dy);
059            final double dist;
060
061            if ((absDx != 0) && (absDy != 0))
062                dist = absDx / absDy;
063            else
064                dist = 0;
065
066            // square drag
067            if ((dist > 0.5) && (dist < 1.5))
068            {
069                // align to DY
070                if (absDx > absDy)
071                {
072                    if (dx >= 0)
073                        dx = absDy;
074                    else
075                        dx = -absDy;
076                }
077                // align to DX
078                else
079                {
080                    if (dy >= 0)
081                        dy = absDx;
082                    else
083                        dy = -absDx;
084                }
085            }
086            else
087            // one direction drag
088            {
089                // drag X
090                if (absDx > absDy)
091                    dy = 0;
092                // drag Y
093                else
094                    dx = 0;
095            }
096
097            // set new position
098            setPosition(pos.getX() + dx, pos.getY() + dy);
099        }
100        else
101        {
102            final double dx = x - startDragMousePosition.getX();
103            final double dy = y - startDragMousePosition.getY();
104
105            // set new position
106            setPosition(startDragPainterPosition.getX() + dx, startDragPainterPosition.getY() + dy);
107        }
108
109        return true;
110    }
111
112    protected abstract Anchor2D getPreviousPoint();
113}