| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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_header_view.h" | 5 #include "ui/message_center/views/notification_header_view.h" |
| 6 | 6 |
| 7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "base/time/time.h" |
| 9 #include "ui/base/l10n/l10n_util.h" | 10 #include "ui/base/l10n/l10n_util.h" |
| 10 #include "ui/gfx/color_palette.h" | 11 #include "ui/gfx/color_palette.h" |
| 11 #include "ui/gfx/font_list.h" | 12 #include "ui/gfx/font_list.h" |
| 12 #include "ui/gfx/paint_vector_icon.h" | 13 #include "ui/gfx/paint_vector_icon.h" |
| 13 #include "ui/message_center/message_center_style.h" | 14 #include "ui/message_center/message_center_style.h" |
| 14 #include "ui/message_center/vector_icons.h" | 15 #include "ui/message_center/vector_icons.h" |
| 15 #include "ui/message_center/views/padded_button.h" | 16 #include "ui/message_center/views/padded_button.h" |
| 16 #include "ui/strings/grit/ui_strings.h" | 17 #include "ui/strings/grit/ui_strings.h" |
| 17 #include "ui/views/animation/flood_fill_ink_drop_ripple.h" | 18 #include "ui/views/animation/flood_fill_ink_drop_ripple.h" |
| 18 #include "ui/views/animation/ink_drop_highlight.h" | 19 #include "ui/views/animation/ink_drop_highlight.h" |
| 19 #include "ui/views/animation/ink_drop_impl.h" | 20 #include "ui/views/animation/ink_drop_impl.h" |
| 20 #include "ui/views/controls/button/image_button.h" | 21 #include "ui/views/controls/button/image_button.h" |
| 21 #include "ui/views/controls/image_view.h" | 22 #include "ui/views/controls/image_view.h" |
| 22 #include "ui/views/controls/label.h" | 23 #include "ui/views/controls/label.h" |
| 23 #include "ui/views/layout/box_layout.h" | 24 #include "ui/views/layout/box_layout.h" |
| 24 #include "ui/views/painter.h" | 25 #include "ui/views/painter.h" |
| 25 | 26 |
| 26 namespace message_center { | 27 namespace message_center { |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 | 30 |
| 30 constexpr int kHeaderHeight = 28; | 31 constexpr int kHeaderHeight = 28; |
| 31 constexpr int kAppIconSize = 12; | 32 constexpr int kAppIconSize = 12; |
| 32 constexpr int kExpandIconSize = 12; | 33 constexpr int kExpandIconSize = 12; |
| 33 constexpr gfx::Insets kHeaderPadding(0, 12, 0, 2); | 34 constexpr gfx::Insets kHeaderPadding(0, 12, 0, 2); |
| 34 constexpr int kHeaderHorizontalSpacing = 2; | 35 constexpr int kHeaderHorizontalSpacing = 2; |
| 35 constexpr int kAppInfoConatainerTopPadding = 12; | 36 constexpr int kAppInfoConatainerTopPadding = 12; |
| 36 // Bullet character. The divider symbol between different parts of the header. | 37 // Bullet character. The divider symbol between different parts of the header. |
| 37 constexpr base::char16 kNotificationHeaderDividerSymbol = 0x2022; | 38 constexpr wchar_t kNotificationHeaderDivider[] = L" \u2022 "; |
| 38 | 39 |
| 39 // Base ink drop color of action buttons. | 40 // Base ink drop color of action buttons. |
| 40 const SkColor kInkDropBaseColor = SkColorSetRGB(0x0, 0x0, 0x0); | 41 const SkColor kInkDropBaseColor = SkColorSetRGB(0x0, 0x0, 0x0); |
| 41 // Ripple ink drop opacity of action buttons. | 42 // Ripple ink drop opacity of action buttons. |
| 42 constexpr float kInkDropRippleVisibleOpacity = 0.08f; | 43 constexpr float kInkDropRippleVisibleOpacity = 0.08f; |
| 43 // Highlight (hover) ink drop opacity of action buttons. | 44 // Highlight (hover) ink drop opacity of action buttons. |
| 44 constexpr float kInkDropHighlightVisibleOpacity = 0.08f; | 45 constexpr float kInkDropHighlightVisibleOpacity = 0.08f; |
| 45 | 46 |
| 47 // base::TimeBase has similar constants, but some of them are missing. |
| 48 constexpr int64_t kMinuteInMillis = 60LL * 1000LL; |
| 49 constexpr int64_t kHourInMillis = 60LL * kMinuteInMillis; |
| 50 constexpr int64_t kDayInMillis = 24LL * kHourInMillis; |
| 51 // In Android, DateUtils.YEAR_IN_MILLIS is 364 days. |
| 52 constexpr int64_t kYearInMillis = 364LL * kDayInMillis; |
| 53 |
| 46 // ExpandButtton forwards all mouse and key events to NotificationHeaderView, | 54 // ExpandButtton forwards all mouse and key events to NotificationHeaderView, |
| 47 // but takes tab focus for accessibility purpose. | 55 // but takes tab focus for accessibility purpose. |
| 48 class ExpandButton : public views::ImageView { | 56 class ExpandButton : public views::ImageView { |
| 49 public: | 57 public: |
| 50 ExpandButton(); | 58 ExpandButton(); |
| 51 ~ExpandButton() override; | 59 ~ExpandButton() override; |
| 52 | 60 |
| 53 void OnPaint(gfx::Canvas* canvas) override; | 61 void OnPaint(gfx::Canvas* canvas) override; |
| 54 void OnFocus() override; | 62 void OnFocus() override; |
| 55 void OnBlur() override; | 63 void OnBlur() override; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 76 void ExpandButton::OnFocus() { | 84 void ExpandButton::OnFocus() { |
| 77 views::ImageView::OnFocus(); | 85 views::ImageView::OnFocus(); |
| 78 SchedulePaint(); | 86 SchedulePaint(); |
| 79 } | 87 } |
| 80 | 88 |
| 81 void ExpandButton::OnBlur() { | 89 void ExpandButton::OnBlur() { |
| 82 views::ImageView::OnBlur(); | 90 views::ImageView::OnBlur(); |
| 83 SchedulePaint(); | 91 SchedulePaint(); |
| 84 } | 92 } |
| 85 | 93 |
| 94 // Do relative time string formatting that is similar to |
| 95 // com.java.android.widget.DateTimeView.updateRelativeTime. |
| 96 // Chromium has its own base::TimeFormat::Simple(), but none of the formats |
| 97 // supported by the function is similar to Android's one. |
| 98 base::string16 FormatToRelativeTime(base::Time past) { |
| 99 base::Time now = base::Time::Now(); |
| 100 int64_t duration = (now - past).InMilliseconds(); |
| 101 if (duration < kMinuteInMillis) { |
| 102 return l10n_util::GetStringUTF16( |
| 103 IDS_MESSAGE_NOTIFICATION_NOW_STRING_SHORTEST); |
| 104 } else if (duration < kHourInMillis) { |
| 105 int count = static_cast<int>(duration / kMinuteInMillis); |
| 106 return l10n_util::GetPluralStringFUTF16( |
| 107 IDS_MESSAGE_NOTIFICATION_DURATION_MINUTES_SHORTEST, count); |
| 108 } else if (duration < kDayInMillis) { |
| 109 int count = static_cast<int>(duration / kHourInMillis); |
| 110 return l10n_util::GetPluralStringFUTF16( |
| 111 IDS_MESSAGE_NOTIFICATION_DURATION_HOURS_SHORTEST, count); |
| 112 } else if (duration < kYearInMillis) { |
| 113 int count = static_cast<int>(duration / kDayInMillis); |
| 114 return l10n_util::GetPluralStringFUTF16( |
| 115 IDS_MESSAGE_NOTIFICATION_DURATION_DAYS_SHORTEST, count); |
| 116 } else { |
| 117 int count = static_cast<int>(duration / kYearInMillis); |
| 118 return l10n_util::GetPluralStringFUTF16( |
| 119 IDS_MESSAGE_NOTIFICATION_DURATION_YEARS_SHORTEST, count); |
| 120 } |
| 121 } |
| 122 |
| 86 } // namespace | 123 } // namespace |
| 87 | 124 |
| 88 NotificationHeaderView::NotificationHeaderView(views::ButtonListener* listener) | 125 NotificationHeaderView::NotificationHeaderView(views::ButtonListener* listener) |
| 89 : views::CustomButton(listener) { | 126 : views::CustomButton(listener) { |
| 90 SetInkDropMode(InkDropMode::ON); | 127 SetInkDropMode(InkDropMode::ON); |
| 91 set_has_ink_drop_action_on_click(true); | 128 set_has_ink_drop_action_on_click(true); |
| 92 set_animate_on_state_change(true); | 129 set_animate_on_state_change(true); |
| 93 set_notify_enter_exit_on_child(true); | 130 set_notify_enter_exit_on_child(true); |
| 94 set_ink_drop_base_color(kInkDropBaseColor); | 131 set_ink_drop_base_color(kInkDropBaseColor); |
| 95 set_ink_drop_visible_opacity(kInkDropRippleVisibleOpacity); | 132 set_ink_drop_visible_opacity(kInkDropRippleVisibleOpacity); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 118 // App name view | 155 // App name view |
| 119 const gfx::FontList& font_list = views::Label().font_list().Derive( | 156 const gfx::FontList& font_list = views::Label().font_list().Derive( |
| 120 -2, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL); | 157 -2, gfx::Font::NORMAL, gfx::Font::Weight::NORMAL); |
| 121 app_name_view_ = new views::Label(base::string16()); | 158 app_name_view_ = new views::Label(base::string16()); |
| 122 app_name_view_->SetFontList(font_list); | 159 app_name_view_->SetFontList(font_list); |
| 123 app_name_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 160 app_name_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 124 app_info_container->AddChildView(app_name_view_); | 161 app_info_container->AddChildView(app_name_view_); |
| 125 | 162 |
| 126 // Summary text divider | 163 // Summary text divider |
| 127 summary_text_divider_ = | 164 summary_text_divider_ = |
| 128 new views::Label(base::ASCIIToUTF16(" ") + | 165 new views::Label(base::WideToUTF16(kNotificationHeaderDivider)); |
| 129 base::string16(1, kNotificationHeaderDividerSymbol) + | |
| 130 base::ASCIIToUTF16(" ")); | |
| 131 summary_text_divider_->SetFontList(font_list); | 166 summary_text_divider_->SetFontList(font_list); |
| 132 summary_text_divider_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 167 summary_text_divider_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 133 summary_text_divider_->SetVisible(false); | 168 summary_text_divider_->SetVisible(false); |
| 134 app_info_container->AddChildView(summary_text_divider_); | 169 app_info_container->AddChildView(summary_text_divider_); |
| 135 | 170 |
| 136 // Summary text view | 171 // Summary text view |
| 137 summary_text_view_ = new views::Label(base::string16()); | 172 summary_text_view_ = new views::Label(base::string16()); |
| 138 summary_text_view_->SetFontList(font_list); | 173 summary_text_view_->SetFontList(font_list); |
| 139 summary_text_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 174 summary_text_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 140 summary_text_view_->SetVisible(false); | 175 summary_text_view_->SetVisible(false); |
| 141 app_info_container->AddChildView(summary_text_view_); | 176 app_info_container->AddChildView(summary_text_view_); |
| 142 | 177 |
| 178 // Timestamp divider |
| 179 timestamp_divider_ = |
| 180 new views::Label(base::WideToUTF16(kNotificationHeaderDivider)); |
| 181 timestamp_divider_->SetFontList(font_list); |
| 182 timestamp_divider_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 183 timestamp_divider_->SetVisible(false); |
| 184 app_info_container->AddChildView(timestamp_divider_); |
| 185 |
| 186 // Timestamp view |
| 187 timestamp_view_ = new views::Label(base::string16()); |
| 188 timestamp_view_->SetFontList(font_list); |
| 189 timestamp_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 190 timestamp_view_->SetVisible(false); |
| 191 app_info_container->AddChildView(timestamp_view_); |
| 192 |
| 143 // Expand button view | 193 // Expand button view |
| 144 expand_button_ = new ExpandButton(); | 194 expand_button_ = new ExpandButton(); |
| 145 app_info_container->AddChildView(expand_button_); | 195 app_info_container->AddChildView(expand_button_); |
| 146 | 196 |
| 147 // Spacer between left-aligned views and right-aligned views | 197 // Spacer between left-aligned views and right-aligned views |
| 148 views::View* spacer = new views::View; | 198 views::View* spacer = new views::View; |
| 149 spacer->SetPreferredSize(gfx::Size(1, kHeaderHeight)); | 199 spacer->SetPreferredSize(gfx::Size(1, kHeaderHeight)); |
| 150 AddChildView(spacer); | 200 AddChildView(spacer); |
| 151 layout->SetFlexForView(spacer, 1); | 201 layout->SetFlexForView(spacer, 1); |
| 152 | 202 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 has_overflow_indicator_ = false; | 248 has_overflow_indicator_ = false; |
| 199 } | 249 } |
| 200 UpdateSummaryTextVisibility(); | 250 UpdateSummaryTextVisibility(); |
| 201 } | 251 } |
| 202 | 252 |
| 203 void NotificationHeaderView::ClearOverflowIndicator() { | 253 void NotificationHeaderView::ClearOverflowIndicator() { |
| 204 has_overflow_indicator_ = false; | 254 has_overflow_indicator_ = false; |
| 205 UpdateSummaryTextVisibility(); | 255 UpdateSummaryTextVisibility(); |
| 206 } | 256 } |
| 207 | 257 |
| 258 void NotificationHeaderView::SetTimestamp(base::Time past) { |
| 259 timestamp_view_->SetText(FormatToRelativeTime(past)); |
| 260 has_timestamp_ = true; |
| 261 UpdateSummaryTextVisibility(); |
| 262 } |
| 263 |
| 264 void NotificationHeaderView::ClearTimestamp() { |
| 265 has_timestamp_ = false; |
| 266 UpdateSummaryTextVisibility(); |
| 267 } |
| 268 |
| 208 void NotificationHeaderView::SetExpandButtonEnabled(bool enabled) { | 269 void NotificationHeaderView::SetExpandButtonEnabled(bool enabled) { |
| 209 // SetInkDropMode iff. the visibility changed. | 270 // SetInkDropMode iff. the visibility changed. |
| 210 // Otherwise, the ink drop animation cannot finish. | 271 // Otherwise, the ink drop animation cannot finish. |
| 211 if (expand_button_->visible() != enabled) | 272 if (expand_button_->visible() != enabled) |
| 212 SetInkDropMode(enabled ? InkDropMode::ON : InkDropMode::OFF); | 273 SetInkDropMode(enabled ? InkDropMode::ON : InkDropMode::OFF); |
| 213 | 274 |
| 214 expand_button_->SetVisible(enabled); | 275 expand_button_->SetVisible(enabled); |
| 215 } | 276 } |
| 216 | 277 |
| 217 void NotificationHeaderView::SetExpanded(bool expanded) { | 278 void NotificationHeaderView::SetExpanded(bool expanded) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 is_control_buttons_visible_); | 344 is_control_buttons_visible_); |
| 284 close_button_->SetVisible(close_button_enabled_ && | 345 close_button_->SetVisible(close_button_enabled_ && |
| 285 is_control_buttons_visible_); | 346 is_control_buttons_visible_); |
| 286 Layout(); | 347 Layout(); |
| 287 } | 348 } |
| 288 | 349 |
| 289 void NotificationHeaderView::UpdateSummaryTextVisibility() { | 350 void NotificationHeaderView::UpdateSummaryTextVisibility() { |
| 290 const bool visible = has_progress_ || has_overflow_indicator_; | 351 const bool visible = has_progress_ || has_overflow_indicator_; |
| 291 summary_text_divider_->SetVisible(visible); | 352 summary_text_divider_->SetVisible(visible); |
| 292 summary_text_view_->SetVisible(visible); | 353 summary_text_view_->SetVisible(visible); |
| 354 timestamp_divider_->SetVisible(!has_progress_ && has_timestamp_); |
| 355 timestamp_view_->SetVisible(!has_progress_ && has_timestamp_); |
| 293 Layout(); | 356 Layout(); |
| 294 } | 357 } |
| 295 | 358 |
| 296 } // namespace message_center | 359 } // namespace message_center |
| OLD | NEW |