27 28 import com.sun.glass.events.KeyEvent; 29 import com.sun.glass.events.TouchEvent; 30 31 import java.security.AccessController; 32 import java.security.PrivilegedAction; 33 import java.util.HashMap; 34 import java.util.Map; 35 import javafx.event.EventType; 36 import javafx.scene.input.SwipeEvent; 37 38 class SwipeGestureRecognizer implements GestureRecognizer { 39 private static final boolean VERBOSE = false; 40 41 // Swipes must be longer than that 42 private static final double DISTANCE_THRESHOLD = 10; // pixel 43 44 // Traveling this distance against the swipe direction at its end cancels it 45 private static final double BACKWARD_DISTANCE_THRASHOLD = 5; // pixel 46 47 // Trajectory tracking period 48 static final long TIME_STEP = 100000000; // nanosec 49 50 private SwipeRecognitionState state = SwipeRecognitionState.IDLE; 51 MultiTouchTracker tracker = new MultiTouchTracker(); 52 private ViewScene scene; 53 54 SwipeGestureRecognizer(final ViewScene scene) { 55 this.scene = scene; 56 } 57 58 @Override 59 public void notifyBeginTouchEvent(long time, int modifiers, boolean isDirect, 60 int touchEventCount) { 61 tracker.params(modifiers, isDirect); 62 } 63 64 @Override 65 public void notifyNextTouchEvent(long time, int type, long touchId, 66 int x, int y, int xAbs, int yAbs) { 67 switch(type) { 68 case TouchEvent.TOUCH_PRESSED: 69 tracker.pressed(touchId, time, x, y, xAbs, yAbs); 306 TouchPointTracker tracker = trackers.get(id); 307 308 if (tracker == null) { 309 // we don't know this ID, something went completely wrong 310 state = SwipeRecognitionState.FAILURE; 311 throw new RuntimeException("Error in swipe gesture " 312 + "recognition: reported unknown touch point"); 313 } 314 315 tracker.progress(nanos, x, y); 316 } 317 318 void reset() { 319 trackers.clear(); 320 cc.reset(); 321 state = SwipeRecognitionState.IDLE; 322 } 323 } 324 325 private static class TouchPointTracker { 326 long time, beginTime, endTime; 327 double beginX, beginY, endX, endY; 328 double beginAbsX, beginAbsY, endAbsX, endAbsY; 329 double lengthX, lengthY; 330 double maxDeviationX, maxDeviationY; 331 double lastXMovement, lastYMovement; 332 double lastX, lastY; 333 334 public void start(long nanos, double x, double y, double absX, double absY) { 335 beginX = x; 336 beginY = y; 337 beginAbsX = absX; 338 beginAbsY = absY; 339 lastX = absX; 340 lastY = absY; 341 beginTime = nanos / 1000000; 342 } 343 344 public void end(long nanos, double x, double y, double absX, double absY) { 345 progress(nanos, x, y); 346 endX = x; 347 endY = y; 348 endAbsX = absX; 349 endAbsY = absY; 350 endTime = nanos / 1000000; 351 } 352 353 public void progress(long nanos, double x, double y) { 354 if (nanos > time + TIME_STEP) { 355 final double deltaX = x - lastX; 356 final double deltaY = y - lastY; 357 358 time = nanos; 359 lengthX += Math.abs(deltaX); 360 lengthY += Math.abs(deltaY); 361 lastX = x; 362 lastY = y; 363 364 final double devX = Math.abs(x - beginAbsX); 365 if (devX > maxDeviationX) { maxDeviationX = devX; } 366 367 final double devY = Math.abs(y - beginAbsY); 368 if (devY > maxDeviationY) { maxDeviationY = devY; } 369 370 if (Math.signum(deltaX) == Math.signum(lastXMovement)) { 371 lastXMovement += deltaX; 372 } else { 373 lastXMovement = deltaX; 374 } 375 376 if (Math.signum(deltaY) == Math.signum(lastYMovement)) { 377 lastYMovement += deltaY; 378 } else { 379 lastYMovement = deltaY; 380 } 381 } 382 } 383 384 public double getDistanceX() { 385 return endX - beginX; 386 } 387 388 public double getDistanceY() { 389 return endY - beginY; 390 } 391 392 public long getDuration() { 393 return endTime - beginTime; 394 } 395 } 396 397 private enum SwipeRecognitionState { 398 IDLE, 399 ADDING, 400 REMOVING, 401 FAILURE | 27 28 import com.sun.glass.events.KeyEvent; 29 import com.sun.glass.events.TouchEvent; 30 31 import java.security.AccessController; 32 import java.security.PrivilegedAction; 33 import java.util.HashMap; 34 import java.util.Map; 35 import javafx.event.EventType; 36 import javafx.scene.input.SwipeEvent; 37 38 class SwipeGestureRecognizer implements GestureRecognizer { 39 private static final boolean VERBOSE = false; 40 41 // Swipes must be longer than that 42 private static final double DISTANCE_THRESHOLD = 10; // pixel 43 44 // Traveling this distance against the swipe direction at its end cancels it 45 private static final double BACKWARD_DISTANCE_THRASHOLD = 5; // pixel 46 47 private SwipeRecognitionState state = SwipeRecognitionState.IDLE; 48 MultiTouchTracker tracker = new MultiTouchTracker(); 49 private ViewScene scene; 50 51 SwipeGestureRecognizer(final ViewScene scene) { 52 this.scene = scene; 53 } 54 55 @Override 56 public void notifyBeginTouchEvent(long time, int modifiers, boolean isDirect, 57 int touchEventCount) { 58 tracker.params(modifiers, isDirect); 59 } 60 61 @Override 62 public void notifyNextTouchEvent(long time, int type, long touchId, 63 int x, int y, int xAbs, int yAbs) { 64 switch(type) { 65 case TouchEvent.TOUCH_PRESSED: 66 tracker.pressed(touchId, time, x, y, xAbs, yAbs); 303 TouchPointTracker tracker = trackers.get(id); 304 305 if (tracker == null) { 306 // we don't know this ID, something went completely wrong 307 state = SwipeRecognitionState.FAILURE; 308 throw new RuntimeException("Error in swipe gesture " 309 + "recognition: reported unknown touch point"); 310 } 311 312 tracker.progress(nanos, x, y); 313 } 314 315 void reset() { 316 trackers.clear(); 317 cc.reset(); 318 state = SwipeRecognitionState.IDLE; 319 } 320 } 321 322 private static class TouchPointTracker { 323 long beginTime, endTime; 324 double beginX, beginY, endX, endY; 325 double beginAbsX, beginAbsY, endAbsX, endAbsY; 326 double lengthX, lengthY; 327 double maxDeviationX, maxDeviationY; 328 double lastXMovement, lastYMovement; 329 double lastX, lastY; 330 331 public void start(long nanos, double x, double y, double absX, double absY) { 332 beginX = x; 333 beginY = y; 334 beginAbsX = absX; 335 beginAbsY = absY; 336 lastX = absX; 337 lastY = absY; 338 beginTime = nanos / 1000000; 339 } 340 341 public void end(long nanos, double x, double y, double absX, double absY) { 342 progress(nanos, absX, absY); 343 endX = x; 344 endY = y; 345 endAbsX = absX; 346 endAbsY = absY; 347 endTime = nanos / 1000000; 348 } 349 350 public void progress(long nanos, double x, double y) { 351 final double deltaX = x - lastX; 352 final double deltaY = y - lastY; 353 354 lengthX += Math.abs(deltaX); 355 lengthY += Math.abs(deltaY); 356 lastX = x; 357 lastY = y; 358 359 final double devX = Math.abs(x - beginAbsX); 360 if (devX > maxDeviationX) { maxDeviationX = devX; } 361 362 final double devY = Math.abs(y - beginAbsY); 363 if (devY > maxDeviationY) { maxDeviationY = devY; } 364 365 if (Math.signum(deltaX) == Math.signum(lastXMovement)) { 366 lastXMovement += deltaX; 367 } else { 368 lastXMovement = deltaX; 369 } 370 371 if (Math.signum(deltaY) == Math.signum(lastYMovement)) { 372 lastYMovement += deltaY; 373 } else { 374 lastYMovement = deltaY; 375 } 376 } 377 378 public double getDistanceX() { 379 return endX - beginX; 380 } 381 382 public double getDistanceY() { 383 return endY - beginY; 384 } 385 386 public long getDuration() { 387 return endTime - beginTime; 388 } 389 } 390 391 private enum SwipeRecognitionState { 392 IDLE, 393 ADDING, 394 REMOVING, 395 FAILURE |