/***********************************************************************
* mt4j Copyright (c) 2008 - 2009, C.Ruff, Fraunhofer-Gesellschaft All rights reserved.
*
* 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 3 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/>.
*
***********************************************************************/
package org.mt4j.input.gestureAction;
import org.mt4j.components.MTComponent;
import org.mt4j.components.TransformSpace;
import org.mt4j.components.visibleComponents.shapes.AbstractShape;
import org.mt4j.input.inputProcessors.IGestureEventListener;
import org.mt4j.util.math.Matrix;
import org.mt4j.util.math.Vector3D;
/**
* The Class DefaultSvgButtonClickAction.
* @author Christopher Ruff
*/
public class DefaultSvgButtonClickAction extends DefaultButtonClickAction implements IGestureEventListener {
/** The width obj space. */
private Vector3D widthObjSpace;
/** The center obj space. */
private Vector3D centerObjSpace;
/** The svg comp. */
private MTComponent svgComp;
/**
* Instantiates a new default svg button click action.
*
* @param svgComp the svg comp
*/
public DefaultSvgButtonClickAction(MTComponent svgComp) { //, MTPolygon largestPolyInSvg
super(DefaultSvgButtonClickAction.getLargestSvgComp(svgComp, null));
this.svgComp = svgComp;
this.width = this.getReferenceComp().getWidthXY(TransformSpace.RELATIVE_TO_PARENT);
// this.width = getCurrentUnscaledWidth();
this.widthObjSpace = this.getWidthVectorLocal();
// this.widthObjSpace = this.getReferenceComp().getWidthXYVectObjSpace();
this.centerObjSpace = this.getReferenceComp().getCenterPointLocal();
}
/**
* Gets the width obj space vector.
*
* @return the width obj space vector
*/
private Vector3D getWidthVectorLocal(){
if (this.getReferenceComp().hasBounds()){
return this.getReferenceComp().getBounds().getWidthXYVectLocal();
}else{
// return new Vector3D(Vector3D.ZERO_VECTOR);
throw new RuntimeException("Couldnt extract the width vector from the svg shape: '" + svgComp.getName() + "'. We need a component or boundingshape that defines the method getWidthXYVectObjSpace()");
}
}
/**
* Returns the component with the largest x,y dimension to use for picking by default and scaling.
*
* @param comp the comp
* @param compWithBiggestBoundingRect the comp with biggest bounding rect
*
* @return the largest svg comp
*/
public static AbstractShape getLargestSvgComp(MTComponent comp, AbstractShape compWithBiggestBoundingRect){
if (comp instanceof AbstractShape) {
AbstractShape shape = (AbstractShape) comp;
float rectWidthGlobal = shape.getWidthXY(TransformSpace.GLOBAL);
float rectHeightGlobal = shape.getHeightXY(TransformSpace.GLOBAL);
if (
compWithBiggestBoundingRect != null
){
// System.out.println("Fromer biggest != null, checking if " + comp.getName() + " is bigger.");
if ( rectWidthGlobal >= compWithBiggestBoundingRect.getWidthXY(TransformSpace.GLOBAL)//biggestWidth
|| rectHeightGlobal >= compWithBiggestBoundingRect.getHeightXY(TransformSpace.GLOBAL)//biggestHeight
){
// System.out.println(comp.getName() + " is bigger!");
compWithBiggestBoundingRect = shape;
}else{
// System.out.println(compWithBiggestBoundingRect.getName() + " is still bigger");
}
}else{
// System.out.println("Reference is null, take " + comp.getName() + " as the new biggest.");
compWithBiggestBoundingRect = shape;
}
}
for(MTComponent child : comp.getChildren()){
compWithBiggestBoundingRect = getLargestSvgComp(child, compWithBiggestBoundingRect);
}
return compWithBiggestBoundingRect;
}
/* (non-Javadoc)
* @see com.jMT.input.gestureAction.DefaultButtonClickAction#getCompToResize()
*/
@Override
public MTComponent getCompToResize() {
return this.svgComp;
}
/* (non-Javadoc)
* @see com.jMT.input.gestureAction.DefaultButtonClickAction#getCurrentUnscaledWidth()
*/
@Override
public float getCurrentUnscaledWidth(){
// Vector3D v = this.getReferenceComp().getWidthXYVectObjSpace();
Vector3D v = getWidthVectorLocal();
Matrix refCompLocalToWorld = new Matrix(this.getReferenceComp().getGlobalMatrix());
//Remove translation for direction vectors(width/height)
refCompLocalToWorld.removeTranslationFromMatrix();
//obj width vect to world space
v.transform(refCompLocalToWorld);
Matrix svgButtonAbsInv = new Matrix(this.getCompToResize().getGlobalInverseMatrix());
//TODO doch wieder localbase von svg dazutransformen?
//svgbutton inverse parent relative machen
svgButtonAbsInv.multLocal(this.getCompToResize().getLocalMatrix());
//Remove translation for direction vectors(width/height)
svgButtonAbsInv.removeTranslationFromMatrix();
//Width vect in svgbutton parent relative space
v.transform(svgButtonAbsInv);
float width = v.length();
return width;
}
/* (non-Javadoc)
* @see com.jMT.input.gestureAction.DefaultButtonClickAction#resize(float, float)
*/
@Override
public void resize(float newWidth, float newHeight){
Matrix refCompLocalToWorld = new Matrix(this.getReferenceComp().getGlobalMatrix());
//Center into world space
Vector3D refCompCenter = this.centerObjSpace.getCopy();
refCompCenter.transform(refCompLocalToWorld);
//Remove translation for direction vectors(width/height)
refCompLocalToWorld.removeTranslationFromMatrix();
//Width vect into world space
Vector3D objSpaceWidth = this.widthObjSpace.getCopy();
objSpaceWidth.transform(refCompLocalToWorld);
// System.out.println(" world Width vect of reference component: " + objSpaceWidth);
/////Transform width/height/center to svgbutton relative
Matrix svgButtonAbsInv = new Matrix(this.getCompToResize().getGlobalInverseMatrix());
//Center in svgbutton relative
refCompCenter.transform(svgButtonAbsInv);
// System.out.println("Centerpoint svgRelative: " + refCompCenter);
//TODO doch wieder localbase von svg dazutransformen?
//svgbutton inverse parent relative machen
svgButtonAbsInv.multLocal(this.getCompToResize().getLocalMatrix());
// //Center in svgbutton relative
// refCompCenter.transform(svgButtonAbsInv);
// System.out.println("Centerpoint svgRelative: " + refCompCenter);
//Remove translation for direction vectors(width/height)
svgButtonAbsInv.removeTranslationFromMatrix();
//Width vect in svgbutton parent relative
objSpaceWidth.transform(svgButtonAbsInv);
// System.out.println(" svgbutton space Width vect of reference component: " + objSpaceWidth);
float width = objSpaceWidth.length();
// System.out.println("WIDTH: " + width);
// System.out.println("new width to set: " + newWidth);
// this.getCompToResize().scale(1/width, 1/width, 1, refCompCenter, TransformSpace.RELATIVE_TO_PARENT);
// this.getCompToResize().scale(newWidth, newWidth, 1, refCompCenter, TransformSpace.RELATIVE_TO_PARENT);
//Svgbutton so scalen, dass reference comp auf unit width 1 gescaled wird
this.getCompToResize().scale(1/width, 1/width, 1, refCompCenter, TransformSpace.LOCAL);
//Svgbutton so scalen, dass reference comp auf unit gew�nschte width gescaled wird
this.getCompToResize().scale(newWidth, newWidth, 1, refCompCenter, TransformSpace.LOCAL);
}
}