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/views/notification_view.h" | 5 #include "ui/message_center/views/notification_view.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 | 52 |
53 #if defined(OS_WIN) | 53 #if defined(OS_WIN) |
54 #include "ui/base/win/shell.h" | 54 #include "ui/base/win/shell.h" |
55 #endif | 55 #endif |
56 | 56 |
57 namespace { | 57 namespace { |
58 | 58 |
59 // Dimensions. | 59 // Dimensions. |
60 const int kProgressBarBottomPadding = 0; | 60 const int kProgressBarBottomPadding = 0; |
61 | 61 |
| 62 const int kCloseIconTopPadding = 5; |
| 63 const int kCloseIconRightPadding = 5; |
| 64 |
62 // static | 65 // static |
63 scoped_ptr<views::Border> MakeEmptyBorder(int top, | 66 scoped_ptr<views::Border> MakeEmptyBorder(int top, |
64 int left, | 67 int left, |
65 int bottom, | 68 int bottom, |
66 int right) { | 69 int right) { |
67 return views::Border::CreateEmptyBorder(top, left, bottom, right); | 70 return views::Border::CreateEmptyBorder(top, left, bottom, right); |
68 } | 71 } |
69 | 72 |
70 // static | 73 // static |
71 scoped_ptr<views::Border> MakeTextBorder(int padding, int top, int bottom) { | 74 scoped_ptr<views::Border> MakeTextBorder(int padding, int top, int bottom) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 // targeting. Using the center point of |rect| preserves this function's | 224 // targeting. Using the center point of |rect| preserves this function's |
222 // expected behavior for the time being. | 225 // expected behavior for the time being. |
223 gfx::Point point = rect.CenterPoint(); | 226 gfx::Point point = rect.CenterPoint(); |
224 | 227 |
225 // Want to return this for underlying views, otherwise GetCursor is not | 228 // Want to return this for underlying views, otherwise GetCursor is not |
226 // called. But buttons are exceptions, they'll have their own event handlings. | 229 // called. But buttons are exceptions, they'll have their own event handlings. |
227 std::vector<views::View*> buttons(action_buttons_.begin(), | 230 std::vector<views::View*> buttons(action_buttons_.begin(), |
228 action_buttons_.end()); | 231 action_buttons_.end()); |
229 if (settings_button_view_) | 232 if (settings_button_view_) |
230 buttons.push_back(settings_button_view_); | 233 buttons.push_back(settings_button_view_); |
231 buttons.push_back(close_button()); | 234 if (close_button_) |
| 235 buttons.push_back(close_button_.get()); |
232 | 236 |
233 for (size_t i = 0; i < buttons.size(); ++i) { | 237 for (size_t i = 0; i < buttons.size(); ++i) { |
234 gfx::Point point_in_child = point; | 238 gfx::Point point_in_child = point; |
235 ConvertPointToTarget(this, buttons[i], &point_in_child); | 239 ConvertPointToTarget(this, buttons[i], &point_in_child); |
236 if (buttons[i]->HitTestPoint(point_in_child)) | 240 if (buttons[i]->HitTestPoint(point_in_child)) |
237 return buttons[i]->GetEventHandlerForPoint(point_in_child); | 241 return buttons[i]->GetEventHandlerForPoint(point_in_child); |
238 } | 242 } |
239 | 243 |
240 return root; | 244 return root; |
241 } | 245 } |
242 | 246 |
243 void NotificationView::CreateOrUpdateViews(const Notification& notification) { | 247 void NotificationView::CreateOrUpdateViews(const Notification& notification) { |
| 248 CreateOrUpdateCloseButtonView(notification); |
244 CreateOrUpdateTitleView(notification); | 249 CreateOrUpdateTitleView(notification); |
245 CreateOrUpdateMessageView(notification); | 250 CreateOrUpdateMessageView(notification); |
246 CreateOrUpdateProgressBarView(notification); | 251 CreateOrUpdateProgressBarView(notification); |
247 CreateOrUpdateListItemViews(notification); | 252 CreateOrUpdateListItemViews(notification); |
248 CreateOrUpdateIconView(notification); | 253 CreateOrUpdateIconView(notification); |
249 CreateOrUpdateImageView(notification); | 254 CreateOrUpdateImageView(notification); |
250 CreateOrUpdateContextMessageView(notification); | 255 CreateOrUpdateContextMessageView(notification); |
251 CreateOrUpdateSettingsButtonView(notification); | 256 CreateOrUpdateSettingsButtonView(notification); |
252 CreateOrUpdateActionButtonViews(notification); | 257 CreateOrUpdateActionButtonViews(notification); |
253 } | 258 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); | 306 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); |
302 AddChildView(bottom_view_); | 307 AddChildView(bottom_view_); |
303 | 308 |
304 CreateOrUpdateViews(notification); | 309 CreateOrUpdateViews(notification); |
305 | 310 |
306 // Put together the different content and control views. Layering those allows | 311 // Put together the different content and control views. Layering those allows |
307 // for proper layout logic and it also allows the close button and small | 312 // for proper layout logic and it also allows the close button and small |
308 // image to overlap the content as needed to provide large enough click and | 313 // image to overlap the content as needed to provide large enough click and |
309 // touch areas (<http://crbug.com/168822> and <http://crbug.com/168856>). | 314 // touch areas (<http://crbug.com/168822> and <http://crbug.com/168856>). |
310 AddChildView(small_image()); | 315 AddChildView(small_image()); |
311 AddChildView(close_button()); | |
312 SetAccessibleName(notification); | 316 SetAccessibleName(notification); |
313 | 317 |
314 SetEventTargeter( | 318 SetEventTargeter( |
315 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); | 319 scoped_ptr<views::ViewTargeter>(new views::ViewTargeter(this))); |
316 } | 320 } |
317 | 321 |
318 NotificationView::~NotificationView() { | 322 NotificationView::~NotificationView() { |
319 } | 323 } |
320 | 324 |
321 gfx::Size NotificationView::GetPreferredSize() const { | 325 gfx::Size NotificationView::GetPreferredSize() const { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 title_lines = | 375 title_lines = |
372 title_view_->GetLinesForWidthAndLimit(width(), kMaxTitleLines); | 376 title_view_->GetLinesForWidthAndLimit(width(), kMaxTitleLines); |
373 } | 377 } |
374 if (message_view_) | 378 if (message_view_) |
375 message_view_->SetLineLimit(GetMessageLineLimit(title_lines, width())); | 379 message_view_->SetLineLimit(GetMessageLineLimit(title_lines, width())); |
376 | 380 |
377 // Top views. | 381 // Top views. |
378 int top_height = top_view_->GetHeightForWidth(content_width); | 382 int top_height = top_view_->GetHeightForWidth(content_width); |
379 top_view_->SetBounds(insets.left(), insets.top(), content_width, top_height); | 383 top_view_->SetBounds(insets.left(), insets.top(), content_width, top_height); |
380 | 384 |
| 385 // Close button. |
| 386 if (close_button_) { |
| 387 gfx::Rect content_bounds = GetContentsBounds(); |
| 388 gfx::Size close_size(close_button_->GetPreferredSize()); |
| 389 gfx::Rect close_rect(content_bounds.right() - close_size.width(), |
| 390 content_bounds.y(), close_size.width(), |
| 391 close_size.height()); |
| 392 close_button_->SetBoundsRect(close_rect); |
| 393 } |
| 394 |
381 // Icon. | 395 // Icon. |
382 icon_view_->SetBounds(insets.left(), insets.top(), kIconSize, kIconSize); | 396 icon_view_->SetBounds(insets.left(), insets.top(), kIconSize, kIconSize); |
383 | 397 |
384 // Settings & Bottom views. | 398 // Settings & Bottom views. |
385 int bottom_y = insets.top() + std::max(top_height, kIconSize); | 399 int bottom_y = insets.top() + std::max(top_height, kIconSize); |
386 int bottom_height = bottom_view_->GetHeightForWidth(content_width); | 400 int bottom_height = bottom_view_->GetHeightForWidth(content_width); |
387 | 401 |
388 if (settings_button_view_) { | 402 if (settings_button_view_) { |
389 gfx::Size settings_size(settings_button_view_->GetPreferredSize()); | 403 gfx::Size settings_size(settings_button_view_->GetPreferredSize()); |
390 settings_button_view_->SetBounds(content_width - settings_size.width(), | 404 settings_button_view_->SetBounds(content_width - settings_size.width(), |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 } | 452 } |
439 | 453 |
440 // See if the button pressed was an action button. | 454 // See if the button pressed was an action button. |
441 for (size_t i = 0; i < action_buttons_.size(); ++i) { | 455 for (size_t i = 0; i < action_buttons_.size(); ++i) { |
442 if (sender == action_buttons_[i]) { | 456 if (sender == action_buttons_[i]) { |
443 controller_->ClickOnNotificationButton(id, i); | 457 controller_->ClickOnNotificationButton(id, i); |
444 return; | 458 return; |
445 } | 459 } |
446 } | 460 } |
447 | 461 |
| 462 if (close_button_ && sender == close_button_.get()) { |
| 463 controller_->RemoveNotification(notification_id(), true); // By user. |
| 464 } |
| 465 |
448 // Let the superclass handle everything else. | 466 // Let the superclass handle everything else. |
449 // Warning: This may cause the NotificationView itself to be deleted, | 467 // Warning: This may cause the NotificationView itself to be deleted, |
450 // so don't do anything afterwards. | 468 // so don't do anything afterwards. |
451 MessageView::ButtonPressed(sender, event); | 469 MessageView::ButtonPressed(sender, event); |
452 } | 470 } |
453 | 471 |
454 void NotificationView::ClickOnNotification(const std::string& notification_id) { | 472 void NotificationView::ClickOnNotification(const std::string& notification_id) { |
455 controller_->ClickOnNotification(notification_id); | 473 controller_->ClickOnNotification(notification_id); |
456 } | 474 } |
457 | 475 |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 if (new_buttons) { | 783 if (new_buttons) { |
766 Layout(); | 784 Layout(); |
767 views::Widget* widget = GetWidget(); | 785 views::Widget* widget = GetWidget(); |
768 if (widget != NULL) { | 786 if (widget != NULL) { |
769 widget->SetSize(widget->GetContentsView()->GetPreferredSize()); | 787 widget->SetSize(widget->GetContentsView()->GetPreferredSize()); |
770 GetWidget()->SynthesizeMouseMoveEvent(); | 788 GetWidget()->SynthesizeMouseMoveEvent(); |
771 } | 789 } |
772 } | 790 } |
773 } | 791 } |
774 | 792 |
| 793 void NotificationView::CreateOrUpdateCloseButtonView( |
| 794 const Notification& notification) { |
| 795 set_slide_out_enabled(!notification.pinned()); |
| 796 |
| 797 if (!notification.pinned() && !close_button_) { |
| 798 PaddedButton* close = new PaddedButton(this); |
| 799 close->SetPadding(-kCloseIconRightPadding, kCloseIconTopPadding); |
| 800 close->SetNormalImage(IDR_NOTIFICATION_CLOSE); |
| 801 close->SetHoveredImage(IDR_NOTIFICATION_CLOSE_HOVER); |
| 802 close->SetPressedImage(IDR_NOTIFICATION_CLOSE_PRESSED); |
| 803 close->set_animate_on_state_change(false); |
| 804 close->SetAccessibleName(l10n_util::GetStringUTF16( |
| 805 IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_ACCESSIBLE_NAME)); |
| 806 // The close button should be added to view hierarchy by the derived class. |
| 807 // This ensures that it is on top of other views. |
| 808 close->set_owned_by_client(); |
| 809 close_button_.reset(close); |
| 810 AddChildView(close_button_.get()); |
| 811 } else if (notification.pinned() && close_button_) { |
| 812 close_button_.reset(); |
| 813 } |
| 814 } |
| 815 |
775 int NotificationView::GetMessageLineLimit(int title_lines, int width) const { | 816 int NotificationView::GetMessageLineLimit(int title_lines, int width) const { |
776 // Image notifications require that the image must be kept flush against | 817 // Image notifications require that the image must be kept flush against |
777 // their icons, but we can allow more text if no image. | 818 // their icons, but we can allow more text if no image. |
778 int effective_title_lines = std::max(0, title_lines - 1); | 819 int effective_title_lines = std::max(0, title_lines - 1); |
779 int line_reduction_from_title = (image_view_ ? 1 : 2) * effective_title_lines; | 820 int line_reduction_from_title = (image_view_ ? 1 : 2) * effective_title_lines; |
780 if (!image_view_) { | 821 if (!image_view_) { |
781 // Title lines are counted as twice as big as message lines for the purpose | 822 // Title lines are counted as twice as big as message lines for the purpose |
782 // of this calculation. | 823 // of this calculation. |
783 // The effect from the title reduction here should be: | 824 // The effect from the title reduction here should be: |
784 // * 0 title lines: 5 max lines message. | 825 // * 0 title lines: 5 max lines message. |
(...skipping 21 matching lines...) Expand all Loading... |
806 std::max(0, message_line_limit - line_reduction_from_title); | 847 std::max(0, message_line_limit - line_reduction_from_title); |
807 | 848 |
808 return message_line_limit; | 849 return message_line_limit; |
809 } | 850 } |
810 | 851 |
811 int NotificationView::GetMessageHeight(int width, int limit) const { | 852 int NotificationView::GetMessageHeight(int width, int limit) const { |
812 return message_view_ ? | 853 return message_view_ ? |
813 message_view_->GetSizeForWidthAndLines(width, limit).height() : 0; | 854 message_view_->GetSizeForWidthAndLines(width, limit).height() : 0; |
814 } | 855 } |
815 | 856 |
| 857 bool NotificationView::IsCloseButtonFocused() { |
| 858 if (!close_button_) |
| 859 return false; |
| 860 |
| 861 views::FocusManager* focus_manager = GetFocusManager(); |
| 862 return focus_manager && |
| 863 focus_manager->GetFocusedView() == close_button_.get(); |
| 864 } |
| 865 |
| 866 void NotificationView::RequestFocusOnCloseButton() { |
| 867 if (close_button_) |
| 868 close_button_->RequestFocus(); |
| 869 } |
| 870 |
| 871 bool NotificationView::IsPinned() { |
| 872 return !close_button_; |
| 873 } |
| 874 |
816 } // namespace message_center | 875 } // namespace message_center |
OLD | NEW |