| // 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 ASH_STYLE_ICON_BUTTON_H_ |
| #define ASH_STYLE_ICON_BUTTON_H_ |
| |
| #include <optional> |
| #include <variant> |
| |
| #include "ash/ash_export.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/third_party/icu/icu_utf.h" |
| #include "ui/base/metadata/metadata_header_macros.h" |
| #include "ui/color/color_id.h" |
| #include "ui/color/color_variant.h" |
| #include "ui/gfx/color_palette.h" |
| #include "ui/views/controls/button/image_button.h" |
| |
| namespace gfx { |
| class ImageSkia; |
| struct VectorIcon; |
| } // namespace gfx |
| |
| namespace ui { |
| class Event; |
| } // namespace ui |
| |
| namespace ash { |
| |
| class BlurredBackgroundShield; |
| |
| // A circular ImageButton that can have small/medium/large different sizes. Each |
| // of them has the floating version, which does not have the background. The |
| // prominent-floating buttons have different icon colors when the button is |
| // focused and unfocused. The button can be togglable if `is_togglable` is set |
| // to true, the icon inside might change on different toggle states. A fixed |
| // size of EmptyBorder will be applied to the button if `has_border` is true, |
| // this is done to help differentiating focus ring from the content of the |
| // button. |
| class ASH_EXPORT IconButton : public views::ImageButton { |
| METADATA_HEADER(IconButton, views::ImageButton) |
| |
| public: |
| enum class Type { |
| kXSmall, |
| kSmall, |
| kMedium, |
| kLarge, |
| kXLarge, |
| kXSmallProminent, |
| kSmallProminent, |
| kMediumProminent, |
| kLargeProminent, |
| kXLargeProminent, |
| kXSmallFloating, |
| kSmallFloating, |
| kMediumFloating, |
| kLargeFloating, |
| kXLargeFloating, |
| kXSmallProminentFloating, |
| kSmallProminentFloating, |
| kMediumProminentFloating, |
| kLargeProminentFloating, |
| kXLargeProminentFloating, |
| }; |
| |
| // Used to determine how the button will behave when disabled. |
| enum class DisabledButtonBehavior { |
| // The button will display toggle button as off. |
| kNone = 0, |
| |
| // The button will display on/off status of toggle. |
| kCanDisplayDisabledToggleValue = 1, |
| }; |
| |
| class Builder { |
| public: |
| Builder(); |
| ~Builder(); |
| |
| // Returns a completely constructed `IconButton`. Fields that are not set |
| // use defaults unless they are required. Builder becomes invalid after |
| // `Build()` is called. |
| std::unique_ptr<IconButton> Build(); |
| |
| Builder& SetCallback(PressedCallback callback); |
| Builder& SetType(Type type); |
| |
| // Set the icon for the button to `icon`. Must be non-null or it will cause |
| // a crash. |
| Builder& SetVectorIcon(const gfx::VectorIcon* icon); |
| |
| // Set a symbol for display. This is only used if icon is not set. |
| // `character` must contain exactly one unicode character or this will fail. |
| Builder& SetSymbol(base_icu::UChar32 character); |
| |
| Builder& SetAccessibleNameId(int accessible_name_id); |
| Builder& SetAccessibleName(const std::u16string& accessible_name); |
| Builder& SetTogglable(bool is_togglable); |
| Builder& SetBorder(bool has_border); |
| Builder& SetViewId(int view_id); |
| Builder& SetEnabled(bool enabled); |
| Builder& SetVisible(bool visible); |
| Builder& SetBackgroundImage(const gfx::ImageSkia& background_image); |
| Builder& SetBackgroundColor(ui::ColorId color_id); |
| |
| private: |
| PressedCallback callback_; |
| Type type_; |
| raw_ptr<const gfx::VectorIcon> icon_; |
| std::optional<base_icu::UChar32> character_; |
| std::variant<int, std::u16string> accessible_name_; |
| bool is_togglable_; |
| bool has_border_; |
| std::optional<int> view_id_; |
| std::optional<bool> enabled_; |
| std::optional<bool> visible_; |
| std::optional<gfx::ImageSkia> background_image_; |
| std::optional<ui::ColorId> background_color_; |
| }; |
| |
| IconButton(PressedCallback callback, |
| Type type, |
| const gfx::VectorIcon* icon, |
| int accessible_name_id); |
| IconButton(PressedCallback callback, |
| Type type, |
| const gfx::VectorIcon* icon, |
| bool is_togglable, |
| bool has_border); |
| IconButton(PressedCallback callback, |
| Type type, |
| const gfx::VectorIcon* icon, |
| const std::u16string& accessible_name, |
| bool is_togglable, |
| bool has_border); |
| IconButton(PressedCallback callback, |
| Type type, |
| const gfx::VectorIcon* icon, |
| int accessible_name_id, |
| bool is_togglable, |
| bool has_border); |
| |
| IconButton(const IconButton&) = delete; |
| IconButton& operator=(const IconButton&) = delete; |
| ~IconButton() override; |
| |
| bool toggled() const { return toggled_; } |
| |
| void SetButtonBehavior(DisabledButtonBehavior button_behavior); |
| |
| // Sets the vector icon of the button, it might change on different `toggled_` |
| // states. |
| void SetVectorIcon(const gfx::VectorIcon& icon); |
| |
| void SetSymbol(base_icu::UChar32 character); |
| |
| // Sets the vector icon used when the button is toggled. If the button does |
| // not specify a toggled vector icon, it will use the same vector icon for |
| // all states. |
| void SetToggledVectorIcon(const gfx::VectorIcon& icon); |
| |
| // Sets the button's background color or toggled color with color value and |
| // color ID when the button wants to have a different background color from |
| // the default one. When both color value and color ID are set, color ID takes |
| // the precedence. |
| void SetBackgroundColor(ui::ColorVariant background_color); |
| void SetBackgroundToggledColor(ui::ColorVariant background_toggled_color); |
| |
| // Sets the button's background image. The |background_image| is resized to |
| // fit the button. Note, if set, |background_image| is painted on top of |
| // the button's existing background color. |
| void SetBackgroundImage(const gfx::ImageSkia& background_image); |
| |
| // Sets the button's icon color or toggled color with color value and color ID |
| // when the button wants to have a different icon color from the default one. |
| // When both color value and color ID are set, color ID takes the precedence. |
| void SetIconColor(ui::ColorVariant icon_color); |
| void SetIconToggledColor(ui::ColorVariant icon_toggled_color); |
| |
| // Sets the size to use for the vector icon in DIPs. |
| void SetIconSize(int size); |
| |
| // Updates the `toggled_` state of the button. |
| void SetToggled(bool toggled); |
| |
| // Sets whether to enable the blurred background shield. Setting blurred |
| // background shield enabled will use a blurred background shield to replace |
| // the current background. For floating type button with untoggled state, |
| // there is no blurred background shield even it is enabled. |
| void SetEnableBlurredBackgroundShield(bool enable); |
| |
| // views::ImageButton: |
| void OnFocus() override; |
| void OnBlur() override; |
| void PaintButtonContents(gfx::Canvas* canvas) override; |
| void NotifyClick(const ui::Event& event) override; |
| |
| protected: |
| void UpdateBackground(); |
| void UpdateBlurredBackgroundShield(); |
| void UpdateVectorIcon(bool color_changes_only = false); |
| |
| void OnEnabledStateChanged(); |
| |
| private: |
| // For unit tests. |
| friend class BluetoothFeaturePodControllerTest; |
| |
| // True if the button is in the state of toggled, even when the button is |
| // disabled. |
| bool IsToggledOn() const; |
| |
| // Updates the accessibility properties directly in the cache, like the role |
| // and the toggle state. |
| void UpdateAccessibilityProperties(); |
| |
| std::pair<ui::ImageModel, ui::ImageModel> VectorImages(const bool is_toggled, |
| ui::ColorVariant color, |
| const int size); |
| |
| const Type type_; |
| raw_ptr<const gfx::VectorIcon> icon_ = nullptr; |
| raw_ptr<const gfx::VectorIcon> toggled_icon_ = nullptr; |
| |
| std::optional<base_icu::UChar32> character_; |
| |
| // True if this button is togglable. |
| const bool is_togglable_ = false; |
| |
| // True if the button is currently toggled. |
| bool toggled_ = false; |
| |
| // Background colors and icon colors. |
| ui::ColorVariant background_color_; |
| ui::ColorVariant background_toggled_color_; |
| ui::ColorVariant icon_color_; |
| ui::ColorVariant icon_toggled_color_; |
| |
| bool blurred_background_shield_enabled_ = false; |
| // Note: the blurred background shield will still be null if the button type |
| // is floating with untoggled state. |
| std::unique_ptr<BlurredBackgroundShield> blurred_background_shield_; |
| |
| // Custom value for icon size (usually used to make the icon smaller). |
| std::optional<int> icon_size_; |
| |
| // Called to update background color when the button is enabled/disabled. |
| base::CallbackListSubscription enabled_changed_subscription_; |
| |
| DisabledButtonBehavior button_behavior_ = DisabledButtonBehavior::kNone; |
| }; |
| |
| } // namespace ash |
| |
| #endif // ASH_STYLE_ICON_BUTTON_H_ |