mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-04-03 21:22:47 +00:00
Bug 1111333 - Enable double-tap-drag to zoom. r=kats
MozReview-Commit-ID: KpwVNZZdLPd
This commit is contained in:
parent
123ab8fe26
commit
907fde9487
1
AUTHORS
1
AUTHORS
@ -290,6 +290,7 @@ Dean Tessman <dean_tessman@hotmail.com>
|
||||
<deneen@alum.bucknell.edu>
|
||||
Denis Antrushin <adu@sparc.spb.su>
|
||||
Denis Issoupov <denis@macadamian.com>
|
||||
Dennis Ek <contact@dennisek.se>
|
||||
Dennis Handly
|
||||
Derrick Rice <derrick.rice@gmail.com>
|
||||
<desale@netscape.com>
|
||||
|
@ -37,6 +37,12 @@ static const uint32_t MAX_TAP_TIME = 300;
|
||||
*/
|
||||
static const float PINCH_START_THRESHOLD = 35.0f;
|
||||
|
||||
/**
|
||||
* Determines how fast a one touch pinch zooms in and out. The greater the
|
||||
* value, the faster it zooms.
|
||||
*/
|
||||
static const float ONE_TOUCH_PINCH_SPEED = 0.005f;
|
||||
|
||||
static bool sLongTapEnabled = true;
|
||||
|
||||
ParentLayerPoint GetCurrentFocus(const MultiTouchInput& aEvent)
|
||||
@ -54,6 +60,13 @@ ParentLayerCoord GetCurrentSpan(const MultiTouchInput& aEvent)
|
||||
return delta.Length();
|
||||
}
|
||||
|
||||
ParentLayerCoord GestureEventListener::GetYSpanFromStartPoint()
|
||||
{
|
||||
const ParentLayerPoint start = mTouchStartPosition;
|
||||
const ParentLayerPoint& current = mTouches[0].mLocalScreenPoint;
|
||||
return current.y - start.y;
|
||||
}
|
||||
|
||||
TapGestureInput CreateTapEvent(const MultiTouchInput& aTouch, TapGestureInput::TapGestureType aType)
|
||||
{
|
||||
return TapGestureInput(aType,
|
||||
@ -93,6 +106,7 @@ nsEventStatus GestureEventListener::HandleInputEvent(const MultiTouchInput& aEve
|
||||
switch (aEvent.mType) {
|
||||
case MultiTouchInput::MULTITOUCH_START:
|
||||
mTouches.Clear();
|
||||
// Cache every touch.
|
||||
for (size_t i = 0; i < aEvent.mTouches.Length(); i++) {
|
||||
mTouches.AppendElement(aEvent.mTouches[i]);
|
||||
}
|
||||
@ -104,6 +118,7 @@ nsEventStatus GestureEventListener::HandleInputEvent(const MultiTouchInput& aEve
|
||||
}
|
||||
break;
|
||||
case MultiTouchInput::MULTITOUCH_MOVE:
|
||||
// Update the screen points of the cached touches.
|
||||
for (size_t i = 0; i < aEvent.mTouches.Length(); i++) {
|
||||
for (size_t j = 0; j < mTouches.Length(); j++) {
|
||||
if (aEvent.mTouches[i].mIdentifier == mTouches[j].mIdentifier) {
|
||||
@ -115,6 +130,7 @@ nsEventStatus GestureEventListener::HandleInputEvent(const MultiTouchInput& aEve
|
||||
rv = HandleInputTouchMove();
|
||||
break;
|
||||
case MultiTouchInput::MULTITOUCH_END:
|
||||
// Remove the cache of the touch that ended.
|
||||
for (size_t i = 0; i < aEvent.mTouches.Length(); i++) {
|
||||
for (size_t j = 0; j < mTouches.Length(); j++) {
|
||||
if (aEvent.mTouches[i].mIdentifier == mTouches[j].mIdentifier) {
|
||||
@ -254,8 +270,7 @@ nsEventStatus GestureEventListener::HandleInputTouchMove()
|
||||
break;
|
||||
|
||||
case GESTURE_FIRST_SINGLE_TOUCH_DOWN:
|
||||
case GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN:
|
||||
case GESTURE_SECOND_SINGLE_TOUCH_DOWN: {
|
||||
case GESTURE_FIRST_SINGLE_TOUCH_MAX_TAP_DOWN: {
|
||||
// If we move too much, bail out of the tap.
|
||||
if (MoveDistanceIsLarge()) {
|
||||
CancelLongTapTimeoutTask();
|
||||
@ -266,6 +281,34 @@ nsEventStatus GestureEventListener::HandleInputTouchMove()
|
||||
break;
|
||||
}
|
||||
|
||||
// The user has performed a double tap, but not lifted her finger.
|
||||
case GESTURE_SECOND_SINGLE_TOUCH_DOWN: {
|
||||
// If touch has moved noticeably (within MAX_TAP_TIME), change state.
|
||||
if (MoveDistanceIsLarge()) {
|
||||
CancelLongTapTimeoutTask();
|
||||
CancelMaxTapTimeoutTask();
|
||||
mSingleTapSent = Nothing();
|
||||
SetState(GESTURE_ONE_TOUCH_PINCH);
|
||||
|
||||
ParentLayerCoord currentSpan = 1.0f;
|
||||
ParentLayerPoint currentFocus = mTouchStartPosition;
|
||||
|
||||
PinchGestureInput pinchEvent(PinchGestureInput::PINCHGESTURE_START,
|
||||
mLastTouchInput.mTime,
|
||||
mLastTouchInput.mTimeStamp,
|
||||
currentFocus,
|
||||
currentSpan,
|
||||
currentSpan,
|
||||
mLastTouchInput.modifiers);
|
||||
|
||||
rv = mAsyncPanZoomController->HandleGestureEvent(pinchEvent);
|
||||
|
||||
mPreviousSpan = currentSpan;
|
||||
mPreviousFocus = currentFocus;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GESTURE_MULTI_TOUCH_DOWN: {
|
||||
if (mLastTouchInput.mTouches.Length() < 2) {
|
||||
NS_WARNING("Wrong input: less than 2 moving points in GESTURE_MULTI_TOUCH_DOWN state");
|
||||
@ -324,6 +367,30 @@ nsEventStatus GestureEventListener::HandleInputTouchMove()
|
||||
break;
|
||||
}
|
||||
|
||||
case GESTURE_ONE_TOUCH_PINCH: {
|
||||
ParentLayerCoord currentSpan = GetYSpanFromStartPoint();
|
||||
float effectiveSpan = 1.0f + (fabsf(currentSpan.value) * ONE_TOUCH_PINCH_SPEED);
|
||||
ParentLayerPoint currentFocus = mTouchStartPosition;
|
||||
|
||||
// Invert zoom.
|
||||
if (currentSpan.value < 0) {
|
||||
effectiveSpan = 1.0f / effectiveSpan;
|
||||
}
|
||||
|
||||
PinchGestureInput pinchEvent(PinchGestureInput::PINCHGESTURE_SCALE,
|
||||
mLastTouchInput.mTime,
|
||||
mLastTouchInput.mTimeStamp,
|
||||
currentFocus,
|
||||
effectiveSpan,
|
||||
mPreviousSpan,
|
||||
mLastTouchInput.modifiers);
|
||||
|
||||
rv = mAsyncPanZoomController->HandleGestureEvent(pinchEvent);
|
||||
mPreviousSpan = effectiveSpan;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_WARNING("Unhandled state upon touch move");
|
||||
SetState(GESTURE_NONE);
|
||||
@ -411,6 +478,23 @@ nsEventStatus GestureEventListener::HandleInputTouchEnd()
|
||||
|
||||
break;
|
||||
|
||||
case GESTURE_ONE_TOUCH_PINCH: {
|
||||
SetState(GESTURE_NONE);
|
||||
ParentLayerPoint point(-1, -1);
|
||||
PinchGestureInput pinchEvent(PinchGestureInput::PINCHGESTURE_END,
|
||||
mLastTouchInput.mTime,
|
||||
mLastTouchInput.mTimeStamp,
|
||||
point,
|
||||
1.0f,
|
||||
1.0f,
|
||||
mLastTouchInput.modifiers);
|
||||
mAsyncPanZoomController->HandleGestureEvent(pinchEvent);
|
||||
|
||||
rv = nsEventStatus_eConsumeNoDefault;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
NS_WARNING("Unhandled state upon touch end");
|
||||
SetState(GESTURE_NONE);
|
||||
|
@ -105,7 +105,8 @@ private:
|
||||
// A user put down her finger again right after a single tap thus the
|
||||
// gesture can't be a single tap, but rather a double tap. But we're
|
||||
// still not sure about that until the user lifts her finger again.
|
||||
// Allowed next states: GESTURE_MULTI_TOUCH_DOWN, GESTURE_NONE.
|
||||
// Allowed next states: GESTURE_MULTI_TOUCH_DOWN, GESTURE_ONE_TOUCH_PINCH,
|
||||
// GESTURE_NONE.
|
||||
GESTURE_SECOND_SINGLE_TOUCH_DOWN,
|
||||
|
||||
// A long touch has happened, but the user still keeps her finger down.
|
||||
@ -122,7 +123,12 @@ private:
|
||||
// There are two or more fingers on the screen, and the user has already
|
||||
// pinched enough for us to start zooming the screen.
|
||||
// Allowed next states: GESTURE_NONE
|
||||
GESTURE_PINCH
|
||||
GESTURE_PINCH,
|
||||
|
||||
// The user has double tapped, but not lifted her finger, and moved her
|
||||
// finger more than PINCH_START_THRESHOLD.
|
||||
// Allowed next states: GESTURE_NONE.
|
||||
GESTURE_ONE_TOUCH_PINCH
|
||||
};
|
||||
|
||||
/**
|
||||
@ -141,6 +147,12 @@ private:
|
||||
|
||||
bool MoveDistanceIsLarge();
|
||||
|
||||
/**
|
||||
* Returns current vertical span, counting from the where the user first put
|
||||
* her finger down.
|
||||
*/
|
||||
ParentLayerCoord GetYSpanFromStartPoint();
|
||||
|
||||
/**
|
||||
* Do actual state transition and reset substates.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user