/*-
* #%L
* Fiji distribution of ImageJ for the life sciences.
* %%
* Copyright (C) 2007 - 2017 Fiji developers.
* %%
* This program 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 2 of the
* License, or (at your option) any later version.
*
* This program 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 this program. If not, see
* <http://www.gnu.org/licenses/gpl-2.0.html>.
* #L%
*/
package spim.fiji.plugin.apply;
import bdv.BigDataViewer;
import bdv.viewer.ViewerFrame;
import java.awt.Button;
import java.awt.Checkbox;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowEvent;
import java.text.DecimalFormat;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.SwingUtilities;
import spim.vecmath.Transform3D;
import net.imglib2.realtransform.AffineTransform3D;
public class BigDataViewerTransformationWindow
{
final AffineTransform3D t;
final protected Timer timer;
protected boolean isRunning = true;
protected boolean wasCancelled = false;
protected boolean ignoreScaling = true;
public BigDataViewerTransformationWindow( final BigDataViewer bdv )
{
this.t = new AffineTransform3D();
final Frame frame = new Frame( "Current Global Transformation" );
frame.setSize( 400, 200 );
/* Instantiation */
final GridBagLayout layout = new GridBagLayout();
final GridBagConstraints c = new GridBagConstraints();
final Label text1 = new Label( "1.00000 0.00000 0.00000 0.00000", Label.CENTER );
final Label text2 = new Label( "0.00000 1.00000 0.00000 0.00000", Label.CENTER );
final Label text3 = new Label( "0.00000 0.00000 1.00000 0.00000", Label.CENTER );
text1.setFont( new Font( Font.MONOSPACED, Font.PLAIN, 14 ) );
text2.setFont( new Font( Font.MONOSPACED, Font.PLAIN, 14 ) );
text3.setFont( new Font( Font.MONOSPACED, Font.PLAIN, 14 ) );
final Button apply = new Button( "Apply Transformation" );
final Button cancel = new Button( "Cancel" );
final Checkbox ignoreScale = new Checkbox( "Ignore scaling factor from BigDataViewer", ignoreScaling );
/* Location */
frame.setLayout( layout );
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
frame.add( text1, c );
++c.gridy;
frame.add( text2, c );
++c.gridy;
frame.add( text3, c );
c.insets = new Insets( 20,0,0,0 );
++c.gridy;
frame.add( ignoreScale, c );
c.insets = new Insets( 20,0,0,0 );
++c.gridy;
frame.add( apply, c );
c.insets = new Insets( 0,0,0,0 );
++c.gridy;
frame.add( cancel, c );
apply.addActionListener( new ApplyButtonListener( frame, bdv ) );
cancel.addActionListener( new CancelButtonListener( frame, bdv ) );
ignoreScale.addItemListener( new ItemListener(){ public void itemStateChanged( final ItemEvent arg0 ) { ignoreScaling = ignoreScale.getState(); } });
frame.setVisible( true );
timer = new Timer();
timer.schedule( new BDVChecker( bdv, text1, text2, text3 ), 500 );
}
public AffineTransform3D getTransform() { return t; }
public boolean isRunning() { return isRunning; }
public boolean wasCancelled() { return wasCancelled; }
protected void close( final Frame parent, final BigDataViewer bdv )
{
if ( parent != null )
parent.dispose();
isRunning = false;
}
protected class CancelButtonListener implements ActionListener
{
final Frame parent;
final BigDataViewer bdv;
public CancelButtonListener( final Frame parent, final BigDataViewer bdv )
{
this.parent = parent;
this.bdv = bdv;
}
@Override
public void actionPerformed( final ActionEvent arg0 )
{
wasCancelled = true;
close( parent, bdv );
}
}
protected class BDVChecker extends TimerTask
{
final BigDataViewer bdv;
final Label text1, text2, text3;
public BDVChecker(
final BigDataViewer bdv,
final Label text1,
final Label text2,
final Label text3 )
{
this.bdv = bdv;
this.text1 = text1;
this.text2 = text2;
this.text3 = text3;
}
@Override
public void run()
{
if ( isRunning )
{
if ( bdv != null )
bdv.getViewer().getState().getViewerTransform( t );
t.set( 0, 0, 3 );
t.set( 0, 1, 3 );
t.set( 0, 2, 3 );
if ( ignoreScaling )
{
final double[] m = new double[ 16 ];
int i = 0;
for ( int row = 0; row < 3; ++row )
for ( int col = 0; col < 4; ++col )
m[ i++ ] = t.get( row, col );
m[ 15 ] = 1;
final Transform3D trans = new Transform3D( m );
trans.setScale( 1 );
trans.get( m );
i = 0;
for ( int row = 0; row < 3; ++row )
for ( int col = 0; col < 4; ++col )
t.set( m[ i++ ], row, col );
}
final DecimalFormat df = new DecimalFormat( "0.00000" );
text1.setText(
df.format( t.get( 0, 0 ) ).substring( 0, 7 ) + " " + df.format( t.get( 0, 1 ) ).substring( 0, 7 ) + " " +
df.format( t.get( 0, 2 ) ).substring( 0, 7 ) + " " + df.format( t.get( 0, 3 ) ).substring( 0, 7 ) );
text2.setText(
df.format( t.get( 1, 0 ) ).substring( 0, 7 ) + " " + df.format( t.get( 1, 1 ) ).substring( 0, 7 ) + " " +
df.format( t.get( 1, 2 ) ).substring( 0, 7 ) + " " + df.format( t.get( 1, 3 ) ).substring( 0, 7 ) );
text3.setText(
df.format( t.get( 2, 0 ) ).substring( 0, 7 ) + " " + df.format( t.get( 2, 1 ) ).substring( 0, 7 ) + " " +
df.format( t.get( 2, 2 ) ).substring( 0, 7 ) + " " + df.format( t.get( 2, 3 ) ).substring( 0, 7 ) );
// Reschedule myself (new instance is required, why?)
timer.schedule( new BDVChecker( bdv,text1, text2, text3 ), 500 );
}
}
}
protected class ApplyButtonListener implements ActionListener
{
final Frame parent;
final BigDataViewer bdv;
public ApplyButtonListener( final Frame parent, final BigDataViewer bdv )
{
this.parent = parent;
this.bdv = bdv;
}
@Override
public void actionPerformed( final ActionEvent arg0 )
{
wasCancelled = false;
close( parent, bdv );
}
}
public static void disposeViewerWindow( final BigDataViewer bdv )
{
try
{
SwingUtilities.invokeAndWait( new Runnable()
{
@Override
public void run()
{
final ViewerFrame frame = bdv.getViewerFrame();
final WindowEvent windowClosing = new WindowEvent( frame, WindowEvent.WINDOW_CLOSING );
frame.dispatchEvent( windowClosing );
}
} );
}
catch ( final Exception e )
{}
}
}