| 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 "components/exo/notification_surface.h" | 8 #include "components/exo/notification_surface.h" |
| 9 #include "components/exo/surface.h" | 9 #include "components/exo/surface.h" |
| 10 #include "third_party/skia/include/core/SkColor.h" | 10 #include "third_party/skia/include/core/SkColor.h" |
| 11 #include "ui/base/l10n/l10n_util.h" | 11 #include "ui/base/l10n/l10n_util.h" |
| 12 #include "ui/base/resource/resource_bundle.h" | 12 #include "ui/base/resource/resource_bundle.h" |
| 13 #include "ui/compositor/layer_animation_observer.h" | 13 #include "ui/compositor/layer_animation_observer.h" |
| 14 #include "ui/display/screen.h" | 14 #include "ui/display/screen.h" |
| 15 #include "ui/events/event_handler.h" | 15 #include "ui/events/event_handler.h" |
| 16 #include "ui/gfx/canvas.h" |
| 17 #include "ui/gfx/image/image_skia.h" |
| 16 #include "ui/gfx/transform.h" | 18 #include "ui/gfx/transform.h" |
| 17 #include "ui/message_center/message_center_style.h" | 19 #include "ui/message_center/message_center_style.h" |
| 18 #include "ui/resources/grit/ui_resources.h" | 20 #include "ui/resources/grit/ui_resources.h" |
| 19 #include "ui/strings/grit/ui_strings.h" | 21 #include "ui/strings/grit/ui_strings.h" |
| 20 #include "ui/views/background.h" | 22 #include "ui/views/background.h" |
| 21 #include "ui/views/border.h" | 23 #include "ui/views/border.h" |
| 22 #include "ui/views/controls/button/image_button.h" | 24 #include "ui/views/controls/button/image_button.h" |
| 23 #include "ui/views/widget/widget.h" | 25 #include "ui/views/widget/widget.h" |
| 24 #include "ui/wm/core/window_util.h" | 26 #include "ui/wm/core/window_util.h" |
| 25 | 27 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq) override {} | 136 void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq) override {} |
| 135 | 137 |
| 136 ArcCustomNotificationView* const owner_; | 138 ArcCustomNotificationView* const owner_; |
| 137 bool sliding_ = false; | 139 bool sliding_ = false; |
| 138 std::unique_ptr<ui::LayerTreeOwner> surface_copy_; | 140 std::unique_ptr<ui::LayerTreeOwner> surface_copy_; |
| 139 | 141 |
| 140 DISALLOW_COPY_AND_ASSIGN(SlideHelper); | 142 DISALLOW_COPY_AND_ASSIGN(SlideHelper); |
| 141 }; | 143 }; |
| 142 | 144 |
| 143 ArcCustomNotificationView::ArcCustomNotificationView( | 145 ArcCustomNotificationView::ArcCustomNotificationView( |
| 144 ArcCustomNotificationItem* item, | 146 ArcCustomNotificationItem* item) |
| 145 exo::NotificationSurface* surface) | 147 : item_(item), |
| 146 : item_(item), event_forwarder_(new EventForwarder(this)) { | 148 notification_key_(item->notification_key()), |
| 147 SetSurface(surface); | 149 event_forwarder_(new EventForwarder(this)) { |
| 150 item_->IncrementWindowRefCount(); |
| 148 item_->AddObserver(this); | 151 item_->AddObserver(this); |
| 149 OnItemPinnedChanged(); | 152 |
| 153 ArcNotificationSurfaceManager::Get()->AddObserver(this); |
| 154 exo::NotificationSurface* surface = |
| 155 ArcNotificationSurfaceManager::Get()->GetSurface(notification_key_); |
| 156 if (surface) |
| 157 OnNotificationSurfaceAdded(surface); |
| 150 | 158 |
| 151 // Create a layer as an anchor to insert surface copy during a slide. | 159 // Create a layer as an anchor to insert surface copy during a slide. |
| 152 SetPaintToLayer(true); | 160 SetPaintToLayer(true); |
| 161 UpdatePreferredSize(); |
| 153 } | 162 } |
| 154 | 163 |
| 155 ArcCustomNotificationView::~ArcCustomNotificationView() { | 164 ArcCustomNotificationView::~ArcCustomNotificationView() { |
| 156 SetSurface(nullptr); | 165 SetSurface(nullptr); |
| 157 if (item_) | 166 if (item_) { |
| 167 item_->DecrementWindowRefCount(); |
| 158 item_->RemoveObserver(this); | 168 item_->RemoveObserver(this); |
| 169 } |
| 170 |
| 171 if (ArcNotificationSurfaceManager::Get()) |
| 172 ArcNotificationSurfaceManager::Get()->RemoveObserver(this); |
| 159 } | 173 } |
| 160 | 174 |
| 161 void ArcCustomNotificationView::CreateFloatingCloseButton() { | 175 void ArcCustomNotificationView::CreateFloatingCloseButton() { |
| 176 if (!surface_) |
| 177 return; |
| 178 |
| 162 floating_close_button_ = new views::ImageButton(this); | 179 floating_close_button_ = new views::ImageButton(this); |
| 163 floating_close_button_->set_background( | 180 floating_close_button_->set_background( |
| 164 views::Background::CreateSolidBackground(SK_ColorTRANSPARENT)); | 181 views::Background::CreateSolidBackground(SK_ColorTRANSPARENT)); |
| 165 | 182 |
| 166 // The sizes below are in DIPs. | 183 // The sizes below are in DIPs. |
| 167 constexpr int kPaddingFromBorder = 4; | 184 constexpr int kPaddingFromBorder = 4; |
| 168 constexpr int kImageSize = 16; | 185 constexpr int kImageSize = 16; |
| 169 constexpr int kTouchExtendedPadding = | 186 constexpr int kTouchExtendedPadding = |
| 170 message_center::kControlButtonSize - kImageSize - kPaddingFromBorder; | 187 message_center::kControlButtonSize - kImageSize - kPaddingFromBorder; |
| 171 floating_close_button_->SetBorder(views::Border::CreateEmptyBorder( | 188 floating_close_button_->SetBorder(views::Border::CreateEmptyBorder( |
| (...skipping 27 matching lines...) Expand all Loading... |
| 199 if (surface_ && surface_->window()) { | 216 if (surface_ && surface_->window()) { |
| 200 surface_->window()->RemoveObserver(this); | 217 surface_->window()->RemoveObserver(this); |
| 201 surface_->window()->RemovePreTargetHandler(event_forwarder_.get()); | 218 surface_->window()->RemovePreTargetHandler(event_forwarder_.get()); |
| 202 } | 219 } |
| 203 | 220 |
| 204 surface_ = surface; | 221 surface_ = surface; |
| 205 | 222 |
| 206 if (surface_ && surface_->window()) { | 223 if (surface_ && surface_->window()) { |
| 207 surface_->window()->AddObserver(this); | 224 surface_->window()->AddObserver(this); |
| 208 surface_->window()->AddPreTargetHandler(event_forwarder_.get()); | 225 surface_->window()->AddPreTargetHandler(event_forwarder_.get()); |
| 226 |
| 227 if (GetWidget()) |
| 228 AttachSurface(); |
| 229 |
| 230 UpdatePinnedState(); |
| 209 } | 231 } |
| 210 } | 232 } |
| 211 | 233 |
| 212 void ArcCustomNotificationView::UpdatePreferredSize() { | 234 void ArcCustomNotificationView::UpdatePreferredSize() { |
| 213 gfx::Size preferred_size = surface_->GetSize(); | 235 gfx::Size preferred_size = |
| 236 surface_ ? surface_->GetSize() : item_ ? item_->snapshot().size() |
| 237 : gfx::Size(); |
| 238 if (preferred_size.IsEmpty()) |
| 239 return; |
| 240 |
| 214 if (preferred_size.width() != message_center::kNotificationWidth) { | 241 if (preferred_size.width() != message_center::kNotificationWidth) { |
| 215 const float scale = static_cast<float>(message_center::kNotificationWidth) / | 242 const float scale = static_cast<float>(message_center::kNotificationWidth) / |
| 216 preferred_size.width(); | 243 preferred_size.width(); |
| 217 preferred_size.SetSize(message_center::kNotificationWidth, | 244 preferred_size.SetSize(message_center::kNotificationWidth, |
| 218 preferred_size.height() * scale); | 245 preferred_size.height() * scale); |
| 219 } | 246 } |
| 220 | 247 |
| 221 SetPreferredSize(preferred_size); | 248 SetPreferredSize(preferred_size); |
| 222 } | 249 } |
| 223 | 250 |
| 224 void ArcCustomNotificationView::UpdateCloseButtonVisiblity() { | 251 void ArcCustomNotificationView::UpdateCloseButtonVisiblity() { |
| 225 if (!surface_ || !floating_close_button_widget_) | 252 if (!surface_ || !floating_close_button_widget_) |
| 226 return; | 253 return; |
| 227 | 254 |
| 228 const bool target_visiblity = | 255 const bool target_visiblity = |
| 229 surface_->window()->GetBoundsInScreen().Contains( | 256 surface_->window()->GetBoundsInScreen().Contains( |
| 230 display::Screen::GetScreen()->GetCursorScreenPoint()); | 257 display::Screen::GetScreen()->GetCursorScreenPoint()); |
| 231 if (target_visiblity == floating_close_button_widget_->IsVisible()) | 258 if (target_visiblity == floating_close_button_widget_->IsVisible()) |
| 232 return; | 259 return; |
| 233 | 260 |
| 234 if (target_visiblity) | 261 if (target_visiblity) |
| 235 floating_close_button_widget_->Show(); | 262 floating_close_button_widget_->Show(); |
| 236 else | 263 else |
| 237 floating_close_button_widget_->Hide(); | 264 floating_close_button_widget_->Hide(); |
| 238 } | 265 } |
| 239 | 266 |
| 267 void ArcCustomNotificationView::UpdatePinnedState() { |
| 268 if (item_->pinned() && floating_close_button_widget_) { |
| 269 floating_close_button_widget_.reset(); |
| 270 } else if (!item_->pinned() && !floating_close_button_widget_) { |
| 271 CreateFloatingCloseButton(); |
| 272 } |
| 273 } |
| 274 |
| 275 void ArcCustomNotificationView::UpdateSnapshot() { |
| 276 // Bail if we have a |surface_| because it controls the sizes and paints UI. |
| 277 if (surface_) |
| 278 return; |
| 279 |
| 280 UpdatePreferredSize(); |
| 281 SchedulePaint(); |
| 282 } |
| 283 |
| 284 void ArcCustomNotificationView::AttachSurface() { |
| 285 if (!GetWidget()) |
| 286 return; |
| 287 |
| 288 UpdatePreferredSize(); |
| 289 Attach(surface_->window()); |
| 290 |
| 291 // Creates slide helper after this view is added to its parent. |
| 292 slide_helper_.reset(new SlideHelper(this)); |
| 293 } |
| 294 |
| 240 void ArcCustomNotificationView::ViewHierarchyChanged( | 295 void ArcCustomNotificationView::ViewHierarchyChanged( |
| 241 const views::View::ViewHierarchyChangedDetails& details) { | 296 const views::View::ViewHierarchyChangedDetails& details) { |
| 242 views::Widget* widget = GetWidget(); | 297 views::Widget* widget = GetWidget(); |
| 243 | 298 |
| 244 if (!details.is_add) { | 299 if (!details.is_add) { |
| 245 // Resets slide helper when this view is removed from its parent. | 300 // Resets slide helper when this view is removed from its parent. |
| 246 slide_helper_.reset(); | 301 slide_helper_.reset(); |
| 247 } | 302 } |
| 248 | 303 |
| 249 // Bail if native_view() has attached to a different widget. | 304 // Bail if native_view() has attached to a different widget. |
| 250 if (widget && native_view() && | 305 if (widget && native_view() && |
| 251 views::Widget::GetTopLevelWidgetForNativeView(native_view()) != widget) { | 306 views::Widget::GetTopLevelWidgetForNativeView(native_view()) != widget) { |
| 252 return; | 307 return; |
| 253 } | 308 } |
| 254 | 309 |
| 255 views::NativeViewHost::ViewHierarchyChanged(details); | 310 views::NativeViewHost::ViewHierarchyChanged(details); |
| 256 | 311 |
| 257 if (!widget || !surface_ || !details.is_add) | 312 if (!widget || !surface_ || !details.is_add) |
| 258 return; | 313 return; |
| 259 | 314 |
| 260 UpdatePreferredSize(); | 315 AttachSurface(); |
| 261 Attach(surface_->window()); | |
| 262 | |
| 263 // Creates slide helper after this view is added to its parent. | |
| 264 slide_helper_.reset(new SlideHelper(this)); | |
| 265 } | 316 } |
| 266 | 317 |
| 267 void ArcCustomNotificationView::Layout() { | 318 void ArcCustomNotificationView::Layout() { |
| 268 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); | 319 base::AutoReset<bool> auto_reset_in_layout(&in_layout_, true); |
| 269 | 320 |
| 270 views::NativeViewHost::Layout(); | 321 views::NativeViewHost::Layout(); |
| 271 | 322 |
| 272 if (!surface_ || !GetWidget()) | 323 if (!surface_ || !GetWidget()) |
| 273 return; | 324 return; |
| 274 | 325 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 293 | 344 |
| 294 gfx::Rect close_button_bounds(floating_close_button_->GetPreferredSize()); | 345 gfx::Rect close_button_bounds(floating_close_button_->GetPreferredSize()); |
| 295 close_button_bounds.set_x(contents_bounds.right() - | 346 close_button_bounds.set_x(contents_bounds.right() - |
| 296 close_button_bounds.width()); | 347 close_button_bounds.width()); |
| 297 close_button_bounds.set_y(contents_bounds.y()); | 348 close_button_bounds.set_y(contents_bounds.y()); |
| 298 floating_close_button_widget_->SetBounds(close_button_bounds); | 349 floating_close_button_widget_->SetBounds(close_button_bounds); |
| 299 | 350 |
| 300 UpdateCloseButtonVisiblity(); | 351 UpdateCloseButtonVisiblity(); |
| 301 } | 352 } |
| 302 | 353 |
| 354 void ArcCustomNotificationView::OnPaint(gfx::Canvas* canvas) { |
| 355 views::NativeViewHost::OnPaint(canvas); |
| 356 |
| 357 // Bail if there is a |surface_| or no item or no snapshot image. |
| 358 if (surface_ || !item_ || item_->snapshot().isNull()) |
| 359 return; |
| 360 const gfx::Rect contents_bounds = GetContentsBounds(); |
| 361 canvas->DrawImageInt(item_->snapshot(), 0, 0, item_->snapshot().width(), |
| 362 item_->snapshot().height(), contents_bounds.x(), |
| 363 contents_bounds.y(), contents_bounds.width(), |
| 364 contents_bounds.height(), false); |
| 365 } |
| 366 |
| 303 void ArcCustomNotificationView::OnKeyEvent(ui::KeyEvent* event) { | 367 void ArcCustomNotificationView::OnKeyEvent(ui::KeyEvent* event) { |
| 304 // Forward to parent CustomNotificationView to handle keyboard dismissal. | 368 // Forward to parent CustomNotificationView to handle keyboard dismissal. |
| 305 parent()->OnKeyEvent(event); | 369 parent()->OnKeyEvent(event); |
| 306 } | 370 } |
| 307 | 371 |
| 308 void ArcCustomNotificationView::OnGestureEvent(ui::GestureEvent* event) { | 372 void ArcCustomNotificationView::OnGestureEvent(ui::GestureEvent* event) { |
| 309 // Forward to parent CustomNotificationView to handle sliding out. | 373 // Forward to parent CustomNotificationView to handle sliding out. |
| 310 parent()->OnGestureEvent(event); | 374 parent()->OnGestureEvent(event); |
| 311 slide_helper_->Update(); | 375 slide_helper_->Update(); |
| 312 } | 376 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 331 const gfx::Rect& old_bounds, | 395 const gfx::Rect& old_bounds, |
| 332 const gfx::Rect& new_bounds) { | 396 const gfx::Rect& new_bounds) { |
| 333 if (in_layout_) | 397 if (in_layout_) |
| 334 return; | 398 return; |
| 335 | 399 |
| 336 UpdatePreferredSize(); | 400 UpdatePreferredSize(); |
| 337 Layout(); | 401 Layout(); |
| 338 } | 402 } |
| 339 | 403 |
| 340 void ArcCustomNotificationView::OnWindowDestroying(aura::Window* window) { | 404 void ArcCustomNotificationView::OnWindowDestroying(aura::Window* window) { |
| 341 window->RemoveObserver(this); | 405 SetSurface(nullptr); |
| 342 } | 406 } |
| 343 | 407 |
| 344 void ArcCustomNotificationView::OnItemDestroying() { | 408 void ArcCustomNotificationView::OnItemDestroying() { |
| 345 item_->RemoveObserver(this); | 409 item_->RemoveObserver(this); |
| 346 item_ = nullptr; | 410 item_ = nullptr; |
| 347 | 411 |
| 348 // Reset |surface_| with |item_| since no one is observing the |surface_| | 412 // Reset |surface_| with |item_| since no one is observing the |surface_| |
| 349 // after |item_| is gone and this view should be removed soon. | 413 // after |item_| is gone and this view should be removed soon. |
| 350 SetSurface(nullptr); | 414 SetSurface(nullptr); |
| 351 } | 415 } |
| 352 | 416 |
| 353 void ArcCustomNotificationView::OnItemPinnedChanged() { | 417 void ArcCustomNotificationView::OnItemUpdated() { |
| 354 if (item_->pinned() && floating_close_button_widget_) { | 418 UpdatePinnedState(); |
| 355 floating_close_button_widget_.reset(); | 419 UpdateSnapshot(); |
| 356 } else if (!item_->pinned() && !floating_close_button_widget_) { | |
| 357 CreateFloatingCloseButton(); | |
| 358 } | |
| 359 } | 420 } |
| 360 | 421 |
| 361 void ArcCustomNotificationView::OnItemNotificationSurfaceRemoved() { | 422 void ArcCustomNotificationView::OnNotificationSurfaceAdded( |
| 423 exo::NotificationSurface* surface) { |
| 424 if (surface->notification_id() != notification_key_) |
| 425 return; |
| 426 |
| 427 SetSurface(surface); |
| 428 } |
| 429 |
| 430 void ArcCustomNotificationView::OnNotificationSurfaceRemoved( |
| 431 exo::NotificationSurface* surface) { |
| 432 if (surface->notification_id() != notification_key_) |
| 433 return; |
| 434 |
| 362 SetSurface(nullptr); | 435 SetSurface(nullptr); |
| 363 } | 436 } |
| 364 | 437 |
| 365 } // namespace arc | 438 } // namespace arc |
| OLD | NEW |