5 #include "flutter/fml/logging.h"
13 #define RETURN_IF_FAILED(operation) \
14 if (FAILED(operation)) { \
15 FML_LOG(ERROR) << #operation << " failed"; \
17 updateManager_ = nullptr; \
18 viewport_ = nullptr; \
22 #define WARN_IF_FAILED(operation) \
23 if (FAILED(operation)) { \
24 FML_LOG(ERROR) << #operation << " failed"; \
29 int32_t DirectManipulationEventHandler::GetDeviceId() {
30 return (int32_t)
reinterpret_cast<int64_t
>(
this);
35 if ((iid == IID_IUnknown) ||
36 (iid == IID_IDirectManipulationViewportEventHandler)) {
37 *ppv =
static_cast<IDirectManipulationViewportEventHandler*
>(
this);
40 }
else if (iid == IID_IDirectManipulationInteractionEventHandler) {
41 *ppv =
static_cast<IDirectManipulationInteractionEventHandler*
>(
this);
48 DirectManipulationEventHandler::GestureData
49 DirectManipulationEventHandler::ConvertToGestureData(
float transform[6]) {
54 const int mantissa_bits_chop = 2;
55 const float factor = (1 << mantissa_bits_chop) + 1;
56 float c = factor * transform[0];
58 c - (c - transform[0]),
65 IDirectManipulationViewport* viewport,
66 DIRECTMANIPULATION_STATUS current,
67 DIRECTMANIPULATION_STATUS previous) {
68 if (during_synthesized_reset_) {
69 during_synthesized_reset_ = current != DIRECTMANIPULATION_READY;
72 during_inertia_ = current == DIRECTMANIPULATION_INERTIA;
73 if (current == DIRECTMANIPULATION_RUNNING) {
74 IDirectManipulationContent*
content;
75 HRESULT hr = viewport->GetPrimaryContent(IID_PPV_ARGS(&
content));
78 hr =
content->GetContentTransform(transform, ARRAYSIZE(transform));
80 initial_gesture_data_ = ConvertToGestureData(transform);
82 FML_LOG(ERROR) <<
"GetContentTransform failed";
85 FML_LOG(ERROR) <<
"GetPrimaryContent failed";
90 }
else if (previous == DIRECTMANIPULATION_RUNNING) {
92 last_pan_delta_x_ = 0.0;
93 last_pan_delta_y_ = 0.0;
97 }
else if (previous == DIRECTMANIPULATION_INERTIA) {
99 (std::max)(std::abs(last_pan_delta_x_), std::abs(last_pan_delta_y_)) >
107 during_synthesized_reset_ =
true;
110 last_pan_delta_x_ = 0.0;
111 last_pan_delta_y_ = 0.0;
113 HRESULT hr = viewport->GetViewportRect(&rect);
115 FML_LOG(ERROR) <<
"Failed to get the current viewport rect";
118 hr = viewport->ZoomToRect(rect.left, rect.top, rect.right, rect.bottom,
121 FML_LOG(ERROR) <<
"Failed to reset the gesture using ZoomToRect";
129 IDirectManipulationViewport* viewport) {
134 IDirectManipulationViewport* viewport,
135 IDirectManipulationContent*
content) {
137 HRESULT hr =
content->GetContentTransform(transform, ARRAYSIZE(transform));
139 FML_LOG(ERROR) <<
"GetContentTransform failed";
142 if (!during_synthesized_reset_) {
143 GestureData data = ConvertToGestureData(transform);
144 float scale = data.scale / initial_gesture_data_.scale;
145 float pan_x = data.pan_x - initial_gesture_data_.pan_x;
146 float pan_y = data.pan_y - initial_gesture_data_.pan_y;
147 last_pan_delta_x_ = pan_x - last_pan_x_;
148 last_pan_delta_y_ = pan_y - last_pan_y_;
153 GetDeviceId(), pan_x, pan_y, scale, 0);
160 IDirectManipulationViewport2* viewport,
161 DIRECTMANIPULATION_INTERACTION_TYPE interaction) {
166 RefCountedThreadSafe::AddRef();
171 RefCountedThreadSafe::Release();
180 CLSCTX_INPROC_SERVER,
181 IID_IDirectManipulationManager, &manager_));
183 IID_IDirectManipulationUpdateManager, &updateManager_));
185 IID_IDirectManipulationViewport,
187 DIRECTMANIPULATION_CONFIGURATION configuration =
188 DIRECTMANIPULATION_CONFIGURATION_INTERACTION |
189 DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_X |
190 DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_Y |
191 DIRECTMANIPULATION_CONFIGURATION_SCALING |
192 DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_INERTIA;
195 DIRECTMANIPULATION_VIEWPORT_OPTIONS_MANUALUPDATE));
196 handler_ = fml::MakeRefCounted<DirectManipulationEventHandler>(
this);
199 RECT rect = {0, 0, (LONG)width, (LONG)height};
208 unsigned int height) {
210 RECT rect = {0, 0, (LONG)width, (LONG)height};
217 handler_->owner_ =
nullptr;
223 WARN_IF_FAILED(viewport_->RemoveEventHandler(viewportHandlerCookie_));
227 if (window_ && manager_) {
233 updateManager_ =
nullptr;
240 viewport_->SetContact(contactId);
250 if (updateManager_) {
251 HRESULT hr = updateManager_->Update(
nullptr);
253 FML_LOG(ERROR) <<
"updateManager_->Update failed";
254 auto error = GetLastError();
255 FML_LOG(ERROR) << error;
257 size_t size = FormatMessageW(
258 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
259 FORMAT_MESSAGE_IGNORE_INSERTS,
260 NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
261 reinterpret_cast<LPWSTR
>(&
message), 0, NULL);