notification_item_view.cc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/app_menu/notification_item_view.h"
  5. #include "ash/public/cpp/app_menu_constants.h"
  6. #include "ui/compositor/layer.h"
  7. #include "ui/gfx/geometry/size.h"
  8. #include "ui/gfx/image/image.h"
  9. #include "ui/gfx/text_elider.h"
  10. #include "ui/message_center/views/proportional_image_view.h"
  11. #include "ui/views/animation/slide_out_controller.h"
  12. #include "ui/views/background.h"
  13. #include "ui/views/border.h"
  14. #include "ui/views/controls/label.h"
  15. #include "ui/views/controls/menu/menu_config.h"
  16. #include "ui/views/layout/box_layout.h"
  17. namespace ash {
  18. namespace {
  19. // Line height of all text in NotificationItemView in dips.
  20. constexpr int kNotificationItemTextLineHeight = 16;
  21. // Padding of |proportional_icon_view_|.
  22. constexpr int kIconVerticalPadding = 4;
  23. constexpr int kIconHorizontalPadding = 12;
  24. // Stroke width of MenuItemView border in dips, used to prevent
  25. // NotificationItemView from exceeding the width of MenuItemView.
  26. constexpr int kBorderStrokeWidth = 1;
  27. // The size of the icon in NotificationItemView in dips.
  28. constexpr gfx::Size kProportionalIconViewSize(24, 24);
  29. // Text color of NotificationItemView's |message_|.
  30. constexpr SkColor kNotificationMessageTextColor =
  31. SkColorSetARGB(179, 0x5F, 0x63, 0x68);
  32. // Text color of NotificationItemView's |title_|.
  33. constexpr SkColor kNotificationTitleTextColor =
  34. SkColorSetARGB(230, 0x21, 0x23, 0x24);
  35. } // namespace
  36. NotificationItemView::NotificationItemView(
  37. NotificationMenuView::Delegate* delegate,
  38. views::SlideOutControllerDelegate* slide_out_controller_delegate,
  39. const std::u16string& title,
  40. const std::u16string& message,
  41. const ui::ImageModel& icon,
  42. const std::string& notification_id)
  43. : delegate_(delegate),
  44. slide_out_controller_(std::make_unique<views::SlideOutController>(
  45. this,
  46. slide_out_controller_delegate)),
  47. title_(title),
  48. message_(message),
  49. notification_id_(notification_id) {
  50. DCHECK(delegate_);
  51. DCHECK(slide_out_controller_delegate);
  52. // Paint to a new layer so |slide_out_controller_| can control the opacity.
  53. SetPaintToLayer();
  54. layer()->SetFillsBoundsOpaquely(true);
  55. SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR(
  56. kNotificationVerticalPadding, kNotificationHorizontalPadding,
  57. kNotificationVerticalPadding, kIconHorizontalPadding)));
  58. SetBackground(views::CreateSolidBackground(SK_ColorWHITE));
  59. text_container_ = new views::View();
  60. text_container_->SetLayoutManager(std::make_unique<views::BoxLayout>(
  61. views::BoxLayout::Orientation::kVertical));
  62. AddChildView(text_container_);
  63. title_label_ = new views::Label(title_);
  64. title_label_->SetEnabledColor(kNotificationTitleTextColor);
  65. title_label_->SetLineHeight(kNotificationItemTextLineHeight);
  66. title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
  67. text_container_->AddChildView(title_label_);
  68. message_label_ = new views::Label(message_);
  69. message_label_->SetEnabledColor(kNotificationMessageTextColor);
  70. message_label_->SetLineHeight(kNotificationItemTextLineHeight);
  71. message_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
  72. text_container_->AddChildView(message_label_);
  73. proportional_icon_view_ =
  74. new message_center::ProportionalImageView(kProportionalIconViewSize);
  75. AddChildView(proportional_icon_view_);
  76. proportional_icon_view_->SetImage(icon, kProportionalIconViewSize);
  77. }
  78. NotificationItemView::~NotificationItemView() = default;
  79. void NotificationItemView::UpdateContents(const std::u16string& title,
  80. const std::u16string& message,
  81. const ui::ImageModel& icon) {
  82. if (title_ != title) {
  83. title_ = title;
  84. title_label_->SetText(title_);
  85. }
  86. if (message_ != message) {
  87. message_ = message;
  88. message_label_->SetText(message_);
  89. }
  90. proportional_icon_view_->SetImage(icon, kProportionalIconViewSize);
  91. }
  92. gfx::Size NotificationItemView::CalculatePreferredSize() const {
  93. return gfx::Size(views::MenuConfig::instance().touchable_menu_min_width -
  94. kBorderStrokeWidth,
  95. kNotificationItemViewHeight);
  96. }
  97. void NotificationItemView::Layout() {
  98. gfx::Insets insets = GetInsets();
  99. // Enforce |text_container_| width, if necessary the labels will elide as a
  100. // result of |text_container_| being too small to hold the full width of its
  101. // children labels.
  102. const gfx::Size text_container_size(
  103. views::MenuConfig::instance().touchable_menu_min_width -
  104. kNotificationHorizontalPadding - kIconHorizontalPadding * 2 -
  105. kProportionalIconViewSize.width(),
  106. title_label_->GetPreferredSize().height() +
  107. message_label_->GetPreferredSize().height());
  108. text_container_->SetBounds(insets.left(), insets.top(),
  109. text_container_size.width(),
  110. text_container_size.height());
  111. proportional_icon_view_->SetBounds(
  112. width() - insets.right() - kProportionalIconViewSize.width(),
  113. insets.top() + kIconVerticalPadding, kProportionalIconViewSize.width(),
  114. kProportionalIconViewSize.height());
  115. }
  116. bool NotificationItemView::OnMousePressed(const ui::MouseEvent& event) {
  117. return true;
  118. }
  119. bool NotificationItemView::OnMouseDragged(const ui::MouseEvent& event) {
  120. return true;
  121. }
  122. void NotificationItemView::OnMouseReleased(const ui::MouseEvent& event) {
  123. gfx::Point location(event.location());
  124. views::View::ConvertPointToScreen(this, &location);
  125. if (!event.IsOnlyLeftMouseButton() ||
  126. !GetBoundsInScreen().Contains(location)) {
  127. return;
  128. }
  129. delegate_->ActivateNotificationAndClose(notification_id_);
  130. }
  131. void NotificationItemView::OnGestureEvent(ui::GestureEvent* event) {
  132. // Drag gestures are handled by |slide_out_controller_|.
  133. switch (event->type()) {
  134. case ui::ET_GESTURE_TAP:
  135. event->SetHandled();
  136. delegate_->ActivateNotificationAndClose(notification_id_);
  137. return;
  138. default:
  139. return;
  140. }
  141. }
  142. } // namespace ash