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
ash / style / counter_expand_button.h [blame]
// Copyright 2024 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_COUNTER_EXPAND_BUTTON_H_
#define ASH_STYLE_COUNTER_EXPAND_BUTTON_H_
#include <string>
#include "ash/ash_export.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/metadata/view_factory.h"
namespace views {
class Label;
class ImageView;
} // namespace views
namespace ash {
// Customized expand button for ash that contains a number counter that
// represents the number of children views and a chevron icon. Used for grouped
// bubble that are available for expanding and collapsing children views.
// /------\
// | 5 \/ |
// \------/
class ASH_EXPORT CounterExpandButton : public views::Button {
METADATA_HEADER(CounterExpandButton, views::Button)
public:
// The type of animation. This is used for animation smoothness histograms.
enum class AnimationType {
// `label_` fading in animation.
kFadeInLabel,
// `label_` fading out animation.
kFadeOutLabel,
// Animating bounds change for the whole button layer.
kBoundsChange,
};
CounterExpandButton();
CounterExpandButton(const CounterExpandButton&) = delete;
CounterExpandButton& operator=(const CounterExpandButton&) = delete;
~CounterExpandButton() override;
void set_label_fading_out(bool label_fading_out) {
label_fading_out_ = label_fading_out;
}
void set_previous_bounds(gfx::Rect previous_bounds) {
previous_bounds_ = previous_bounds;
}
views::Label* label() { return label_; }
// Changes the expanded state. The icon will change.
void SetExpanded(bool expanded);
bool expanded() const { return expanded_; }
// Whether the label displaying the number of children in a grouped bubble
// needs to be displayed.
bool ShouldShowLabel() const;
// Updates the count of total grouped child views in the parent container and
// updates the text for the label accordingly.
void UpdateCounter(int count);
// Performs expand/collapse animation. This includes bounds change and fade
// in/out `label_`.
void AnimateExpandCollapse();
// Returns the animation smoothness histogram name used for the animation type
// `type`.
virtual const std::string GetAnimationHistogramName(AnimationType type);
// views::Button:
void OnThemeChanged() override;
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
size_t counter_for_test() const { return counter_; }
protected:
views::ImageView* image() { return image_; }
// Bounds change animation happens during expand/collapse and converting from
// single to group animation.
void AnimateBoundsChange(int duration_in_ms,
gfx::Tween::Type tween_type,
const std::string& animation_histogram_name);
// Generates the icons used for chevron in the expanded and collapsed state.
void UpdateIcons();
// Updates the tooltip of the button.
void UpdateTooltip();
// Returns the tooltip text on the button in expanded/collapsed state.
virtual std::u16string GetExpandedStateTooltipText() const;
virtual std::u16string GetCollapsedStateTooltipText() const;
private:
void UpdateBackgroundColor();
// Owned by views hierarchy.
raw_ptr<views::Label> label_;
raw_ptr<views::ImageView> image_;
// Cached icons used to display the chevron in the button.
gfx::ImageSkia expanded_image_;
gfx::ImageSkia collapsed_image_;
// Used in layer bounds animation.
gfx::Rect previous_bounds_;
// The number shown on `label_`. This is used to show the total number of
// grouped child views in this button's parent view.
size_t counter_ = 0;
// The expand state of the button.
bool expanded_ = false;
// True if `label_` is in its fade out animation.
bool label_fading_out_ = false;
base::WeakPtrFactory<CounterExpandButton> weak_factory_{this};
};
BEGIN_VIEW_BUILDER(/*no export*/, CounterExpandButton, views::Button)
END_VIEW_BUILDER
} // namespace ash
DEFINE_VIEW_BUILDER(/* no export */, ash::CounterExpandButton)
#endif // ASH_STYLE_COUNTER_EXPAND_BUTTON_H_