| // 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_STYLE_TAB_SLIDER_BUTTON_H_ |
| #define ASH_STYLE_TAB_SLIDER_BUTTON_H_ |
| |
| #include <string> |
| |
| #include "ash/ash_export.h" |
| #include "ash/style/tab_slider.h" |
| #include "base/memory/raw_ptr.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/background.h" |
| #include "ui/views/controls/button/button.h" |
| #include "ui/views/controls/image_view.h" |
| |
| namespace gfx { |
| struct VectorIcon; |
| } // namespace gfx |
| |
| namespace views { |
| class Label; |
| } // namespace views |
| |
| namespace ash { |
| |
| // A base class for tab slider buttons used in `TabSlider`. The button has |
| // selected and unselected states. When clicking the button, it will be set to |
| // selected. After a button is added to a tab slider, selecting the button will |
| // deselect the other buttons in the tab slider. |
| class ASH_EXPORT TabSliderButton : public views::Button { |
| METADATA_HEADER(TabSliderButton, views::Button) |
| |
| public: |
| TabSliderButton(PressedCallback callback, const std::u16string& tooltip_text); |
| |
| TabSliderButton(const TabSliderButton&) = delete; |
| TabSliderButton& operator=(const TabSliderButton&) = delete; |
| |
| ~TabSliderButton() override; |
| |
| bool selected() const { return selected_; } |
| |
| // Called when the button is added to a tab slider. |
| void AddedToSlider(TabSlider* tab_slider); |
| |
| // Changes the selected state. |
| void SetSelected(bool selected); |
| |
| // Returns the recommended color id for the current button state. |
| ui::ColorId GetColorIdOnButtonState(); |
| |
| private: |
| // Called when the button selected state is changed. |
| virtual void OnSelectedChanged() = 0; |
| |
| // views::Button: |
| void NotifyClick(const ui::Event& event) override; |
| |
| // Not owned by button. |
| raw_ptr<TabSlider> tab_slider_ = nullptr; |
| // The selected state indicating if the button is selected. |
| bool selected_ = false; |
| }; |
| |
| // An extension of `TabSliderButton` which is a circle button with an icon in |
| // the center. The icon has different color schemes for selected, unselected, |
| // and disabled states. |
| class ASH_EXPORT IconSliderButton : public TabSliderButton { |
| METADATA_HEADER(IconSliderButton, TabSliderButton) |
| |
| public: |
| IconSliderButton(PressedCallback callback, |
| const gfx::VectorIcon* icon, |
| const std::u16string& tooltip_text_base = u""); |
| IconSliderButton(const IconSliderButton&) = delete; |
| IconSliderButton& operator=(const IconSliderButton&) = delete; |
| ~IconSliderButton() override; |
| |
| private: |
| // TabSliderButton: |
| void OnSelectedChanged() override; |
| |
| // views::Button: |
| void OnThemeChanged() override; |
| void PaintButtonContents(gfx::Canvas* canvas) override; |
| |
| const raw_ptr<const gfx::VectorIcon> icon_; |
| }; |
| |
| // An extension of `TabSliderButton` which is rounded rect button with a label |
| // in the center. The label text has different color schemes for selected, |
| // unselected, and disabled states. |
| class ASH_EXPORT LabelSliderButton : public TabSliderButton { |
| METADATA_HEADER(LabelSliderButton, TabSliderButton) |
| |
| public: |
| LabelSliderButton(PressedCallback callback, |
| const std::u16string& text, |
| const std::u16string& tooltip_text_base = u""); |
| LabelSliderButton(const LabelSliderButton&) = delete; |
| LabelSliderButton& operator=(const LabelSliderButton&) = delete; |
| ~LabelSliderButton() override; |
| |
| private: |
| // Update label color according to the current button state. |
| void UpdateLabelColor(); |
| |
| // TabSliderButton: |
| void OnSelectedChanged() override; |
| |
| // views::Button: |
| gfx::Size CalculatePreferredSize( |
| const views::SizeBounds& available_size) const override; |
| void StateChanged(ButtonState old_state) override; |
| |
| // Owned by the view hierarchy. |
| raw_ptr<views::Label> label_; |
| }; |
| |
| // A `TabSliderButton` which shows an icon either: |
| // - Next to a label (`horizontal == true`). |
| // - Above a label (`horizontal == false`). |
| class ASH_EXPORT IconLabelSliderButton : public TabSliderButton { |
| METADATA_HEADER(IconLabelSliderButton, TabSliderButton) |
| |
| public: |
| static constexpr TabSlider::InitParams kSliderParams{ |
| /*internal_border_padding=*/4, |
| /*between_child_spacing=*/0, |
| /*has_background=*/true, |
| /*has_selector_animation=*/true, |
| /*distribute_space_evenly=*/true}; |
| |
| IconLabelSliderButton(PressedCallback callback, |
| const gfx::VectorIcon* icon, |
| const std::u16string& text, |
| const std::u16string& tooltip_text_base = u"", |
| bool horizontal = false); |
| IconLabelSliderButton(const IconLabelSliderButton&) = delete; |
| IconLabelSliderButton& operator=(const IconLabelSliderButton&) = delete; |
| ~IconLabelSliderButton() override; |
| |
| private: |
| // views::View: |
| gfx::Size CalculatePreferredSize( |
| const views::SizeBounds& available_size) const override; |
| |
| // Update label color according to the current button state. |
| void UpdateColors(); |
| |
| // TabSliderButton: |
| void OnSelectedChanged() override; |
| |
| // Owned by the views hierarchy. |
| const raw_ptr<views::ImageView> image_view_; |
| const raw_ptr<views::Label> label_; |
| }; |
| |
| } // namespace ash |
| |
| #endif // ASH_STYLE_TAB_SLIDER_BUTTON_H_ |