| // Copyright 2013 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_DIRECT_MANIPULATION_H_ | |
| #define FLUTTER_SHELL_PLATFORM_WINDOWS_DIRECT_MANIPULATION_H_ | |
| #include "flutter/fml/memory/ref_counted.h" | |
| #include <wrl/client.h> | |
| #include "directmanipulation.h" | |
| namespace flutter { | |
| class FlutterWindow; | |
| class WindowBindingHandlerDelegate; | |
| class DirectManipulationEventHandler; | |
| // Owner for a DirectManipulation event handler, contains the link between | |
| // DirectManipulation and WindowBindingHandlerDelegate. | |
| class DirectManipulationOwner { | |
| public: | |
| explicit DirectManipulationOwner(FlutterWindow* window); | |
| virtual ~DirectManipulationOwner() = default; | |
| // Initialize a DirectManipulation viewport with specified width and height. | |
| // These should match the width and height of the application window. | |
| int Init(unsigned int width, unsigned int height); | |
| // Resize the DirectManipulation viewport. Should be called when the | |
| // application window is resized. | |
| void ResizeViewport(unsigned int width, unsigned int height); | |
| // Set the WindowBindingHandlerDelegate which will receive callbacks based on | |
| // DirectManipulation updates. | |
| void SetBindingHandlerDelegate( | |
| WindowBindingHandlerDelegate* binding_handler_delegate); | |
| // Called when DM_POINTERHITTEST occurs with an acceptable pointer type. Will | |
| // start DirectManipulation for that interaction. | |
| virtual void SetContact(UINT contactId); | |
| // Called to get updates from DirectManipulation. Should be called frequently | |
| // to provide smooth updates. | |
| void Update(); | |
| // Release child event handler and OS resources. | |
| void Destroy(); | |
| // The target that should be updated when DirectManipulation provides a new | |
| // pan/zoom transformation. | |
| WindowBindingHandlerDelegate* binding_handler_delegate; | |
| private: | |
| // The window gesture input is occuring on. | |
| FlutterWindow* window_; | |
| // Cookie needed to register child event handler with viewport. | |
| DWORD viewportHandlerCookie_; | |
| // Object needed for operation of the DirectManipulation API. | |
| Microsoft::WRL::ComPtr<IDirectManipulationManager> manager_; | |
| // Object needed for operation of the DirectManipulation API. | |
| Microsoft::WRL::ComPtr<IDirectManipulationUpdateManager> updateManager_; | |
| // Object needed for operation of the DirectManipulation API. | |
| Microsoft::WRL::ComPtr<IDirectManipulationViewport> viewport_; | |
| // Child needed for operation of the DirectManipulation API. | |
| fml::RefPtr<DirectManipulationEventHandler> handler_; | |
| FML_DISALLOW_COPY_AND_ASSIGN(DirectManipulationOwner); | |
| }; | |
| // Implements DirectManipulation event handling interfaces, receives calls from | |
| // system when gesture events occur. | |
| class DirectManipulationEventHandler | |
| : public fml::RefCountedThreadSafe<DirectManipulationEventHandler>, | |
| public IDirectManipulationViewportEventHandler, | |
| public IDirectManipulationInteractionEventHandler { | |
| friend class DirectManipulationOwner; | |
| FML_FRIEND_REF_COUNTED_THREAD_SAFE(DirectManipulationEventHandler); | |
| FML_FRIEND_MAKE_REF_COUNTED(DirectManipulationEventHandler); | |
| public: | |
| explicit DirectManipulationEventHandler(DirectManipulationOwner* owner) | |
| : owner_(owner) {} | |
| // |IUnknown| | |
| STDMETHODIMP QueryInterface(REFIID iid, void** ppv) override; | |
| // |IUnknown| | |
| ULONG STDMETHODCALLTYPE AddRef() override; | |
| // |IUnknown| | |
| ULONG STDMETHODCALLTYPE Release() override; | |
| // |IDirectManipulationViewportEventHandler| | |
| HRESULT STDMETHODCALLTYPE | |
| OnViewportStatusChanged(IDirectManipulationViewport* viewport, | |
| DIRECTMANIPULATION_STATUS current, | |
| DIRECTMANIPULATION_STATUS previous) override; | |
| // |IDirectManipulationViewportEventHandler| | |
| HRESULT STDMETHODCALLTYPE | |
| OnViewportUpdated(IDirectManipulationViewport* viewport) override; | |
| // |IDirectManipulationViewportEventHandler| | |
| HRESULT STDMETHODCALLTYPE | |
| OnContentUpdated(IDirectManipulationViewport* viewport, | |
| IDirectManipulationContent* content) override; | |
| // |IDirectManipulationInteractionEventHandler| | |
| HRESULT STDMETHODCALLTYPE | |
| OnInteraction(IDirectManipulationViewport2* viewport, | |
| DIRECTMANIPULATION_INTERACTION_TYPE interaction) override; | |
| private: | |
| struct GestureData { | |
| float scale; | |
| float pan_x; | |
| float pan_y; | |
| }; | |
| // Convert transform array to Flutter-usable values. | |
| GestureData ConvertToGestureData(float transform[6]); | |
| // Unique identifier to associate with all gesture event updates. | |
| int32_t GetDeviceId(); | |
| // Parent object, used to store the target for gesture event updates. | |
| DirectManipulationOwner* owner_; | |
| // We need to reset some parts of DirectManipulation after each gesture | |
| // A flag is needed to ensure that false events created as the reset occurs | |
| // are not sent to the flutter framework. | |
| bool during_synthesized_reset_ = false; | |
| // Store whether current events are from synthetic inertia rather than user | |
| // input. | |
| bool during_inertia_ = false; | |
| // The transform might not be able to be reset before the next gesture, so | |
| // the initial state needs to be stored for reference. | |
| GestureData initial_gesture_data_ = { | |
| 1, // scale | |
| 0, // pan_x | |
| 0, // pan_y | |
| }; | |
| // Store the difference between the last pan offsets to determine if inertia | |
| // has been cancelled in the middle of an animation. | |
| float last_pan_x_ = 0.0; | |
| float last_pan_y_ = 0.0; | |
| float last_pan_delta_x_ = 0.0; | |
| float last_pan_delta_y_ = 0.0; | |
| }; | |
| } // namespace flutter | |
| #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_DIRECT_MANIPULATION_H_ |