ghost_image_view.cc 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright 2019 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_list/views/ghost_image_view.h"
  5. #include "ash/public/cpp/app_list/app_list_config.h"
  6. #include "ash/style/dark_light_mode_controller_impl.h"
  7. #include "ui/base/metadata/metadata_impl_macros.h"
  8. #include "ui/compositor/layer.h"
  9. #include "ui/compositor/scoped_layer_animation_settings.h"
  10. #include "ui/gfx/animation/tween.h"
  11. #include "ui/gfx/canvas.h"
  12. #include "ui/gfx/color_palette.h"
  13. namespace ash {
  14. namespace {
  15. constexpr int kGhostCircleStrokeWidth = 2;
  16. constexpr int kGhostColorOpacity = 0x4D; // 30% opacity.
  17. constexpr base::TimeDelta kGhostFadeInOutLength = base::Milliseconds(180);
  18. constexpr gfx::Tween::Type kGhostTween = gfx::Tween::FAST_OUT_SLOW_IN;
  19. } // namespace
  20. GhostImageView::GhostImageView(GridIndex index)
  21. : is_hiding_(false), index_(index) {}
  22. GhostImageView::~GhostImageView() {
  23. StopObservingImplicitAnimations();
  24. }
  25. void GhostImageView::Init(const gfx::Rect& drop_target_bounds,
  26. int grid_focus_corner_radius) {
  27. corner_radius_ = grid_focus_corner_radius;
  28. SetPaintToLayer();
  29. layer()->SetFillsBoundsOpaquely(false);
  30. layer()->SetOpacity(0.0f);
  31. SetBoundsRect(drop_target_bounds);
  32. }
  33. void GhostImageView::FadeOut() {
  34. if (is_hiding_)
  35. return;
  36. is_hiding_ = true;
  37. DoAnimation(true /* fade out */);
  38. }
  39. void GhostImageView::FadeIn() {
  40. DoAnimation(false /* fade in */);
  41. }
  42. void GhostImageView::SetTransitionOffset(
  43. const gfx::Vector2d& transition_offset) {
  44. SetPosition(bounds().origin() + transition_offset);
  45. }
  46. void GhostImageView::DoAnimation(bool hide) {
  47. ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator());
  48. animation.SetTransitionDuration(kGhostFadeInOutLength);
  49. animation.SetTweenType(kGhostTween);
  50. if (hide) {
  51. animation.AddObserver(this);
  52. animation.SetPreemptionStrategy(
  53. ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
  54. layer()->SetOpacity(0.0f);
  55. return;
  56. }
  57. layer()->SetOpacity(1.0f);
  58. }
  59. void GhostImageView::OnPaint(gfx::Canvas* canvas) {
  60. cc::PaintFlags flags;
  61. flags.setAntiAlias(true);
  62. flags.setColor(DarkLightModeControllerImpl::Get()->IsDarkModeEnabled()
  63. ? gfx::kGoogleGrey200
  64. : gfx::kGoogleGrey900);
  65. flags.setAlpha(kGhostColorOpacity);
  66. flags.setStyle(cc::PaintFlags::kStroke_Style);
  67. flags.setStrokeWidth(kGhostCircleStrokeWidth);
  68. gfx::Rect bounds = GetContentsBounds();
  69. bounds.Inset(gfx::Insets(kGhostCircleStrokeWidth / 2));
  70. canvas->DrawRoundRect(gfx::RectF(bounds), corner_radius_, flags);
  71. }
  72. void GhostImageView::OnImplicitAnimationsCompleted() {
  73. // Delete this GhostImageView when the fade out animation is done.
  74. delete this;
  75. }
  76. BEGIN_METADATA(GhostImageView, views::View)
  77. END_METADATA
  78. } // namespace ash