Commit 3a4236be authored by Aldo Culquicondor's avatar Aldo Culquicondor Committed by Commit Bot

VR: Adding support for touch move events in the input handler

Bug: 846478
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_vr
Change-Id: If825417bb9682cfc98299df85bb3e4960001977c
Reviewed-on: https://chromium-review.googlesource.com/1073871
Commit-Queue: Aldo Culquicondor <acondor@chromium.org>
Reviewed-by: default avatarAmirhossein Simjour <asimjour@chromium.org>
Cr-Commit-Position: refs/heads/master@{#563055}
parent fe89fd3b
...@@ -209,6 +209,17 @@ void UiElement::OnButtonUp(const gfx::PointF& position) { ...@@ -209,6 +209,17 @@ void UiElement::OnButtonUp(const gfx::PointF& position) {
} }
} }
void UiElement::OnTouchMove(const gfx::PointF& position) {
if (GetSounds().touch_move != kSoundNone && audio_delegate_) {
audio_delegate_->PlaySound(GetSounds().touch_move);
}
if (event_handlers_.touch_move) {
event_handlers_.touch_move.Run(position);
} else if (parent() && bubble_events()) {
parent()->OnTouchMove(position);
}
}
void UiElement::OnFlingCancel(std::unique_ptr<blink::WebGestureEvent> gesture, void UiElement::OnFlingCancel(std::unique_ptr<blink::WebGestureEvent> gesture,
const gfx::PointF& position) {} const gfx::PointF& position) {}
void UiElement::OnScrollBegin(std::unique_ptr<blink::WebGestureEvent> gesture, void UiElement::OnScrollBegin(std::unique_ptr<blink::WebGestureEvent> gesture,
......
...@@ -67,6 +67,7 @@ struct VR_EXPORT EventHandlers { ...@@ -67,6 +67,7 @@ struct VR_EXPORT EventHandlers {
base::RepeatingCallback<void(const gfx::PointF&)> hover_move; base::RepeatingCallback<void(const gfx::PointF&)> hover_move;
base::RepeatingCallback<void()> button_down; base::RepeatingCallback<void()> button_down;
base::RepeatingCallback<void()> button_up; base::RepeatingCallback<void()> button_up;
base::RepeatingCallback<void(const gfx::PointF&)> touch_move;
base::RepeatingCallback<void(bool)> focus_change; base::RepeatingCallback<void(bool)> focus_change;
}; };
...@@ -153,6 +154,7 @@ class VR_EXPORT UiElement : public cc::AnimationTarget { ...@@ -153,6 +154,7 @@ class VR_EXPORT UiElement : public cc::AnimationTarget {
virtual void OnHoverMove(const gfx::PointF& position); virtual void OnHoverMove(const gfx::PointF& position);
virtual void OnButtonDown(const gfx::PointF& position); virtual void OnButtonDown(const gfx::PointF& position);
virtual void OnButtonUp(const gfx::PointF& position); virtual void OnButtonUp(const gfx::PointF& position);
virtual void OnTouchMove(const gfx::PointF& position);
virtual void OnFlingCancel(std::unique_ptr<blink::WebGestureEvent> gesture, virtual void OnFlingCancel(std::unique_ptr<blink::WebGestureEvent> gesture,
const gfx::PointF& position); const gfx::PointF& position);
virtual void OnScrollBegin(std::unique_ptr<blink::WebGestureEvent> gesture, virtual void OnScrollBegin(std::unique_ptr<blink::WebGestureEvent> gesture,
...@@ -536,7 +538,7 @@ class VR_EXPORT UiElement : public cc::AnimationTarget { ...@@ -536,7 +538,7 @@ class VR_EXPORT UiElement : public cc::AnimationTarget {
// A signal to the input routing machinery that this element accepts scrolls. // A signal to the input routing machinery that this element accepts scrolls.
bool scrollable_ = false; bool scrollable_ = false;
// If true, events such as OnButtonDown, OnBubbleUp, etc, get bubbled up the // If true, events such as OnButtonDown, OnHoverEnter, etc, get bubbled up the
// parent chain. // parent chain.
bool bubble_events_ = false; bool bubble_events_ = false;
......
...@@ -12,9 +12,10 @@ namespace vr { ...@@ -12,9 +12,10 @@ namespace vr {
struct Sounds { struct Sounds {
SoundId hover_enter = kSoundNone; SoundId hover_enter = kSoundNone;
SoundId hover_leave = kSoundNone; SoundId hover_leave = kSoundNone;
SoundId hover_move = kSoundNone;
SoundId button_down = kSoundNone; SoundId button_down = kSoundNone;
SoundId button_up = kSoundNone; SoundId button_up = kSoundNone;
SoundId hover_move = kSoundNone; SoundId touch_move = kSoundNone;
}; };
} // namespace vr } // namespace vr
......
...@@ -116,18 +116,21 @@ void UiInputManager::HandleInput(base::TimeTicks current_time, ...@@ -116,18 +116,21 @@ void UiInputManager::HandleInput(base::TimeTicks current_time,
} }
auto element_local_point = reticle_model->target_local_point; auto element_local_point = reticle_model->target_local_point;
UiElement* captured_element = nullptr;
if (input_capture_element_id_) { if (input_capture_element_id_) {
auto* captured = scene_->GetUiElementById(input_capture_element_id_); captured_element = scene_->GetUiElementById(input_capture_element_id_);
if (captured && captured->IsVisible()) { if (captured_element && captured_element->IsVisible()) {
HitTestRequest request; HitTestRequest request;
request.ray_target = reticle_model->target_point; request.ray_target = reticle_model->target_point;
request.max_distance_to_plane = 2 * scene_->background_distance(); request.max_distance_to_plane = 2 * scene_->background_distance();
HitTestResult result; HitTestResult result;
captured->HitTest(request, &result); captured_element->HitTest(request, &result);
element_local_point = result.local_hit_point; element_local_point = result.local_hit_point;
if (result.type == HitTestResult::Type::kNone) { if (result.type == HitTestResult::Type::kNone) {
element_local_point = kInvalidTargetPoint; element_local_point = kInvalidTargetPoint;
} }
} else {
captured_element = nullptr;
} }
} }
...@@ -147,11 +150,15 @@ void UiInputManager::HandleInput(base::TimeTicks current_time, ...@@ -147,11 +150,15 @@ void UiInputManager::HandleInput(base::TimeTicks current_time,
return; return;
} }
SendHoverEvents(target_element, reticle_model->target_local_point); SendHoverEvents(target_element, reticle_model->target_local_point,
controller_model.touchpad_button_state != ButtonState::DOWN);
if (controller_model.touchpad_button_state == ButtonState::DOWN &&
captured_element) {
captured_element->OnTouchMove(element_local_point);
}
SendButtonDown(target_element, reticle_model->target_local_point, SendButtonDown(target_element, reticle_model->target_local_point,
controller_model.touchpad_button_state); controller_model.touchpad_button_state);
SendButtonUp(element_local_point, controller_model.touchpad_button_state); SendButtonUp(element_local_point, controller_model.touchpad_button_state);
previous_button_state_ = controller_model.touchpad_button_state; previous_button_state_ = controller_model.touchpad_button_state;
} }
...@@ -190,18 +197,14 @@ void UiInputManager::SendScrollEnd(GestureList* gesture_list, ...@@ -190,18 +197,14 @@ void UiInputManager::SendScrollEnd(GestureList* gesture_list,
DCHECK_EQ(gesture_list->front()->GetType(), DCHECK_EQ(gesture_list->front()->GetType(),
blink::WebInputEvent::kGestureScrollEnd); blink::WebInputEvent::kGestureScrollEnd);
} }
if (element) { DCHECK(!element || element->scrollable());
DCHECK(element->scrollable());
}
if (gesture_list->empty() || gesture_list->front()->GetType() != if (gesture_list->empty() || gesture_list->front()->GetType() !=
blink::WebInputEvent::kGestureScrollEnd) { blink::WebInputEvent::kGestureScrollEnd) {
return; return;
} }
DCHECK_LE(gesture_list->size(), 1LU); DCHECK_LE(gesture_list->size(), 1LU);
fling_target_id_ = input_capture_element_id_; fling_target_id_ = input_capture_element_id_;
if (element) { element->OnScrollEnd(std::move(gesture_list->front()), target_point);
element->OnScrollEnd(std::move(gesture_list->front()), target_point);
}
gesture_list->erase(gesture_list->begin()); gesture_list->erase(gesture_list->begin());
input_capture_element_id_ = 0; input_capture_element_id_ = 0;
in_scroll_ = false; in_scroll_ = false;
...@@ -248,9 +251,11 @@ void UiInputManager::SendScrollUpdate(GestureList* gesture_list, ...@@ -248,9 +251,11 @@ void UiInputManager::SendScrollUpdate(GestureList* gesture_list,
} }
void UiInputManager::SendHoverEvents(UiElement* target, void UiInputManager::SendHoverEvents(UiElement* target,
const gfx::PointF& target_point) { const gfx::PointF& target_point,
bool send_move) {
if (target && target->id() == hover_target_id_) { if (target && target->id() == hover_target_id_) {
SendMove(target, target_point); if (send_move)
target->OnHoverMove(target_point);
return; return;
} }
...@@ -265,23 +270,6 @@ void UiInputManager::SendHoverEvents(UiElement* target, ...@@ -265,23 +270,6 @@ void UiInputManager::SendHoverEvents(UiElement* target,
} }
} }
void UiInputManager::SendMove(UiElement* element,
const gfx::PointF& target_point) {
DCHECK(element);
if (!element) {
return;
}
// TODO(mthiesse, vollick): Content is currently way too sensitive to
// mouse moves for how noisy the controller is. It's almost impossible
// to click a link without unintentionally starting a drag event. For
// this reason we disable mouse moves, only delivering a down and up
// event.
if (element->name() == kContentQuad && in_click_) {
return;
}
element->OnHoverMove(target_point);
}
void UiInputManager::SendButtonDown(UiElement* target, void UiInputManager::SendButtonDown(UiElement* target,
const gfx::PointF& target_point, const gfx::PointF& target_point,
ButtonState button_state) { ButtonState button_state) {
...@@ -303,24 +291,19 @@ void UiInputManager::SendButtonDown(UiElement* target, ...@@ -303,24 +291,19 @@ void UiInputManager::SendButtonDown(UiElement* target,
bool UiInputManager::SendButtonUp(const gfx::PointF& target_point, bool UiInputManager::SendButtonUp(const gfx::PointF& target_point,
ButtonState button_state) { ButtonState button_state) {
if (!in_click_) { if (!in_click_ || previous_button_state_ == button_state ||
return false;
}
if (previous_button_state_ == button_state ||
button_state != ButtonState::UP) { button_state != ButtonState::UP) {
return false; return false;
} }
in_click_ = false; in_click_ = false;
if (!input_capture_element_id_) { if (!input_capture_element_id_)
return false; return false;
}
UiElement* element = scene_->GetUiElementById(input_capture_element_id_); UiElement* element = scene_->GetUiElementById(input_capture_element_id_);
if (element) { if (element) {
element->OnButtonUp(target_point); element->OnButtonUp(target_point);
// Clicking outside of the focused element causes it to lose focus. // Clicking outside of the focused element causes it to lose focus.
if (element->id() != focused_element_id_ && element->focusable()) { if (element->id() != focused_element_id_ && element->focusable())
UnfocusFocusedElement(); UnfocusFocusedElement();
}
} }
input_capture_element_id_ = 0; input_capture_element_id_ = 0;
......
...@@ -85,7 +85,9 @@ class VR_EXPORT UiInputManager { ...@@ -85,7 +85,9 @@ class VR_EXPORT UiInputManager {
void SendScrollUpdate(GestureList* gesture_list, void SendScrollUpdate(GestureList* gesture_list,
const gfx::PointF& target_point); const gfx::PointF& target_point);
void SendHoverEvents(UiElement* target, const gfx::PointF& target_point); void SendHoverEvents(UiElement* target,
const gfx::PointF& target_point,
bool send_move);
void SendMove(UiElement* element, const gfx::PointF& target_point); void SendMove(UiElement* element, const gfx::PointF& target_point);
void SendButtonDown(UiElement* target, void SendButtonDown(UiElement* target,
const gfx::PointF& target_point, const gfx::PointF& target_point,
......
...@@ -50,6 +50,7 @@ class MockRect : public Rect { ...@@ -50,6 +50,7 @@ class MockRect : public Rect {
MOCK_METHOD1(OnHoverMove, void(const gfx::PointF& position)); MOCK_METHOD1(OnHoverMove, void(const gfx::PointF& position));
MOCK_METHOD1(OnButtonDown, void(const gfx::PointF& position)); MOCK_METHOD1(OnButtonDown, void(const gfx::PointF& position));
MOCK_METHOD1(OnButtonUp, void(const gfx::PointF& position)); MOCK_METHOD1(OnButtonUp, void(const gfx::PointF& position));
MOCK_METHOD1(OnTouchMove, void(const gfx::PointF& position));
MOCK_METHOD2(OnScrollBegin, MOCK_METHOD2(OnScrollBegin,
void(std::unique_ptr<blink::WebGestureEvent>, void(std::unique_ptr<blink::WebGestureEvent>,
const gfx::PointF&)); const gfx::PointF&));
...@@ -289,11 +290,14 @@ TEST_F(UiInputManagerTest, HoverClick) { ...@@ -289,11 +290,14 @@ TEST_F(UiInputManagerTest, HoverClick) {
Mock::VerifyAndClearExpectations(p_element); Mock::VerifyAndClearExpectations(p_element);
// Press the button while on the element. // Press the button while on the element.
EXPECT_CALL(*p_element, OnHoverMove(_));
EXPECT_CALL(*p_element, OnButtonDown(_)); EXPECT_CALL(*p_element, OnButtonDown(_));
HandleInput(kForwardVector, kDown); HandleInput(kForwardVector, kDown);
Mock::VerifyAndClearExpectations(p_element); Mock::VerifyAndClearExpectations(p_element);
EXPECT_CALL(*p_element, OnTouchMove(_));
HandleInput(kForwardVector, kDown);
Mock::VerifyAndClearExpectations(p_element);
// Release the button while on the element. // Release the button while on the element.
EXPECT_CALL(*p_element, OnHoverMove(_)); EXPECT_CALL(*p_element, OnHoverMove(_));
EXPECT_CALL(*p_element, OnButtonUp(_)); EXPECT_CALL(*p_element, OnButtonUp(_));
...@@ -306,7 +310,8 @@ TEST_F(UiInputManagerTest, HoverClick) { ...@@ -306,7 +310,8 @@ TEST_F(UiInputManagerTest, HoverClick) {
Mock::VerifyAndClearExpectations(p_element); Mock::VerifyAndClearExpectations(p_element);
// Press while not on the element, move over the element, move away, then // Press while not on the element, move over the element, move away, then
// release. The element should receive hover events. // release. The element should receive hover enter/leave, but not hover move
// nor touch events.
HandleInput(kBackwardVector, kDown); HandleInput(kBackwardVector, kDown);
EXPECT_CALL(*p_element, OnHoverEnter(_)); EXPECT_CALL(*p_element, OnHoverEnter(_));
HandleInput(kForwardVector, kDown); HandleInput(kForwardVector, kDown);
...@@ -314,11 +319,13 @@ TEST_F(UiInputManagerTest, HoverClick) { ...@@ -314,11 +319,13 @@ TEST_F(UiInputManagerTest, HoverClick) {
HandleInput(kBackwardVector, kUp); HandleInput(kBackwardVector, kUp);
Mock::VerifyAndClearExpectations(p_element); Mock::VerifyAndClearExpectations(p_element);
// Press on an element, move away, then release. // Press on an element, move away, then release. The element should receive
// hover leave, but keep receiving touch move events until release.
EXPECT_CALL(*p_element, OnHoverEnter(_)); EXPECT_CALL(*p_element, OnHoverEnter(_));
EXPECT_CALL(*p_element, OnButtonDown(_)); EXPECT_CALL(*p_element, OnButtonDown(_));
HandleInput(kForwardVector, kDown); HandleInput(kForwardVector, kDown);
EXPECT_CALL(*p_element, OnHoverLeave()); EXPECT_CALL(*p_element, OnHoverLeave());
EXPECT_CALL(*p_element, OnTouchMove(_));
HandleInput(kBackwardVector, kDown); HandleInput(kBackwardVector, kDown);
Mock::VerifyAndClearExpectations(p_element); Mock::VerifyAndClearExpectations(p_element);
EXPECT_CALL(*p_element, OnButtonUp(_)); EXPECT_CALL(*p_element, OnButtonUp(_));
...@@ -327,7 +334,8 @@ TEST_F(UiInputManagerTest, HoverClick) { ...@@ -327,7 +334,8 @@ TEST_F(UiInputManagerTest, HoverClick) {
} }
// Test pressing the button while on an element, moving to another element, and // Test pressing the button while on an element, moving to another element, and
// releasing the button. Upon release, the previous element should see its click // releasing the button. Before release, the first element should still receive
// touch move events. Upon release, the previous element should see its click
// and hover states cleared, and the new element should see a hover. // and hover states cleared, and the new element should see a hover.
TEST_F(UiInputManagerTest, ReleaseButtonOnAnotherElement) { TEST_F(UiInputManagerTest, ReleaseButtonOnAnotherElement) {
StrictMock<MockRect>* p_front_element = CreateAndAddMockElement(-5.f); StrictMock<MockRect>* p_front_element = CreateAndAddMockElement(-5.f);
...@@ -342,6 +350,7 @@ TEST_F(UiInputManagerTest, ReleaseButtonOnAnotherElement) { ...@@ -342,6 +350,7 @@ TEST_F(UiInputManagerTest, ReleaseButtonOnAnotherElement) {
HandleInput(kForwardVector, kDown); HandleInput(kForwardVector, kDown);
EXPECT_CALL(*p_front_element, OnHoverLeave()); EXPECT_CALL(*p_front_element, OnHoverLeave());
EXPECT_CALL(*p_back_element, OnHoverEnter(_)); EXPECT_CALL(*p_back_element, OnHoverEnter(_));
EXPECT_CALL(*p_front_element, OnTouchMove(_));
HandleInput(kBackwardVector, kDown); HandleInput(kBackwardVector, kDown);
EXPECT_CALL(*p_back_element, OnHoverMove(_)); EXPECT_CALL(*p_back_element, OnHoverMove(_));
EXPECT_CALL(*p_front_element, OnButtonUp(_)); EXPECT_CALL(*p_front_element, OnButtonUp(_));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment