package com.indago.iddea.view.viewer; /* * #%L * ImgLib2: a general-purpose, multidimensional image processing library. * %% * Copyright (C) 2009 - 2014 Stephan Preibisch, Tobias Pietzsch, Barry DeZonia, * Stephan Saalfeld, Albert Cardona, Curtis Rueden, Christian Dietz, Jean-Yves * Tinevez, Johannes Schindelin, Lee Kamentsky, Larry Lindsey, Grant Harris, * Mark Hiner, Aivar Grislis, Martin Horn, Nick Perry, Michael Zinsmaier, * Steffen Jaensch, Jan Funke, Mark Longair, and Dimiter Prodanov. * %% * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * #L% */ import java.awt.event.MouseEvent; import net.imglib2.realtransform.AffineTransform2D; import net.imglib2.ui.TransformEventHandler; import net.imglib2.ui.TransformEventHandler2D; import net.imglib2.ui.TransformEventHandlerFactory; import net.imglib2.ui.TransformListener; /** * This class is inherited from {@link TransformEventHandler2D} overriding setCanvasSize which is * able to scale it according to the minimum value between height and width. * * @author HongKee Moon */ public class InteractiveTransformEventHandler2D extends TransformEventHandler2D { final static private TransformEventHandlerFactory< AffineTransform2D > factory = new TransformEventHandlerFactory< AffineTransform2D >() { @Override public TransformEventHandler< AffineTransform2D > create( final TransformListener< AffineTransform2D > transformListener ) { return new InteractiveTransformEventHandler2D( transformListener ); } }; public static TransformEventHandlerFactory< AffineTransform2D > factory() { return factory; } public InteractiveTransformEventHandler2D( final TransformListener< AffineTransform2D > listener ) { super(listener); } @Override public void setCanvasSize( final int width, final int height, final boolean updateTransform ) { if ( updateTransform ) { synchronized ( affine ) { affine.set( affine.get( 0, 2 ) - canvasW / 2, 0, 2 ); affine.set( affine.get( 1, 2 ) - canvasH / 2, 1, 2 ); if(width - height < 0) affine.scale( ( double ) width / canvasW ); else affine.scale( ( double ) height / canvasH ); affine.set( affine.get( 0, 2 ) + width / 2, 0, 2 ); affine.set( affine.get( 1, 2 ) + height / 2, 1, 2 ); update(); } } canvasW = width; canvasH = height; centerX = width / 2; centerY = height / 2; } @Override public void mousePressed( final MouseEvent e ) { synchronized ( affine ) { oX = e.getX(); oY = e.getY(); affineDragStart.set( affine ); } } @Override public void mouseDragged( final MouseEvent e ) { synchronized ( affine ) { final int modifiers = e.getModifiersEx(); if ( ( modifiers & MouseEvent.BUTTON1_DOWN_MASK ) != 0 ) // rotate { affine.set( affineDragStart ); final double dX = e.getX() - oX; final double dY = e.getY() - oY; final double theta = Math.atan2( dY, dX ) - Math.atan2( oY, oX ); rotate( theta ); } else if ( ( modifiers & ( MouseEvent.BUTTON2_DOWN_MASK | MouseEvent.BUTTON3_DOWN_MASK ) ) != 0 ) // translate { affine.set( affineDragStart ); final double dX = oX - e.getX(); final double dY = oY - e.getY(); affine.set( affine.get( 0, 2 ) - dX, 0, 2 ); affine.set( affine.get( 1, 2 ) - dY, 1, 2 ); } update(); } } /** * Rotate by d radians. Mouse X and Y should be kept. * Florian requested this feature(#1066 in redmine) */ private void rotate( final double d ) { // center shift affine.set( affine.get( 0, 2 ) - oX, 0, 2 ); affine.set( affine.get( 1, 2 ) - oY, 1, 2 ); // rotate affine.rotate( d ); // center un-shift affine.set( affine.get( 0, 2 ) + oX, 0, 2 ); affine.set( affine.get( 1, 2 ) + oY, 1, 2 ); } }