1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/vr/platform_ui_input_delegate.h"
6 
7 #include "base/callback_helpers.h"
8 #include "base/time/time.h"
9 #include "chrome/browser/vr/platform_input_handler.h"
10 
11 namespace vr {
12 
13 namespace {
14 
15 static constexpr gfx::PointF kOutOfBoundsPoint = {-0.5f, -0.5f};
16 
17 }  // namespace
18 
PlatformUiInputDelegate()19 PlatformUiInputDelegate::PlatformUiInputDelegate() {}
PlatformUiInputDelegate(PlatformInputHandler * input_handler)20 PlatformUiInputDelegate::PlatformUiInputDelegate(
21     PlatformInputHandler* input_handler)
22     : input_handler_(input_handler) {}
23 
24 PlatformUiInputDelegate::~PlatformUiInputDelegate() = default;
25 
OnHoverEnter(const gfx::PointF & normalized_hit_point,base::TimeTicks timestamp)26 void PlatformUiInputDelegate::OnHoverEnter(
27     const gfx::PointF& normalized_hit_point,
28     base::TimeTicks timestamp) {
29   SendGestureToTarget(
30       MakeInputEvent(InputEvent::kHoverEnter, normalized_hit_point, timestamp));
31 }
32 
OnHoverLeave(base::TimeTicks timestamp)33 void PlatformUiInputDelegate::OnHoverLeave(base::TimeTicks timestamp) {
34   // Note that we send an out of bounds hover leave event. With blink feature
35   // UpdateHoverPostLayout turned on, a MouseMove event will dispatched post a
36   // Layout. Sending a mouse leave event at 0,0 will result continuous
37   // MouseMove events sent to the content if the content keeps relayout itself.
38   // See https://crbug.com/762573 for details.
39   SendGestureToTarget(
40       MakeInputEvent(InputEvent::kHoverLeave, kOutOfBoundsPoint, timestamp));
41 }
42 
OnHoverMove(const gfx::PointF & normalized_hit_point,base::TimeTicks timestamp)43 void PlatformUiInputDelegate::OnHoverMove(
44     const gfx::PointF& normalized_hit_point,
45     base::TimeTicks timestamp) {
46   SendGestureToTarget(
47       MakeInputEvent(InputEvent::kHoverMove, normalized_hit_point, timestamp));
48 }
49 
OnButtonDown(const gfx::PointF & normalized_hit_point,base::TimeTicks timestamp)50 void PlatformUiInputDelegate::OnButtonDown(
51     const gfx::PointF& normalized_hit_point,
52     base::TimeTicks timestamp) {
53   SendGestureToTarget(
54       MakeInputEvent(InputEvent::kButtonDown, normalized_hit_point, timestamp));
55 }
56 
OnButtonUp(const gfx::PointF & normalized_hit_point,base::TimeTicks timestamp)57 void PlatformUiInputDelegate::OnButtonUp(
58     const gfx::PointF& normalized_hit_point,
59     base::TimeTicks timestamp) {
60   SendGestureToTarget(
61       MakeInputEvent(InputEvent::kButtonUp, normalized_hit_point, timestamp));
62 }
63 
OnTouchMove(const gfx::PointF & normalized_hit_point,base::TimeTicks timestamp)64 void PlatformUiInputDelegate::OnTouchMove(
65     const gfx::PointF& normalized_hit_point,
66     base::TimeTicks timestamp) {
67   SendGestureToTarget(
68       MakeInputEvent(InputEvent::kMove, normalized_hit_point, timestamp));
69 }
70 
OnInputEvent(std::unique_ptr<InputEvent> event,const gfx::PointF & normalized_hit_point)71 void PlatformUiInputDelegate::OnInputEvent(
72     std::unique_ptr<InputEvent> event,
73     const gfx::PointF& normalized_hit_point) {
74   UpdateGesture(normalized_hit_point, event.get());
75   SendGestureToTarget(std::move(event));
76 }
77 
UpdateGesture(const gfx::PointF & normalized_content_hit_point,InputEvent * gesture)78 void PlatformUiInputDelegate::UpdateGesture(
79     const gfx::PointF& normalized_content_hit_point,
80     InputEvent* gesture) {
81   gesture->set_position_in_widget(
82       ScalePoint(normalized_content_hit_point, size_.width(), size_.height()));
83 }
84 
SendGestureToTarget(std::unique_ptr<InputEvent> event)85 void PlatformUiInputDelegate::SendGestureToTarget(
86     std::unique_ptr<InputEvent> event) {
87   if (!event || !input_handler_)
88     return;
89 
90   input_handler_->ForwardEventToPlatformUi(std::move(event));
91 }
92 
MakeInputEvent(InputEvent::Type type,const gfx::PointF & normalized_web_content_location,base::TimeTicks time_stamp) const93 std::unique_ptr<InputEvent> PlatformUiInputDelegate::MakeInputEvent(
94     InputEvent::Type type,
95     const gfx::PointF& normalized_web_content_location,
96     base::TimeTicks time_stamp) const {
97   gfx::Point location = CalculateLocation(normalized_web_content_location);
98 
99   auto event = std::make_unique<InputEvent>(type);
100   event->set_time_stamp(time_stamp);
101   event->SetPositionInWidget(location.x(), location.y());
102   return event;
103 }
104 
CalculateLocation(const gfx::PointF & normalized_web_content_location) const105 gfx::Point PlatformUiInputDelegate::CalculateLocation(
106     const gfx::PointF& normalized_web_content_location) const {
107   return gfx::Point(size_.width() * normalized_web_content_location.x(),
108                     size_.height() * normalized_web_content_location.y());
109 }
110 
111 }  // namespace vr
112