/***********************************************************************
* mt4j Copyright (c) 2008 - 2009 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.inputProcessors.globalProcessors;
import java.util.HashMap;
import java.util.Map;
import org.mt4j.MTApplication;
import org.mt4j.components.MTComponent;
import org.mt4j.components.bounds.IBoundingShape;
import org.mt4j.components.visibleComponents.shapes.AbstractShape;
import org.mt4j.components.visibleComponents.shapes.MTEllipse;
import org.mt4j.components.visibleComponents.widgets.MTOverlayContainer;
import org.mt4j.input.inputData.AbstractCursorInputEvt;
import org.mt4j.input.inputData.InputCursor;
import org.mt4j.input.inputData.MTInputEvent;
import org.mt4j.sceneManagement.Iscene;
import org.mt4j.util.MTColor;
import org.mt4j.util.math.Vector3D;
import processing.core.PApplet;
/**
* The Class CursorTracer. A global input processor tracking all AbstractCursorInputEvt events and
* displays a circle at that position.
*
* @author Christopher Ruff
*/
public class CursorTracer extends AbstractGlobalInputProcessor{
/** The app. */
private MTApplication app;
/** The cursor id to display shape. */
private Map<InputCursor, AbstractShape>cursorIDToDisplayShape;
/** The scene. */
private Iscene scene;
/** The overlay group. */
private MTComponent overlayGroup;
/**
* Instantiates a new cursor tracer.
*
* @param mtApp the mt app
* @param currentScene the current scene
*/
public CursorTracer(MTApplication mtApp, Iscene currentScene){
this.app = mtApp;
this.scene = currentScene;
this.cursorIDToDisplayShape = new HashMap<InputCursor, AbstractShape>();
// this.overlayGroup = new MTComponent(app, "Cursor Trace group", new MTCamera(app));
// this.overlayGroup.setDepthBufferDisabled(true);
// //Send overlay group to front again if it isnt - check each frame if its on front!
// overlayGroup.setController(new IMTController() {
// public void update(long timeDelta) {
// MTComponent parent = overlayGroup.getParent();
// if (parent != null){
// int childCount = parent.getChildCount();
// if (childCount > 0
// && !parent.getChildByIndex(childCount-1).equals(overlayGroup))
// {
// app.invokeLater(new Runnable() {
// public void run(){
// MTComponent parent = overlayGroup.getParent();
// if (parent != null){
// parent.removeChild(overlayGroup);
// parent.addChild(overlayGroup);
// }
// }
// });
// }
// }
// }
// });
// MTOverlayContainer overlay = checkForExistingOverlay(scene.getCanvas());
//
this.overlayGroup = new MTOverlayContainer(app, "Cursor Trace group");
mtApp.invokeLater(new Runnable() {
public void run() {
scene.getCanvas().addChild(overlayGroup);
}
});
// //FIXME REMOVE
// compToCreationTime = new HashMap<MTComponent, Long>();
// mtApp.registerPre(this);
}
// private HashMap<MTComponent, Long> compToCreationTime; //FIXME REMOVE LATER
// public void pre(){
// Set<MTComponent> comps = compToCreationTime.keySet();
// long currentTime = System.currentTimeMillis();
// for (MTComponent component : comps) {
// InputCursor c = (InputCursor) component.getUserData("Cursor");
// Long creationTime = compToCreationTime.get(component);
// long duration = currentTime - creationTime;
// if (duration > 1000){
// System.out.println("--> CURSOR: " + c.getId() + " seems to be STUCK!");
// }
// }
// }
// private MTOverlayContainer checkForExistingOverlay(MTCanvas canvas){
// MTComponent[] canvasChildren = canvas.getChildren();
// MTOverlayContainer overlay = null;
// for (int i = 0; i < canvasChildren.length; i++) {
// MTComponent component = canvasChildren[i];
// if (component instanceof MTOverlayContainer) {
//// MTOverlayContainer foundOverlay = (MTOverlayContainer) component;
// overlay = (MTOverlayContainer)component;
// }
// }
// return overlay;
// }
/**
* Creates the display component.
*
* @param applet the applet
* @param position the position
*
* @return the abstract shape
*/
protected AbstractShape createDisplayComponent(PApplet applet, Vector3D position){
MTEllipse displayShape = new CursorEllipse(applet, position, 15, 15);
displayShape.setPickable(false);
displayShape.setNoFill(true);
displayShape.setDrawSmooth(true);
displayShape.setStrokeWeight(2);
displayShape.setStrokeColor(new MTColor(100, 130, 220, 255));
return displayShape;
}
private class CursorEllipse extends MTEllipse{
public CursorEllipse(PApplet applet, Vector3D centerPoint,float radiusX, int segments) {
super(applet, centerPoint, radiusX, radiusX, segments);
}
@Override
protected IBoundingShape computeDefaultBounds() {
return null;
}
@Override
protected void setDefaultGestureActions() {
//Dont need gestures
}
}
/* (non-Javadoc)
* @see org.mt4j.input.inputProcessors.globalProcessors.AbstractGlobalInputProcessor#processInputEvtImpl(org.mt4j.input.inputData.MTInputEvent)
*/
@Override
public void processInputEvtImpl(MTInputEvent inputEvent) {
if (inputEvent instanceof AbstractCursorInputEvt) {
AbstractCursorInputEvt cursorEvt = (AbstractCursorInputEvt)inputEvent;
InputCursor c = ((AbstractCursorInputEvt)inputEvent).getCursor();
Vector3D position = new Vector3D(cursorEvt.getPosX(), cursorEvt.getPosY());
AbstractShape displayShape = null;
switch (cursorEvt.getId()) {
case AbstractCursorInputEvt.INPUT_DETECTED:
displayShape = createDisplayComponent(app, position);
cursorIDToDisplayShape.put(c, displayShape);
overlayGroup.addChild(displayShape);
// compToCreationTime.put(displayShape, System.currentTimeMillis()); //FIXME REMOVE
// displayShape.setUserData("Cursor", c);//FIXME REMOVE
break;
case AbstractCursorInputEvt.INPUT_UPDATED:
displayShape = cursorIDToDisplayShape.get(c);
if (displayShape != null){
displayShape.setPositionGlobal(position);
}
break;
case AbstractCursorInputEvt.INPUT_ENDED:
displayShape = cursorIDToDisplayShape.remove(c);
if (displayShape != null){
displayShape.destroy();
}
break;
default:
break;
}
}
}
}