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
ash / wm / overview / birch / birch_bar_view.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_WM_OVERVIEW_BIRCH_BIRCH_BAR_VIEW_H_
#define ASH_WM_OVERVIEW_BIRCH_BIRCH_BAR_VIEW_H_
#include "ash/ash_export.h"
#include "ash/wm/overview/birch/birch_chip_button.h"
#include "base/memory/weak_ptr.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/base/models/image_model.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/layout/box_layout_view.h"
namespace aura {
class Window;
} // namespace aura
namespace views {
class Widget;
} // namespace views
namespace ash {
class BirchItem;
// The birch chips bar container holds up to four birch chips. It has a
// responsive layout to adjust the chips position according to the number of
// chips present and the available space. The chips will be in a row if they can
// fit in the space. Otherwise, the chips will be in the 2x2 grids. The birch
// bar has a two levels nested box layout view:
//
// BirchBarView (2x1)
// |
// -----Primary Row (1xn)
// |
// -----Secondary Row (1xn)
//
// The BirchBarView owns the primary and secondary chips rows, which are both
// horizontal box layout views. The chips will be in the primary row, if they
// fit in the work area. Otherwise, the third and fourth chips will be moved to
// the secondary row.
class ASH_EXPORT BirchBarView : public views::BoxLayoutView {
METADATA_HEADER(BirchBarView, views::BoxLayoutView)
public:
static constexpr int kMaxChipsNum = 4;
enum class State {
kLoading, // The bar is waiting for data on creation.
kLoadingForInformedRestore, // The bar is waiting for data on creation for
// informed restore.
kLoadingByUser, // The bar is waiting for data when enabled by user.
kReloading, // The bar is waiting for data when suggestion types are
// modified.
kShuttingDown, // The bar is shutting down when disabled.
kNormal, // The bar is showing chips.
};
enum class RelayoutReason {
// Relayout caused by filling in new suggestions after data fetched from
// model.
kSetup,
// Relayout caused by filling in new suggestions when the bar is enabled by
// user.
kSetupByUser,
// Relayout caused by adding or removing chips.
kAddRemoveChip,
// Relayout caused by available space change.
kAvailableSpaceChanged,
// Relayout caused by clearing chips when the bar is disabled by user.
kClearOnDisabled,
};
// The callback which is called when the birch bar view relayouts due to given
// reason.
using RelayoutCallback = base::RepeatingCallback<void(RelayoutReason)>;
explicit BirchBarView(aura::Window* root_window);
BirchBarView(const BirchBarView&) = delete;
BirchBarView& operator=(const BirchBarView&) = delete;
~BirchBarView() override;
// Creates a birch bar widget for given `root_window`.
static std::unique_ptr<views::Widget> CreateBirchBarWidget(
aura::Window* root_window);
const std::vector<raw_ptr<BirchChipButtonBase>>& chips() const {
return chips_;
}
void SetState(State state);
// Clears the items cached in the `BirchChipButtons`.
void ShutdownChips();
// Updates the birch bar's available space and relayout the bar according to
// the updated available space. Note that the function must be called before
// getting the view's preferred size.
void UpdateAvailableSpace(int available_space);
// Registers a relayout callback.
void SetRelayoutCallback(RelayoutCallback callback);
// Gets current number of chips.
int GetChipsNum() const;
// Clear existing chips and create new chips with given items.
void SetupChips(const std::vector<raw_ptr<BirchItem>>& items);
// Adds a new chip with given item.
void AddChip(BirchItem* birch_item);
// Removes the chip of `removed_item` and attaches a new chip with
// `attached_item` if it's not null.
void RemoveChip(BirchItem* removed_item, BirchItem* attached_item = nullptr);
// Re-initializes the chip corresponding to the given `item`.
void UpdateChip(BirchItem* item);
// Gets the maximum height of the bar with full chips.
int GetMaximumHeight() const;
// Returns if there are on-going animations.
bool IsAnimating();
private:
friend class OverviewGridTestApi;
// The layouts that the birch bar may use. When current available space can
// hold all present chips, a 1x4 grids layout is used. Otherwise, a 2x2 grids
// layout is used.
enum class LayoutType {
kOneByFour,
kTwoByTwo,
};
// Creates a chip for given `item`.
std::unique_ptr<BirchChipButtonBase> CreateChipForItem(BirchItem* item);
void AttachChip(std::unique_ptr<BirchChipButtonBase> chip);
// Remove all current chips.
void Clear();
// Calculates the chip size according to current shelf position and display
// size.
gfx::Size GetChipSize(aura::Window* root_window) const;
// Gets expected layout types according to the given number of chips and
// current available space.
LayoutType GetExpectedLayoutType(int chip_num) const;
// Rearranges the chips according to current expected layout type.
void Relayout(RelayoutReason reason);
// Called after relayout.
void OnRelayout(RelayoutReason reason);
// Adds loading chips to show loading animations.
void AddLoadingChips();
// Adds reloading chips to show reloading animations.
void AddReloadingChips();
// Performs the fade-in animation of chips.
void FadeInChips();
// Performs fade-out animation on current chips.
void FadeOutChips();
// Called when fade-out animation is aborted.
void OnFadeOutAborted();
// Called after chips fading-in animations are done during setting up.
void OnSetupEnded();
// Called after chips fading-out animations are done during shutting down.
void OnShutdownEnded();
// Called after the removing chip fade-out animation is done.
void OnRemovingChipFadeOutEnded(BirchChipButtonBase* removing_chip);
// Called when remove a chip from the bar with the single row.
void RemoveChipFromOneRowBar(BirchChipButtonBase* removing_chip);
// Called when remove a chip from the bar with two rows.
void RemoveChipFromTwoRowsBar(BirchChipButtonBase* removing_chip);
// Possibly show the privacy nudge about context menu options for
// controlling suggestion types.
void MaybeShowPrivacyNudge();
// Cached chip size.
const gfx::Size chip_size_;
// Cached available space.
int available_space_ = 0;
// Chips rows owned by this.
raw_ptr<BoxLayoutView> primary_row_;
// The secondary row only exists when it holds chips. Otherwise, there will
// always be child spacing between the rows.
raw_ptr<BoxLayoutView> secondary_row_ = nullptr;
State state_ = State::kNormal;
// The chips are owned by either primary or secondary row.
std::vector<raw_ptr<BirchChipButtonBase>> chips_;
// The chips which are waiting to be attached.
base::circular_deque<std::unique_ptr<BirchChipButtonBase>> chips_to_attach_;
// Called after relayout.
RelayoutCallback relayout_callback_;
// Called after chips fade-out animation.
base::OnceClosure shutdown_callback_;
};
} // namespace ash
#endif // ASH_WM_OVERVIEW_BIRCH_BIRCH_BAR_VIEW_H_