/** * Squidy is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Squidy 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squidy. If not, see <http://www.gnu.org/licenses/>. * * 2006-2009 Human-Computer Interaction Group, University of Konstanz. * <http://hci.uni-konstanz.de> * * Please contact info@squidy-lib.de or visit our website http://squidy-lib.de for * further information. */ /** * */ package org.squidy.nodes; import java.util.Arrays; import java.util.Hashtable; import java.util.Iterator; import java.util.Timer; import java.util.Vector; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlType; import org.squidy.manager.ProcessException; import org.squidy.manager.controls.Slider; import org.squidy.manager.data.DataConstant; import org.squidy.manager.data.IData; import org.squidy.manager.data.IDataContainer; import org.squidy.manager.data.Processor; import org.squidy.manager.data.Property; import org.squidy.manager.data.Processor.Status; import org.squidy.manager.data.impl.DataPosition2D; import org.squidy.manager.model.AbstractNode; /** * <code>Doubleclick</code>. * * <pre> * Date: Okt 12, 2009 * Time: 15:32:29 PM * </pre> * * * @author * Nicolas Hirrle * <a href="mailto:nihirrle@htwg-konstanz.de">nihirrle@htwg-konstanz.de</a> * Human-Computer Interaction Group * University of Konstanz * * @version $Id: Doubleclick.java 772 2011-09-16 15:39:44Z raedle $ * @since 2.0.0 */ @Processor( name = "Doubleclick", icon = "/org/squidy/nodes/image/48x48/tactilefinger.png", description = "Stops unwanted doubleclicks", types = { Processor.Type.FILTER }, tags = { }, status = Status.UNSTABLE ) @Deprecated public class Doubleclick extends AbstractNode { // ################################################################################ // BEGIN OF PROPERTIES // ################################################################################ @XmlAttribute(name = "Interpolate-Time") @Property( name = "Interpolate-Time", description = "Time (in ms) where lost cursors are interpolated (so that windows doesn't interpret it as a doubleclick)." ) @Slider(type = Integer.class, minimumValue = 0, maximumValue = 2000, showLabels = true, showTicks = true, majorTicks = 1000, minorTicks = 50, snapToTicks = false) private int interpolateTime = 50; public int getInterpolateTime() { return interpolateTime; } public void setInterpolateTime(int interpolateTime) { this.interpolateTime = interpolateTime; } // ################################################################################ // END OF PROPERTIES // ################################################################################ // ################################################################################ // BEGIN OF LAUNCH // ################################################################################ private class DataTime { private long time; private DataPosition2D dataPos2D = new DataPosition2D(); public DataTime(long time, DataPosition2D dataPos) { this.time = time; this.dataPos2D = dataPos; } }; private Hashtable<Integer, DataTime> interpolateCursors = new Hashtable<Integer, DataTime>(); // id als key und value: removetime und Dataposition2d /* (non-Javadoc) * @see org.squidy.manager.model.AbstractNode#onStart() */ @Override public void onStart() throws ProcessException { interpolateCursors.clear(); } /* (non-Javadoc) * @see org.squidy.manager.model.AbstractNode#onStop() */ @Override public void onStop() throws ProcessException { interpolateCursors.clear(); } // ################################################################################ // END OF LAUNCH // ################################################################################ // ################################################################################ // BEGIN OF PROCESS // ################################################################################ private long lastProcessedTime; private boolean printText = false; /* (non-Javadoc) * @see org.squidy.manager.model.AbstractNode#beforeDataContainerProcessing(org.squidy.manager.data.IDataContainer) */ @Override public IDataContainer preProcess(IDataContainer dataContainer) { if (printText) System.out.println("start------"); IDataContainer dataContP = interpolate(dataContainer); return super.preProcess(dataContP); } /** * Uncomment method if processing of data position 2d is desired. * * @param dataToken The data token object. * @return Any desired data object of interface IData. */ public IData process(DataPosition2D dataPosition2D) { actualizeCursors (dataPosition2D); return dataPosition2D; } /* (non-Javadoc) * @see org.squidy.manager.model.AbstractNode#afterDataContainerProcessing(org.squidy.manager.data.IDataContainer) */ @Override public IDataContainer postProcess(IDataContainer dataContainer) { if (printText) System.out.println("end-----"); return super.postProcess(dataContainer); } private IDataContainer interpolate(IDataContainer dataContainer) { Vector<IData> dataCont = new Vector<IData>(Arrays.asList(dataContainer.getData())); Iterator<Integer> hashIterator = interpolateCursors.keySet().iterator(); while (hashIterator.hasNext()) { boolean inContainer = false; int id = hashIterator.next(); for (IData data : dataContainer.getData()) { if (data instanceof DataPosition2D) { int idTmp = (Integer) data.getAttribute(DataConstant.SESSION_ID); if (id == idTmp) { inContainer = true; break; } } } if (inContainer == false) { DataTime dt = interpolateCursors.get(id); long accTime = System.currentTimeMillis(); if (accTime - dt.time <= interpolateTime) { dt.dataPos2D.setAttribute(ReacTIVision.TUIO_CURSOR, "interpolated"); dataCont.add(dt.dataPos2D); }else{ hashIterator.remove(); } } } IData[] arr = new IData[dataCont.size()]; dataCont.toArray(arr); IDataContainer dataContP = dataContainer.getClone(); dataContP.setData(arr); return dataContP; } private void actualizeCursors (DataPosition2D dataPosition2D) { DataPosition2D dataPos = dataPosition2D; if (dataPos.hasAttribute(TUIO.ORIGIN_ADDRESS)) { if (dataPos.getAttribute(TUIO.ORIGIN_ADDRESS).equals("/tuio/2Dcur")) { int id = (Integer) dataPos.getAttribute(DataConstant.SESSION_ID); if (dataPos.getAttribute(ReacTIVision.TUIO_CURSOR) != "interpolated") { long lastTime = System.currentTimeMillis(); DataTime dt = new DataTime(lastTime, dataPos); interpolateCursors.put(id, dt); } if (printText) System.out.println(dataPos.getAttribute(ReacTIVision.TUIO_CURSOR) + " on ID: " + dataPos.getAttribute(DataConstant.SESSION_ID)); } } } // ################################################################################ // END OF PROCESS // ################################################################################ }