1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
// Copyright 2015 The Chromium 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 UI_WIN_DIRECT_MANIPULATION_H_
#define UI_WIN_DIRECT_MANIPULATION_H_
#include <windows.h>
#include <directmanipulation.h>
#include <wrl.h>
#include <memory>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "ui/base/ui_base_export.h"
#include "ui/base/win/window_event_target.h"
#include "ui/gfx/geometry/rect.h"
namespace content {
class DirectManipulationBrowserTest;
} // namespace content
namespace ui {
namespace win {
class DirectManipulationUnitTest;
class DirectManipulationHelper;
// DirectManipulationHandler receives status update and gesture events from
// Direct Manipulation API.
class DirectManipulationHandler
: public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags<
Microsoft::WRL::RuntimeClassType::ClassicCom>,
Microsoft::WRL::Implements<
Microsoft::WRL::RuntimeClassFlags<
Microsoft::WRL::RuntimeClassType::ClassicCom>,
Microsoft::WRL::FtmBase,
IDirectManipulationViewportEventHandler>> {
public:
explicit DirectManipulationHandler(DirectManipulationHelper* helper,
WindowEventTarget* event_target);
// WindowEventTarget updates for every DM_POINTERHITTEST in case window
// hierarchy changed.
void SetWindowEventTarget(WindowEventTarget* event_target);
void SetDeviceScaleFactor(float device_scale_factor);
private:
friend DirectManipulationUnitTest;
DirectManipulationHandler();
~DirectManipulationHandler() override;
enum class Gesture { kNone, kScroll, kFling, kPinch };
void TransitionToState(Gesture gesture);
HRESULT STDMETHODCALLTYPE
OnViewportStatusChanged(_In_ IDirectManipulationViewport* viewport,
_In_ DIRECTMANIPULATION_STATUS current,
_In_ DIRECTMANIPULATION_STATUS previous) override;
HRESULT STDMETHODCALLTYPE
OnViewportUpdated(_In_ IDirectManipulationViewport* viewport) override;
HRESULT STDMETHODCALLTYPE
OnContentUpdated(_In_ IDirectManipulationViewport* viewport,
_In_ IDirectManipulationContent* content) override;
DirectManipulationHelper* helper_ = nullptr;
WindowEventTarget* event_target_ = nullptr;
float device_scale_factor_ = 1.0f;
float last_scale_ = 1.0f;
int last_x_offset_ = 0;
int last_y_offset_ = 0;
bool first_ready_ = false;
bool should_send_scroll_begin_ = false;
// Current recognized gesture from Direct Manipulation.
Gesture gesture_state_ = Gesture::kNone;
DISALLOW_COPY_AND_ASSIGN(DirectManipulationHandler);
};
// Windows 10 provides a new API called Direct Manipulation which generates
// smooth scroll and scale factor via IDirectManipulationViewportEventHandler
// on precision touchpad.
// 1. The foreground window is checked to see if it is a Direct Manipulation
// consumer.
// 2. Call SetContact in Direct Manipulation takes over the following scrolling
// when DM_POINTERHITTEST.
// 3. OnViewportStatusChanged will be called when the gesture phase change.
// OnContentUpdated will be called when the gesture update.
class UI_BASE_EXPORT DirectManipulationHelper {
public:
// Creates and initializes an instance of this class if Direct Manipulation is
// enabled on the platform. Returns nullptr if it disabled or failed on
// initialization.
static std::unique_ptr<DirectManipulationHelper> CreateInstance(
HWND window,
WindowEventTarget* event_target);
// Creates and initializes an instance for testing.
static std::unique_ptr<DirectManipulationHelper> CreateInstanceForTesting(
WindowEventTarget* event_target,
Microsoft::WRL::ComPtr<IDirectManipulationViewport> viewport);
~DirectManipulationHelper();
// Registers and activates the passed in |window| as a Direct Manipulation
// consumer.
void Activate();
// Deactivates Direct Manipulation processing on the passed in |window|.
void Deactivate();
// Reset the fake viewport for gesture end.
HRESULT ResetViewport(bool need_animtation);
// Pass the pointer hit test to Direct Manipulation. Return true indicated we
// need poll for new events every frame from here.
bool OnPointerHitTest(WPARAM w_param, WindowEventTarget* event_target);
// On each frame poll new Direct Manipulation events. Return true if we still
// need poll for new events on next frame, otherwise stop request need begin
// frame.
bool PollForNextEvent();
private:
friend class content::DirectManipulationBrowserTest;
friend class DirectManipulationUnitTest;
DirectManipulationHelper();
// This function instantiates Direct Manipulation and creates a viewport for
// the passed in |window|. Return false if initialize failed.
bool Initialize(WindowEventTarget* event_target);
void SetDeviceScaleFactorForTesting(float factor);
Microsoft::WRL::ComPtr<IDirectManipulationManager> manager_;
Microsoft::WRL::ComPtr<IDirectManipulationUpdateManager> update_manager_;
Microsoft::WRL::ComPtr<IDirectManipulationViewport> viewport_;
Microsoft::WRL::ComPtr<DirectManipulationHandler> event_handler_;
HWND window_;
DWORD view_port_handler_cookie_;
bool need_poll_events_ = false;
DISALLOW_COPY_AND_ASSIGN(DirectManipulationHelper);
};
} // namespace win
} // namespace ui
#endif // UI_WIN_DIRECT_MANIPULATION_H_
|