#ifndef UI_VIEWS_CONTROLS_BUTTON_IMAGE_BUTTON_H_
#define UI_VIEWS_CONTROLS_BUTTON_IMAGE_BUTTON_H_
#include <array>
#include <memory>
#include <utility>
#include "base/gtest_prod_util.h"
#include "ui/base/models/image_model.h"
#include "ui/base/resource/resource_scale_factor.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/metadata/view_factory.h"
namespace views {
class VIEWS_EXPORT ImageButton : public Button {
METADATA_HEADER(ImageButton, Button)
public:
enum HorizontalAlignment { ALIGN_LEFT = 0, ALIGN_CENTER, ALIGN_RIGHT };
enum VerticalAlignment { ALIGN_TOP = 0, ALIGN_MIDDLE, ALIGN_BOTTOM };
explicit ImageButton(PressedCallback callback = PressedCallback());
ImageButton(const ImageButton&) = delete;
ImageButton& operator=(const ImageButton&) = delete;
~ImageButton() override;
virtual gfx::ImageSkia GetImage(ButtonState state) const;
virtual void SetImageModel(ButtonState state,
const ui::ImageModel& image_model);
void SetBackgroundImage(SkColor color,
const gfx::ImageSkia* image,
const gfx::ImageSkia* mask);
HorizontalAlignment GetImageHorizontalAlignment() const;
VerticalAlignment GetImageVerticalAlignment() const;
void SetImageHorizontalAlignment(HorizontalAlignment h_alignment);
void SetImageVerticalAlignment(VerticalAlignment v_alignment);
gfx::Size GetMinimumImageSize() const;
void SetMinimumImageSize(const gfx::Size& size);
void SetDrawImageMirrored(bool mirrored) { draw_image_mirrored_ = mirrored; }
gfx::Size CalculatePreferredSize(
const SizeBounds& available_size) const override;
views::PaintInfo::ScaleType GetPaintScaleType() const override;
void OnThemeChanged() override;
enum class MaterialIconStyle { kSmall, kLarge };
static std::unique_ptr<ImageButton> CreateIconButton(
PressedCallback callback,
const gfx::VectorIcon& icon,
const std::u16string& accessible_name,
MaterialIconStyle icon_style = MaterialIconStyle::kLarge,
std::optional<gfx::Insets> insets = std::nullopt);
protected:
void PaintButtonContents(gfx::Canvas* canvas) override;
virtual gfx::ImageSkia GetImageToPaint();
void UpdateButtonBackground(ui::ResourceScaleFactor scale_factor);
std::array<ui::ImageModel, STATE_COUNT> images_;
gfx::ImageSkia background_image_;
private:
FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, Basics);
FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, ImagePositionWithBorder);
FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, LeftAlignedMirrored);
FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, RightAlignedMirrored);
FRIEND_TEST_ALL_PREFIXES(ImageButtonTest, ImagePositionWithBackground);
FRIEND_TEST_ALL_PREFIXES(ImageButtonFactoryTest, CreateVectorImageButton);
const gfx::Point ComputeImagePaintPosition(const gfx::ImageSkia& image) const;
HorizontalAlignment h_alignment_ = ALIGN_LEFT;
VerticalAlignment v_alignment_ = ALIGN_TOP;
gfx::Size minimum_image_size_;
bool draw_image_mirrored_ = false;
};
BEGIN_VIEW_BUILDER(VIEWS_EXPORT, ImageButton, Button)
VIEW_BUILDER_PROPERTY(bool, DrawImageMirrored)
VIEW_BUILDER_PROPERTY(ImageButton::HorizontalAlignment,
ImageHorizontalAlignment)
VIEW_BUILDER_PROPERTY(ImageButton::VerticalAlignment, ImageVerticalAlignment)
VIEW_BUILDER_PROPERTY(gfx::Size, MinimumImageSize)
VIEW_BUILDER_METHOD(SetImageModel, Button::ButtonState, const ui::ImageModel&)
END_VIEW_BUILDER
class VIEWS_EXPORT ToggleImageButton : public ImageButton {
METADATA_HEADER(ToggleImageButton, ImageButton)
public:
explicit ToggleImageButton(PressedCallback callback = PressedCallback());
ToggleImageButton(const ToggleImageButton&) = delete;
ToggleImageButton& operator=(const ToggleImageButton&) = delete;
~ToggleImageButton() override;
bool GetToggled() const;
void SetToggled(bool toggled);
void SetToggledImage(ButtonState state, const gfx::ImageSkia* image);
void SetToggledImageModel(ButtonState state,
const ui::ImageModel& image_model);
void SetToggledBackground(std::unique_ptr<Background> b);
Background* GetToggledBackground() const { return toggled_background_.get(); }
std::u16string GetToggledTooltipText() const;
void SetToggledTooltipText(const std::u16string& tooltip);
std::u16string GetToggledAccessibleName() const;
void SetToggledAccessibleName(const std::u16string& name);
void UpdateAccessibleCheckedState() override;
gfx::ImageSkia GetImage(ButtonState state) const override;
void SetImageModel(ButtonState state,
const ui::ImageModel& image_model) override;
void OnPaintBackground(gfx::Canvas* canvas) override;
void OnTooltipTextChanged(const std::u16string& old_tooltip) override;
void UpdateAccessibleRoleIfNeeded();
private:
void UpdateAccessibleName();
void UpdateTooltipText();
std::array<ui::ImageModel, STATE_COUNT> alternate_images_;
bool toggled_ = false;
std::unique_ptr<Background> toggled_background_;
std::u16string toggled_tooltip_text_;
std::u16string toggled_accessible_name_;
std::u16string untoggled_tooltip_text_;
};
BEGIN_VIEW_BUILDER(VIEWS_EXPORT, ToggleImageButton, ImageButton)
VIEW_BUILDER_PROPERTY(bool, Toggled)
VIEW_BUILDER_PROPERTY(std::unique_ptr<Background>, ToggledBackground)
VIEW_BUILDER_PROPERTY(std::u16string, ToggledTooltipText)
VIEW_BUILDER_PROPERTY(std::u16string, ToggledAccessibleName)
VIEW_BUILDER_METHOD(SetToggledImageModel,
Button::ButtonState,
const ui::ImageModel&)
END_VIEW_BUILDER
}
DEFINE_VIEW_BUILDER(VIEWS_EXPORT, ImageButton)
DEFINE_VIEW_BUILDER(VIEWS_EXPORT, ToggleImageButton)
#endif