1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
// Copyright 2017 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_CONTROLS_HOVER_BUTTON_H_
#define CHROME_BROWSER_UI_VIEWS_CONTROLS_HOVER_BUTTON_H_
#include <string>
#include <vector>
#include "base/callback_list.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "base/types/pass_key.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/metadata/view_factory.h"
namespace media_router {
FORWARD_DECLARE_TEST(CastDialogSinkButtonTest, SetTitleLabel);
FORWARD_DECLARE_TEST(CastDialogSinkButtonTest, SetStatusLabel);
} // namespace media_router
namespace webid {
class AccountSelectionViewTestBase;
}
namespace ui {
class ImageModel;
}
namespace views {
class Label;
class View;
} // namespace views
class HoverButtonTest;
class HoverButtonController;
class PageInfoBubbleViewBrowserTest;
// A button taking the full width of its parent that shows a background color
// when hovered over.
class HoverButton : public views::LabelButton {
METADATA_HEADER(HoverButton, views::LabelButton)
public:
HoverButton();
// Creates a single line hover button with no icon.
HoverButton(PressedCallback callback, const std::u16string& text);
// Creates a single line hover button with an icon.
HoverButton(PressedCallback callback,
const ui::ImageModel& icon,
const std::u16string& text);
// Creates a HoverButton with custom subviews. |icon_view| replaces the
// LabelButton icon, and titles appear on separate rows. An empty |subtitle|
// and |footer| will vertically center |title|. |footer| will be shown below
// |title| and |subtitle|. |secondary_view|, when set, is shown on the
// opposite side of the button from |icon_view|. When
// |add_vertical_label_spacing| is false it will not add vertical spacing to
// the label wrapper. Warning: |icon_view| must have a fixed size and be
// correctly set during its constructor for the HoverButton to layout
// correctly.
HoverButton(
PressedCallback callback,
std::unique_ptr<views::View> icon_view,
const std::u16string& title,
const std::u16string& subtitle = std::u16string(),
std::unique_ptr<views::View> secondary_view = nullptr,
bool add_vertical_label_spacing = true,
const std::u16string& footer = std::u16string(),
int icon_label_spacing = ChromeLayoutProvider::Get()->GetDistanceMetric(
views::DISTANCE_RELATED_LABEL_HORIZONTAL),
bool multiline_subtitle = false);
HoverButton(const HoverButton&) = delete;
HoverButton& operator=(const HoverButton&) = delete;
~HoverButton() override;
// views::LabelButton:
void SetCallback(PressedCallback callback) override;
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
void SetBorder(std::unique_ptr<views::Border> b) override;
void PreferredSizeChanged() override;
void OnViewBoundsChanged(View* observed_view) override;
// Sets the text style of the title considering the color of the background.
// Passing |background_color| makes sure that the text color will not be
// changed to a color that is not readable on the specified background.
// Sets the title's enabled color to |color_id|, if present.
void SetTitleTextStyle(views::style::TextStyle text_style,
SkColor background_color,
std::optional<ui::ColorId> color_id);
// Set the text context and style of the subtitle.
void SetSubtitleTextStyle(int text_context,
views::style::TextStyle text_style);
// Set the text context and style of the footer.
void SetFooterTextStyle(int text_context, views::style::TextStyle text_style);
// Adds a11y text to the button, which will be read out when the button is
// focused.
void AddExtraAccessibleText(const std::u16string& text);
void SetIconHorizontalMargins(int left, int right);
PressedCallback& callback(base::PassKey<HoverButtonController>) {
return callback_;
}
views::Label* title() { return title_; }
const views::Label* title() const { return title_; }
protected:
// views::MenuButton:
KeyClickAction GetKeyClickActionForEvent(const ui::KeyEvent& event) override;
void StateChanged(ButtonState old_state) override;
views::View* GetTooltipHandlerForPoint(const gfx::Point& point) override;
views::Label* subtitle() const { return subtitle_; }
views::Label* footer() const { return footer_; }
views::View* icon_view() const { return icon_view_; }
views::View* secondary_view() const { return secondary_view_; }
private:
FRIEND_TEST_ALL_PREFIXES(media_router::CastDialogSinkButtonTest,
SetTitleLabel);
FRIEND_TEST_ALL_PREFIXES(media_router::CastDialogSinkButtonTest,
SetStatusLabel);
friend class webid::AccountSelectionViewTestBase;
friend class HoverButtonTest;
friend class PageInfoBubbleViewBrowserTest;
// Updates the accessible name and tooltip of the button if necessary based on
// `title_` and `subtitle_` labels.
void UpdateTooltipAndAccessibleName();
void OnPressed(const ui::Event& event);
// Create the label for subtitle or footer.
std::unique_ptr<views::Label> CreateSecondaryLabel(
const std::u16string& text);
PressedCallback callback_;
raw_ptr<views::Label> title_ = nullptr;
raw_ptr<views::View> icon_wrapper_ = nullptr;
raw_ptr<views::View> label_wrapper_ = nullptr;
raw_ptr<views::Label> subtitle_ = nullptr;
raw_ptr<views::Label> footer_ = nullptr;
raw_ptr<views::View> icon_view_ = nullptr;
raw_ptr<views::View> secondary_view_ = nullptr;
std::u16string additional_accessible_text_;
std::vector<base::CallbackListSubscription> text_changed_subscriptions_;
base::ScopedObservation<views::View, views::ViewObserver> label_observation_{
this};
};
BEGIN_VIEW_BUILDER(, HoverButton, views::LabelButton)
VIEW_BUILDER_METHOD(SetTitleTextStyle,
views::style::TextStyle,
SkColor,
std::optional<ui::ColorId>)
END_VIEW_BUILDER
DEFINE_VIEW_BUILDER(, HoverButton)
#endif // CHROME_BROWSER_UI_VIEWS_CONTROLS_HOVER_BUTTON_H_
|