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
ash / system / notification_center / views / message_view_container.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_SYSTEM_NOTIFICATION_CENTER_VIEWS_MESSAGE_VIEW_CONTAINER_H_
#define ASH_SYSTEM_NOTIFICATION_CENTER_VIEWS_MESSAGE_VIEW_CONTAINER_H_
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/message_center/views/message_view.h"
#include "ui/views/view.h"
namespace message_center {
class Notification;
} // namespace message_center
namespace ash {
class NotificationListView;
class NotificationSwipeControlView;
// Container view for `MessageView` objects, which are initialized with a
// `message_center::Notification`.
class MessageViewContainer : public views::View,
public message_center::MessageView::Observer {
METADATA_HEADER(MessageViewContainer, views::View)
public:
explicit MessageViewContainer(
std::unique_ptr<message_center::MessageView> message_view,
NotificationListView* list_view = nullptr);
MessageViewContainer(const MessageViewContainer&) = delete;
MessageViewContainer& operator=(const MessageViewContainer&) = delete;
~MessageViewContainer() override = default;
// Calls `GetHeightForWidth` on the cached `message_view_`.
int CalculateHeight() const;
// Updates the corner radius based on if the view is at the top or the bottom
// of its parent list view. If `force_update` is true, the corner radius and
// background will be updated even if `is_top` and `is_bottom` have the same
// value as the stored variables.
void UpdateBorder(const bool is_top,
const bool is_bottom,
const bool force_update = false);
// Gets the `notification_id` stored in `message_view_`.
const std::string GetNotificationId() const;
// Forwards call to `UpdateWithNotification` in `message_view_`.
void UpdateWithNotification(const message_center::Notification& notification);
message_center::MessageView* message_view() { return message_view_; }
const message_center::MessageView* message_view() const {
return message_view_;
}
base::TimeDelta GetBoundsAnimationDuration() const;
void SetExpandedBySystem(bool expanded);
void SlideOutAndClose();
void CloseSwipeControl();
// Allows NotificationListView to force preferred size to change during
// animations.
void TriggerPreferredSizeChangedForAnimation();
// views::View:
gfx::Size CalculatePreferredSize(
const views::SizeBounds& available_size) const override;
void ChildPreferredSizeChanged(views::View* child) override;
// MessageView::Observer:
void OnSlideChanged(const std::string& notification_id) override;
void OnSlideEnded(const std::string& notification_id) override;
void OnPreSlideOut(const std::string& notification_id) override;
void OnSlideOut(const std::string& notification_id) override;
void set_start_bounds(const gfx::Rect& start_bounds) {
start_bounds_ = start_bounds;
}
void set_target_bounds(const gfx::Rect& target_bounds) {
target_bounds_ = target_bounds;
}
void set_is_removed(bool is_removed) { is_removed_ = is_removed; }
void set_needs_bounds_animation(bool needs_bounds_animation) {
needs_bounds_animation_ = needs_bounds_animation;
}
void set_disable_default_background(bool disable_default_background) {
disable_default_background_ = disable_default_background;
}
void set_need_update_corner_radius(bool need_update_corner_radius) {
need_update_corner_radius_ = need_update_corner_radius;
}
gfx::Rect start_bounds() const { return start_bounds_; }
gfx::Rect target_bounds() const { return target_bounds_; }
bool is_removed() const { return is_removed_; }
bool needs_bounds_animation() const { return needs_bounds_animation_; }
bool is_slid_out() { return is_slid_out_; }
// Returns if the notification is pinned i.e. can be removed manually.
bool IsPinned() const;
// Returns if the notification is a parent of other grouped notifications.
bool IsGroupParent() const;
// Returns the direction that the notification is swiped out. If swiped to the
// left, it returns -1 and if sipwed to the right, it returns 1. By default
// (i.e. the notification is removed but not by touch gesture), it returns 1.
int GetSlideDirection() const {
return message_view_->GetSlideAmount() < 0 ? -1 : 1;
}
bool is_top() { return is_top_; }
bool is_bottom() { return is_bottom_; }
private:
// Used to track if this view is at the top or bottom of its parent list view
// and prevent unnecessary updates.
bool is_top_ = false;
bool is_bottom_ = false;
// Cached to return to previous state after slide animation ends.
bool previous_is_bottom_ = false;
bool previous_is_top_ = false;
// The bounds that the container starts animating from. If not animating, it's
// ignored.
gfx::Rect start_bounds_;
// The final bounds of the container. If not animating, it's same as the
// actual bounds().
gfx::Rect target_bounds_;
// True when the notification is removed and during slide out animation.
bool is_removed_ = false;
// True if the notification is slid out completely.
bool is_slid_out_ = false;
// True if the notification is slid out through SlideOutAndClose()
// programagically. False if slid out manually by the user.
bool is_slid_out_programatically_ = false;
// Whether expanded state is being set programmatically. Used to prevent
// animating programmatic expands which occur on open.
bool expanding_by_system_ = false;
// Set to flag the view as requiring an expand or collapse animation.
bool needs_bounds_animation_ = false;
// `need_update_corner_radius_` indicates that we need to update the corner
// radius of the view when sliding.
bool need_update_corner_radius_ = true;
// Indicates if this view should not draw a background, used for custom
// notification views which handle their own background.
bool disable_default_background_ = false;
// Owned by the views hierarchy.
const raw_ptr<NotificationListView> list_view_;
raw_ptr<NotificationSwipeControlView> control_view_;
raw_ptr<message_center::MessageView> message_view_;
};
} // namespace ash
#endif // ASH_SYSTEM_NOTIFICATION_CENTER_VIEWS_MESSAGE_VIEW_CONTAINER_H_