package net.sf.latexdraw.instruments;
import javax.swing.AbstractButton;
import javax.swing.JLabel;
import javax.swing.JSpinner;
import net.sf.latexdraw.actions.shape.RotateShapes;
import net.sf.latexdraw.badaboom.BadaboomCollector;
import net.sf.latexdraw.glib.models.interfaces.shape.IGroup;
import net.sf.latexdraw.glib.models.interfaces.shape.IShape;
import net.sf.latexdraw.lang.LangTool;
import net.sf.latexdraw.util.LResources;
import org.malai.instrument.Interactor;
import org.malai.swing.interaction.library.ButtonPressed;
import org.malai.swing.interaction.library.SpinnerModified;
import org.malai.swing.ui.SwingUIComposer;
import org.malai.swing.widget.MButton;
import org.malai.swing.widget.MSpinner;
import scala.Option;
/**
* This instrument modifies the rotation angle of selected shapes.<br>
* <br>
* This file is part of LaTeXDraw.<br>
* Copyright (c) 2005-2014 Arnaud BLOUIN<br>
* <br>
* LaTeXDraw 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.
* <br>
* LaTeXDraw is distributed 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.<br>
* <br>
* 12/31/2010<br>
* @author Arnaud BLOUIN
* @since 3.0
*/
public class ShapeRotationCustomiser extends ShapePropertyCustomiser {
/** The rotation button to perform 90 degree rotation. */
protected MButton rotate90Button;
/** The rotation button to perform 180 degree rotation. */
protected MButton rotate180Button;
/** The rotation button to perform 270 degree rotation. */
protected MButton rotate270Button;
/** The field that modifies the rotation angle. */
protected MSpinner rotationField;
/**
* Creates the instrument.
* @param composer The composer that manages the widgets of the instrument.
* @param hand The Hand instrument.
* @param pencil The Pencil instrument.
* @throws IllegalArgumentException If one of the given argument is null.
* @since 3.0
*/
public ShapeRotationCustomiser(final SwingUIComposer<?> composer, final Hand hand, final Pencil pencil) {
super(composer, hand, pencil);
initialiseWidgets();
}
@Override
protected void initialiseWidgets() {
rotate90Button = new MButton(LResources.ROTATE_90_ICON);
rotate90Button.setMargin(LResources.INSET_BUTTON);
rotate90Button.setToolTipText(LangTool.INSTANCE.getString18("LaTeXDrawFrame.3")); //$NON-NLS-1$
rotate180Button = new MButton(LResources.ROTATE_180_ICON);
rotate180Button.setMargin(LResources.INSET_BUTTON);
rotate180Button.setToolTipText(LangTool.INSTANCE.getString18("LaTeXDrawFrame.4")); //$NON-NLS-1$
rotate270Button = new MButton(LResources.ROTATE_270_ICON);
rotate270Button.setMargin(LResources.INSET_BUTTON);
rotate270Button.setToolTipText(LangTool.INSTANCE.getString18("LaTeXDrawFrame.5")); //$NON-NLS-1$
rotationField = new MSpinner(new MSpinner.MSpinnerNumberModel(0., -360., 360., 0.1), new JLabel(LangTool.INSTANCE.getStringDialogFrame("AbstractParametersFrame.7"))); //$NON-NLS-1$
rotationField.setEditor(new JSpinner.NumberEditor(rotationField, "0.0")); //$NON-NLS-1$
}
@Override
protected void setWidgetsVisible(final boolean visible) {
composer.setWidgetVisible(rotate180Button, visible);
composer.setWidgetVisible(rotate270Button, visible);
composer.setWidgetVisible(rotate90Button, visible);
composer.setWidgetVisible(rotationField, visible);
}
@Override
protected void update(final IGroup shape) {
if(shape!=null)
rotationField.setValueSafely(Math.toDegrees(shape.getRotationAngle()));
}
@Override
protected void initialiseInteractors() {
try{
addInteractor(new ButtonPress2RotateShape(this));
addInteractor(new Spinner2RotateShape(this));
}catch(InstantiationException | IllegalAccessException e){
BadaboomCollector.INSTANCE.add(e);
}
}
/**
* @return The rotation button to perform 90 degree rotation.
* @since 3.0
*/
public MButton getRotate90Button() {
return rotate90Button;
}
/**
* @return The rotation button to perform 180 degree rotation.
* @since 3.0
*/
public MButton getRotate180Button() {
return rotate180Button;
}
/**
* @return The rotation button to perform 270 degree rotation.
* @since 3.0
*/
public MButton getRotate270Button() {
return rotate270Button;
}
/**
* @return The field that modifies the rotation angle.
* @since 3.0
*/
public MSpinner getRotationField() {
return rotationField;
}
}
/**
* This link maps a spinner to an action that rotates the selected shapes.
*/
class Spinner2RotateShape extends Interactor<RotateShapes, SpinnerModified, ShapeRotationCustomiser> {
/**
* Creates the link.
* @param ins The instrument that contains the link.
* @throws InstantiationException If an error of instantiation (interaction, action) occurs.
* @throws IllegalAccessException If no free-parameter constructor are provided.
*/
Spinner2RotateShape(final ShapeRotationCustomiser ins) throws InstantiationException, IllegalAccessException {
super(ins, false, RotateShapes.class, SpinnerModified.class);
}
@Override
public boolean isConditionRespected() {
return instrument.getRotationField()==interaction.getSpinner();
}
@Override
public void updateAction() {
final Option<IShape> obj = action.shape();
if(obj.isDefined())
action.setRotationAngle(Math.toRadians(Double.valueOf(interaction.getSpinner().getValue().toString()))-obj.get().getRotationAngle());
}
@Override
public void initAction() {
final IShape sh = instrument.pencil.canvas().getDrawing().getSelection().duplicateDeep(false);
action.setShape(sh);
action.setGravityCentre(sh.getGravityCentre());
}
}
/**
* This link maps a button to an action that rotates the selected shapes.
*/
class ButtonPress2RotateShape extends Interactor<RotateShapes, ButtonPressed, ShapeRotationCustomiser> {
/**
* Creates the link.
* @param ins The instrument that contains the link.
* @throws InstantiationException If an error of instantiation (interaction, action) occurs.
* @throws IllegalAccessException If no free-parameter constructor are provided.
*/
ButtonPress2RotateShape(final ShapeRotationCustomiser ins) throws InstantiationException, IllegalAccessException {
super(ins, false, RotateShapes.class, ButtonPressed.class);
}
@Override
public boolean isConditionRespected() {
final AbstractButton button = interaction.getButton();
return button==instrument.rotate90Button || button==instrument.rotate180Button || button==instrument.rotate270Button;
}
@Override
public void initAction() {
final double angle;
final AbstractButton button = interaction.getButton();
if(button==instrument.rotate90Button)
angle = Math.PI/2.;
else if(button==instrument.rotate180Button)
angle = Math.PI;
else
angle = -Math.PI/2.;
action.setGravityCentre(instrument.pencil.canvas().getDrawing().getSelection().getGravityCentre());
action.setRotationAngle(angle);
action.setShape(instrument.pencil.canvas().getDrawing().getSelection().duplicateDeep(false));
}
}