blob: 22efae4ab3c5a9739c8b15d333dfb4e30ceac484 [file] [log] [blame]
// 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_