blob: aa6287b812b32ed29009ae64f6beb3aeea682c74 [file]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_CONTROLS_BUTTON_IMAGE_BUTTON_H_
#define UI_VIEWS_CONTROLS_BUTTON_IMAGE_BUTTON_H_
#include <memory>
#include "base/gtest_prod_util.h"
#include "ui/base/layout.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 {
public:
METADATA_HEADER(ImageButton);
// An enum describing the horizontal alignment of images on Buttons.
enum HorizontalAlignment { ALIGN_LEFT = 0, ALIGN_CENTER, ALIGN_RIGHT };
// An enum describing the vertical alignment of images on Buttons.
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;
// Returns the image for a given |state|.
virtual const gfx::ImageSkia& GetImage(ButtonState state) const;
// Set the image the button should use for the provided state.
void SetImage(ButtonState state, const gfx::ImageSkia* image);
// As above, but takes a const ref. TODO(estade): all callers should be
// updated to use this version, and then the implementations can be
// consolidated.
virtual void SetImage(ButtonState state, const gfx::ImageSkia& image);
// Set the background details. The background image uses the same alignment
// as the image.
void SetBackgroundImage(SkColor color,
const gfx::ImageSkia* image,
const gfx::ImageSkia* mask);
// How the image is laid out within the button's bounds.
HorizontalAlignment GetImageHorizontalAlignment() const;
VerticalAlignment GetImageVerticalAlignment() const;
void SetImageHorizontalAlignment(HorizontalAlignment h_alignment);
void SetImageVerticalAlignment(VerticalAlignment v_alignment);
// The minimum size of the contents (not including the border). The contents
// will be at least this size, but may be larger if the image itself is
// larger.
gfx::Size GetMinimumImageSize() const;
void SetMinimumImageSize(const gfx::Size& size);
// Whether we should draw our images resources horizontally flipped.
void SetDrawImageMirrored(bool mirrored) { draw_image_mirrored_ = mirrored; }
// Overridden from View:
gfx::Size CalculatePreferredSize() const override;
views::PaintInfo::ScaleType GetPaintScaleType() const override;
protected:
// Overridden from Button:
void PaintButtonContents(gfx::Canvas* canvas) override;
// Returns the image to paint. This is invoked from paint and returns a value
// from images.
virtual gfx::ImageSkia GetImageToPaint();
// Updates button background for |scale_factor|.
void UpdateButtonBackground(ui::ResourceScaleFactor scale_factor);
// The images used to render the different states of this button.
gfx::ImageSkia images_[STATE_COUNT];
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);
// Returns the correct position of the image for painting.
const gfx::Point ComputeImagePaintPosition(const gfx::ImageSkia& image) const;
// Image alignment.
HorizontalAlignment h_alignment_ = ALIGN_LEFT;
VerticalAlignment v_alignment_ = ALIGN_TOP;
gfx::Size minimum_image_size_;
// Whether we draw our resources horizontally flipped. This can happen in the
// linux titlebar, where image resources were designed to be flipped so a
// small curved corner in the close button designed to fit into the frame
// resources.
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)
END_VIEW_BUILDER
////////////////////////////////////////////////////////////////////////////////
//
// ToggleImageButton
//
// A toggle-able ImageButton. It swaps out its graphics when toggled.
//
////////////////////////////////////////////////////////////////////////////////
class VIEWS_EXPORT ToggleImageButton : public ImageButton {
public:
METADATA_HEADER(ToggleImageButton);
explicit ToggleImageButton(PressedCallback callback = PressedCallback());
ToggleImageButton(const ToggleImageButton&) = delete;
ToggleImageButton& operator=(const ToggleImageButton&) = delete;
~ToggleImageButton() override;
// Change the toggled state.
bool GetToggled() const;
void SetToggled(bool toggled);
// Like ImageButton::SetImage(), but to set the graphics used for the
// "has been toggled" state. Must be called for each button state
// before the button is toggled.
void SetToggledImage(ButtonState state, const gfx::ImageSkia* image);
// Like Views::SetBackground(), but to set the background color used for the
// "has been toggled" state.
void SetToggledBackground(std::unique_ptr<Background> b);
Background* GetToggledBackground() const { return toggled_background_.get(); }
// Get/Set the tooltip text displayed when the button is toggled.
std::u16string GetToggledTooltipText() const;
void SetToggledTooltipText(const std::u16string& tooltip);
// Get/Set the accessible text used when the button is toggled.
std::u16string GetToggledAccessibleName() const;
void SetToggledAccessibleName(const std::u16string& name);
// Overridden from ImageButton:
const gfx::ImageSkia& GetImage(ButtonState state) const override;
void SetImage(ButtonState state, const gfx::ImageSkia& image) override;
// Overridden from View:
std::u16string GetTooltipText(const gfx::Point& p) const override;
void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
void OnPaintBackground(gfx::Canvas* canvas) override;
private:
// The parent class's images_ member is used for the current images,
// and this array is used to hold the alternative images.
// We swap between the two when toggling.
gfx::ImageSkia alternate_images_[STATE_COUNT];
// True if the button is currently toggled.
bool toggled_ = false;
std::unique_ptr<Background> toggled_background_;
// The parent class's tooltip_text_ is displayed when not toggled, and
// this one is shown when toggled.
std::u16string toggled_tooltip_text_;
// The parent class's accessibility data is used when not toggled, and this
// one is used when toggled.
std::u16string toggled_accessible_name_;
};
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)
END_VIEW_BUILDER
} // namespace views
DEFINE_VIEW_BUILDER(VIEWS_EXPORT, ImageButton)
DEFINE_VIEW_BUILDER(VIEWS_EXPORT, ToggleImageButton)
#endif // UI_VIEWS_CONTROLS_BUTTON_IMAGE_BUTTON_H_