Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(718)

Side by Side Diff: ui/message_center/views/message_popup_collection.cc

Issue 369573004: Separate the logic of popup alignment and workarea handling as delegate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_popup_collection.h" 5 #include "ui/message_center/views/message_popup_collection.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/i18n/rtl.h" 10 #include "base/i18n/rtl.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/weak_ptr.h" 12 #include "base/memory/weak_ptr.h"
13 #include "base/run_loop.h" 13 #include "base/run_loop.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "base/timer/timer.h" 15 #include "base/timer/timer.h"
16 #include "ui/accessibility/ax_enums.h" 16 #include "ui/accessibility/ax_enums.h"
17 #include "ui/gfx/animation/animation_delegate.h" 17 #include "ui/gfx/animation/animation_delegate.h"
18 #include "ui/gfx/animation/slide_animation.h" 18 #include "ui/gfx/animation/slide_animation.h"
19 #include "ui/gfx/screen.h" 19 #include "ui/gfx/screen.h"
20 #include "ui/message_center/message_center.h" 20 #include "ui/message_center/message_center.h"
21 #include "ui/message_center/message_center_style.h" 21 #include "ui/message_center/message_center_style.h"
22 #include "ui/message_center/message_center_tray.h" 22 #include "ui/message_center/message_center_tray.h"
23 #include "ui/message_center/notification.h" 23 #include "ui/message_center/notification.h"
24 #include "ui/message_center/notification_list.h" 24 #include "ui/message_center/notification_list.h"
25 #include "ui/message_center/views/message_view_context_menu_controller.h" 25 #include "ui/message_center/views/message_view_context_menu_controller.h"
26 #include "ui/message_center/views/notification_view.h" 26 #include "ui/message_center/views/notification_view.h"
27 #include "ui/message_center/views/popup_alignment_delegate.h"
27 #include "ui/message_center/views/toast_contents_view.h" 28 #include "ui/message_center/views/toast_contents_view.h"
28 #include "ui/views/background.h" 29 #include "ui/views/background.h"
29 #include "ui/views/layout/fill_layout.h" 30 #include "ui/views/layout/fill_layout.h"
30 #include "ui/views/view.h" 31 #include "ui/views/view.h"
31 #include "ui/views/views_delegate.h" 32 #include "ui/views/views_delegate.h"
32 #include "ui/views/widget/widget.h" 33 #include "ui/views/widget/widget.h"
33 #include "ui/views/widget/widget_delegate.h" 34 #include "ui/views/widget/widget_delegate.h"
34 35
35 namespace message_center { 36 namespace message_center {
36 namespace { 37 namespace {
37 38
38 // Timeout between the last user-initiated close of the toast and the moment 39 // Timeout between the last user-initiated close of the toast and the moment
39 // when normal layout/update of the toast stack continues. If the last toast was 40 // when normal layout/update of the toast stack continues. If the last toast was
40 // just closed, the timeout is shorter. 41 // just closed, the timeout is shorter.
41 const int kMouseExitedDeferTimeoutMs = 200; 42 const int kMouseExitedDeferTimeoutMs = 200;
42 43
43 // The margin between messages (and between the anchor unless 44 // The margin between messages (and between the anchor unless
44 // first_item_has_no_margin was specified). 45 // first_item_has_no_margin was specified).
45 const int kToastMarginY = kMarginBetweenItems; 46 const int kToastMarginY = kMarginBetweenItems;
46 #if defined(OS_CHROMEOS)
47 const int kToastMarginX = 3;
48 #else
49 const int kToastMarginX = kMarginBetweenItems;
50 #endif
51
52
53 // If there should be no margin for the first item, this value needs to be
54 // substracted to flush the message to the shelf (the width of the border +
55 // shadow).
56 const int kNoToastMarginBorderAndShadowOffset = 2;
57 47
58 } // namespace. 48 } // namespace.
59 49
60 MessagePopupCollection::MessagePopupCollection(gfx::NativeView parent, 50 MessagePopupCollection::MessagePopupCollection(
61 MessageCenter* message_center, 51 gfx::NativeView parent,
62 MessageCenterTray* tray, 52 MessageCenter* message_center,
63 bool first_item_has_no_margin) 53 MessageCenterTray* tray,
54 PopupAlignmentDelegate* alignment_delegate)
64 : parent_(parent), 55 : parent_(parent),
65 message_center_(message_center), 56 message_center_(message_center),
66 tray_(tray), 57 tray_(tray),
67 display_id_(gfx::Display::kInvalidDisplayID), 58 alignment_delegate_(alignment_delegate),
68 screen_(NULL),
69 defer_counter_(0), 59 defer_counter_(0),
70 latest_toast_entered_(NULL), 60 latest_toast_entered_(NULL),
71 user_is_closing_toasts_by_clicking_(false), 61 user_is_closing_toasts_by_clicking_(false),
72 first_item_has_no_margin_(first_item_has_no_margin),
73 context_menu_controller_(new MessageViewContextMenuController(this)), 62 context_menu_controller_(new MessageViewContextMenuController(this)),
74 weak_factory_(this) { 63 weak_factory_(this) {
75 DCHECK(message_center_); 64 DCHECK(message_center_);
76 defer_timer_.reset(new base::OneShotTimer<MessagePopupCollection>); 65 defer_timer_.reset(new base::OneShotTimer<MessagePopupCollection>);
77 message_center_->AddObserver(this); 66 message_center_->AddObserver(this);
67 alignment_delegate_->set_collection(this);
78 } 68 }
79 69
80 MessagePopupCollection::~MessagePopupCollection() { 70 MessagePopupCollection::~MessagePopupCollection() {
81 weak_factory_.InvalidateWeakPtrs(); 71 weak_factory_.InvalidateWeakPtrs();
82 72
83 if (screen_)
84 screen_->RemoveObserver(this);
85 message_center_->RemoveObserver(this); 73 message_center_->RemoveObserver(this);
86 74
87 CloseAllWidgets(); 75 CloseAllWidgets();
88 } 76 }
89 77
90 void MessagePopupCollection::ClickOnNotification( 78 void MessagePopupCollection::ClickOnNotification(
91 const std::string& notification_id) { 79 const std::string& notification_id) {
92 message_center_->ClickOnNotification(notification_id); 80 message_center_->ClickOnNotification(notification_id);
93 } 81 }
94 82
(...skipping 30 matching lines...) Expand all
125 113
126 void MessagePopupCollection::UpdateWidgets() { 114 void MessagePopupCollection::UpdateWidgets() {
127 NotificationList::PopupNotifications popups = 115 NotificationList::PopupNotifications popups =
128 message_center_->GetPopupNotifications(); 116 message_center_->GetPopupNotifications();
129 117
130 if (popups.empty()) { 118 if (popups.empty()) {
131 CloseAllWidgets(); 119 CloseAllWidgets();
132 return; 120 return;
133 } 121 }
134 122
135 bool top_down = alignment_ & POPUP_ALIGNMENT_TOP; 123 bool top_down = alignment_delegate_->IsTopDown();
136 int base = GetBaseLine(toasts_.empty() ? NULL : toasts_.back()); 124 int base = GetBaseLine(toasts_.empty() ? NULL : toasts_.back());
137 125
138 // Iterate in the reverse order to keep the oldest toasts on screen. Newer 126 // Iterate in the reverse order to keep the oldest toasts on screen. Newer
139 // items may be ignored if there are no room to place them. 127 // items may be ignored if there are no room to place them.
140 for (NotificationList::PopupNotifications::const_reverse_iterator iter = 128 for (NotificationList::PopupNotifications::const_reverse_iterator iter =
141 popups.rbegin(); iter != popups.rend(); ++iter) { 129 popups.rbegin(); iter != popups.rend(); ++iter) {
142 if (FindToast((*iter)->id())) 130 if (FindToast((*iter)->id()))
143 continue; 131 continue;
144 132
145 NotificationView* view = 133 NotificationView* view =
146 NotificationView::Create(NULL, 134 NotificationView::Create(NULL,
147 *(*iter), 135 *(*iter),
148 true); // Create top-level notification. 136 true); // Create top-level notification.
149 view->set_context_menu_controller(context_menu_controller_.get()); 137 view->set_context_menu_controller(context_menu_controller_.get());
150 int view_height = ToastContentsView::GetToastSizeForView(view).height(); 138 int view_height = ToastContentsView::GetToastSizeForView(view).height();
151 int height_available = top_down ? work_area_.bottom() - base : base; 139 int height_available =
140 top_down ? alignment_delegate_->GetWorkAreaBottom() - base : base;
152 141
153 if (height_available - view_height - kToastMarginY < 0) { 142 if (height_available - view_height - kToastMarginY < 0) {
154 delete view; 143 delete view;
155 break; 144 break;
156 } 145 }
157 146
158 ToastContentsView* toast = 147 ToastContentsView* toast =
159 new ToastContentsView((*iter)->id(), weak_factory_.GetWeakPtr()); 148 new ToastContentsView((*iter)->id(), weak_factory_.GetWeakPtr());
160 // There will be no contents already since this is a new ToastContentsView. 149 // There will be no contents already since this is a new ToastContentsView.
161 toast->SetContents(view, /*a11y_feedback_for_updates=*/false); 150 toast->SetContents(view, /*a11y_feedback_for_updates=*/false);
162 toasts_.push_back(toast); 151 toasts_.push_back(toast);
163 view->set_controller(toast); 152 view->set_controller(toast);
164 153
165 gfx::Size preferred_size = toast->GetPreferredSize(); 154 gfx::Size preferred_size = toast->GetPreferredSize();
166 gfx::Point origin(GetToastOriginX(gfx::Rect(preferred_size)), base); 155 gfx::Point origin(
156 alignment_delegate_->GetToastOriginX(gfx::Rect(preferred_size)), base);
167 // The toast slides in from the edge of the screen horizontally. 157 // The toast slides in from the edge of the screen horizontally.
168 if (alignment_ & POPUP_ALIGNMENT_LEFT) 158 if (alignment_delegate_->IsFromLeft())
169 origin.set_x(origin.x() - preferred_size.width()); 159 origin.set_x(origin.x() - preferred_size.width());
170 else 160 else
171 origin.set_x(origin.x() + preferred_size.width()); 161 origin.set_x(origin.x() + preferred_size.width());
172 if (top_down) 162 if (top_down)
173 origin.set_y(origin.y() + view_height); 163 origin.set_y(origin.y() + view_height);
174 164
175 toast->RevealWithAnimation(origin); 165 toast->RevealWithAnimation(origin);
176 166
177 // Shift the base line to be a few pixels above the last added toast or (few 167 // Shift the base line to be a few pixels above the last added toast or (few
178 // pixels below last added toast if top-aligned). 168 // pixels below last added toast if top-aligned).
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 void MessagePopupCollection::RemoveToast(ToastContentsView* toast, 236 void MessagePopupCollection::RemoveToast(ToastContentsView* toast,
247 bool mark_as_shown) { 237 bool mark_as_shown) {
248 ForgetToast(toast); 238 ForgetToast(toast);
249 239
250 toast->CloseWithAnimation(); 240 toast->CloseWithAnimation();
251 241
252 if (mark_as_shown) 242 if (mark_as_shown)
253 message_center_->MarkSinglePopupAsShown(toast->id(), false); 243 message_center_->MarkSinglePopupAsShown(toast->id(), false);
254 } 244 }
255 245
256 int MessagePopupCollection::GetToastOriginX(const gfx::Rect& toast_bounds)
257 const {
258 #if defined(OS_CHROMEOS)
259 // In ChromeOS, RTL UI language mirrors the whole desktop layout, so the toast
260 // widgets should be at the bottom-left instead of bottom right.
261 if (base::i18n::IsRTL())
262 return work_area_.x() + kToastMarginX;
263 #endif
264 if (alignment_ & POPUP_ALIGNMENT_LEFT)
265 return work_area_.x() + kToastMarginX;
266 return work_area_.right() - kToastMarginX - toast_bounds.width();
267 }
268
269 void MessagePopupCollection::RepositionWidgets() { 246 void MessagePopupCollection::RepositionWidgets() {
270 bool top_down = alignment_ & POPUP_ALIGNMENT_TOP; 247 bool top_down = alignment_delegate_->IsTopDown();
271 int base = GetBaseLine(NULL); // We don't want to position relative to last 248 int base = GetBaseLine(NULL); // We don't want to position relative to last
272 // toast - we want re-position. 249 // toast - we want re-position.
273 250
274 for (Toasts::const_iterator iter = toasts_.begin(); iter != toasts_.end();) { 251 for (Toasts::const_iterator iter = toasts_.begin(); iter != toasts_.end();) {
275 Toasts::const_iterator curr = iter++; 252 Toasts::const_iterator curr = iter++;
276 gfx::Rect bounds((*curr)->bounds()); 253 gfx::Rect bounds((*curr)->bounds());
277 bounds.set_x(GetToastOriginX(bounds)); 254 bounds.set_x(alignment_delegate_->GetToastOriginX(bounds));
278 bounds.set_y(alignment_ & POPUP_ALIGNMENT_TOP ? base 255 bounds.set_y(top_down ? base : base - bounds.height());
279 : base - bounds.height());
280 256
281 // The notification may scrolls the boundary of the screen due to image 257 // The notification may scrolls the boundary of the screen due to image
282 // load and such notifications should disappear. Do not call 258 // load and such notifications should disappear. Do not call
283 // CloseWithAnimation, we don't want to show the closing animation, and we 259 // CloseWithAnimation, we don't want to show the closing animation, and we
284 // don't want to mark such notifications as shown. See crbug.com/233424 260 // don't want to mark such notifications as shown. See crbug.com/233424
285 if ((top_down ? work_area_.bottom() - bounds.bottom() : bounds.y()) >= 0) 261 if ((top_down ? alignment_delegate_->GetWorkAreaBottom() - bounds.bottom()
262 : bounds.y()) >= 0)
286 (*curr)->SetBoundsWithAnimation(bounds); 263 (*curr)->SetBoundsWithAnimation(bounds);
287 else 264 else
288 RemoveToast(*curr, /*mark_as_shown=*/false); 265 RemoveToast(*curr, /*mark_as_shown=*/false);
289 266
290 // Shift the base line to be a few pixels above the last added toast or (few 267 // Shift the base line to be a few pixels above the last added toast or (few
291 // pixels below last added toast if top-aligned). 268 // pixels below last added toast if top-aligned).
292 if (top_down) 269 if (top_down)
293 base += bounds.height() + kToastMarginY; 270 base += bounds.height() + kToastMarginY;
294 else 271 else
295 base -= bounds.height() + kToastMarginY; 272 base -= bounds.height() + kToastMarginY;
296 } 273 }
297 } 274 }
298 275
299 void MessagePopupCollection::RepositionWidgetsWithTarget() { 276 void MessagePopupCollection::RepositionWidgetsWithTarget() {
300 if (toasts_.empty()) 277 if (toasts_.empty())
301 return; 278 return;
302 279
303 bool top_down = alignment_ & POPUP_ALIGNMENT_TOP; 280 bool top_down = alignment_delegate_->IsTopDown();
304 281
305 // Nothing to do if there are no widgets above target if bottom-aligned or no 282 // Nothing to do if there are no widgets above target if bottom-aligned or no
306 // widgets below target if top-aligned. 283 // widgets below target if top-aligned.
307 if (top_down ? toasts_.back()->origin().y() < target_top_edge_ 284 if (top_down ? toasts_.back()->origin().y() < target_top_edge_
308 : toasts_.back()->origin().y() > target_top_edge_) 285 : toasts_.back()->origin().y() > target_top_edge_)
309 return; 286 return;
310 287
311 Toasts::reverse_iterator iter = toasts_.rbegin(); 288 Toasts::reverse_iterator iter = toasts_.rbegin();
312 for (; iter != toasts_.rend(); ++iter) { 289 for (; iter != toasts_.rend(); ++iter) {
313 // We only reposition widgets above target if bottom-aligned or widgets 290 // We only reposition widgets above target if bottom-aligned or widgets
(...skipping 16 matching lines...) Expand all
330 bounds.set_y(bounds.y() - slide_length); 307 bounds.set_y(bounds.y() - slide_length);
331 else 308 else
332 bounds.set_y(bounds.y() + slide_length); 309 bounds.set_y(bounds.y() + slide_length);
333 (*iter)->SetBoundsWithAnimation(bounds); 310 (*iter)->SetBoundsWithAnimation(bounds);
334 311
335 if (iter == toasts_.rbegin()) 312 if (iter == toasts_.rbegin())
336 break; 313 break;
337 } 314 }
338 } 315 }
339 316
340 void MessagePopupCollection::ComputePopupAlignment(gfx::Rect work_area,
341 gfx::Rect screen_bounds) {
342 // If the taskbar is at the top, render notifications top down. Some platforms
343 // like Gnome can have taskbars at top and bottom. In this case it's more
344 // likely that the systray is on the top one.
345 alignment_ = work_area.y() > screen_bounds.y() ? POPUP_ALIGNMENT_TOP
346 : POPUP_ALIGNMENT_BOTTOM;
347
348 // If the taskbar is on the left show the notifications on the left. Otherwise
349 // show it on right since it's very likely that the systray is on the right if
350 // the taskbar is on the top or bottom.
351 // Since on some platforms like Ubuntu Unity there's also a launcher along
352 // with a taskbar (panel), we need to check that there is really nothing at
353 // the top before concluding that the taskbar is at the left.
354 alignment_ = static_cast<PopupAlignment>(
355 alignment_ |
356 ((work_area.x() > screen_bounds.x() && work_area.y() == screen_bounds.y())
357 ? POPUP_ALIGNMENT_LEFT
358 : POPUP_ALIGNMENT_RIGHT));
359 }
360
361 int MessagePopupCollection::GetBaseLine(ToastContentsView* last_toast) const { 317 int MessagePopupCollection::GetBaseLine(ToastContentsView* last_toast) const {
362 bool top_down = alignment_ & POPUP_ALIGNMENT_TOP; 318 if (!last_toast) {
363 int base; 319 return alignment_delegate_->GetBaseLine();
364 320 } else if (alignment_delegate_->IsTopDown()) {
365 if (top_down) { 321 return toasts_.back()->bounds().bottom() + kToastMarginY;
366 if (!last_toast) {
367 base = work_area_.y();
368 if (!first_item_has_no_margin_)
369 base += kToastMarginY;
370 else
371 base -= kNoToastMarginBorderAndShadowOffset;
372 } else {
373 base = toasts_.back()->bounds().bottom() + kToastMarginY;
374 }
375 } else { 322 } else {
376 if (!last_toast) { 323 return toasts_.back()->origin().y() - kToastMarginY;
377 base = work_area_.bottom();
378 if (!first_item_has_no_margin_)
379 base -= kToastMarginY;
380 else
381 base += kNoToastMarginBorderAndShadowOffset;
382 } else {
383 base = toasts_.back()->origin().y() - kToastMarginY;
384 }
385 } 324 }
386 return base;
387 } 325 }
388 326
389 void MessagePopupCollection::OnNotificationAdded( 327 void MessagePopupCollection::OnNotificationAdded(
390 const std::string& notification_id) { 328 const std::string& notification_id) {
391 DoUpdateIfPossible(); 329 DoUpdateIfPossible();
392 } 330 }
393 331
394 void MessagePopupCollection::OnNotificationRemoved( 332 void MessagePopupCollection::OnNotificationRemoved(
395 const std::string& notification_id, 333 const std::string& notification_id,
396 bool by_user) { 334 bool by_user) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 DoUpdateIfPossible(); 439 DoUpdateIfPossible();
502 } 440 }
503 441
504 // This is the main sequencer of tasks. It does a step, then waits for 442 // This is the main sequencer of tasks. It does a step, then waits for
505 // all started transitions to play out before doing the next step. 443 // all started transitions to play out before doing the next step.
506 // First, remove all expired toasts. 444 // First, remove all expired toasts.
507 // Then, reposition widgets (the reposition on close happens before all 445 // Then, reposition widgets (the reposition on close happens before all
508 // deferred tasks are even able to run) 446 // deferred tasks are even able to run)
509 // Then, see if there is vacant space for new toasts. 447 // Then, see if there is vacant space for new toasts.
510 void MessagePopupCollection::DoUpdateIfPossible() { 448 void MessagePopupCollection::DoUpdateIfPossible() {
511 if (!screen_) {
512 gfx::Display display;
513 if (!parent_) {
514 // On Win+Aura, we don't have a parent since the popups currently show up
515 // on the Windows desktop, not in the Aura/Ash desktop. This code will
516 // display the popups on the primary display.
517 screen_ = gfx::Screen::GetNativeScreen();
518 display = screen_->GetPrimaryDisplay();
519 } else {
520 screen_ = gfx::Screen::GetScreenFor(parent_);
521 display = screen_->GetDisplayNearestWindow(parent_);
522 }
523 screen_->AddObserver(this);
524
525 display_id_ = display.id();
526 // |work_area_| can be set already and it should not be overwritten here.
527 if (work_area_.IsEmpty()) {
528 work_area_ = display.work_area();
529 ComputePopupAlignment(work_area_, display.bounds());
530 }
531 }
532
533 if (defer_counter_ > 0) 449 if (defer_counter_ > 0)
534 return; 450 return;
535 451
536 RepositionWidgets(); 452 RepositionWidgets();
537 453
538 if (defer_counter_ > 0) 454 if (defer_counter_ > 0)
539 return; 455 return;
540 456
541 // Reposition could create extra space which allows additional widgets. 457 // Reposition could create extra space which allows additional widgets.
542 UpdateWidgets(); 458 UpdateWidgets();
543 459
544 if (defer_counter_ > 0) 460 if (defer_counter_ > 0)
545 return; 461 return;
546 462
547 // Test support. Quit the test run loop when no more updates are deferred, 463 // Test support. Quit the test run loop when no more updates are deferred,
548 // meaining th echeck for updates did not cause anything to change so no new 464 // meaining th echeck for updates did not cause anything to change so no new
549 // transition animations were started. 465 // transition animations were started.
550 if (run_loop_for_test_.get()) 466 if (run_loop_for_test_.get())
551 run_loop_for_test_->Quit(); 467 run_loop_for_test_->Quit();
552 } 468 }
553 469
554 void MessagePopupCollection::SetDisplayInfo(const gfx::Rect& work_area,
555 const gfx::Rect& screen_bounds) {
556 if (work_area_ == work_area)
557 return;
558
559 work_area_ = work_area;
560 ComputePopupAlignment(work_area, screen_bounds);
561 RepositionWidgets();
562 }
563
564 void MessagePopupCollection::OnDisplayAdded(const gfx::Display& new_display) {
565 }
566
567 void MessagePopupCollection::OnDisplayRemoved(const gfx::Display& old_display) {
568 if (display_id_ == old_display.id() && !parent_) {
569 gfx::Display display = gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
570 display_id_ = display.id();
571 SetDisplayInfo(display.work_area(), display.bounds());
572 }
573 }
574
575 void MessagePopupCollection::OnDisplayMetricsChanged( 470 void MessagePopupCollection::OnDisplayMetricsChanged(
576 const gfx::Display& display, uint32_t metrics) { 471 const gfx::Display& display) {
577 if (display.id() != display_id_) 472 alignment_delegate_->RecomputeAlignment(display);
578 return;
579
580 SetDisplayInfo(display.work_area(), display.bounds());
581 } 473 }
582 474
583 views::Widget* MessagePopupCollection::GetWidgetForTest(const std::string& id) 475 views::Widget* MessagePopupCollection::GetWidgetForTest(const std::string& id)
584 const { 476 const {
585 for (Toasts::const_iterator iter = toasts_.begin(); iter != toasts_.end(); 477 for (Toasts::const_iterator iter = toasts_.begin(); iter != toasts_.end();
586 ++iter) { 478 ++iter) {
587 if ((*iter)->id() == id) 479 if ((*iter)->id() == id)
588 return (*iter)->GetWidget(); 480 return (*iter)->GetWidget();
589 } 481 }
590 return NULL; 482 return NULL;
(...skipping 17 matching lines...) Expand all
608 views::Widget* widget = (*iter)->GetWidget(); 500 views::Widget* widget = (*iter)->GetWidget();
609 if (widget) 501 if (widget)
610 return widget->GetWindowBoundsInScreen(); 502 return widget->GetWindowBoundsInScreen();
611 break; 503 break;
612 } 504 }
613 } 505 }
614 return gfx::Rect(); 506 return gfx::Rect();
615 } 507 }
616 508
617 } // namespace message_center 509 } // namespace message_center
OLDNEW
« no previous file with comments | « ui/message_center/views/message_popup_collection.h ('k') | ui/message_center/views/message_popup_collection_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698