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(), |
| 391 close_size.width(), |
| 392 close_size.height()); |
| 393 close_button_->SetBoundsRect(close_rect); |
| 394 } |
| 395 |
381 // Icon. | 396 // Icon. |
382 icon_view_->SetBounds(insets.left(), insets.top(), kIconSize, kIconSize); | 397 icon_view_->SetBounds(insets.left(), insets.top(), kIconSize, kIconSize); |
383 | 398 |
384 // Settings & Bottom views. | 399 // Settings & Bottom views. |
385 int bottom_y = insets.top() + std::max(top_height, kIconSize); | 400 int bottom_y = insets.top() + std::max(top_height, kIconSize); |
386 int bottom_height = bottom_view_->GetHeightForWidth(content_width); | 401 int bottom_height = bottom_view_->GetHeightForWidth(content_width); |
387 | 402 |
388 if (settings_button_view_) { | 403 if (settings_button_view_) { |
389 gfx::Size settings_size(settings_button_view_->GetPreferredSize()); | 404 gfx::Size settings_size(settings_button_view_->GetPreferredSize()); |
390 settings_button_view_->SetBounds(content_width - settings_size.width(), | 405 settings_button_view_->SetBounds(content_width - settings_size.width(), |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
438 } | 453 } |
439 | 454 |
440 // See if the button pressed was an action button. | 455 // See if the button pressed was an action button. |
441 for (size_t i = 0; i < action_buttons_.size(); ++i) { | 456 for (size_t i = 0; i < action_buttons_.size(); ++i) { |
442 if (sender == action_buttons_[i]) { | 457 if (sender == action_buttons_[i]) { |
443 controller_->ClickOnNotificationButton(id, i); | 458 controller_->ClickOnNotificationButton(id, i); |
444 return; | 459 return; |
445 } | 460 } |
446 } | 461 } |
447 | 462 |
| 463 if (close_button_ && sender == close_button_.get()) { |
| 464 controller_->RemoveNotification(notification_id(), true); // By user. |
| 465 } |
| 466 |
448 // Let the superclass handle everything else. | 467 // Let the superclass handle everything else. |
449 // Warning: This may cause the NotificationView itself to be deleted, | 468 // Warning: This may cause the NotificationView itself to be deleted, |
450 // so don't do anything afterwards. | 469 // so don't do anything afterwards. |
451 MessageView::ButtonPressed(sender, event); | 470 MessageView::ButtonPressed(sender, event); |
452 } | 471 } |
453 | 472 |
454 void NotificationView::ClickOnNotification(const std::string& notification_id) { | 473 void NotificationView::ClickOnNotification(const std::string& notification_id) { |
455 controller_->ClickOnNotification(notification_id); | 474 controller_->ClickOnNotification(notification_id); |
456 } | 475 } |
457 | 476 |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
765 if (new_buttons) { | 784 if (new_buttons) { |
766 Layout(); | 785 Layout(); |
767 views::Widget* widget = GetWidget(); | 786 views::Widget* widget = GetWidget(); |
768 if (widget != NULL) { | 787 if (widget != NULL) { |
769 widget->SetSize(widget->GetContentsView()->GetPreferredSize()); | 788 widget->SetSize(widget->GetContentsView()->GetPreferredSize()); |
770 GetWidget()->SynthesizeMouseMoveEvent(); | 789 GetWidget()->SynthesizeMouseMoveEvent(); |
771 } | 790 } |
772 } | 791 } |
773 } | 792 } |
774 | 793 |
| 794 void NotificationView::CreateOrUpdateCloseButtonView( |
| 795 const Notification& notification) { |
| 796 set_closable(notification.closable()); |
| 797 |
| 798 if (notification.closable() && !close_button_) { |
| 799 PaddedButton *close = new PaddedButton(this); |
| 800 close->SetPadding(-kCloseIconRightPadding, kCloseIconTopPadding); |
| 801 close->SetNormalImage(IDR_NOTIFICATION_CLOSE); |
| 802 close->SetHoveredImage(IDR_NOTIFICATION_CLOSE_HOVER); |
| 803 close->SetPressedImage(IDR_NOTIFICATION_CLOSE_PRESSED); |
| 804 close->set_animate_on_state_change(false); |
| 805 close->SetAccessibleName(l10n_util::GetStringUTF16( |
| 806 IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_ACCESSIBLE_NAME)); |
| 807 // The close button should be added to view hierarchy by the derived class. |
| 808 // This ensures that it is on top of other views. |
| 809 close->set_owned_by_client(); |
| 810 close_button_.reset(close); |
| 811 AddChildView(close_button_.get()); |
| 812 } else if (!notification.closable() && close_button_) { |
| 813 close_button_.reset(); |
| 814 } |
| 815 } |
| 816 |
775 int NotificationView::GetMessageLineLimit(int title_lines, int width) const { | 817 int NotificationView::GetMessageLineLimit(int title_lines, int width) const { |
776 // Image notifications require that the image must be kept flush against | 818 // Image notifications require that the image must be kept flush against |
777 // their icons, but we can allow more text if no image. | 819 // their icons, but we can allow more text if no image. |
778 int effective_title_lines = std::max(0, title_lines - 1); | 820 int effective_title_lines = std::max(0, title_lines - 1); |
779 int line_reduction_from_title = (image_view_ ? 1 : 2) * effective_title_lines; | 821 int line_reduction_from_title = (image_view_ ? 1 : 2) * effective_title_lines; |
780 if (!image_view_) { | 822 if (!image_view_) { |
781 // Title lines are counted as twice as big as message lines for the purpose | 823 // Title lines are counted as twice as big as message lines for the purpose |
782 // of this calculation. | 824 // of this calculation. |
783 // The effect from the title reduction here should be: | 825 // The effect from the title reduction here should be: |
784 // * 0 title lines: 5 max lines message. | 826 // * 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); | 848 std::max(0, message_line_limit - line_reduction_from_title); |
807 | 849 |
808 return message_line_limit; | 850 return message_line_limit; |
809 } | 851 } |
810 | 852 |
811 int NotificationView::GetMessageHeight(int width, int limit) const { | 853 int NotificationView::GetMessageHeight(int width, int limit) const { |
812 return message_view_ ? | 854 return message_view_ ? |
813 message_view_->GetSizeForWidthAndLines(width, limit).height() : 0; | 855 message_view_->GetSizeForWidthAndLines(width, limit).height() : 0; |
814 } | 856 } |
815 | 857 |
| 858 bool NotificationView::IsCloseButtonFocused() { |
| 859 if (!close_button_) |
| 860 return false; |
| 861 |
| 862 views::FocusManager* focus_manager = GetFocusManager(); |
| 863 return focus_manager && |
| 864 focus_manager->GetFocusedView() == close_button_.get(); |
| 865 } |
| 866 |
| 867 void NotificationView::RequestFocusOnCloseButton() { |
| 868 if (close_button_) |
| 869 close_button_->RequestFocus(); |
| 870 } |
| 871 |
| 872 bool NotificationView::IsClosable() { |
| 873 return close_button_; |
| 874 } |
| 875 |
816 } // namespace message_center | 876 } // namespace message_center |
OLD | NEW |