/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
class DManipEventHandler : public IDirectManipulationViewportEventHandler, public IDirectManipulationInteractionEventHandler { public: typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
enumclass Phase { eStart, eMiddle, eEnd }; // Return value indicates if we sent an event or not and hence if we should // update mLastScale. (We only want to send pinch events if the computed // deltaY for the corresponding WidgetWheelEvent would be non-zero.) bool SendPinch(Phase aPhase, float aScale); void SendPan(Phase aPhase, float x, float y, bool aIsInertia); staticvoid SendPanCommon(nsWindow* aWindow, Phase aPhase,
ScreenPoint aPosition, double aDeltaX, double aDeltaY, Modifiers aMods, bool aIsInertia);
if (current == DIRECTMANIPULATION_INERTIA) { if (previous != DIRECTMANIPULATION_RUNNING || mState != State::ePanning) { // xxx transition to none? return S_OK;
}
TransitionToState(State::eInertia);
}
if (current == DIRECTMANIPULATION_RUNNING) { // INERTIA -> RUNNING, should start a new sequence. if (previous == DIRECTMANIPULATION_INERTIA) {
TransitionToState(State::eNone);
}
}
if (current != DIRECTMANIPULATION_ENABLED &&
current != DIRECTMANIPULATION_READY) { return S_OK;
}
// A session has ended, reset the transform. if (mLastScale != 1.f || mLastXOffset != 0.f || mLastYOffset != 0.f) {
HRESULT hr =
viewport->ZoomToRect(0, 0, mBounds.width, mBounds.height, false); if (!SUCCEEDED(hr)) {
NS_WARNING("ZoomToRect failed");
}
}
mLastScale = 1.f;
mLastXOffset = 0.f;
mLastYOffset = 0.f;
// End the previous sequence. switch (prevState) { case State::ePanning: { // ePanning -> *: PanEnd
SendPan(Phase::eEnd, 0.f, 0.f, false); break;
} case State::eInertia: { // eInertia -> *: MomentumEnd
SendPan(Phase::eEnd, 0.f, 0.f, true); break;
} case State::ePinching: {
MOZ_ASSERT(aNewState == State::eNone); // ePinching -> eNone: PinchEnd. ePinching should only transition to // eNone. // Only send a pinch end if we sent a pinch start. if (!mShouldSendPinchStart) {
SendPinch(Phase::eEnd, 0.f);
}
mShouldSendPinchStart = false; break;
} case State::eNone: { // eNone -> *: no cleanup is needed. break;
} default:
MOZ_ASSERT(false);
}
// Start the new sequence. switch (aNewState) { case State::ePanning: { // eInertia, eNone -> ePanning: PanStart. // We're being called from OnContentUpdated, it has the coords we need to // pass to SendPan(Phase::eStart), so set mShouldSendPanStart and when we // return OnContentUpdated will check it and call SendPan(Phase::eStart).
mShouldSendPanStart = true; break;
} case State::eInertia: { // Only ePanning can transition to eInertia.
MOZ_ASSERT(prevState == State::ePanning);
SendPan(Phase::eStart, 0.f, 0.f, true); break;
} case State::ePinching: { // * -> ePinching: PinchStart. // Pinch gesture may begin with some scroll events. // We're being called from OnContentUpdated, it has the scale we need to // pass to SendPinch(Phase::eStart), so set mShouldSendPinchStart and when // we return OnContentUpdated will check it and call // SendPinch(Phase::eStart).
mShouldSendPinchStart = true; break;
} case State::eNone: { // * -> eNone: only cleanup is needed. break;
} default:
MOZ_ASSERT(false);
}
}
// Not different from last time. if (FuzzyEqualsMultiplicative(scale, mLastScale) && xoffset == mLastXOffset &&
yoffset == mLastYOffset) { return S_OK;
}
// Consider this is a Scroll when scale factor equals 1.0. if (FuzzyEqualsMultiplicative(scale, 1.f)) { if (mState == State::eNone) {
TransitionToState(State::ePanning);
}
} else { // Pinch gesture may begin with some scroll events.
TransitionToState(State::ePinching);
}
if (mState == State::ePanning || mState == State::eInertia) { // Accumulate the offset (by not updating mLastX/YOffset) until we have at // least one pixel. float dx = std::abs(mLastXOffset - xoffset); float dy = std::abs(mLastYOffset - yoffset); if (dx < 1.f && dy < 1.f) { return S_OK;
}
}
bool updateLastScale = true; if (mState == State::ePanning) { if (mShouldSendPanStart) {
SendPan(Phase::eStart, mLastXOffset - xoffset, mLastYOffset - yoffset, false);
mShouldSendPanStart = false;
} else {
SendPan(Phase::eMiddle, mLastXOffset - xoffset, mLastYOffset - yoffset, false);
}
} elseif (mState == State::eInertia) {
SendPan(Phase::eMiddle, mLastXOffset - xoffset, mLastYOffset - yoffset, true);
} elseif (mState == State::ePinching) { if (mShouldSendPinchStart) {
updateLastScale = SendPinch(Phase::eStart, scale); // Only clear mShouldSendPinchStart if we actually sent the event // (updateLastScale tells us if we sent an event). if (updateLastScale) {
mShouldSendPinchStart = false;
}
} else {
updateLastScale = SendPinch(Phase::eMiddle, scale);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.