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
|
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_TABS_ALERT_INDICATOR_BUTTON_H_
#define CHROME_BROWSER_UI_VIEWS_TABS_ALERT_INDICATOR_BUTTON_H_
#include <memory>
#include <optional>
#include "base/memory/raw_ptr.h"
#include "chrome/browser/ui/tabs/tab_utils.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/models/image_model.h"
#include "ui/color/color_id.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/view_targeter_delegate.h"
class Tab;
namespace gfx {
class Animation;
class AnimationDelegate;
} // namespace gfx
namespace tabs {
enum class TabAlert;
} // namespace tabs
// This is an ImageButton subclass that serves as both the alert indicator icon
// (audio, tab capture, etc.), and as a mute button. It is meant to only be
// used as a child view of Tab.
//
// When the indicator is transitioned to the audio playing or muting state, the
// button functionality is enabled and begins handling mouse events. Otherwise,
// this view behaves like an image and all mouse events will be handled by the
// Tab (its parent View).
class AlertIndicatorButton : public views::ImageButton,
public views::ViewTargeterDelegate {
METADATA_HEADER(AlertIndicatorButton, views::ImageButton)
public:
explicit AlertIndicatorButton(Tab* parent_tab);
AlertIndicatorButton(const AlertIndicatorButton&) = delete;
AlertIndicatorButton& operator=(const AlertIndicatorButton&) = delete;
~AlertIndicatorButton() override;
// Returns the current TabAlert except, while the indicator image is
// fading out, returns the prior TabAlert.
std::optional<tabs::TabAlert> showing_alert_state() const {
return showing_alert_state_;
}
// Calls ResetImages(), starts fade animations, and activates/deactivates
// button functionality as appropriate.
void TransitionToAlertState(std::optional<tabs::TabAlert> next_state);
// Determines whether the AlertIndicatorButton will be clickable for toggling
// muting. This should be called whenever the active/inactive state of a tab
// has changed. Internally, TransitionToAlertState() and OnBoundsChanged()
// calls this when the TabAlert or the bounds have changed.
void UpdateEnabledForMuteToggle();
// Called when the parent tab's button color changes. Determines whether
// ResetImages() needs to be called.
void OnParentTabButtonColorChanged();
protected:
// views::View:
View* GetTooltipHandlerForPoint(const gfx::Point& point) override;
bool OnMousePressed(const ui::MouseEvent& event) override;
void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
// views::ViewTargeterDelegate
bool DoesIntersectRect(const View* target,
const gfx::Rect& rect) const override;
// views::Button:
void NotifyClick(const ui::Event& event) override;
// views::Button:
bool IsTriggerableEvent(const ui::Event& event) override;
void PaintButtonContents(gfx::Canvas* canvas) override;
// views::ImageButton:
gfx::ImageSkia GetImageToPaint() override;
private:
friend class TabContentsTest;
friend class TabTest;
class FadeAnimationDelegate;
// Returns a non-continuous Animation that performs a fade-in or fade-out
// appropriate for the given `alert_state`. This is used by the tab alert
// indicator to alert the user that recording, tab capture, or audio playback
// has started/stopped.
std::unique_ptr<gfx::Animation> CreateTabAlertIndicatorFadeAnimation(
std::optional<tabs::TabAlert> alert_state);
// Returns the tab (parent view) of this AlertIndicatorButton.
Tab* GetTab();
// Resets the images to display on the button to reflect `state` and the
// parent tab's button color. Should be called when either of these changes.
void UpdateIconForAlertState(tabs::TabAlert state);
const raw_ptr<Tab> parent_tab_;
std::optional<tabs::TabAlert> alert_state_;
// Alert indicator fade-in/out animation (i.e., only on show/hide, not a
// continuous animation).
std::unique_ptr<gfx::AnimationDelegate> fade_animation_delegate_;
std::unique_ptr<gfx::Animation> fade_animation_;
std::optional<tabs::TabAlert> showing_alert_state_;
// The time when the alert indicator is displayed when a camera and/or a
// microphone are captured.
base::Time camera_mic_indicator_start_time_;
// Duration of the fade-out animation to verify it in unit tests. Despite
// `fade_animation_` being properly initialized, in tests, it does not show
// the correct duration.
base::TimeDelta fadeout_animation_duration_for_testing_;
};
#endif // CHROME_BROWSER_UI_VIEWS_TABS_ALERT_INDICATOR_BUTTON_H_
|