blob: 1031ae4466c3a84dd0e893b3ee0de5d00627e9d6 [file] [log] [blame]
// Copyright 2024 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_PERMISSIONS_CHIP_PERMISSION_CHIP_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_PERMISSIONS_CHIP_PERMISSION_CHIP_VIEW_H_
#include "base/check_is_test.h"
#include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
#include "chrome/browser/ui/views/permissions/chip/permission_chip_theme.h"
#include "chrome/browser/ui/views/permissions/permission_prompt_style.h"
#include "components/permissions/permission_actions_history.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/models/image_model.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/vector_icon_types.h"
#include "ui/views/controls/button/md_text_button.h"
#include "ui/views/view_tracker.h"
class MultiImageContainer;
// UI component for chip button located in the omnibox. A button with an icon
// and text, with rounded corners.
class PermissionChipView : public views::MdTextButton {
METADATA_HEADER(PermissionChipView, views::MdTextButton)
public:
DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kElementIdForTesting);
explicit PermissionChipView(PressedCallback callback);
PermissionChipView(const PermissionChipView& button) = delete;
PermissionChipView& operator=(const PermissionChipView& button) = delete;
~PermissionChipView() override;
class Observer : public base::CheckedObserver {
public:
virtual void OnChipVisibilityChanged(bool is_visible) {}
virtual void OnExpandAnimationEnded() {}
virtual void OnCollapseAnimationEnded() {}
virtual void OnMousePressed() {}
};
void VisibilityChanged(views::View* starting_from, bool is_visible) override;
void AnimateCollapse(base::TimeDelta duration);
void AnimateExpand(base::TimeDelta duration);
void AnimateToFit(base::TimeDelta duration);
void ResetAnimation(double value = 0);
bool is_fully_collapsed() const { return fully_collapsed_; }
bool is_animating() const { return animation_->is_animating(); }
gfx::SlideAnimation* animation_for_testing() { return animation_.get(); }
// views::AnimationDelegateViews:
void AnimationEnded(const gfx::Animation* animation) override;
void AnimationProgressed(const gfx::Animation* animation) override;
// views::MdTextButton:
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
bool OnMousePressed(const ui::MouseEvent& event) override;
void OnThemeChanged() override;
void UpdateBackgroundColor() override;
// Customize the button.
void SetUserDecision(permissions::PermissionAction user_decision);
void SetTheme(PermissionChipTheme theme);
void SetMessage(std::u16string message);
void SetBlockedIconShowing(bool should_show_blocked_icon);
void SetPermissionPromptStyle(PermissionPromptStyle prompt_style);
void SetChipIcon(const gfx::VectorIcon& icon);
void SetChipIcon(const gfx::VectorIcon* icon);
bool ShouldShowBlockedIcon() const { return should_show_blocked_icon_; }
permissions::PermissionAction GetUserDecision() const {
return user_decision_;
}
PermissionPromptStyle GetPermissionPromptStyle() const {
return prompt_style_;
}
PermissionChipTheme theme() const { return theme_; }
// Returns whether the theme describes a request state (true) or indicator
// state (false).
bool GetIsRequestForTesting() const;
// Add/remove observer.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
void UpdateForDividerVisibility(bool is_divider_visible,
int divider_arc_width = 0);
int GetIconViewWidth() const;
protected:
MultiImageContainer* multi_image_container();
// The following virtual functions are used for the non-error state permission
// chips (default/neutral states). For any other changes to the look and feel
// of the chips, consider subclassing and overriding as needed.
virtual ui::ImageModel GetIconImageModel() const;
virtual const gfx::VectorIcon& GetIcon() const;
virtual SkColor GetForegroundColor() const;
virtual SkColor GetBackgroundColor() const;
// Updates the icon, and then updates text, icon, and background colors from
// the theme.
void UpdateIconAndColors();
private:
// Performs a full animation from 0 to 1, ending up at the preferred size of
// the chip.
void ForceAnimateExpand();
// Performs a full collapse from 1 to 0, ending up at base_width_ + fixed
// width.
void ForceAnimateCollapse();
void OnAnimationValueMaybeChanged();
int GetIconSize() const;
int GetCornerRadius() const;
gfx::RoundedCornersF GetCornerRadii() const;
gfx::Insets GetPadding() const;
// An animation used for expanding and collapsing the chip.
std::unique_ptr<gfx::SlideAnimation> animation_;
PermissionChipTheme theme_ = PermissionChipTheme::kNormalVisibility;
// Denotes the chips current prompt style. This influences what appears in the
// location bar. Currently this will be some combination of text, icon, and
// prompt bubble.
PermissionPromptStyle prompt_style_ = PermissionPromptStyle::kChip;
// Denotes the current action / settings the user has selected on the omnibox
// chip prompt. Ex: "Allow", "Allow Once", "Not allowed".
permissions::PermissionAction user_decision_ =
permissions::PermissionAction::GRANTED;
// True when the blocked icon is currently showing in the omnibox chip. This
// usually happens when the user has disabled / "Not allowed" a permission
// such as location or notifications. False otherwise.
bool should_show_blocked_icon_ = false;
int base_width_ = 0;
// If chip is collapsed. In the collapsed state, only an icon is visible,
// without text.
bool fully_collapsed_ = false;
bool is_divider_visible_ = false;
raw_ptr<const gfx::VectorIcon> icon_ = &gfx::VectorIcon::EmptyIcon();
base::ObserverList<Observer> observers_;
};
#endif // CHROME_BROWSER_UI_VIEWS_PERMISSIONS_CHIP_PERMISSION_CHIP_VIEW_H_