| // Copyright 2017 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 CHROME_BROWSER_VR_UI_INPUT_MANAGER_H_ |
| #define CHROME_BROWSER_VR_UI_INPUT_MANAGER_H_ |
| |
| #include <memory> |
| #include <vector> |
| |
| #include "base/time/time.h" |
| #include "chrome/browser/vr/model/controller_model.h" |
| #include "chrome/browser/vr/vr_ui_export.h" |
| #include "ui/gfx/geometry/point3_f.h" |
| #include "ui/gfx/geometry/point_f.h" |
| #include "ui/gfx/geometry/vector3d_f.h" |
| #include "ui/gfx/transform.h" |
| |
| namespace vr { |
| |
| class UiScene; |
| class UiElement; |
| class InputEvent; |
| struct RenderInfo; |
| struct ReticleModel; |
| struct EditedText; |
| |
| using InputEventList = std::vector<std::unique_ptr<InputEvent>>; |
| |
| // Based on controller input finds the hit UI element and determines the |
| // interaction with UI elements and the web contents. |
| class VR_UI_EXPORT UiInputManager { |
| public: |
| // When testing, it can be useful to hit test directly along the laser. |
| // Updating the strategy permits this behavior, but it should not be used in |
| // production. In production, we hit test along a ray that extends from the |
| // world origin to a point far along the laser. |
| enum HitTestStrategy { |
| PROJECT_TO_WORLD_ORIGIN, |
| PROJECT_TO_LASER_ORIGIN_FOR_TEST, |
| }; |
| |
| explicit UiInputManager(UiScene* scene); |
| ~UiInputManager(); |
| void HandleInput(base::TimeTicks current_time, |
| const RenderInfo& render_info, |
| const ControllerModel& controller_model, |
| ReticleModel* reticle_model, |
| InputEventList* input_event_list); |
| |
| void OnPause(); |
| |
| // Text input related. |
| void RequestFocus(int element_id); |
| void RequestUnfocus(int element_id); |
| void OnInputEdited(const EditedText& info); |
| void OnInputCommitted(const EditedText& info); |
| void OnKeyboardHidden(); |
| |
| bool controller_resting_in_viewport() const { |
| return controller_resting_in_viewport_; |
| } |
| |
| void set_hit_test_strategy(HitTestStrategy strategy) { |
| hit_test_strategy_ = strategy; |
| } |
| |
| private: |
| void SendFlingCancel(InputEventList* input_event_list, |
| const gfx::PointF& target_point); |
| void SendScrollEnd(InputEventList* input_event_list, |
| const gfx::PointF& target_point, |
| ControllerModel::ButtonState button_state); |
| void SendScrollBegin(UiElement* target, |
| InputEventList* input_event_list, |
| const gfx::PointF& target_point); |
| void SendScrollUpdate(InputEventList* input_event_list, |
| const gfx::PointF& target_point); |
| |
| void SendHoverLeave(UiElement* current_target, base::TimeTicks timestamp); |
| void SendHoverEnter(UiElement* target, |
| const gfx::PointF& target_point, |
| base::TimeTicks timestamp); |
| void SendHoverMove(UiElement* target, |
| const gfx::PointF& target_point, |
| base::TimeTicks timestamp); |
| |
| void SendButtonUp(const gfx::PointF& target_point, |
| ControllerModel::ButtonState button_state, |
| base::TimeTicks timestamp); |
| void SendButtonDown(UiElement* target, |
| const gfx::PointF& target_point, |
| ControllerModel::ButtonState button_state, |
| base::TimeTicks timestamp); |
| void SendTouchMove(const gfx::PointF& target_point, |
| base::TimeTicks timestamp); |
| |
| UiElement* GetTargetElement(const ControllerModel& controller_model, |
| ReticleModel* reticle_model, |
| const InputEventList& input_event_list) const; |
| void UpdateControllerFocusState(base::TimeTicks current_time, |
| const RenderInfo& render_info, |
| const ControllerModel& controller_model); |
| |
| void UnfocusFocusedElement(); |
| |
| gfx::PointF GetCapturedElementHitPoint( |
| const gfx::Point3F& target_point) const; |
| |
| UiScene* scene_; |
| int hover_target_id_ = 0; |
| // TODO(mthiesse): We shouldn't have a fling target. Elements should fling |
| // independently and we should only cancel flings on the relevant element |
| // when we do cancel flings. |
| int fling_target_id_ = 0; |
| int input_capture_element_id_ = 0; |
| int focused_element_id_ = 0; |
| bool in_click_ = false; |
| bool in_scroll_ = false; |
| |
| HitTestStrategy hit_test_strategy_ = HitTestStrategy::PROJECT_TO_WORLD_ORIGIN; |
| |
| ControllerModel::ButtonState previous_button_state_ = |
| ControllerModel::ButtonState::kUp; |
| |
| base::TimeTicks last_controller_outside_viewport_time_; |
| bool controller_resting_in_viewport_ = false; |
| }; |
| |
| } // namespace vr |
| |
| #endif // CHROME_BROWSER_VR_UI_INPUT_MANAGER_H_ |