Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/message_center_bubble.h" | 5 #include "ui/message_center/message_center_bubble.h" |
| 6 | 6 |
| 7 #include "grit/ui_strings.h" | 7 #include "grit/ui_strings.h" |
| 8 #include "third_party/skia/include/core/SkPaint.h" | 8 #include "third_party/skia/include/core/SkPaint.h" |
| 9 #include "ui/base/l10n/l10n_util.h" | 9 #include "ui/base/l10n/l10n_util.h" |
| 10 #include "ui/base/resource/resource_bundle.h" | 10 #include "ui/base/resource/resource_bundle.h" |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 else | 229 else |
| 230 NOTREACHED(); | 230 NOTREACHED(); |
| 231 } | 231 } |
| 232 | 232 |
| 233 views::Label* notification_label_; | 233 views::Label* notification_label_; |
| 234 views::Button* settings_button_; | 234 views::Button* settings_button_; |
| 235 | 235 |
| 236 DISALLOW_COPY_AND_ASSIGN(WebNotificationButtonView2); | 236 DISALLOW_COPY_AND_ASSIGN(WebNotificationButtonView2); |
| 237 }; | 237 }; |
| 238 | 238 |
| 239 // A custom scroll-view that has a specified size. | 239 // A custom scroll view whose height has a minimum and maximum value and whose |
| 240 class FixedSizedScrollView : public views::ScrollView { | 240 // scroll bar disappears when not needed. |
| 241 class BoundedScrollView : public views::ScrollView { | |
| 241 public: | 242 public: |
| 242 FixedSizedScrollView() { | 243 BoundedScrollView(int min_height, int max_height) |
| 244 : min_height_(min_height), | |
| 245 max_height_(max_height) { | |
| 243 set_focusable(true); | 246 set_focusable(true); |
| 244 set_notify_enter_exit_on_child(true); | 247 set_notify_enter_exit_on_child(true); |
| 245 if (IsRichNotificationEnabled()) { | 248 if (IsRichNotificationEnabled()) { |
| 246 set_background(views::Background::CreateSolidBackground( | 249 set_background(views::Background::CreateSolidBackground( |
| 247 kMessageCenterBackgroundColor)); | 250 kMessageCenterBackgroundColor)); |
| 248 } | 251 } |
| 249 } | 252 } |
| 250 | 253 |
| 251 virtual ~FixedSizedScrollView() {} | 254 virtual ~BoundedScrollView() {} |
| 252 | |
| 253 void SetFixedSize(const gfx::Size& size) { | |
| 254 if (fixed_size_ == size) | |
| 255 return; | |
| 256 fixed_size_ = size; | |
| 257 PreferredSizeChanged(); | |
| 258 } | |
| 259 | 255 |
| 260 // views::View overrides. | 256 // views::View overrides. |
| 261 virtual gfx::Size GetPreferredSize() OVERRIDE { | 257 virtual gfx::Size GetPreferredSize() OVERRIDE { |
| 262 gfx::Size size = fixed_size_.IsEmpty() ? | 258 gfx::Size size = contents()->GetPreferredSize(); |
| 263 contents()->GetPreferredSize() : fixed_size_; | 259 size.ClampToMin(gfx::Size(size.width(), min_height_)); |
| 260 size.ClampToMax(gfx::Size(size.width(), max_height_)); | |
| 264 gfx::Insets insets = GetInsets(); | 261 gfx::Insets insets = GetInsets(); |
| 265 size.Enlarge(insets.width(), insets.height()); | 262 size.Enlarge(insets.width(), insets.height()); |
| 266 return size; | 263 return size; |
| 267 } | 264 } |
| 268 | 265 |
| 269 virtual void Layout() OVERRIDE { | 266 virtual void Layout() OVERRIDE { |
| 270 gfx::Rect bounds = gfx::Rect(contents()->GetPreferredSize()); | 267 // Lay out the view as if it will have a scroll bar. |
| 271 bounds.set_width(std::max(0, width() - GetScrollBarWidth())); | 268 gfx::Rect content_bounds = gfx::Rect(contents()->GetPreferredSize()); |
| 272 contents()->SetBoundsRect(bounds); | 269 content_bounds.set_width(std::max(0, width() - GetScrollBarWidth())); |
| 270 contents()->SetBoundsRect(content_bounds); | |
| 271 views::ScrollView::Layout(); | |
| 273 | 272 |
| 274 views::ScrollView::Layout(); | 273 // But use the scroll bar space if no scroll bar is needed. |
| 275 if (!vertical_scroll_bar()->visible()) { | 274 if (!vertical_scroll_bar()->visible()) { |
| 276 gfx::Rect bounds = contents()->bounds(); | 275 content_bounds = contents()->bounds(); |
| 277 bounds.set_width(bounds.width() + GetScrollBarWidth()); | 276 content_bounds.set_width(content_bounds.width() + GetScrollBarWidth()); |
| 278 contents()->SetBoundsRect(bounds); | 277 contents()->SetBoundsRect(content_bounds); |
| 279 } | 278 } |
| 280 } | 279 } |
| 281 | 280 |
| 282 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE { | 281 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE { |
| 283 gfx::Rect bounds = gfx::Rect(contents()->GetPreferredSize()); | 282 // Make sure any content resizing takes into account the scroll bar. |
| 284 bounds.set_width(std::max(0, width() - GetScrollBarWidth())); | 283 gfx::Rect content_bounds = gfx::Rect(contents()->GetPreferredSize()); |
| 285 contents()->SetBoundsRect(bounds); | 284 content_bounds.set_width(std::max(0, width() - GetScrollBarWidth())); |
| 285 contents()->SetBoundsRect(content_bounds); | |
| 286 } | 286 } |
| 287 | 287 |
| 288 private: | 288 private: |
| 289 gfx::Size fixed_size_; | 289 int min_height_; |
| 290 int max_height_; | |
| 290 | 291 |
| 291 DISALLOW_COPY_AND_ASSIGN(FixedSizedScrollView); | 292 DISALLOW_COPY_AND_ASSIGN(BoundedScrollView); |
| 292 }; | 293 }; |
| 293 | 294 |
| 294 // Container for the messages. | 295 // Container for the messages. |
| 295 class ScrollContentView : public views::View { | 296 class MessagesView : public views::View { |
|
Jun Mukai
2013/02/26 02:23:30
I think it's too hard to distinguish this from mes
dharcourt
2013/02/26 03:23:30
Good point. What would you think of MessageListVie
| |
| 296 public: | 297 public: |
| 297 ScrollContentView() { | 298 MessagesView(views::View *message_center_view) |
| 299 : message_center_view_(message_center_view) { | |
| 298 if (IsRichNotificationEnabled()) { | 300 if (IsRichNotificationEnabled()) { |
| 299 // Set the margin to 0 for the layout. BoxLayout assumes the same margin | 301 // Set the margin to 0 for the layout. BoxLayout assumes the same margin |
| 300 // for top and bottom, but the bottom margin here should be smaller | 302 // for top and bottom, but the bottom margin here should be smaller |
| 301 // because of the shadow of message view. Use an empty border instead | 303 // because of the shadow of message view. Use an empty border instead |
| 302 // to provide this margin. | 304 // to provide this margin. |
| 303 gfx::Insets shadow_insets = GetItemShadowInsets(); | 305 gfx::Insets shadow_insets = GetItemShadowInsets(); |
| 304 SetLayoutManager( | 306 SetLayoutManager( |
| 305 new views::BoxLayout(views::BoxLayout::kVertical, | 307 new views::BoxLayout(views::BoxLayout::kVertical, |
| 306 0, | 308 0, |
| 307 0, | 309 0, |
| 308 kMarginBetweenItems - shadow_insets.bottom())); | 310 kMarginBetweenItems - shadow_insets.bottom())); |
| 309 set_background(views::Background::CreateSolidBackground( | 311 set_background(views::Background::CreateSolidBackground( |
| 310 kMessageCenterBackgroundColor)); | 312 kMessageCenterBackgroundColor)); |
| 311 set_border(views::Border::CreateEmptyBorder( | 313 set_border(views::Border::CreateEmptyBorder( |
| 312 kMarginBetweenItems - shadow_insets.top(), /* top */ | 314 kMarginBetweenItems - shadow_insets.top(), /* top */ |
| 313 kMarginBetweenItems - shadow_insets.left(), /* left */ | 315 kMarginBetweenItems - shadow_insets.left(), /* left */ |
| 314 0, /* bottom */ | 316 0, /* bottom */ |
| 315 kMarginBetweenItems - shadow_insets.right() /* right */ )); | 317 kMarginBetweenItems - shadow_insets.right() /* right */ )); |
| 316 } else { | 318 } else { |
| 317 views::BoxLayout* layout = | 319 views::BoxLayout* layout = |
| 318 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1); | 320 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1); |
| 319 layout->set_spread_blank_space(true); | 321 layout->set_spread_blank_space(true); |
| 320 SetLayoutManager(layout); | 322 SetLayoutManager(layout); |
| 321 } | 323 } |
| 322 } | 324 } |
| 323 | 325 |
| 324 virtual ~ScrollContentView() { | 326 virtual ~MessagesView() { |
| 325 } | 327 } |
| 326 | 328 |
| 327 virtual gfx::Size GetPreferredSize() OVERRIDE { | 329 protected: |
| 328 if (!preferred_size_.IsEmpty()) | 330 // views::View overrides. |
| 329 return preferred_size_; | 331 virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE { |
| 330 return views::View::GetPreferredSize(); | 332 // Since the parent of this view is a Viewport and since Viewports ignore |
| 333 // ChildPreferredSizeChanged() calls, ask the MessageCenterView directly | |
| 334 // to update its layout for the preferred size change. | |
| 335 message_center_view_->Layout(); | |
| 331 } | 336 } |
| 332 | 337 |
| 333 void set_preferred_size(const gfx::Size& size) { preferred_size_ = size; } | 338 private: |
| 339 views::View *message_center_view_; | |
| 334 | 340 |
| 335 private: | 341 DISALLOW_COPY_AND_ASSIGN(MessagesView); |
| 336 gfx::Size preferred_size_; | |
| 337 DISALLOW_COPY_AND_ASSIGN(ScrollContentView); | |
| 338 }; | 342 }; |
| 339 | 343 |
| 340 // A border to provide the shadow for each card. | 344 // A border to provide the shadow for each card. |
| 341 // Current shadow should look like css box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) | 345 // Current shadow should look like css box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) |
| 342 class MessageViewShadowBorder : public views::Border { | 346 class MessageViewShadowBorder : public views::Border { |
| 343 public: | 347 public: |
| 344 MessageViewShadowBorder() : views::Border() {} | 348 MessageViewShadowBorder() : views::Border() {} |
| 345 virtual ~MessageViewShadowBorder() {} | 349 virtual ~MessageViewShadowBorder() {} |
| 346 | 350 |
| 347 protected: | 351 protected: |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 361 canvas->DrawRect(bounds, paint); | 365 canvas->DrawRect(bounds, paint); |
| 362 } | 366 } |
| 363 | 367 |
| 364 virtual gfx::Insets GetInsets() const OVERRIDE { | 368 virtual gfx::Insets GetInsets() const OVERRIDE { |
| 365 return GetItemShadowInsets(); | 369 return GetItemShadowInsets(); |
| 366 } | 370 } |
| 367 }; | 371 }; |
| 368 | 372 |
| 369 } // namespace | 373 } // namespace |
| 370 | 374 |
| 371 // Message Center contents. | 375 // View that displays the whole message center. |
| 372 class MessageCenterContentsView : public views::View { | 376 class MessageCenterView : public views::View { |
| 373 public: | 377 public: |
| 374 explicit MessageCenterContentsView(MessageCenterBubble* bubble, | 378 explicit MessageCenterView(MessageCenterBubble* bubble, |
| 375 NotificationList::Delegate* list_delegate) | 379 NotificationList::Delegate* list_delegate) |
| 376 : list_delegate_(list_delegate), | 380 : list_delegate_(list_delegate), |
| 377 bubble_(bubble) { | 381 bubble_(bubble) { |
| 378 int between_child = IsRichNotificationEnabled() ? 0 : 1; | 382 int between_child = IsRichNotificationEnabled() ? 0 : 1; |
| 379 SetLayoutManager( | 383 SetLayoutManager( |
| 380 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, between_child)); | 384 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, between_child)); |
| 381 | 385 |
| 382 scroll_content_ = new ScrollContentView; | 386 |
| 383 scroller_ = new FixedSizedScrollView; | 387 if (IsRichNotificationEnabled()) |
| 384 scroller_->SetContents(scroll_content_); | 388 button_view_ = new WebNotificationButtonView2(list_delegate); |
| 385 AddChildView(scroller_); | 389 else |
| 390 button_view_ = new WebNotificationButtonView(list_delegate); | |
|
dharcourt
2013/02/23 04:32:00
Button creation had to be moved up in this method
| |
| 391 | |
| 392 const int button_height = button_view_->GetPreferredSize().height(); | |
| 393 const int min_height = kMessageBubbleBaseMinHeight - button_height; | |
| 394 const int max_height = bubble_->max_height() - button_height; | |
| 395 scroller_ = new BoundedScrollView(min_height, max_height); | |
| 386 | 396 |
| 387 if (get_use_acceleration_when_possible()) { | 397 if (get_use_acceleration_when_possible()) { |
| 388 scroller_->SetPaintToLayer(true); | 398 scroller_->SetPaintToLayer(true); |
| 389 scroller_->SetFillsBoundsOpaquely(false); | 399 scroller_->SetFillsBoundsOpaquely(false); |
| 390 scroller_->layer()->SetMasksToBounds(true); | 400 scroller_->layer()->SetMasksToBounds(true); |
| 391 } | 401 } |
| 392 | 402 |
| 393 if (IsRichNotificationEnabled()) | 403 messages_view_ = new MessagesView(this); |
| 394 button_view_ = new WebNotificationButtonView2(list_delegate); | 404 scroller_->SetContents(messages_view_); |
| 395 else | 405 |
| 396 button_view_ = new WebNotificationButtonView(list_delegate); | 406 AddChildView(scroller_); |
| 397 AddChildView(button_view_); | 407 AddChildView(button_view_); |
| 398 } | 408 } |
| 399 | 409 |
| 400 void FocusContents() { | 410 void FocusContents() { |
| 401 scroller_->RequestFocus(); | 411 scroller_->RequestFocus(); |
| 402 } | 412 } |
| 403 | 413 |
| 404 void Update(const NotificationList::Notifications& notifications) { | 414 void Update(const NotificationList::Notifications& notifications) { |
| 405 scroll_content_->RemoveAllChildViews(true); | 415 messages_view_->RemoveAllChildViews(true); |
| 406 scroll_content_->set_preferred_size(gfx::Size()); | |
| 407 size_t num_children = 0; | 416 size_t num_children = 0; |
| 408 for (NotificationList::Notifications::const_iterator iter = | 417 for (NotificationList::Notifications::const_iterator iter = |
| 409 notifications.begin(); iter != notifications.end(); ++iter) { | 418 notifications.begin(); iter != notifications.end(); ++iter) { |
| 410 MessageView* view = | 419 MessageView* view = |
| 411 NotificationView::ViewForNotification(*iter, list_delegate_); | 420 NotificationView::ViewForNotification(*iter, list_delegate_); |
| 412 view->set_scroller(scroller_); | 421 view->set_scroller(scroller_); |
|
dharcourt
2013/02/23 04:32:00
SetUpView() is now avoided as MessageView and all
| |
| 413 view->SetUpView(); | |
| 414 if (IsRichNotificationEnabled()) | 422 if (IsRichNotificationEnabled()) |
| 415 view->set_border(new MessageViewShadowBorder()); | 423 view->set_border(new MessageViewShadowBorder()); |
| 416 scroll_content_->AddChildView(view); | 424 messages_view_->AddChildView(view); |
| 417 if (++num_children >= | 425 if (++num_children >= |
| 418 NotificationList::kMaxVisibleMessageCenterNotifications) { | 426 NotificationList::kMaxVisibleMessageCenterNotifications) { |
| 419 break; | 427 break; |
| 420 } | 428 } |
| 421 } | 429 } |
| 422 if (num_children == 0) { | 430 if (num_children == 0) { |
| 423 views::Label* label = new views::Label(l10n_util::GetStringUTF16( | 431 views::Label* label = new views::Label(l10n_util::GetStringUTF16( |
| 424 IDS_MESSAGE_CENTER_NO_MESSAGES)); | 432 IDS_MESSAGE_CENTER_NO_MESSAGES)); |
| 425 label->SetFont(label->font().DeriveFont(1)); | 433 label->SetFont(label->font().DeriveFont(1)); |
| 426 label->SetEnabledColor(SK_ColorGRAY); | 434 label->SetEnabledColor(SK_ColorGRAY); |
| 427 // Set transparent background to ensure that subpixel rendering | 435 // Set transparent background to ensure that subpixel rendering |
| 428 // is disabled. See crbug.com/169056 | 436 // is disabled. See crbug.com/169056 |
| 429 label->SetBackgroundColor(kTransparentColor); | 437 label->SetBackgroundColor(kTransparentColor); |
| 430 scroll_content_->AddChildView(label); | 438 messages_view_->AddChildView(label); |
| 431 button_view_->SetCloseAllVisible(false); | 439 button_view_->SetCloseAllVisible(false); |
| 432 scroller_->set_focusable(false); | 440 scroller_->set_focusable(false); |
| 433 } else { | 441 } else { |
| 434 button_view_->SetCloseAllVisible(true); | 442 button_view_->SetCloseAllVisible(true); |
| 435 scroller_->set_focusable(true); | 443 scroller_->set_focusable(true); |
| 436 } | 444 } |
| 437 SizeScrollContent(); | |
| 438 Layout(); | 445 Layout(); |
| 439 if (GetWidget()) | |
| 440 GetWidget()->GetRootView()->SchedulePaint(); | |
| 441 } | 446 } |
| 442 | 447 |
| 443 size_t NumMessageViews() const { | 448 size_t NumMessageViews() const { |
| 444 return scroll_content_->child_count(); | 449 return messages_view_->child_count(); |
| 450 } | |
| 451 | |
| 452 protected: | |
| 453 // views::View overrides. | |
| 454 virtual void Layout() OVERRIDE { | |
| 455 scroller_->SizeToPreferredSize(); | |
| 456 views::View::Layout(); | |
| 457 if (GetWidget()) | |
| 458 GetWidget()->GetRootView()->SchedulePaint(); | |
| 459 bubble_->bubble_view()->UpdateBubble(); | |
| 445 } | 460 } |
| 446 | 461 |
| 447 private: | 462 private: |
| 448 void SizeScrollContent() { | |
| 449 gfx::Size scroll_size = scroll_content_->GetPreferredSize(); | |
| 450 const int button_height = button_view_->GetPreferredSize().height(); | |
| 451 const int min_height = kMessageBubbleBaseMinHeight - button_height; | |
| 452 const int max_height = bubble_->max_height() - button_height; | |
| 453 int scroll_height = std::min(std::max( | |
| 454 scroll_size.height(), min_height), max_height); | |
| 455 scroll_size.set_height(scroll_height); | |
| 456 if (scroll_height == min_height) | |
| 457 scroll_content_->set_preferred_size(scroll_size); | |
| 458 else | |
| 459 scroll_content_->set_preferred_size(gfx::Size()); | |
| 460 scroller_->SetFixedSize(scroll_size); | |
| 461 scroller_->SizeToPreferredSize(); | |
| 462 scroll_content_->InvalidateLayout(); | |
| 463 } | |
| 464 | |
| 465 NotificationList::Delegate* list_delegate_; | 463 NotificationList::Delegate* list_delegate_; |
| 466 FixedSizedScrollView* scroller_; | 464 BoundedScrollView* scroller_; |
| 467 ScrollContentView* scroll_content_; | 465 MessagesView* messages_view_; |
| 468 WebNotificationButtonViewBase* button_view_; | 466 WebNotificationButtonViewBase* button_view_; |
| 469 MessageCenterBubble* bubble_; | 467 MessageCenterBubble* bubble_; |
| 470 | 468 |
| 471 DISALLOW_COPY_AND_ASSIGN(MessageCenterContentsView); | 469 DISALLOW_COPY_AND_ASSIGN(MessageCenterView); |
| 472 }; | 470 }; |
| 473 | 471 |
| 474 // Message Center Bubble. | 472 // Message Center Bubble. |
| 475 MessageCenterBubble::MessageCenterBubble(NotificationList::Delegate* delegate) | 473 MessageCenterBubble::MessageCenterBubble(NotificationList::Delegate* delegate) |
| 476 : MessageBubbleBase(delegate), | 474 : MessageBubbleBase(delegate), |
| 477 contents_view_(NULL) { | 475 contents_view_(NULL) { |
| 478 } | 476 } |
| 479 | 477 |
| 480 MessageCenterBubble::~MessageCenterBubble() {} | 478 MessageCenterBubble::~MessageCenterBubble() {} |
| 481 | 479 |
| 482 views::TrayBubbleView::InitParams MessageCenterBubble::GetInitParams( | 480 views::TrayBubbleView::InitParams MessageCenterBubble::GetInitParams( |
| 483 views::TrayBubbleView::AnchorAlignment anchor_alignment) { | 481 views::TrayBubbleView::AnchorAlignment anchor_alignment) { |
| 484 views::TrayBubbleView::InitParams init_params = | 482 views::TrayBubbleView::InitParams init_params = |
| 485 GetDefaultInitParams(anchor_alignment); | 483 GetDefaultInitParams(anchor_alignment); |
| 486 if (IsRichNotificationEnabled()) { | 484 if (IsRichNotificationEnabled()) { |
| 487 init_params.min_width += kMarginBetweenItems * 2; | 485 init_params.min_width += kMarginBetweenItems * 2; |
| 488 init_params.max_width += kMarginBetweenItems * 2; | 486 init_params.max_width += kMarginBetweenItems * 2; |
| 489 } | 487 } |
| 490 init_params.max_height = max_height(); | 488 init_params.max_height = max_height(); |
| 491 init_params.can_activate = true; | 489 init_params.can_activate = true; |
| 492 return init_params; | 490 return init_params; |
| 493 } | 491 } |
| 494 | 492 |
| 495 void MessageCenterBubble::InitializeContents( | 493 void MessageCenterBubble::InitializeContents( |
| 496 views::TrayBubbleView* new_bubble_view) { | 494 views::TrayBubbleView* new_bubble_view) { |
| 497 set_bubble_view(new_bubble_view); | 495 set_bubble_view(new_bubble_view); |
| 498 contents_view_ = new MessageCenterContentsView(this, list_delegate()); | 496 contents_view_ = new MessageCenterView(this, list_delegate()); |
| 499 bubble_view()->AddChildView(contents_view_); | 497 bubble_view()->AddChildView(contents_view_); |
| 500 UpdateBubbleView(); | 498 UpdateBubbleView(); |
| 501 contents_view_->FocusContents(); | 499 contents_view_->FocusContents(); |
| 502 } | 500 } |
| 503 | 501 |
| 504 void MessageCenterBubble::OnBubbleViewDestroyed() { | 502 void MessageCenterBubble::OnBubbleViewDestroyed() { |
| 505 contents_view_ = NULL; | 503 contents_view_ = NULL; |
| 506 } | 504 } |
| 507 | 505 |
| 508 void MessageCenterBubble::UpdateBubbleView() { | 506 void MessageCenterBubble::UpdateBubbleView() { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 519 } | 517 } |
| 520 | 518 |
| 521 void MessageCenterBubble::OnMouseExitedView() { | 519 void MessageCenterBubble::OnMouseExitedView() { |
| 522 } | 520 } |
| 523 | 521 |
| 524 size_t MessageCenterBubble::NumMessageViewsForTest() const { | 522 size_t MessageCenterBubble::NumMessageViewsForTest() const { |
| 525 return contents_view_->NumMessageViews(); | 523 return contents_view_->NumMessageViews(); |
| 526 } | 524 } |
| 527 | 525 |
| 528 } // namespace message_center | 526 } // namespace message_center |
| OLD | NEW |