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
|
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_CAPTURE_MODE_CAPTURE_MODE_DEMO_TOOLS_CONTROLLER_H_
#define ASH_CAPTURE_MODE_CAPTURE_MODE_DEMO_TOOLS_CONTROLLER_H_
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "ui/base/ime/input_method_observer.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/events/keycodes/keyboard_codes_posix.h"
#include "ui/views/widget/unique_widget_ptr.h"
#include "ui/views/widget/widget.h"
namespace ui {
class KeyEvent;
} // namespace ui
namespace ash {
class PointerHighlightLayer;
class KeyComboView;
class VideoRecordingWatcher;
using MouseHighlightLayers =
std::vector<std::unique_ptr<PointerHighlightLayer>>;
using TouchHighlightLayersMap =
base::flat_map<ui::PointerId, std::unique_ptr<PointerHighlightLayer>>;
// Observes and decides whether to show clicks (or taps) highlights and a helper
// widget that represents the currently pressed key combination or not. The key
// combination will be used to construct or modify the `KeyComboViewer`. The
// `CaptureModeDemoToolsController` will only be available during video
// recording and has to be explicitly enabled by the user.
class CaptureModeDemoToolsController : public ui::InputMethodObserver {
public:
explicit CaptureModeDemoToolsController(
VideoRecordingWatcher* video_recording_watcher);
CaptureModeDemoToolsController(const CaptureModeDemoToolsController&) =
delete;
CaptureModeDemoToolsController& operator=(
const CaptureModeDemoToolsController&) = delete;
~CaptureModeDemoToolsController() override;
const views::Widget* key_combo_widget() const {
return key_combo_widget_.get();
}
// Decides whether to show a helper widget for the `event` or not.
void OnKeyEvent(ui::KeyEvent* event);
// Creates a new highlight layer each time it gets called and performs the
// grow-and-fade-out animation on it.
void PerformMousePressAnimation(const gfx::PointF& event_location_in_window);
// Refreshes the bounds of `key_combo_widget_`.
void RefreshBounds();
// Decides whether to show the highlight for the touch event or not.
void OnTouchEvent(ui::EventType event_type,
ui::PointerId pointer_id,
const gfx::PointF& event_location_in_window);
// ui::InputMethodObserver:
void OnFocus() override {}
void OnBlur() override {}
void OnCaretBoundsChanged(const ui::TextInputClient* client) override {}
void OnTextInputStateChanged(const ui::TextInputClient* client) override;
void OnInputMethodDestroyed(const ui::InputMethod* input_method) override {}
private:
friend class CaptureModeDemoToolsTestApi;
void OnKeyUpEvent(ui::KeyEvent* event);
void OnKeyDownEvent(ui::KeyEvent* event);
// Refreshes the state of the `key_combo_view_` based on the current state of
// `modifiers_` and `last_non_modifier_key_`.
void RefreshKeyComboViewer();
gfx::Rect CalculateKeyComboWidgetBounds() const;
// Returns true if there is no modifier keys pressed and the non-modifier key
// can not be displayed independently.
bool ShouldResetKeyComboWidget() const;
// Resets the `key_combo_widget_` when the `key_up_refresh_timer_` expires.
void AnimateToResetKeyComboWidget();
void UpdateTextInputType(const ui::TextInputClient* client);
// Called when the mouse highlight animation ends to remove the corresponding
// pointer highlight from the `mouse_highlight_layers_`.
void OnMouseHighlightAnimationEnded(
PointerHighlightLayer* pointer_highlight_layer_ptr);
// Creates a new highlight layer each time it gets called and performs the
// grow animation on it.
void OnTouchDown(const ui::PointerId& pointer_id,
const gfx::PointF& event_location_in_window);
// Performs the grow-and-fade-out animation on an existing highlight layer
// that corresponds to the given `pointer_id`.
void OnTouchUp(const ui::PointerId& pointer_id,
const gfx::PointF& event_location_in_window);
// Sets the bounds of the touch highlight layer that corresponds to the
// `pointer_id` based on the `event_location_in_window` of the touch event
// when it gets called on touch dragged.
void OnTouchDragged(const ui::PointerId& pointer_id,
const gfx::PointF& event_location_in_window);
const raw_ptr<VideoRecordingWatcher> video_recording_watcher_;
views::UniqueWidgetPtr key_combo_widget_;
raw_ptr<KeyComboView> key_combo_view_ = nullptr;
// The state of the modifier keys i.e. Shift/Ctrl/Alt/Launcher keys.
int modifiers_ = 0;
// The most recently pressed non-modifier key.
ui::KeyboardCode last_non_modifier_key_ = ui::VKEY_UNKNOWN;
// True if the cursor and focus is currently in a text input
// field, false otherwise.
bool in_text_input_ = false;
// Used to hold on `RefreshKeyComboViewer`. The key combo widget will be
// scheduled to hide after `capture_mode::kRefreshKeyComboWidgetLongDelay`
// when a key up event is received, and the remaining pressed keys are no
// longer displayable, e.g. for a key combo Ctrl
// + C, after Ctrl is released, the remaining C is no longer displayable on
// its own as a complete key combo, so the widget will be scheduled to hide
// after `capture_mode::kRefreshKeyComboWidgetLongDelay`. Otherwise
// `capture_mode::kRefreshKeyComboWidgetShortDelay` will be used as the
// threshold duration to decide the user intention on whether to do an update
// or release multiple keys at one time.
base::OneShotTimer key_up_refresh_timer_;
// Contains all the mouse highlight layers that are being animated.
MouseHighlightLayers mouse_highlight_layers_;
// Maps the PointerHighlightLayer of the touch event by the pointer id as the
// key.
TouchHighlightLayersMap touch_pointer_id_to_highlight_layer_map_;
// If set, it will be called when the mouse highlight animation is completed.
base::OnceClosure on_mouse_highlight_animation_ended_callback_for_test_;
base::WeakPtrFactory<CaptureModeDemoToolsController> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_CAPTURE_MODE_CAPTURE_MODE_DEMO_TOOLS_CONTROLLER_H_
|