00001 package edu.stanford.hci.r3.events.handlers;
00002
00003 import edu.stanford.hci.r3.events.EventHandler;
00004 import edu.stanford.hci.r3.events.PenEvent;
00005
00018 public abstract class ClickHandler extends EventHandler {
00019
00024 private class ClickNotifier implements Runnable {
00025
00026 private boolean doNotNotify;
00027
00028 private PenEvent event;
00029
00030 public ClickNotifier(PenEvent myEvent) {
00031 event = myEvent;
00032 }
00033
00037 public void run() {
00038 try {
00039 Thread.sleep(MILLIS_TO_DELAY);
00040 } catch (InterruptedException e) {
00041 e.printStackTrace();
00042 }
00043 if (doNotNotify) {
00044
00045 return;
00046 }
00047 released(event);
00048 clicked(event);
00049 lastClickTime = event.getTimestamp();
00050 penDownHappened = false;
00051 }
00052
00056 public void setDoNotNotify(boolean b) {
00057 doNotNotify = b;
00058 }
00059 }
00060
00064 private static final long MILLIS_TO_DELAY = 30;
00065
00069 protected int clickCount = 1;
00070
00074 private boolean filterJitteryPenEvents = true;
00075
00079 private ClickNotifier lastClickNotifier;
00080
00085 private long lastClickTime = 0;
00086
00091 private PenEvent lastEvent;
00092
00093 private long lastPenUpTime;
00094
00098 protected int maxMillisBetweenMultipleClicks = 300;
00099
00103 private boolean penDownHappened = false;
00104
00108 public abstract void clicked(PenEvent e);
00109
00119 public void handleEvent(PenEvent event) {
00120 if (event.isTypePenDown()) {
00121 long currPenDownTime = System.currentTimeMillis();
00122 long diff = currPenDownTime - lastPenUpTime;
00123 if (diff > MILLIS_TO_DELAY) {
00124
00125 pressed(event);
00126 penDownHappened = true;
00127 } else {
00128
00129
00130 if (lastClickNotifier != null) {
00131 lastClickNotifier.setDoNotNotify(true);
00132 lastClickNotifier = null;
00133 }
00134 }
00135 } else if (event.isTypePenUp()) {
00136
00137 lastPenUpTime = System.currentTimeMillis();
00138
00139
00140 if (penDownHappened) {
00141 if (event.getTimestamp() - lastClickTime <= maxMillisBetweenMultipleClicks) {
00142 clickCount++;
00143 } else {
00144 clickCount = 1;
00145 }
00146
00147 if (filterJitteryPenEvents) {
00148 lastClickNotifier = new ClickNotifier(lastEvent);
00149 new Thread(lastClickNotifier).start();
00150 } else {
00151 released(lastEvent);
00152 clicked(lastEvent);
00153 lastClickTime = event.getTimestamp();
00154 penDownHappened = false;
00155 }
00156 }
00157 }
00158 lastEvent = event;
00159
00160
00161 }
00162
00166 public abstract void pressed(PenEvent e);
00167
00171 public abstract void released(PenEvent e);
00172
00173 public String toString() {
00174 return "ClickHandler";
00175 }
00176 }