/***********************************************************************
* mt4j Copyright (c) 2008 - 2010 Christopher 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.MTApplication;
import org.mt4j.components.MTComponent;
import org.mt4j.components.interfaces.IMTController;
import org.mt4j.components.visibleComponents.shapes.MTEllipse;
import org.mt4j.input.inputProcessors.IGestureEventListener;
import org.mt4j.input.inputProcessors.MTGestureEvent;
import org.mt4j.input.inputProcessors.componentProcessors.tapAndHoldProcessor.TapAndHoldEvent;
import org.mt4j.util.MTColor;
import org.mt4j.util.camera.MTCamera;
import org.mt4j.util.math.Vector3D;
import org.mt4j.util.math.Vertex;
import processing.core.PApplet;
/**
* The Class TapAndHoldVisualizer. Animates the drawing of a circle
* to indicate the status of the tap&hold gesture in progress.
*
* @author Christopher Ruff
*/
public class TapAndHoldVisualizer implements IGestureEventListener {
/** The app. */
private MTApplication app;
/** The parent. */
private MTComponent parent;
/** The cam. */
private MTCamera cam;
/** The e. */
private HoldEllipse e;
/**
* Instantiates a new tap and hold visualizer.
*
* @param app the app
* @param parent the parent
*/
public TapAndHoldVisualizer(MTApplication app, MTComponent parent) {
super();
this.app = app;
this.parent = parent;
cam = new MTCamera(app);
e = new HoldEllipse(app, new Vector3D(0, 0), 35, 35, 50);
e.setPickable(false);
e.unregisterAllInputProcessors();
e.setStrokeColor(new MTColor(240,50,50,200));
e.setStrokeWeight(4);
e.setNoFill(true);
e.setDepthBufferDisabled(true);
e.attachCamera(cam);
e.setVisible(false);
e.setDegrees(0);
e.setController(new IMTController() {
public void update(long timeDelta) {
MTComponent parent = e.getParent();
if (parent != null){
int childCount = parent.getChildCount();
if (childCount > 0
&& !parent.getChildByIndex(childCount-1).equals(e))
{
TapAndHoldVisualizer.this.app.invokeLater(new Runnable() {
public void run(){
MTComponent parent = e.getParent();
if (parent != null){
parent.removeChild(e);
parent.addChild(e);
}
}
});
}
}
}
});
}
/* (non-Javadoc)
* @see org.mt4j.input.inputProcessors.IGestureEventListener#processGestureEvent(org.mt4j.input.inputProcessors.MTGestureEvent)
*/
public boolean processGestureEvent(MTGestureEvent ge) {
TapAndHoldEvent t = (TapAndHoldEvent)ge;
float d = 360f * t.getElapsedTimeNormalized();
// float a = 255 * t.getElapsedTimeNormalized();
float a = 205 * t.getElapsedTimeNormalized();
switch (t.getId()) {
case TapAndHoldEvent.GESTURE_DETECTED:
parent.addChild(e);
e.setDegrees(0);
e.recreate(false);
e.setPositionGlobal(new Vector3D(t.getLocationOnScreen().x, t.getLocationOnScreen().y));
break;
case TapAndHoldEvent.GESTURE_UPDATED:
e.setVisible(true);
if (d >= 350){ //FIXME HACK to display the circle really closed before the end
d = 360;
e.setDegrees(d);
e.recreate(true);
MTColor stroke = e.getStrokeColor();
e.setStrokeColor(new MTColor(stroke.getR(), stroke.getG(), stroke.getB(), 255));
}else{
e.setDegrees(d);
e.recreate(false);
MTColor stroke = e.getStrokeColor();
e.setStrokeColor(new MTColor(stroke.getR(), stroke.getG(), stroke.getB(), a));
}
break;
case TapAndHoldEvent.GESTURE_ENDED:
e.setVisible(false);
parent.removeChild(e);
break;
default:
break;
}
return false;
}
/**
* The Class HoldEllipse.
*
* @author Christopher Ruff
*/
private class HoldEllipse extends MTEllipse{
/** The segments. */
private int segments;
/**
* Instantiates a new hold ellipse.
*
* @param applet the applet
* @param centerPoint the center point
* @param radiusX the radius x
* @param radiusY the radius y
* @param segments the segments
*/
public HoldEllipse(PApplet applet, Vector3D centerPoint, float radiusX,float radiusY, int segments) {
super(applet, centerPoint, radiusX, radiusY, segments);
this.segments = segments;
}
@Override
protected void setDefaultGestureActions() {
//no gestures
}
/**
* Recreate.
*
* @param close the close
*/
public void recreate(boolean close){
if (close){
setVertices(getVertices(segments));
}else{
Vertex[] verts = getVertices(segments);
Vertex[] v = new Vertex[verts.length -1];
System.arraycopy(verts, 0, v, 0, verts.length-1);
setVertices(v);
}
}
}
}