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 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
|
// 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_PILL_BUTTON_H_
#define ASH_STYLE_PILL_BUTTON_H_
#include <optional>
#include "ash/ash_export.h"
#include "base/memory/raw_ptr.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/label_button.h"
#include "ui/views/metadata/view_factory.h"
namespace ash {
class BlurredBackgroundShield;
// A label button with a rounded rectangle background. It can have an icon
// inside as well, and its text and background colors will be different based on
// the type of the button.
class ASH_EXPORT PillButton : public views::LabelButton {
METADATA_HEADER(PillButton, views::LabelButton)
public:
static constexpr int kPillButtonHorizontalSpacing = 16;
static constexpr int kPaddingReductionForIcon = 4;
// The PillButton style is defined with 4 features:
// 1. Color variant defines which background, text, and icon color scheme to
// be used, for example Default, Floating, Alert, etc.
// 2. Button size indicates whether we should use the default size 32 or a
// large size 36.
// 3. With/without an icon.
// 4. Icon position: leading or following.
// For ease of extracting features from a button type, each feature is
// represented by a different bit mask.
using TypeFlag = int;
static constexpr TypeFlag kDefault = 1;
static constexpr TypeFlag kDefaultElevated = 1 << 1;
static constexpr TypeFlag kPrimary = 1 << 2;
static constexpr TypeFlag kSecondary = 1 << 3;
static constexpr TypeFlag kFloating = 1 << 4;
static constexpr TypeFlag kAlert = 1 << 5;
// TODO(crbug.com/1355517): Get rid of `kAccent` after CrosNext is fully
// launched.
static constexpr TypeFlag kAccent = 1 << 6;
static constexpr TypeFlag kLarge = 1 << 7;
static constexpr TypeFlag kIconLeading = 1 << 8;
static constexpr TypeFlag kIconFollowing = 1 << 9;
// Types of the PillButton. Each type is represented as the bitwise OR
// operation of the feature bit masks. The naming rule of the button type is
// k{Color Variant}{Button Size}{Icon}{Icon Position}.
enum Type {
// PillButton with default text and background colors, a leading icon.
kDefaultWithIconLeading = kDefault | kIconLeading,
// PillButton with default text and background colors, a following icon.
kDefaultWithIconFollowing = kDefault | kIconFollowing,
// PillButton with default text and background colors, a large button size,
// a leading icon.
kDefaultLargeWithIconLeading = kDefault | kLarge | kIconLeading,
// PillButton with default text and background colors, a large button size,
// a following icon.
kDefaultLargeWithIconFollowing = kDefault | kLarge | kIconFollowing,
// PillButton with default text and background colors, no icon.
kDefaultWithoutIcon = kDefault,
// PillButton with default text and background colors, a large button size,
// no icon.
kDefaultLargeWithoutIcon = kDefault | kLarge,
// PillButton with default-elevated text and background colors, a leading
// icon.
kDefaultElevatedWithIconLeading = kDefaultElevated | kIconLeading,
// PillButton with default-elevated text and background colors, a following
// icon.
kDefaultElevatedWithIconFollowing = kDefaultElevated | kIconFollowing,
// PillButton with default-elevated text and background colors, a large
// button size, a leading icon.
kDefaultElevatedLargeWithIconLeading =
kDefaultElevated | kLarge | kIconLeading,
// PillButton with default-elevated text and background colors, a large
// button size, a following icon.
kDefaultElevatedLargeWithIconFollowing =
kDefaultElevated | kLarge | kIconFollowing,
// PillButton with default-elevated text and background colors, no icon.
kDefaultElevatedWithoutIcon = kDefaultElevated,
// PillButton with default-elevated text and background colors, a large
// button size,
// no icon.
kDefaultElevatedLargeWithoutIcon = kDefaultElevated | kLarge,
// PillButton with primary text and background colors, a leading icon.
kPrimaryWithIconLeading = kPrimary | kIconLeading,
// PillButton with primary text and background colors, a following icon.
kPrimaryWithIconFollowing = kPrimary | kIconFollowing,
// PillButton with primary text and background colors, a large button size,
// a leading icon.
kPrimaryLargeWithIconLeading = kPrimary | kLarge | kIconLeading,
// PillButton with primary text and background colors, a large button size,
// a following icon.
kPrimaryLargeWithIconFollowing = kPrimary | kLarge | kIconFollowing,
// PillButton with primary text and background colors, no icon.
kPrimaryWithoutIcon = kPrimary,
// PillButton with primary text and background colors, a large button size,
// no icon.
kPrimaryLargeWithoutIcon = kPrimary | kLarge,
// PillButton with secondary text and background colors, a leading icon.
kSecondaryWithIconLeading = kSecondary | kIconLeading,
// PillButton with secondary text and background colors, a following icon.
kSecondaryWithIconFollowing = kSecondary | kIconFollowing,
// PillButton with secondary text and background colors, a large button
// size, a leading icon.
kSecondaryLargeWithIconLeading = kSecondary | kLarge | kIconLeading,
// PillButton with secondary text and background colors, a large button
// size, a following icon.
kSecondaryLargeWithIconFollowing = kSecondary | kLarge | kIconFollowing,
// PillButton with secondary text and background colors, no icon.
kSecondaryWithoutIcon = kSecondary,
// PillButton with secondary text and background colors, a large button
// size, no icon.
kSecondaryLargeWithoutIcon = kSecondary | kLarge,
// PillButton with floating text colors, no background, a leading icon.
kFloatingWithIconLeading = kFloating | kIconLeading,
// PillButton with floating text colors, no background, a following icon.
kFloatingWithIconFollowing = kFloating | kIconFollowing,
// PillButton with floating text colors, no background, a large button size,
// a leading icon.
kFloatingLargeWithIconLeading = kFloating | kLarge | kIconLeading,
// PillButton with floating text colors, no background, a large button size,
// a following icon.
kFloatingLargeWithIconFollowing = kFloating | kLarge | kIconFollowing,
// PillButton with floating text colors, no background, no icon.
kFloatingWithoutIcon = kFloating,
// PillButton with floating text colors, no background, a large button size,
// no icon.
kFloatingLargeWithoutIcon = kFloating | kLarge,
// PillButton with alert text and background colors, a leading icon.
kAlertWithIconLeading = kAlert | kIconLeading,
// PillButton with alert text and background colors, a following icon.
kAlertWithIconFollowing = kAlert | kIconFollowing,
// PillButton with alert text and background colors, a large button size, a
// leading icon.
kAlertLargeWithIconLeading = kAlert | kLarge | kIconLeading,
// PillButton with alert text and background colors, a large button size, a
// following icon.
kAlertLargeWithIconFollowing = kAlert | kLarge | kIconFollowing,
// PillButton with alert text and background colors, no icon.
kAlertWithoutIcon = kAlert,
// PillButton with alert text and background colors, a large button size, no
// icon.
kAlertLargeWithoutIcon = kAlert | kLarge,
// Old button types.
// TODO(crbug.com/1355517): Get rid of these types after CrosNext is fully
// launched.
// PillButton with accent text and background colors, no icon.
kAccentWithoutIcon = kAccent,
// PillButton with accent text, no background, no icon.
kAccentFloatingWithoutIcon = kAccent | kFloating,
};
explicit PillButton(
PressedCallback callback = PressedCallback(),
const std::u16string& text = std::u16string(),
Type type = Type::kDefaultWithoutIcon,
const gfx::VectorIcon* icon = nullptr,
int horizontal_spacing = kPillButtonHorizontalSpacing,
int padding_reduction_for_icon = kPaddingReductionForIcon);
PillButton(const PillButton&) = delete;
PillButton& operator=(const PillButton&) = delete;
~PillButton() override;
// views::LabelButton:
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
gfx::Insets GetInsets() const override;
void UpdateBackgroundColor() override;
views::PropertyEffects UpdateStyleToIndicateDefaultStatus() override;
void SetText(std::u16string_view text) override;
void OnSetTooltipText(const std::u16string& tooltip_text) override;
// Sets the button's background color, text's color or icon's color. Note, do
// this only when the button wants to have different colors from the default
// ones.
void SetBackgroundColor(const SkColor background_color);
void SetBackgroundColorId(ui::ColorId background_color_id);
void SetButtonTextColor(const SkColor text_color);
void SetButtonTextColorId(ui::ColorId text_color_id);
void SetIconColor(const SkColor icon_color);
void SetIconColorId(ui::ColorId icon_color_id);
// TODO(b/290639214): This method is deprecating. Try not to change button
// type afterward. If a new button type is needed, please create a new
// instance.
void SetPillButtonType(Type type);
// Sets the button's label to use the default label font, which is smaller
// and less heavily weighted.
void SetUseDefaultLabelFont();
// Sets if the button should enable the background blur. Once the button
// enables the background blur, it will use `BlurredBackgroundShield` as the
// background which is performance consuming so only use it as needed.
void SetEnableBackgroundBlur(bool enable);
void SetTextWithStringId(int message_id);
void SetUseLabelAsDefaultTooltip(bool use_label_as_default_tooltip);
private:
// Initializes the button layout, focus ring and background according to the
// button type.
void Init();
void UpdateTextColor();
void UpdateIconColor();
// Returns the spacing on the side where the icon locates. The value is set
// smaller to make the spacing on two sides visually look the same.
int GetHorizontalSpacingWithIcon() const;
void UpdateTooltipText();
Type type_;
const raw_ptr<const gfx::VectorIcon> icon_;
// Horizontal spacing of this button. `kPillButtonHorizontalSpacing` will be
// set as the default value.
int horizontal_spacing_;
// The padding reduced by icon.
int padding_reduction_for_icon_;
// Custom colors and color IDs.
std::optional<ui::ColorVariant> background_color_;
std::optional<ui::ColorVariant> text_color_;
std::optional<ui::ColorVariant> icon_color_;
bool enable_background_blur_ = false;
std::unique_ptr<BlurredBackgroundShield> blurred_background_;
// Indicates if we are going to use the label contents for tooltip as default.
bool use_label_as_default_tooltip_ = true;
// When the tooltip becomes equal to Label's Text, this variable holds the
// original value of the tooltip text if the Label's Text was not used.
std::u16string original_tooltip_text_;
// Called to update background color when the button is enabled/disabled.
base::CallbackListSubscription enabled_changed_subscription_;
};
BEGIN_VIEW_BUILDER(ASH_EXPORT, PillButton, views::LabelButton)
VIEW_BUILDER_PROPERTY(const SkColor, BackgroundColor)
VIEW_BUILDER_PROPERTY(ui::ColorId, BackgroundColorId)
VIEW_BUILDER_PROPERTY(const SkColor, ButtonTextColor)
VIEW_BUILDER_PROPERTY(ui::ColorId, ButtonTextColorId)
VIEW_BUILDER_PROPERTY(const SkColor, IconColor)
VIEW_BUILDER_PROPERTY(ui::ColorId, IconColorId)
VIEW_BUILDER_PROPERTY(PillButton::Type, PillButtonType)
VIEW_BUILDER_PROPERTY(bool, EnableBackgroundBlur)
VIEW_BUILDER_PROPERTY(int, TextWithStringId)
VIEW_BUILDER_PROPERTY(bool, UseLabelAsDefaultTooltip)
END_VIEW_BUILDER
} // namespace ash
DEFINE_VIEW_BUILDER(ASH_EXPORT, ash::PillButton)
#endif // ASH_STYLE_PILL_BUTTON_H_
|