1 // Copyright 2017 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 #ifndef ASH_HIGHLIGHTER_HIGHLIGHTER_CONTROLLER_H_ 6 #define ASH_HIGHLIGHTER_HIGHLIGHTER_CONTROLLER_H_ 7 8 #include <memory> 9 10 #include "ash/ash_export.h" 11 #include "ash/fast_ink/fast_ink_pointer_controller.h" 12 #include "base/callback.h" 13 #include "base/memory/weak_ptr.h" 14 #include "base/observer_list.h" 15 #include "ui/views/widget/unique_widget_ptr.h" 16 17 namespace base { 18 class OneShotTimer; 19 } 20 21 namespace gfx { 22 class Rect; 23 } 24 25 namespace ash { 26 27 class HighlighterView; 28 29 // Highlighter enabled state that is notified to observers. 30 enum class HighlighterEnabledState { 31 // Highlighter is enabled by any ways. 32 kEnabled, 33 // Highlighter is disabled by user directly, for example disabling palette 34 // tool by user actions on palette menu. 35 kDisabledByUser, 36 // Highlighter is disabled on metalayer session complete. 37 kDisabledBySessionComplete, 38 // Highlighter is disabled on metalayer session abort. An abort may occur due 39 // to dismissal of Assistant UI or due to interruption by user via hotword. 40 kDisabledBySessionAbort, 41 }; 42 43 // Controller for the highlighter functionality. 44 // Enables/disables highlighter as well as receives points 45 // and passes them off to be rendered. 46 class ASH_EXPORT HighlighterController 47 : public fast_ink::FastInkPointerController { 48 public: 49 // Interface for classes that wish to be notified with highlighter status. 50 class Observer { 51 public: 52 // Called when highlighter enabled state changes. OnHighlighterEnabledChanged(HighlighterEnabledState state)53 virtual void OnHighlighterEnabledChanged(HighlighterEnabledState state) {} 54 55 // Called when highlighter selection is recognized. OnHighlighterSelectionRecognized(const gfx::Rect & rect)56 virtual void OnHighlighterSelectionRecognized(const gfx::Rect& rect) {} 57 58 protected: 59 virtual ~Observer() = default; 60 }; 61 62 HighlighterController(); 63 ~HighlighterController() override; 64 enabled_state()65 HighlighterEnabledState enabled_state() { return enabled_state_; } 66 67 void AddObserver(Observer* observer); 68 void RemoveObserver(Observer* observer); 69 70 // Set the callback to exit the highlighter mode. If |require_success| is 71 // true, the callback will be called only after a successful gesture 72 // recognition. If |require_success| is false, the callback will be called 73 // after the first complete gesture, regardless of the recognition result. 74 void SetExitCallback(base::OnceClosure callback, bool require_success); 75 76 // Update highlighter enabled |state| and notify observers. 77 void UpdateEnabledState(HighlighterEnabledState enabled_state); 78 79 // Aborts the current metalayer session. If no metalayer session exists, 80 // calling this method is a no-op. 81 void AbortSession(); 82 83 private: 84 friend class HighlighterControllerTestApi; 85 86 // fast_ink::FastInkPointerController: 87 void SetEnabled(bool enabled) override; 88 views::View* GetPointerView() const override; 89 void CreatePointerView(base::TimeDelta presentation_delay, 90 aura::Window* root_window) override; 91 void UpdatePointerView(ui::TouchEvent* event) override; 92 void DestroyPointerView() override; 93 bool CanStartNewGesture(ui::TouchEvent* event) override; 94 95 // Performs gesture recognition, initiates appropriate visual effects, 96 // notifies the observer if necessary. 97 void RecognizeGesture(); 98 99 // Destroys |highlighter_view_widget_|, if it exists. 100 void DestroyHighlighterView(); 101 102 // Destroys |result_view_widget_|, if it exists. 103 void DestroyResultView(); 104 105 // Calls and clears the mode exit callback, if it is set. 106 void CallExitCallback(); 107 108 // Returns the Widget contents view of the highlighter widget as 109 // HighlighterView*. 110 HighlighterView* GetHighlighterView(); 111 112 // Caches the highlighter enabled state. 113 HighlighterEnabledState enabled_state_ = 114 HighlighterEnabledState::kDisabledByUser; 115 116 // |highlighter_view_widget_| will only hold an instance when the highlighter 117 // is enabled and activated (pressed or dragged) and until the fade out 118 // animation is done. 119 views::UniqueWidgetPtr highlighter_view_widget_; 120 121 // |result_view_widget_| will only hold an instance when the selection result 122 // animation is in progress. 123 views::UniqueWidgetPtr result_view_widget_; 124 125 // Time of the session start (e.g. when the controller was enabled). 126 base::TimeTicks session_start_; 127 128 // Time of the previous gesture end, valid after the first gesture 129 // within the session is complete. 130 base::TimeTicks previous_gesture_end_; 131 132 // Gesture counter withing a session. 133 int gesture_counter_ = 0; 134 135 // Recognized gesture counter withing a session. 136 int recognized_gesture_counter_ = 0; 137 138 // Not null while waiting for the next event to continue an interrupted 139 // stroke. 140 std::unique_ptr<base::OneShotTimer> interrupted_stroke_timer_; 141 142 // The callback to exit the mode in the UI. 143 base::OnceClosure exit_callback_; 144 145 // If true, the mode is not exited until a valid selection is made. 146 bool require_success_ = true; 147 148 base::ObserverList<Observer>::Unchecked observers_; 149 150 base::WeakPtrFactory<HighlighterController> weak_factory_{this}; 151 152 DISALLOW_COPY_AND_ASSIGN(HighlighterController); 153 }; 154 155 } // namespace ash 156 157 #endif // ASH_HIGHLIGHTER_HIGHLIGHTER_CONTROLLER_H_ 158