OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/message_center/views/message_center_view.h" | 5 #include "ui/message_center/views/message_center_view.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 #include <map> | 8 #include <map> |
9 | 9 |
10 #include "base/command_line.h" | |
11 #include "base/memory/weak_ptr.h" | 10 #include "base/memory/weak_ptr.h" |
12 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
13 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
14 #include "ui/base/l10n/l10n_util.h" | 13 #include "ui/base/l10n/l10n_util.h" |
15 #include "ui/gfx/animation/multi_animation.h" | 14 #include "ui/gfx/animation/multi_animation.h" |
16 #include "ui/gfx/animation/slide_animation.h" | |
17 #include "ui/gfx/canvas.h" | 15 #include "ui/gfx/canvas.h" |
18 #include "ui/gfx/geometry/insets.h" | 16 #include "ui/gfx/geometry/insets.h" |
19 #include "ui/gfx/geometry/rect.h" | 17 #include "ui/gfx/geometry/rect.h" |
20 #include "ui/gfx/geometry/size.h" | 18 #include "ui/gfx/geometry/size.h" |
21 #include "ui/message_center/message_center.h" | 19 #include "ui/message_center/message_center.h" |
22 #include "ui/message_center/message_center_style.h" | 20 #include "ui/message_center/message_center_style.h" |
23 #include "ui/message_center/message_center_switches.h" | |
24 #include "ui/message_center/message_center_tray.h" | 21 #include "ui/message_center/message_center_tray.h" |
25 #include "ui/message_center/message_center_types.h" | 22 #include "ui/message_center/message_center_types.h" |
26 #include "ui/message_center/views/message_center_button_bar.h" | 23 #include "ui/message_center/views/message_center_button_bar.h" |
| 24 #include "ui/message_center/views/message_list_view.h" |
27 #include "ui/message_center/views/message_view.h" | 25 #include "ui/message_center/views/message_view.h" |
28 #include "ui/message_center/views/message_view_context_menu_controller.h" | 26 #include "ui/message_center/views/message_view_context_menu_controller.h" |
29 #include "ui/message_center/views/notification_view.h" | 27 #include "ui/message_center/views/notification_view.h" |
30 #include "ui/message_center/views/notifier_settings_view.h" | 28 #include "ui/message_center/views/notifier_settings_view.h" |
31 #include "ui/resources/grit/ui_resources.h" | 29 #include "ui/resources/grit/ui_resources.h" |
32 #include "ui/strings/grit/ui_strings.h" | 30 #include "ui/strings/grit/ui_strings.h" |
33 #include "ui/views/animation/bounds_animator.h" | |
34 #include "ui/views/animation/bounds_animator_observer.h" | |
35 #include "ui/views/background.h" | 31 #include "ui/views/background.h" |
36 #include "ui/views/border.h" | 32 #include "ui/views/border.h" |
37 #include "ui/views/controls/button/button.h" | 33 #include "ui/views/controls/button/button.h" |
38 #include "ui/views/controls/label.h" | 34 #include "ui/views/controls/label.h" |
39 #include "ui/views/controls/scroll_view.h" | 35 #include "ui/views/controls/scroll_view.h" |
40 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h" | 36 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h" |
41 #include "ui/views/layout/box_layout.h" | |
42 #include "ui/views/layout/fill_layout.h" | 37 #include "ui/views/layout/fill_layout.h" |
43 #include "ui/views/widget/widget.h" | 38 #include "ui/views/widget/widget.h" |
44 | 39 |
45 namespace message_center { | 40 namespace message_center { |
46 | 41 |
47 namespace { | 42 namespace { |
48 | 43 |
49 const SkColor kNoNotificationsTextColor = SkColorSetRGB(0xb4, 0xb4, 0xb4); | 44 const SkColor kNoNotificationsTextColor = SkColorSetRGB(0xb4, 0xb4, 0xb4); |
50 #if defined(OS_LINUX) && defined(OS_CHROMEOS) | 45 #if defined(OS_LINUX) && defined(OS_CHROMEOS) |
51 const SkColor kTransparentColor = SkColorSetARGB(0, 0, 0, 0); | 46 const SkColor kTransparentColor = SkColorSetARGB(0, 0, 0, 0); |
52 #endif | 47 #endif |
53 const int kAnimateClearingNextNotificationDelayMS = 40; | |
54 | 48 |
55 const int kDefaultAnimationDurationMs = 120; | 49 const int kDefaultAnimationDurationMs = 120; |
56 const int kDefaultFrameRateHz = 60; | 50 const int kDefaultFrameRateHz = 60; |
57 | 51 |
58 void SetViewHierarchyEnabled(views::View* view, bool enabled) { | 52 void SetViewHierarchyEnabled(views::View* view, bool enabled) { |
59 for (int i = 0; i < view->child_count(); i++) | 53 for (int i = 0; i < view->child_count(); i++) |
60 SetViewHierarchyEnabled(view->child_at(i), enabled); | 54 SetViewHierarchyEnabled(view->child_at(i), enabled); |
61 view->SetEnabled(enabled); | 55 view->SetEnabled(enabled); |
62 } | 56 } |
63 | 57 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 int NoNotificationMessageView::GetHeightForWidth(int width) const { | 96 int NoNotificationMessageView::GetHeightForWidth(int width) const { |
103 return kMinScrollViewHeight; | 97 return kMinScrollViewHeight; |
104 } | 98 } |
105 | 99 |
106 void NoNotificationMessageView::Layout() { | 100 void NoNotificationMessageView::Layout() { |
107 int text_height = label_->GetHeightForWidth(width()); | 101 int text_height = label_->GetHeightForWidth(width()); |
108 int margin = (height() - text_height) / 2; | 102 int margin = (height() - text_height) / 2; |
109 label_->SetBounds(0, margin, width(), text_height); | 103 label_->SetBounds(0, margin, width(), text_height); |
110 } | 104 } |
111 | 105 |
112 // Displays a list of messages for rich notifications. Functions as an array of | |
113 // MessageViews and animates them on transitions. It also supports | |
114 // repositioning. | |
115 class MessageListView : public views::View, | |
116 public views::BoundsAnimatorObserver { | |
117 public: | |
118 explicit MessageListView(MessageCenterView* message_center_view, | |
119 bool top_down); | |
120 ~MessageListView() override; | |
121 | |
122 void AddNotificationAt(MessageView* view, int i); | |
123 void RemoveNotification(MessageView* view); | |
124 void UpdateNotification(MessageView* view, const Notification& notification); | |
125 void SetRepositionTarget(const gfx::Rect& target_rect); | |
126 void ResetRepositionSession(); | |
127 void ClearAllNotifications(const gfx::Rect& visible_scroll_rect); | |
128 | |
129 protected: | |
130 // Overridden from views::View. | |
131 void Layout() override; | |
132 gfx::Size GetPreferredSize() const override; | |
133 int GetHeightForWidth(int width) const override; | |
134 void PaintChildren(const ui::PaintContext& context) override; | |
135 void ReorderChildLayers(ui::Layer* parent_layer) override; | |
136 | |
137 // Overridden from views::BoundsAnimatorObserver. | |
138 void OnBoundsAnimatorProgressed(views::BoundsAnimator* animator) override; | |
139 void OnBoundsAnimatorDone(views::BoundsAnimator* animator) override; | |
140 | |
141 private: | |
142 bool IsValidChild(const views::View* child) const; | |
143 void DoUpdateIfPossible(); | |
144 | |
145 // Animates all notifications below target upwards to align with the top of | |
146 // the last closed notification. | |
147 void AnimateNotificationsBelowTarget(); | |
148 // Animates all notifications above target downwards to align with the top of | |
149 // the last closed notification. | |
150 void AnimateNotificationsAboveTarget(); | |
151 | |
152 // Schedules animation for a child to the specified position. Returns false | |
153 // if |child| will disappear after the animation. | |
154 bool AnimateChild(views::View* child, int top, int height); | |
155 | |
156 // Animate clearing one notification. | |
157 void AnimateClearingOneNotification(); | |
158 MessageCenterView* message_center_view() const { | |
159 return message_center_view_; | |
160 } | |
161 | |
162 MessageCenterView* message_center_view_; // Weak reference. | |
163 // The top position of the reposition target rectangle. | |
164 int reposition_top_; | |
165 int fixed_height_; | |
166 bool has_deferred_task_; | |
167 bool clear_all_started_; | |
168 bool top_down_; | |
169 std::set<views::View*> adding_views_; | |
170 std::set<views::View*> deleting_views_; | |
171 std::set<views::View*> deleted_when_done_; | |
172 std::list<views::View*> clearing_all_views_; | |
173 scoped_ptr<views::BoundsAnimator> animator_; | |
174 base::WeakPtrFactory<MessageListView> weak_ptr_factory_; | |
175 | |
176 DISALLOW_COPY_AND_ASSIGN(MessageListView); | |
177 }; | |
178 | |
179 MessageListView::MessageListView(MessageCenterView* message_center_view, | |
180 bool top_down) | |
181 : message_center_view_(message_center_view), | |
182 reposition_top_(-1), | |
183 fixed_height_(0), | |
184 has_deferred_task_(false), | |
185 clear_all_started_(false), | |
186 top_down_(top_down), | |
187 weak_ptr_factory_(this) { | |
188 views::BoxLayout* layout = | |
189 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1); | |
190 layout->SetDefaultFlex(1); | |
191 SetLayoutManager(layout); | |
192 | |
193 // Set the margin to 0 for the layout. BoxLayout assumes the same margin | |
194 // for top and bottom, but the bottom margin here should be smaller | |
195 // because of the shadow of message view. Use an empty border instead | |
196 // to provide this margin. | |
197 gfx::Insets shadow_insets = MessageView::GetShadowInsets(); | |
198 set_background(views::Background::CreateSolidBackground( | |
199 kMessageCenterBackgroundColor)); | |
200 SetBorder(views::Border::CreateEmptyBorder( | |
201 top_down ? 0 : kMarginBetweenItems - shadow_insets.top(), /* top */ | |
202 kMarginBetweenItems - shadow_insets.left(), /* left */ | |
203 top_down ? kMarginBetweenItems - shadow_insets.bottom() : 0, /* bottom */ | |
204 kMarginBetweenItems - shadow_insets.right() /* right */)); | |
205 } | |
206 | |
207 MessageListView::~MessageListView() { | |
208 if (animator_.get()) | |
209 animator_->RemoveObserver(this); | |
210 } | |
211 | |
212 void MessageListView::Layout() { | |
213 if (animator_.get()) | |
214 return; | |
215 | |
216 gfx::Rect child_area = GetContentsBounds(); | |
217 int top = child_area.y(); | |
218 int between_items = | |
219 kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); | |
220 | |
221 for (int i = 0; i < child_count(); ++i) { | |
222 views::View* child = child_at(i); | |
223 if (!child->visible()) | |
224 continue; | |
225 int height = child->GetHeightForWidth(child_area.width()); | |
226 child->SetBounds(child_area.x(), top, child_area.width(), height); | |
227 top += height + between_items; | |
228 } | |
229 } | |
230 | |
231 void MessageListView::AddNotificationAt(MessageView* view, int index) { | |
232 // |index| refers to a position in a subset of valid children. |real_index| | |
233 // in a list includes the invalid children, so we compute the real index by | |
234 // walking the list until |index| number of valid children are encountered, | |
235 // or to the end of the list. | |
236 int real_index = 0; | |
237 while (real_index < child_count()) { | |
238 if (IsValidChild(child_at(real_index))) { | |
239 --index; | |
240 if (index < 0) | |
241 break; | |
242 } | |
243 ++real_index; | |
244 } | |
245 | |
246 AddChildViewAt(view, real_index); | |
247 if (GetContentsBounds().IsEmpty()) | |
248 return; | |
249 | |
250 adding_views_.insert(view); | |
251 DoUpdateIfPossible(); | |
252 } | |
253 | |
254 void MessageListView::RemoveNotification(MessageView* view) { | |
255 DCHECK_EQ(view->parent(), this); | |
256 if (GetContentsBounds().IsEmpty()) { | |
257 delete view; | |
258 } else { | |
259 if (view->layer()) { | |
260 deleting_views_.insert(view); | |
261 } else { | |
262 if (animator_.get()) | |
263 animator_->StopAnimatingView(view); | |
264 delete view; | |
265 } | |
266 DoUpdateIfPossible(); | |
267 } | |
268 } | |
269 | |
270 void MessageListView::UpdateNotification(MessageView* view, | |
271 const Notification& notification) { | |
272 int index = GetIndexOf(view); | |
273 DCHECK_LE(0, index); // GetIndexOf is negative if not a child. | |
274 | |
275 if (animator_.get()) | |
276 animator_->StopAnimatingView(view); | |
277 if (deleting_views_.find(view) != deleting_views_.end()) | |
278 deleting_views_.erase(view); | |
279 if (deleted_when_done_.find(view) != deleted_when_done_.end()) | |
280 deleted_when_done_.erase(view); | |
281 view->UpdateWithNotification(notification); | |
282 DoUpdateIfPossible(); | |
283 } | |
284 | |
285 gfx::Size MessageListView::GetPreferredSize() const { | |
286 int width = 0; | |
287 for (int i = 0; i < child_count(); i++) { | |
288 const views::View* child = child_at(i); | |
289 if (IsValidChild(child)) | |
290 width = std::max(width, child->GetPreferredSize().width()); | |
291 } | |
292 | |
293 return gfx::Size(width + GetInsets().width(), | |
294 GetHeightForWidth(width + GetInsets().width())); | |
295 } | |
296 | |
297 int MessageListView::GetHeightForWidth(int width) const { | |
298 if (fixed_height_ > 0) | |
299 return fixed_height_; | |
300 | |
301 width -= GetInsets().width(); | |
302 int height = 0; | |
303 int padding = 0; | |
304 for (int i = 0; i < child_count(); ++i) { | |
305 const views::View* child = child_at(i); | |
306 if (!IsValidChild(child)) | |
307 continue; | |
308 height += child->GetHeightForWidth(width) + padding; | |
309 padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); | |
310 } | |
311 | |
312 return height + GetInsets().height(); | |
313 } | |
314 | |
315 void MessageListView::PaintChildren(const ui::PaintContext& context) { | |
316 // Paint in the inversed order. Otherwise upper notification may be | |
317 // hidden by the lower one. | |
318 for (int i = child_count() - 1; i >= 0; --i) { | |
319 if (!child_at(i)->layer()) | |
320 child_at(i)->Paint(context); | |
321 } | |
322 } | |
323 | |
324 void MessageListView::ReorderChildLayers(ui::Layer* parent_layer) { | |
325 // Reorder children to stack the last child layer at the top. Otherwise | |
326 // upper notification may be hidden by the lower one. | |
327 for (int i = 0; i < child_count(); ++i) { | |
328 if (child_at(i)->layer()) | |
329 parent_layer->StackAtBottom(child_at(i)->layer()); | |
330 } | |
331 } | |
332 | |
333 void MessageListView::SetRepositionTarget(const gfx::Rect& target) { | |
334 reposition_top_ = target.y(); | |
335 fixed_height_ = GetHeightForWidth(width()); | |
336 } | |
337 | |
338 void MessageListView::ResetRepositionSession() { | |
339 // Don't call DoUpdateIfPossible(), but let Layout() do the task without | |
340 // animation. Reset will cause the change of the bubble size itself, and | |
341 // animation from the old location will look weird. | |
342 if (reposition_top_ >= 0 && animator_.get()) { | |
343 has_deferred_task_ = false; | |
344 // cancel cause OnBoundsAnimatorDone which deletes |deleted_when_done_|. | |
345 animator_->Cancel(); | |
346 STLDeleteContainerPointers(deleting_views_.begin(), deleting_views_.end()); | |
347 deleting_views_.clear(); | |
348 adding_views_.clear(); | |
349 animator_.reset(); | |
350 } | |
351 | |
352 reposition_top_ = -1; | |
353 fixed_height_ = 0; | |
354 } | |
355 | |
356 void MessageListView::ClearAllNotifications( | |
357 const gfx::Rect& visible_scroll_rect) { | |
358 for (int i = 0; i < child_count(); ++i) { | |
359 views::View* child = child_at(i); | |
360 if (!child->visible()) | |
361 continue; | |
362 if (gfx::IntersectRects(child->bounds(), visible_scroll_rect).IsEmpty()) | |
363 continue; | |
364 clearing_all_views_.push_back(child); | |
365 } | |
366 DoUpdateIfPossible(); | |
367 } | |
368 | |
369 void MessageListView::OnBoundsAnimatorProgressed( | |
370 views::BoundsAnimator* animator) { | |
371 DCHECK_EQ(animator_.get(), animator); | |
372 for (std::set<views::View*>::iterator iter = deleted_when_done_.begin(); | |
373 iter != deleted_when_done_.end(); ++iter) { | |
374 const gfx::SlideAnimation* animation = animator->GetAnimationForView(*iter); | |
375 if (animation) | |
376 (*iter)->layer()->SetOpacity(animation->CurrentValueBetween(1.0, 0.0)); | |
377 } | |
378 } | |
379 | |
380 void MessageListView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) { | |
381 STLDeleteContainerPointers( | |
382 deleted_when_done_.begin(), deleted_when_done_.end()); | |
383 deleted_when_done_.clear(); | |
384 | |
385 if (clear_all_started_) { | |
386 clear_all_started_ = false; | |
387 message_center_view()->OnAllNotificationsCleared(); | |
388 } | |
389 | |
390 if (has_deferred_task_) { | |
391 has_deferred_task_ = false; | |
392 DoUpdateIfPossible(); | |
393 } | |
394 | |
395 if (GetWidget()) | |
396 GetWidget()->SynthesizeMouseMoveEvent(); | |
397 } | |
398 | |
399 bool MessageListView::IsValidChild(const views::View* child) const { | |
400 return child->visible() && | |
401 deleting_views_.find(const_cast<views::View*>(child)) == | |
402 deleting_views_.end() && | |
403 deleted_when_done_.find(const_cast<views::View*>(child)) == | |
404 deleted_when_done_.end(); | |
405 } | |
406 | |
407 void MessageListView::DoUpdateIfPossible() { | |
408 gfx::Rect child_area = GetContentsBounds(); | |
409 if (child_area.IsEmpty()) | |
410 return; | |
411 | |
412 if (animator_.get() && animator_->IsAnimating()) { | |
413 has_deferred_task_ = true; | |
414 return; | |
415 } | |
416 | |
417 if (!animator_.get()) { | |
418 animator_.reset(new views::BoundsAnimator(this)); | |
419 animator_->AddObserver(this); | |
420 } | |
421 | |
422 if (!clearing_all_views_.empty()) { | |
423 AnimateClearingOneNotification(); | |
424 return; | |
425 } | |
426 | |
427 if (top_down_ || | |
428 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
429 switches::kEnableMessageCenterAlwaysScrollUpUponNotificationRemoval)) | |
430 AnimateNotificationsBelowTarget(); | |
431 else | |
432 AnimateNotificationsAboveTarget(); | |
433 | |
434 adding_views_.clear(); | |
435 deleting_views_.clear(); | |
436 } | |
437 | |
438 void MessageListView::AnimateNotificationsBelowTarget() { | |
439 int last_index = -1; | |
440 for (int i = 0; i < child_count(); ++i) { | |
441 views::View* child = child_at(i); | |
442 if (!IsValidChild(child)) { | |
443 AnimateChild(child, child->y(), child->height()); | |
444 } else if (reposition_top_ < 0 || child->y() > reposition_top_) { | |
445 // Find first notification below target (or all notifications if no | |
446 // target). | |
447 last_index = i; | |
448 break; | |
449 } | |
450 } | |
451 if (last_index > 0) { | |
452 int between_items = | |
453 kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); | |
454 int top = (reposition_top_ > 0) ? reposition_top_ : GetInsets().top(); | |
455 | |
456 for (int i = last_index; i < child_count(); ++i) { | |
457 // Animate notifications below target upwards. | |
458 views::View* child = child_at(i); | |
459 if (AnimateChild(child, top, child->height())) | |
460 top += child->height() + between_items; | |
461 } | |
462 } | |
463 } | |
464 | |
465 void MessageListView::AnimateNotificationsAboveTarget() { | |
466 int last_index = -1; | |
467 for (int i = child_count() - 1; i >= 0; --i) { | |
468 views::View* child = child_at(i); | |
469 if (!IsValidChild(child)) { | |
470 AnimateChild(child, child->y(), child->height()); | |
471 } else if (reposition_top_ < 0 || child->y() < reposition_top_) { | |
472 // Find first notification above target (or all notifications if no | |
473 // target). | |
474 last_index = i; | |
475 break; | |
476 } | |
477 } | |
478 if (last_index >= 0) { | |
479 int between_items = | |
480 kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); | |
481 int bottom = (reposition_top_ > 0) | |
482 ? reposition_top_ + child_at(last_index)->height() | |
483 : GetHeightForWidth(width()) - GetInsets().bottom(); | |
484 for (int i = last_index; i >= 0; --i) { | |
485 // Animate notifications above target downwards. | |
486 views::View* child = child_at(i); | |
487 if (AnimateChild(child, bottom - child->height(), child->height())) | |
488 bottom -= child->height() + between_items; | |
489 } | |
490 } | |
491 } | |
492 | |
493 bool MessageListView::AnimateChild(views::View* child, int top, int height) { | |
494 gfx::Rect child_area = GetContentsBounds(); | |
495 if (adding_views_.find(child) != adding_views_.end()) { | |
496 child->SetBounds(child_area.right(), top, child_area.width(), height); | |
497 animator_->AnimateViewTo( | |
498 child, gfx::Rect(child_area.x(), top, child_area.width(), height)); | |
499 } else if (deleting_views_.find(child) != deleting_views_.end()) { | |
500 DCHECK(child->layer()); | |
501 // No moves, but animate to fade-out. | |
502 animator_->AnimateViewTo(child, child->bounds()); | |
503 deleted_when_done_.insert(child); | |
504 return false; | |
505 } else { | |
506 gfx::Rect target(child_area.x(), top, child_area.width(), height); | |
507 if (child->bounds().origin() != target.origin()) | |
508 animator_->AnimateViewTo(child, target); | |
509 else | |
510 child->SetBoundsRect(target); | |
511 } | |
512 return true; | |
513 } | |
514 | |
515 void MessageListView::AnimateClearingOneNotification() { | |
516 DCHECK(!clearing_all_views_.empty()); | |
517 | |
518 clear_all_started_ = true; | |
519 | |
520 views::View* child = clearing_all_views_.front(); | |
521 clearing_all_views_.pop_front(); | |
522 | |
523 // Slide from left to right. | |
524 gfx::Rect new_bounds = child->bounds(); | |
525 new_bounds.set_x(new_bounds.right() + kMarginBetweenItems); | |
526 animator_->AnimateViewTo(child, new_bounds); | |
527 | |
528 // Schedule to start sliding out next notification after a short delay. | |
529 if (!clearing_all_views_.empty()) { | |
530 base::MessageLoop::current()->PostDelayedTask( | |
531 FROM_HERE, | |
532 base::Bind(&MessageListView::AnimateClearingOneNotification, | |
533 weak_ptr_factory_.GetWeakPtr()), | |
534 base::TimeDelta::FromMilliseconds( | |
535 kAnimateClearingNextNotificationDelayMS)); | |
536 } | |
537 } | |
538 | |
539 // MessageCenterView /////////////////////////////////////////////////////////// | 106 // MessageCenterView /////////////////////////////////////////////////////////// |
540 | 107 |
541 MessageCenterView::MessageCenterView(MessageCenter* message_center, | 108 MessageCenterView::MessageCenterView(MessageCenter* message_center, |
542 MessageCenterTray* tray, | 109 MessageCenterTray* tray, |
543 int max_height, | 110 int max_height, |
544 bool initially_settings_visible, | 111 bool initially_settings_visible, |
545 bool top_down, | 112 bool top_down, |
546 const base::string16& title) | 113 const base::string16& title) |
547 : message_center_(message_center), | 114 : message_center_(message_center), |
548 tray_(tray), | 115 tray_(tray), |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1006 scroller_->InvalidateLayout(); | 573 scroller_->InvalidateLayout(); |
1007 PreferredSizeChanged(); | 574 PreferredSizeChanged(); |
1008 Layout(); | 575 Layout(); |
1009 } | 576 } |
1010 | 577 |
1011 void MessageCenterView::SetNotificationViewForTest(MessageView* view) { | 578 void MessageCenterView::SetNotificationViewForTest(MessageView* view) { |
1012 message_list_view_->AddNotificationAt(view, 0); | 579 message_list_view_->AddNotificationAt(view, 0); |
1013 } | 580 } |
1014 | 581 |
1015 } // namespace message_center | 582 } // namespace message_center |
OLD | NEW |