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

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

Issue 1645843003: Implement Non-Closable Notification (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 10 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
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698