OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/arc/notification/arc_custom_notification_view.h" | 5 #include "ui/arc/notification/arc_custom_notification_view.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "components/exo/notification_surface.h" | 9 #include "components/exo/notification_surface.h" |
10 #include "components/exo/surface.h" | 10 #include "components/exo/surface.h" |
11 #include "third_party/skia/include/core/SkColor.h" | 11 #include "third_party/skia/include/core/SkColor.h" |
12 #include "ui/base/l10n/l10n_util.h" | 12 #include "ui/base/l10n/l10n_util.h" |
13 #include "ui/base/resource/resource_bundle.h" | 13 #include "ui/base/resource/resource_bundle.h" |
14 #include "ui/compositor/layer_animation_observer.h" | 14 #include "ui/compositor/layer_animation_observer.h" |
15 #include "ui/display/screen.h" | 15 #include "ui/display/screen.h" |
16 #include "ui/events/event_handler.h" | 16 #include "ui/events/event_handler.h" |
17 #include "ui/gfx/canvas.h" | 17 #include "ui/gfx/canvas.h" |
18 #include "ui/gfx/image/image_skia.h" | 18 #include "ui/gfx/image/image_skia.h" |
19 #include "ui/gfx/transform.h" | 19 #include "ui/gfx/transform.h" |
20 #include "ui/message_center/message_center_style.h" | 20 #include "ui/message_center/message_center_style.h" |
21 #include "ui/message_center/views/custom_notification_view.h" | 21 #include "ui/message_center/views/custom_notification_view.h" |
22 #include "ui/resources/grit/ui_resources.h" | 22 #include "ui/resources/grit/ui_resources.h" |
23 #include "ui/strings/grit/ui_strings.h" | 23 #include "ui/strings/grit/ui_strings.h" |
24 #include "ui/views/background.h" | 24 #include "ui/views/background.h" |
25 #include "ui/views/border.h" | 25 #include "ui/views/border.h" |
26 #include "ui/views/controls/button/image_button.h" | 26 #include "ui/views/controls/button/image_button.h" |
| 27 #include "ui/views/focus/focus_manager.h" |
27 #include "ui/views/painter.h" | 28 #include "ui/views/painter.h" |
| 29 #include "ui/views/widget/root_view.h" |
28 #include "ui/views/widget/widget.h" | 30 #include "ui/views/widget/widget.h" |
29 #include "ui/wm/core/window_util.h" | 31 #include "ui/wm/core/window_util.h" |
30 | 32 |
31 namespace arc { | 33 namespace arc { |
32 | 34 |
33 class ArcCustomNotificationView::EventForwarder : public ui::EventHandler { | 35 class ArcCustomNotificationView::EventForwarder : public ui::EventHandler { |
34 public: | 36 public: |
35 explicit EventForwarder(ArcCustomNotificationView* owner) : owner_(owner) {} | 37 explicit EventForwarder(ArcCustomNotificationView* owner) : owner_(owner) {} |
36 ~EventForwarder() override = default; | 38 ~EventForwarder() override = default; |
37 | 39 |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 bool IsPinned() const override { | 170 bool IsPinned() const override { |
169 return owner_->floating_close_button_ == nullptr; | 171 return owner_->floating_close_button_ == nullptr; |
170 } | 172 } |
171 | 173 |
172 private: | 174 private: |
173 ArcCustomNotificationView* const owner_; | 175 ArcCustomNotificationView* const owner_; |
174 | 176 |
175 DISALLOW_COPY_AND_ASSIGN(ContentViewDelegate); | 177 DISALLOW_COPY_AND_ASSIGN(ContentViewDelegate); |
176 }; | 178 }; |
177 | 179 |
| 180 class ArcCustomNotificationView::CloseButton : public views::ImageButton { |
| 181 public: |
| 182 explicit CloseButton(ArcCustomNotificationView* owner) |
| 183 : views::ImageButton(owner), owner_(owner) { |
| 184 set_background( |
| 185 views::Background::CreateSolidBackground(SK_ColorTRANSPARENT)); |
| 186 SetFocusForPlatform(); |
| 187 SetFocusPainter(views::Painter::CreateSolidFocusPainter( |
| 188 message_center::kFocusBorderColor, gfx::Insets(1, 2, 2, 2))); |
| 189 |
| 190 // The sizes below are in DIPs. |
| 191 constexpr int kPaddingFromBorder = 4; |
| 192 constexpr int kImageSize = 16; |
| 193 constexpr int kTouchExtendedPadding = |
| 194 message_center::kControlButtonSize - kImageSize - kPaddingFromBorder; |
| 195 SetBorder( |
| 196 views::CreateEmptyBorder(kPaddingFromBorder, kTouchExtendedPadding, |
| 197 kTouchExtendedPadding, kPaddingFromBorder)); |
| 198 |
| 199 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 200 SetImage(views::CustomButton::STATE_NORMAL, |
| 201 rb.GetImageSkiaNamed(IDR_ARC_NOTIFICATION_CLOSE)); |
| 202 set_animate_on_state_change(false); |
| 203 SetAccessibleName(l10n_util::GetStringUTF16( |
| 204 IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_ACCESSIBLE_NAME)); |
| 205 SetTooltipText(l10n_util::GetStringUTF16( |
| 206 IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_TOOLTIP)); |
| 207 } |
| 208 |
| 209 void OnFocus() override { |
| 210 views::ImageButton::OnFocus(); |
| 211 owner_->UpdateCloseButtonVisiblity(); |
| 212 } |
| 213 |
| 214 void OnBlur() override { |
| 215 views::ImageButton::OnBlur(); |
| 216 owner_->UpdateCloseButtonVisiblity(); |
| 217 } |
| 218 |
| 219 private: |
| 220 ArcCustomNotificationView* const owner_; |
| 221 }; |
| 222 |
178 ArcCustomNotificationView::ArcCustomNotificationView( | 223 ArcCustomNotificationView::ArcCustomNotificationView( |
179 ArcCustomNotificationItem* item) | 224 ArcCustomNotificationItem* item) |
180 : item_(item), | 225 : item_(item), |
181 notification_key_(item->notification_key()), | 226 notification_key_(item->notification_key()), |
182 event_forwarder_(new EventForwarder(this)) { | 227 event_forwarder_(new EventForwarder(this)) { |
183 SetFocusBehavior(FocusBehavior::ALWAYS); | 228 SetFocusBehavior(FocusBehavior::ALWAYS); |
184 | 229 |
185 item_->IncrementWindowRefCount(); | 230 item_->IncrementWindowRefCount(); |
186 item_->AddObserver(this); | 231 item_->AddObserver(this); |
187 | 232 |
(...skipping 21 matching lines...) Expand all Loading... |
209 | 254 |
210 std::unique_ptr<message_center::CustomNotificationContentViewDelegate> | 255 std::unique_ptr<message_center::CustomNotificationContentViewDelegate> |
211 ArcCustomNotificationView::CreateContentViewDelegate() { | 256 ArcCustomNotificationView::CreateContentViewDelegate() { |
212 return base::MakeUnique<ArcCustomNotificationView::ContentViewDelegate>(this); | 257 return base::MakeUnique<ArcCustomNotificationView::ContentViewDelegate>(this); |
213 } | 258 } |
214 | 259 |
215 void ArcCustomNotificationView::CreateFloatingCloseButton() { | 260 void ArcCustomNotificationView::CreateFloatingCloseButton() { |
216 if (!surface_) | 261 if (!surface_) |
217 return; | 262 return; |
218 | 263 |
219 // TODO(yhanada): Make the close button get focus after the entire | 264 floating_close_button_ = new CloseButton(this); |
220 // notification | |
221 floating_close_button_ = new views::ImageButton(this); | |
222 floating_close_button_->set_background( | |
223 views::Background::CreateSolidBackground(SK_ColorTRANSPARENT)); | |
224 floating_close_button_->SetFocusForPlatform(); | |
225 floating_close_button_->SetFocusPainter( | |
226 views::Painter::CreateSolidFocusPainter(message_center::kFocusBorderColor, | |
227 gfx::Insets(1, 2, 2, 2))); | |
228 | |
229 // The sizes below are in DIPs. | |
230 constexpr int kPaddingFromBorder = 4; | |
231 constexpr int kImageSize = 16; | |
232 constexpr int kTouchExtendedPadding = | |
233 message_center::kControlButtonSize - kImageSize - kPaddingFromBorder; | |
234 floating_close_button_->SetBorder( | |
235 views::CreateEmptyBorder(kPaddingFromBorder, kTouchExtendedPadding, | |
236 kTouchExtendedPadding, kPaddingFromBorder)); | |
237 | |
238 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
239 floating_close_button_->SetImage( | |
240 views::CustomButton::STATE_NORMAL, | |
241 rb.GetImageSkiaNamed(IDR_ARC_NOTIFICATION_CLOSE)); | |
242 floating_close_button_->set_animate_on_state_change(false); | |
243 floating_close_button_->SetAccessibleName(l10n_util::GetStringUTF16( | |
244 IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_ACCESSIBLE_NAME)); | |
245 floating_close_button_->SetTooltipText(l10n_util::GetStringUTF16( | |
246 IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_TOOLTIP)); | |
247 | 265 |
248 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); | 266 views::Widget::InitParams params(views::Widget::InitParams::TYPE_CONTROL); |
249 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; | 267 params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; |
250 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 268 params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
251 params.parent = surface_->window(); | 269 params.parent = surface_->window(); |
252 | 270 |
253 floating_close_button_widget_.reset(new views::Widget); | 271 floating_close_button_widget_.reset(new views::Widget); |
254 floating_close_button_widget_->Init(params); | 272 floating_close_button_widget_->Init(params); |
255 floating_close_button_widget_->SetContentsView(floating_close_button_); | 273 floating_close_button_widget_->SetContentsView(floating_close_button_); |
256 | 274 |
| 275 // Put the close button into the focus chain. |
| 276 floating_close_button_widget_->SetFocusTraversableParent( |
| 277 GetWidget()->GetFocusTraversable()); |
| 278 floating_close_button_widget_->SetFocusTraversableParentView(this); |
| 279 |
257 Layout(); | 280 Layout(); |
258 } | 281 } |
259 | 282 |
260 void ArcCustomNotificationView::SetSurface(exo::NotificationSurface* surface) { | 283 void ArcCustomNotificationView::SetSurface(exo::NotificationSurface* surface) { |
261 if (surface_ == surface) | 284 if (surface_ == surface) |
262 return; | 285 return; |
263 | 286 |
264 // Reset |floating_close_button_widget_| when |surface_| is changed. | 287 // Reset |floating_close_button_widget_| when |surface_| is changed. |
265 floating_close_button_widget_.reset(); | 288 floating_close_button_widget_.reset(); |
266 | 289 |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 static_cast<message_center::CustomNotificationView*>(parent()) | 474 static_cast<message_center::CustomNotificationView*>(parent()) |
452 ->OnContentFocused(); | 475 ->OnContentFocused(); |
453 } | 476 } |
454 | 477 |
455 void ArcCustomNotificationView::OnBlur() { | 478 void ArcCustomNotificationView::OnBlur() { |
456 NativeViewHost::OnBlur(); | 479 NativeViewHost::OnBlur(); |
457 static_cast<message_center::CustomNotificationView*>(parent()) | 480 static_cast<message_center::CustomNotificationView*>(parent()) |
458 ->OnContentBlured(); | 481 ->OnContentBlured(); |
459 } | 482 } |
460 | 483 |
| 484 views::FocusTraversable* ArcCustomNotificationView::GetFocusTraversable() { |
| 485 if (floating_close_button_widget_) |
| 486 return static_cast<views::internal::RootView*>( |
| 487 floating_close_button_widget_->GetRootView()); |
| 488 return nullptr; |
| 489 } |
| 490 |
461 void ArcCustomNotificationView::ButtonPressed(views::Button* sender, | 491 void ArcCustomNotificationView::ButtonPressed(views::Button* sender, |
462 const ui::Event& event) { | 492 const ui::Event& event) { |
463 if (item_ && !item_->pinned() && sender == floating_close_button_) { | 493 if (item_ && !item_->pinned() && sender == floating_close_button_) { |
464 item_->CloseFromCloseButton(); | 494 item_->CloseFromCloseButton(); |
465 } | 495 } |
466 } | 496 } |
467 | 497 |
468 void ArcCustomNotificationView::OnWindowBoundsChanged( | 498 void ArcCustomNotificationView::OnWindowBoundsChanged( |
469 aura::Window* window, | 499 aura::Window* window, |
470 const gfx::Rect& old_bounds, | 500 const gfx::Rect& old_bounds, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 | 534 |
505 void ArcCustomNotificationView::OnNotificationSurfaceRemoved( | 535 void ArcCustomNotificationView::OnNotificationSurfaceRemoved( |
506 exo::NotificationSurface* surface) { | 536 exo::NotificationSurface* surface) { |
507 if (surface->notification_id() != notification_key_) | 537 if (surface->notification_id() != notification_key_) |
508 return; | 538 return; |
509 | 539 |
510 SetSurface(nullptr); | 540 SetSurface(nullptr); |
511 } | 541 } |
512 | 542 |
513 } // namespace arc | 543 } // namespace arc |
OLD | NEW |