| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chromoting; | 5 package org.chromium.chromoting; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.graphics.Matrix; | 8 import android.graphics.Matrix; |
| 9 import android.graphics.PointF; | 9 import android.graphics.PointF; |
| 10 import android.graphics.Rect; | 10 import android.graphics.Rect; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 * trigger more swipe actions. | 86 * trigger more swipe actions. |
| 87 */ | 87 */ |
| 88 private boolean mSwipeCompleted = false; | 88 private boolean mSwipeCompleted = false; |
| 89 | 89 |
| 90 /** | 90 /** |
| 91 * Set to true when a 1 finger pan gesture originates with a longpress. Thi
s means the user | 91 * Set to true when a 1 finger pan gesture originates with a longpress. Thi
s means the user |
| 92 * is performing a drag operation. | 92 * is performing a drag operation. |
| 93 */ | 93 */ |
| 94 private boolean mIsDragging = false; | 94 private boolean mIsDragging = false; |
| 95 | 95 |
| 96 private Event.ParameterCallback<Boolean, Void> mProcessAnimationCallback; |
| 97 |
| 96 /** | 98 /** |
| 97 * This class implements fling animation for cursor | 99 * This class implements fling animation for cursor |
| 98 */ | 100 */ |
| 99 private class CursorAnimationJob extends FlingAnimationJob { | 101 private class CursorAnimationJob extends FlingAnimationJob { |
| 100 public CursorAnimationJob(Context context) { | 102 public CursorAnimationJob(Context context) { |
| 101 super(context); | 103 super(context); |
| 102 } | 104 } |
| 103 | 105 |
| 104 @Override | 106 @Override |
| 105 protected void processAction(float deltaX, float deltaY) { | 107 protected void processAction(float deltaX, float deltaY) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 float density = context.getResources().getDisplayMetrics().density; | 205 float density = context.getResources().getDisplayMetrics().density; |
| 204 mSwipeThreshold = 40 * density; | 206 mSwipeThreshold = 40 * density; |
| 205 | 207 |
| 206 mEdgeSlopInPx = ViewConfiguration.get(context).getScaledEdgeSlop(); | 208 mEdgeSlopInPx = ViewConfiguration.get(context).getScaledEdgeSlop(); |
| 207 | 209 |
| 208 mInputStrategy = new NullInputStrategy(); | 210 mInputStrategy = new NullInputStrategy(); |
| 209 | 211 |
| 210 mCursorAnimationJob = new CursorAnimationJob(context); | 212 mCursorAnimationJob = new CursorAnimationJob(context); |
| 211 mScrollAnimationJob = new ScrollAnimationJob(context); | 213 mScrollAnimationJob = new ScrollAnimationJob(context); |
| 212 | 214 |
| 215 mProcessAnimationCallback = new Event.ParameterCallback<Boolean, Void>()
{ |
| 216 @Override |
| 217 public Boolean run(Void p) { |
| 218 return processAnimation(); |
| 219 } |
| 220 }; |
| 221 |
| 213 attachViewEvents(viewer); | 222 attachViewEvents(viewer); |
| 214 } | 223 } |
| 215 | 224 |
| 216 public void processAnimation() { | 225 /** |
| 217 boolean active = mCursorAnimationJob.processAnimation(); | 226 * Steps forward the animation. |
| 218 active |= mScrollAnimationJob.processAnimation(); | 227 * @return true if the animation is not finished yet. |
| 228 */ |
| 229 private boolean processAnimation() { |
| 230 return mCursorAnimationJob.processAnimation() || mScrollAnimationJob.pro
cessAnimation(); |
| 231 } |
| 219 | 232 |
| 220 if (!active) { | 233 /** |
| 221 mViewer.setAnimationEnabled(false); | 234 * Start stepping animation when onCanvasRendered is triggered. |
| 222 } | 235 */ |
| 236 private void startAnimation() { |
| 237 mViewer.onCanvasRendered().addSelfRemovable(mProcessAnimationCallback); |
| 238 } |
| 239 |
| 240 /** |
| 241 * Abort all animations. |
| 242 */ |
| 243 private void abortAnimation() { |
| 244 mCursorAnimationJob.abortAnimation(); |
| 245 mScrollAnimationJob.abortAnimation(); |
| 223 } | 246 } |
| 224 | 247 |
| 225 public void init(Desktop desktop, final InputEventSender injector) { | 248 public void init(Desktop desktop, final InputEventSender injector) { |
| 226 Preconditions.notNull(injector); | 249 Preconditions.notNull(injector); |
| 227 desktop.onInputModeChanged().add( | 250 desktop.onInputModeChanged().add( |
| 228 new Event.ParameterRunnable<InputModeChangedEventParameter>() { | 251 new Event.ParameterRunnable<InputModeChangedEventParameter>() { |
| 229 @Override | 252 @Override |
| 230 public void run(InputModeChangedEventParameter parameter) { | 253 public void run(InputModeChangedEventParameter parameter) { |
| 231 handleInputModeChanged(parameter, injector); | 254 handleInputModeChanged(parameter, injector); |
| 232 } | 255 } |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 | 340 |
| 318 // Avoid short-circuit logic evaluation - ensure all gesture detectors s
ee all events so | 341 // Avoid short-circuit logic evaluation - ensure all gesture detectors s
ee all events so |
| 319 // that they generate correct notifications. | 342 // that they generate correct notifications. |
| 320 boolean handled = mScroller.onTouchEvent(event); | 343 boolean handled = mScroller.onTouchEvent(event); |
| 321 handled |= mZoomer.onTouchEvent(event); | 344 handled |= mZoomer.onTouchEvent(event); |
| 322 handled |= mTapDetector.onTouchEvent(event); | 345 handled |= mTapDetector.onTouchEvent(event); |
| 323 mSwipePinchDetector.onTouchEvent(event); | 346 mSwipePinchDetector.onTouchEvent(event); |
| 324 | 347 |
| 325 switch (event.getActionMasked()) { | 348 switch (event.getActionMasked()) { |
| 326 case MotionEvent.ACTION_DOWN: | 349 case MotionEvent.ACTION_DOWN: |
| 327 mViewer.setAnimationEnabled(false); | 350 abortAnimation(); |
| 328 mSuppressCursorMovement = false; | 351 mSuppressCursorMovement = false; |
| 329 mSuppressFling = false; | 352 mSuppressFling = false; |
| 330 mSwipeCompleted = false; | 353 mSwipeCompleted = false; |
| 331 mIsDragging = false; | 354 mIsDragging = false; |
| 332 break; | 355 break; |
| 333 | 356 |
| 334 case MotionEvent.ACTION_POINTER_DOWN: | 357 case MotionEvent.ACTION_POINTER_DOWN: |
| 335 mTotalMotionY = 0; | 358 mTotalMotionY = 0; |
| 336 break; | 359 break; |
| 337 | 360 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 366 float[] imagePoint = mapScreenPointToImagePoint(screenCenterX, screenCen
terY); | 389 float[] imagePoint = mapScreenPointToImagePoint(screenCenterX, screenCen
terY); |
| 367 mDesktopCanvas.setViewportPosition(imagePoint[0], imagePoint[1]); | 390 mDesktopCanvas.setViewportPosition(imagePoint[0], imagePoint[1]); |
| 368 | 391 |
| 369 moveCursorToScreenPoint(screenCenterX, screenCenterY); | 392 moveCursorToScreenPoint(screenCenterX, screenCenterY); |
| 370 mDesktopCanvas.repositionImage(true); | 393 mDesktopCanvas.repositionImage(true); |
| 371 } | 394 } |
| 372 | 395 |
| 373 private void setInputStrategy(InputStrategyInterface inputStrategy) { | 396 private void setInputStrategy(InputStrategyInterface inputStrategy) { |
| 374 // Since the rules for flinging differ between input modes, we want to s
top running the | 397 // Since the rules for flinging differ between input modes, we want to s
top running the |
| 375 // current fling animation when the mode changes to prevent a wonky expe
rience. | 398 // current fling animation when the mode changes to prevent a wonky expe
rience. |
| 376 mCursorAnimationJob.abortAnimation(); | 399 abortAnimation(); |
| 377 mScrollAnimationJob.abortAnimation(); | |
| 378 mInputStrategy = inputStrategy; | 400 mInputStrategy = inputStrategy; |
| 379 } | 401 } |
| 380 | 402 |
| 381 /** Moves the desired center of the viewport using the specified deltas. */ | 403 /** Moves the desired center of the viewport using the specified deltas. */ |
| 382 private void moveViewportByOffset(float deltaX, float deltaY) { | 404 private void moveViewportByOffset(float deltaX, float deltaY) { |
| 383 // If we are in an indirect mode or are in the middle of a drag operatio
n, then we want to | 405 // If we are in an indirect mode or are in the middle of a drag operatio
n, then we want to |
| 384 // invert the direction of the operation (i.e. follow the motion of the
finger). | 406 // invert the direction of the operation (i.e. follow the motion of the
finger). |
| 385 boolean followCursor = (mInputStrategy.isIndirectInputMode() || mIsDragg
ing); | 407 boolean followCursor = (mInputStrategy.isIndirectInputMode() || mIsDragg
ing); |
| 386 if (followCursor) { | 408 if (followCursor) { |
| 387 deltaX = -deltaX; | 409 deltaX = -deltaX; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 * Called when a fling gesture is recognized. | 534 * Called when a fling gesture is recognized. |
| 513 */ | 535 */ |
| 514 @Override | 536 @Override |
| 515 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) { | 537 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) { |
| 516 if (mSuppressFling) { | 538 if (mSuppressFling) { |
| 517 return false; | 539 return false; |
| 518 } | 540 } |
| 519 | 541 |
| 520 if (mScrollFling) { | 542 if (mScrollFling) { |
| 521 mScrollAnimationJob.startAnimation(velocityX, velocityY); | 543 mScrollAnimationJob.startAnimation(velocityX, velocityY); |
| 522 mViewer.setAnimationEnabled(true); | 544 startAnimation(); |
| 523 mScrollFling = false; | 545 mScrollFling = false; |
| 524 return true; | 546 return true; |
| 525 } | 547 } |
| 526 | 548 |
| 527 if (mSuppressCursorMovement) { | 549 if (mSuppressCursorMovement) { |
| 528 return false; | 550 return false; |
| 529 } | 551 } |
| 530 | 552 |
| 531 // If cursor movement is suppressed, fling also needs to be suppress
ed, as the | 553 // If cursor movement is suppressed, fling also needs to be suppress
ed, as the |
| 532 // gesture-detector will still generate onFling() notifications base
d on movement of | 554 // gesture-detector will still generate onFling() notifications base
d on movement of |
| 533 // the fingers, which would result in unwanted cursor movement. | 555 // the fingers, which would result in unwanted cursor movement. |
| 534 mCursorAnimationJob.startAnimation(velocityX, velocityY); | 556 mCursorAnimationJob.startAnimation(velocityX, velocityY); |
| 535 mViewer.setAnimationEnabled(true); | 557 startAnimation(); |
| 536 return true; | 558 return true; |
| 537 } | 559 } |
| 538 | 560 |
| 539 /** Called when the user is in the process of pinch-zooming. */ | 561 /** Called when the user is in the process of pinch-zooming. */ |
| 540 @Override | 562 @Override |
| 541 public boolean onScale(ScaleGestureDetector detector) { | 563 public boolean onScale(ScaleGestureDetector detector) { |
| 542 if (!mSwipePinchDetector.isPinching()) { | 564 if (!mSwipePinchDetector.isPinching()) { |
| 543 return false; | 565 return false; |
| 544 } | 566 } |
| 545 | 567 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 float[] mappedPoints = mapScreenPointToImagePoint(screenX, screenY); | 664 float[] mappedPoints = mapScreenPointToImagePoint(screenX, screenY); |
| 643 | 665 |
| 644 float imageWidth = (float) mRenderData.imageWidth + EPSILON; | 666 float imageWidth = (float) mRenderData.imageWidth + EPSILON; |
| 645 float imageHeight = (float) mRenderData.imageHeight + EPSILON; | 667 float imageHeight = (float) mRenderData.imageHeight + EPSILON; |
| 646 | 668 |
| 647 return mappedPoints[0] < -EPSILON || mappedPoints[0] > imageWidth | 669 return mappedPoints[0] < -EPSILON || mappedPoints[0] > imageWidth |
| 648 || mappedPoints[1] < -EPSILON || mappedPoints[1] > imageHeig
ht; | 670 || mappedPoints[1] < -EPSILON || mappedPoints[1] > imageHeig
ht; |
| 649 } | 671 } |
| 650 } | 672 } |
| 651 } | 673 } |
| OLD | NEW |