split_view_divider_handler_view.cc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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/wm/splitview/split_view_divider_handler_view.h"
  5. #include "ash/display/screen_orientation_controller.h"
  6. #include "ash/shell.h"
  7. #include "ash/style/ash_color_provider.h"
  8. #include "ash/wm/splitview/split_view_constants.h"
  9. #include "ash/wm/splitview/split_view_utils.h"
  10. #include "base/timer/timer.h"
  11. #include "ui/compositor/layer.h"
  12. #include "ui/gfx/animation/animation_delegate.h"
  13. #include "ui/gfx/animation/slide_animation.h"
  14. #include "ui/views/background.h"
  15. namespace ash {
  16. namespace {
  17. SkColor GetBackgroundColor() {
  18. return AshColorProvider::Get()->GetContentLayerColor(
  19. AshColorProvider::ContentLayerType::kIconColorPrimary);
  20. }
  21. } // namespace
  22. class SplitViewDividerHandlerView::SelectionAnimation
  23. : public gfx::SlideAnimation,
  24. public gfx::AnimationDelegate {
  25. public:
  26. SelectionAnimation(SplitViewDividerHandlerView* white_handler_view)
  27. : gfx::SlideAnimation(this), white_handler_view_(white_handler_view) {
  28. SetSlideDuration(kSplitviewDividerSelectionStatusChangeDuration);
  29. SetTweenType(gfx::Tween::EASE_IN);
  30. }
  31. SelectionAnimation(const SelectionAnimation&) = delete;
  32. SelectionAnimation& operator=(const SelectionAnimation&) = delete;
  33. ~SelectionAnimation() override = default;
  34. void UpdateWhiteHandlerBounds() {
  35. white_handler_view_->SetBounds(
  36. CurrentValueBetween(kSplitviewWhiteBarShortSideLength,
  37. kSplitviewWhiteBarRadius * 2),
  38. CurrentValueBetween(kSplitviewWhiteBarLongSideLength,
  39. kSplitviewWhiteBarRadius * 2),
  40. /*signed_offset=*/0);
  41. }
  42. private:
  43. // gfx::AnimationDelegate:
  44. void AnimationProgressed(const gfx::Animation* animation) override {
  45. UpdateWhiteHandlerBounds();
  46. white_handler_view_->UpdateCornerRadius(CurrentValueBetween(
  47. kSplitviewWhiteBarCornerRadius, kSplitviewWhiteBarRadius));
  48. }
  49. SplitViewDividerHandlerView* white_handler_view_;
  50. };
  51. class SplitViewDividerHandlerView::SpawningAnimation
  52. : public gfx::SlideAnimation,
  53. public gfx::AnimationDelegate {
  54. public:
  55. SpawningAnimation(SplitViewDividerHandlerView* white_handler_view,
  56. int divider_signed_offset)
  57. : gfx::SlideAnimation(this),
  58. white_handler_view_(white_handler_view),
  59. spawn_signed_offset_(divider_signed_offset +
  60. (divider_signed_offset > 0
  61. ? kSplitviewWhiteBarSpawnUnsignedOffset
  62. : -kSplitviewWhiteBarSpawnUnsignedOffset)) {
  63. SetSlideDuration(kSplitviewDividerSpawnDuration);
  64. SetTweenType(gfx::Tween::LINEAR_OUT_SLOW_IN);
  65. }
  66. SpawningAnimation(const SpawningAnimation&) = delete;
  67. SpawningAnimation& operator=(const SpawningAnimation&) = delete;
  68. ~SpawningAnimation() override = default;
  69. void Activate() {
  70. white_handler_view_->SetVisible(false);
  71. delay_timer_.Start(FROM_HERE, kSplitviewDividerSpawnDelay, this,
  72. &SpawningAnimation::StartAnimation);
  73. }
  74. bool IsActive() const { return delay_timer_.IsRunning() || is_animating(); }
  75. void UpdateWhiteHandlerBounds() {
  76. DCHECK(IsActive());
  77. white_handler_view_->SetBounds(
  78. kSplitviewWhiteBarShortSideLength,
  79. CurrentValueBetween(kSplitviewWhiteBarSpawnLongSideLength,
  80. kSplitviewWhiteBarLongSideLength),
  81. CurrentValueBetween(spawn_signed_offset_, 0));
  82. }
  83. private:
  84. void StartAnimation() {
  85. DCHECK(!white_handler_view_->GetVisible());
  86. white_handler_view_->SetVisible(true);
  87. DCHECK(!is_animating());
  88. Show();
  89. DCHECK_EQ(0.0, GetCurrentValue());
  90. UpdateWhiteHandlerBounds();
  91. }
  92. // gfx::AnimationDelegate:
  93. void AnimationProgressed(const gfx::Animation* animation) override {
  94. UpdateWhiteHandlerBounds();
  95. }
  96. SplitViewDividerHandlerView* white_handler_view_;
  97. int spawn_signed_offset_;
  98. base::OneShotTimer delay_timer_;
  99. };
  100. SplitViewDividerHandlerView::SplitViewDividerHandlerView()
  101. : selection_animation_(std::make_unique<SelectionAnimation>(this)) {
  102. SetPaintToLayer();
  103. SetBackground(views::CreateRoundedRectBackground(
  104. GetBackgroundColor(), kSplitviewWhiteBarCornerRadius));
  105. }
  106. SplitViewDividerHandlerView::~SplitViewDividerHandlerView() = default;
  107. void SplitViewDividerHandlerView::DoSpawningAnimation(
  108. int divider_signed_offset) {
  109. spawning_animation_ =
  110. std::make_unique<SpawningAnimation>(this, divider_signed_offset);
  111. spawning_animation_->Activate();
  112. }
  113. void SplitViewDividerHandlerView::Refresh(bool is_resizing) {
  114. spawning_animation_.reset();
  115. SetVisible(true);
  116. selection_animation_->UpdateWhiteHandlerBounds();
  117. if (is_resizing)
  118. selection_animation_->Show();
  119. else
  120. selection_animation_->Hide();
  121. }
  122. void SplitViewDividerHandlerView::UpdateCornerRadius(float radius) {
  123. layer()->SetRoundedCornerRadius(gfx::RoundedCornersF{radius});
  124. }
  125. void SplitViewDividerHandlerView::SetBounds(int short_length,
  126. int long_length,
  127. int signed_offset) {
  128. const bool landscape = IsCurrentScreenOrientationLandscape();
  129. gfx::Rect bounds = landscape ? gfx::Rect(short_length, long_length)
  130. : gfx::Rect(long_length, short_length);
  131. bounds.Offset(parent()->GetLocalBounds().CenterPoint() -
  132. bounds.CenterPoint() +
  133. (landscape ? gfx::Vector2d(signed_offset, 0)
  134. : gfx::Vector2d(0, signed_offset)));
  135. SetBoundsRect(bounds);
  136. }
  137. void SplitViewDividerHandlerView::OnPaint(gfx::Canvas* canvas) {
  138. views::View::OnPaint(canvas);
  139. // It's needed to avoid artifacts when tapping on the divider quickly.
  140. canvas->DrawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
  141. views::View::OnPaint(canvas);
  142. }
  143. void SplitViewDividerHandlerView::OnThemeChanged() {
  144. views::View::OnThemeChanged();
  145. background()->SetNativeControlColor(GetBackgroundColor());
  146. SchedulePaint();
  147. }
  148. } // namespace ash