Chromium Code Reviews| 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/views/animation/square_ink_drop_ripple.h" | 5 #include "ui/views/animation/square_ink_drop_ripple.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "ui/compositor/layer.h" | 10 #include "ui/compositor/layer.h" |
| 11 #include "ui/compositor/layer_animation_sequence.h" | 11 #include "ui/compositor/layer_animation_sequence.h" |
| 12 #include "ui/compositor/scoped_layer_animation_settings.h" | 12 #include "ui/compositor/scoped_layer_animation_settings.h" |
| 13 #include "ui/gfx/geometry/point3_f.h" | 13 #include "ui/gfx/geometry/point3_f.h" |
| 14 #include "ui/gfx/geometry/point_conversions.h" | 14 #include "ui/gfx/geometry/point_conversions.h" |
| 15 #include "ui/gfx/geometry/point_f.h" | 15 #include "ui/gfx/geometry/point_f.h" |
| 16 #include "ui/gfx/geometry/vector3d_f.h" | 16 #include "ui/gfx/geometry/vector3d_f.h" |
| 17 #include "ui/gfx/transform_util.h" | 17 #include "ui/gfx/transform_util.h" |
| 18 #include "ui/views/animation/ink_drop_painted_layer_delegates.h" | 18 #include "ui/views/animation/ink_drop_painted_layer_delegates.h" |
| 19 #include "ui/views/view.h" | 19 #include "ui/views/view.h" |
| 20 | 20 |
| 21 namespace views { | |
| 22 | |
| 21 namespace { | 23 namespace { |
| 22 | 24 |
| 23 // The minimum scale factor to use when scaling rectangle layers. Smaller values | 25 // The minimum scale factor to use when scaling rectangle layers. Smaller values |
| 24 // were causing visual anomalies. | 26 // were causing visual anomalies. |
| 25 const float kMinimumRectScale = 0.0001f; | 27 const float kMinimumRectScale = 0.0001f; |
| 26 | 28 |
| 27 // The minimum scale factor to use when scaling circle layers. Smaller values | 29 // The minimum scale factor to use when scaling circle layers. Smaller values |
| 28 // were causing visual anomalies. | 30 // were causing visual anomalies. |
| 29 const float kMinimumCircleScale = 0.001f; | 31 const float kMinimumCircleScale = 0.001f; |
| 30 | 32 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 200, // ALTERNATE_ACTION_TRIGGERED_TRANSFORM | 122 200, // ALTERNATE_ACTION_TRIGGERED_TRANSFORM |
| 121 200, // ACTIVATED_CIRCLE_TRANSFORM | 123 200, // ACTIVATED_CIRCLE_TRANSFORM |
| 122 160, // ACTIVATED_RECT_TRANSFORM | 124 160, // ACTIVATED_RECT_TRANSFORM |
| 123 150, // DEACTIVATED_FADE_OUT | 125 150, // DEACTIVATED_FADE_OUT |
| 124 200, // DEACTIVATED_TRANSFORM | 126 200, // DEACTIVATED_TRANSFORM |
| 125 }; | 127 }; |
| 126 | 128 |
| 127 // Returns the InkDropState sub animation duration for the given |state|. | 129 // Returns the InkDropState sub animation duration for the given |state|. |
| 128 base::TimeDelta GetAnimationDuration(InkDropSubAnimations state) { | 130 base::TimeDelta GetAnimationDuration(InkDropSubAnimations state) { |
| 129 return base::TimeDelta::FromMilliseconds( | 131 return base::TimeDelta::FromMilliseconds( |
| 130 (views::InkDropRipple::UseFastAnimations() | 132 (InkDropRipple::UseFastAnimations() |
| 131 ? 1 | 133 ? 1 |
| 132 : views::InkDropRipple::kSlowAnimationDurationFactor) * | 134 : InkDropRipple::kSlowAnimationDurationFactor) * |
| 133 kAnimationDurationInMs[state]); | 135 kAnimationDurationInMs[state]); |
| 134 } | 136 } |
| 135 | 137 |
| 136 // Calculates a Transform for a circle layer. The transform will be set up to | |
| 137 // translate by -|center_offset|, scale, and then translate to the target point | |
| 138 // defined by |target_center_x| and |target_center_y|. | |
| 139 gfx::Transform CalculateCircleTransform(const gfx::Vector2dF& center_offset, | |
| 140 float scale, | |
| 141 float target_center_x, | |
| 142 float target_center_y) { | |
| 143 gfx::Transform transform; | |
| 144 transform.Translate(target_center_x, target_center_y); | |
| 145 transform.Scale(scale, scale); | |
| 146 transform.Translate(-center_offset.x(), -center_offset.y()); | |
| 147 return transform; | |
| 148 } | |
| 149 | |
| 150 // Calculates a Transform for a rectangle layer. The transform will be set up to | |
| 151 // translate by -|center_offset| and then scale by the |x_scale| and |y_scale| | |
| 152 // factors. | |
| 153 gfx::Transform CalculateRectTransform(const gfx::Vector2dF& center_offset, | |
| 154 float x_scale, | |
| 155 float y_scale) { | |
| 156 gfx::Transform transform; | |
| 157 transform.Scale(x_scale, y_scale); | |
| 158 transform.Translate(-center_offset.x(), -center_offset.y()); | |
| 159 return transform; | |
| 160 } | |
| 161 | |
| 162 } // namespace | 138 } // namespace |
| 163 | 139 |
| 164 namespace views { | |
| 165 | |
| 166 SquareInkDropRipple::SquareInkDropRipple(const gfx::Size& large_size, | 140 SquareInkDropRipple::SquareInkDropRipple(const gfx::Size& large_size, |
| 167 int large_corner_radius, | 141 int large_corner_radius, |
| 168 const gfx::Size& small_size, | 142 const gfx::Size& small_size, |
| 169 int small_corner_radius, | 143 int small_corner_radius, |
| 170 const gfx::Point& center_point, | 144 const gfx::Point& center_point, |
| 171 SkColor color, | 145 SkColor color, |
| 172 float visible_opacity) | 146 float visible_opacity) |
| 173 : activated_shape_(ROUNDED_RECT), | 147 : activated_shape_(ROUNDED_RECT), |
| 174 visible_opacity_(visible_opacity), | 148 visible_opacity_(visible_opacity), |
| 175 large_size_(large_size), | 149 large_size_(large_size), |
| 176 large_corner_radius_(large_corner_radius), | 150 large_corner_radius_(large_corner_radius), |
| 177 small_size_(small_size), | 151 small_size_(small_size), |
| 178 small_corner_radius_(small_corner_radius), | 152 small_corner_radius_(small_corner_radius), |
| 153 center_point_(center_point), | |
| 179 circle_layer_delegate_(new CircleLayerDelegate( | 154 circle_layer_delegate_(new CircleLayerDelegate( |
| 180 color, | 155 color, |
| 181 std::min(large_size_.width(), large_size_.height()) / 2)), | 156 std::min(large_size_.width(), large_size_.height()) / 2)), |
| 182 rect_layer_delegate_( | 157 rect_layer_delegate_( |
| 183 new RectangleLayerDelegate(color, gfx::SizeF(large_size_))), | 158 new RectangleLayerDelegate(color, gfx::SizeF(large_size_))), |
| 184 root_layer_(ui::LAYER_NOT_DRAWN) { | 159 root_layer_(ui::LAYER_NOT_DRAWN) { |
| 185 root_layer_.set_name("SquareInkDropRipple:ROOT_LAYER"); | 160 root_layer_.set_name("SquareInkDropRipple:ROOT_LAYER"); |
| 186 | 161 |
| 187 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | 162 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) |
| 188 AddPaintLayer(static_cast<PaintedShape>(i)); | 163 AddPaintLayer(static_cast<PaintedShape>(i)); |
| 189 | 164 |
| 190 root_layer_.SetMasksToBounds(false); | 165 root_layer_.SetMasksToBounds(false); |
| 191 root_layer_.SetBounds(gfx::Rect(large_size_)); | 166 root_layer_.SetBounds(gfx::Rect(large_size_)); |
| 192 | 167 |
| 193 gfx::Transform transform; | |
| 194 transform.Translate(center_point.x(), center_point.y()); | |
| 195 root_layer_.SetTransform(transform); | |
| 196 | |
| 197 SetStateToHidden(); | 168 SetStateToHidden(); |
| 198 } | 169 } |
| 199 | 170 |
| 200 SquareInkDropRipple::~SquareInkDropRipple() { | 171 SquareInkDropRipple::~SquareInkDropRipple() { |
| 201 // Explicitly aborting all the animations ensures all callbacks are invoked | 172 // Explicitly aborting all the animations ensures all callbacks are invoked |
| 202 // while this instance still exists. | 173 // while this instance still exists. |
| 203 AbortAllAnimations(); | 174 AbortAllAnimations(); |
| 204 } | 175 } |
| 205 | 176 |
| 206 void SquareInkDropRipple::SnapToActivated() { | 177 void SquareInkDropRipple::SnapToActivated() { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 CalculateCircleTransforms(small_size_, &transforms); | 229 CalculateCircleTransforms(small_size_, &transforms); |
| 259 AnimateToTransforms( | 230 AnimateToTransforms( |
| 260 transforms, GetAnimationDuration(HIDDEN_TRANSFORM), | 231 transforms, GetAnimationDuration(HIDDEN_TRANSFORM), |
| 261 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | 232 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
| 262 gfx::Tween::EASE_IN_OUT, animation_observer); | 233 gfx::Tween::EASE_IN_OUT, animation_observer); |
| 263 } | 234 } |
| 264 break; | 235 break; |
| 265 case InkDropState::ACTION_PENDING: | 236 case InkDropState::ACTION_PENDING: |
| 266 DCHECK_EQ(InkDropState::HIDDEN, old_ink_drop_state) | 237 DCHECK_EQ(InkDropState::HIDDEN, old_ink_drop_state) |
| 267 << " old_ink_drop_state=" << ToString(old_ink_drop_state); | 238 << " old_ink_drop_state=" << ToString(old_ink_drop_state); |
| 268 ; | |
| 269 AnimateToOpacity(visible_opacity_, | 239 AnimateToOpacity(visible_opacity_, |
| 270 GetAnimationDuration(ACTION_PENDING_FADE_IN), | 240 GetAnimationDuration(ACTION_PENDING_FADE_IN), |
| 271 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | 241 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
| 272 gfx::Tween::EASE_IN, animation_observer); | 242 gfx::Tween::EASE_IN, animation_observer); |
| 273 AnimateToOpacity(visible_opacity_, | 243 AnimateToOpacity(visible_opacity_, |
| 274 GetAnimationDuration(ACTION_PENDING_TRANSFORM), | 244 GetAnimationDuration(ACTION_PENDING_TRANSFORM), |
| 275 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | 245 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, |
| 276 gfx::Tween::EASE_IN, animation_observer); | 246 gfx::Tween::EASE_IN, animation_observer); |
| 277 CalculateCircleTransforms(large_size_, &transforms); | 247 CalculateCircleTransforms(large_size_, &transforms); |
| 278 AnimateToTransforms(transforms, | 248 AnimateToTransforms(transforms, |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 453 } | 423 } |
| 454 | 424 |
| 455 void SquareInkDropRipple::CalculateCircleTransforms( | 425 void SquareInkDropRipple::CalculateCircleTransforms( |
| 456 const gfx::Size& size, | 426 const gfx::Size& size, |
| 457 InkDropTransforms* transforms_out) const { | 427 InkDropTransforms* transforms_out) const { |
| 458 CalculateRectTransforms(size, std::min(size.width(), size.height()) / 2.0f, | 428 CalculateRectTransforms(size, std::min(size.width(), size.height()) / 2.0f, |
| 459 transforms_out); | 429 transforms_out); |
| 460 } | 430 } |
| 461 | 431 |
| 462 void SquareInkDropRipple::CalculateRectTransforms( | 432 void SquareInkDropRipple::CalculateRectTransforms( |
| 463 const gfx::Size& size, | 433 const gfx::Size& desired_size, |
| 464 float corner_radius, | 434 float corner_radius, |
| 465 InkDropTransforms* transforms_out) const { | 435 InkDropTransforms* transforms_out) const { |
| 466 DCHECK_GE(size.width() / 2.0f, corner_radius) | 436 DCHECK_GE(desired_size.width() / 2.0f, corner_radius) |
| 467 << "The circle's diameter should not be greater than the total width."; | 437 << "The circle's diameter should not be greater than the total width."; |
| 468 DCHECK_GE(size.height() / 2.0f, corner_radius) | 438 DCHECK_GE(desired_size.height() / 2.0f, corner_radius) |
| 469 << "The circle's diameter should not be greater than the total height."; | 439 << "The circle's diameter should not be greater than the total height."; |
| 470 | 440 |
| 441 gfx::SizeF size(desired_size); | |
|
bruthig
2017/04/12 17:57:39
nit: Consider renaming as |effective_size|.
Evan Stade
2017/04/12 23:48:28
it's used so often below I wanted to keep it short
| |
| 442 // This function can be called before the layer's been added to a view, | |
| 443 // either at construction time or in tests. | |
| 444 if (root_layer_.GetCompositor()) { | |
| 445 // Modify |desired_size| so that the ripple aligns to pixel bounds. | |
| 446 const float dsf = root_layer_.GetCompositor()->device_scale_factor(); | |
| 447 gfx::RectF ripple_bounds((gfx::PointF(center_point_)), gfx::SizeF()); | |
|
bruthig
2017/04/12 17:57:39
I'm assuming the 'extra' parenthesis are required.
Evan Stade
2017/04/12 23:48:28
yes. disambiguates a function call or some such.
| |
| 448 ripple_bounds.Inset(-gfx::InsetsF(desired_size.height() / 2.0f, | |
| 449 desired_size.width() / 2.0f)); | |
| 450 ripple_bounds.Scale(dsf); | |
| 451 ripple_bounds = gfx::RectF(gfx::ToEnclosingRect(ripple_bounds)); | |
| 452 ripple_bounds.Scale(1.0f / dsf); | |
| 453 size = ripple_bounds.size(); | |
| 454 } | |
| 455 | |
| 471 // The shapes are drawn such that their center points are not at the origin. | 456 // The shapes are drawn such that their center points are not at the origin. |
| 472 // Thus we use the CalculateCircleTransform() and CalculateRectTransform() | 457 // Thus we use the CalculateCircleTransform() and CalculateRectTransform() |
| 473 // methods to calculate the complex Transforms. | 458 // methods to calculate the complex Transforms. |
| 474 | 459 |
| 475 const float circle_scale = std::max( | 460 const float circle_scale = std::max( |
| 476 kMinimumCircleScale, | 461 kMinimumCircleScale, |
| 477 corner_radius / static_cast<float>(circle_layer_delegate_->radius())); | 462 corner_radius / static_cast<float>(circle_layer_delegate_->radius())); |
| 478 | 463 |
| 479 const float circle_target_x_offset = size.width() / 2.0f - corner_radius; | 464 const float circle_target_x_offset = size.width() / 2.0f - corner_radius; |
| 480 const float circle_target_y_offset = size.height() / 2.0f - corner_radius; | 465 const float circle_target_y_offset = size.height() / 2.0f - corner_radius; |
| 481 | 466 |
| 482 const gfx::Vector2dF circle_center_offset = | |
| 483 circle_layer_delegate_->GetCenteringOffset(); | |
| 484 (*transforms_out)[TOP_LEFT_CIRCLE] = CalculateCircleTransform( | 467 (*transforms_out)[TOP_LEFT_CIRCLE] = CalculateCircleTransform( |
| 485 circle_center_offset, circle_scale, -circle_target_x_offset, | 468 circle_scale, -circle_target_x_offset, -circle_target_y_offset); |
| 486 -circle_target_y_offset); | 469 (*transforms_out)[TOP_RIGHT_CIRCLE] = CalculateCircleTransform( |
| 470 circle_scale, circle_target_x_offset, -circle_target_y_offset); | |
| 471 (*transforms_out)[BOTTOM_RIGHT_CIRCLE] = CalculateCircleTransform( | |
| 472 circle_scale, circle_target_x_offset, circle_target_y_offset); | |
| 473 (*transforms_out)[BOTTOM_LEFT_CIRCLE] = CalculateCircleTransform( | |
| 474 circle_scale, -circle_target_x_offset, circle_target_y_offset); | |
| 487 | 475 |
| 488 (*transforms_out)[TOP_RIGHT_CIRCLE] = | 476 const float rect_delegate_width = rect_layer_delegate_->size().width(); |
| 489 CalculateCircleTransform(circle_center_offset, circle_scale, | 477 const float rect_delegate_height = rect_layer_delegate_->size().height(); |
| 490 circle_target_x_offset, -circle_target_y_offset); | |
| 491 | 478 |
| 492 (*transforms_out)[BOTTOM_RIGHT_CIRCLE] = | |
| 493 CalculateCircleTransform(circle_center_offset, circle_scale, | |
| 494 circle_target_x_offset, circle_target_y_offset); | |
| 495 | |
| 496 (*transforms_out)[BOTTOM_LEFT_CIRCLE] = | |
| 497 CalculateCircleTransform(circle_center_offset, circle_scale, | |
| 498 -circle_target_x_offset, circle_target_y_offset); | |
| 499 | |
| 500 const float rect_delegate_width = | |
| 501 static_cast<float>(rect_layer_delegate_->size().width()); | |
| 502 const float rect_delegate_height = | |
| 503 static_cast<float>(rect_layer_delegate_->size().height()); | |
| 504 | |
| 505 const gfx::Vector2dF rect_center_offset = | |
| 506 rect_layer_delegate_->GetCenteringOffset(); | |
| 507 (*transforms_out)[HORIZONTAL_RECT] = CalculateRectTransform( | 479 (*transforms_out)[HORIZONTAL_RECT] = CalculateRectTransform( |
| 508 rect_center_offset, | |
| 509 std::max(kMinimumRectScale, size.width() / rect_delegate_width), | 480 std::max(kMinimumRectScale, size.width() / rect_delegate_width), |
| 510 std::max(kMinimumRectScale, | 481 std::max(kMinimumRectScale, |
| 511 (size.height() - 2.0f * corner_radius) / rect_delegate_height)); | 482 (size.height() - 2.0f * corner_radius) / rect_delegate_height)); |
| 512 | 483 |
| 513 (*transforms_out)[VERTICAL_RECT] = CalculateRectTransform( | 484 (*transforms_out)[VERTICAL_RECT] = CalculateRectTransform( |
| 514 rect_center_offset, | |
| 515 std::max(kMinimumRectScale, | 485 std::max(kMinimumRectScale, |
| 516 (size.width() - 2.0f * corner_radius) / rect_delegate_width), | 486 (size.width() - 2.0f * corner_radius) / rect_delegate_width), |
| 517 std::max(kMinimumRectScale, size.height() / rect_delegate_height)); | 487 std::max(kMinimumRectScale, size.height() / rect_delegate_height)); |
| 518 } | 488 } |
| 519 | 489 |
| 490 gfx::Transform SquareInkDropRipple::CalculateCircleTransform( | |
| 491 float scale, | |
| 492 float target_center_x, | |
| 493 float target_center_y) const { | |
| 494 gfx::Transform transform; | |
| 495 // Offset for the center point of the ripple. | |
| 496 transform.Translate(center_point_.x(), center_point_.y()); | |
| 497 // Move circle to target. | |
| 498 transform.Translate(target_center_x, target_center_y); | |
| 499 transform.Scale(scale, scale); | |
| 500 // Align center point of the painted circle. | |
| 501 const gfx::Vector2dF circle_center_offset = | |
| 502 circle_layer_delegate_->GetCenteringOffset(); | |
| 503 transform.Translate(-circle_center_offset.x(), -circle_center_offset.y()); | |
| 504 return transform; | |
| 505 } | |
| 506 | |
| 507 gfx::Transform SquareInkDropRipple::CalculateRectTransform( | |
| 508 float x_scale, | |
| 509 float y_scale) const { | |
| 510 gfx::Transform transform; | |
| 511 transform.Translate(center_point_.x(), center_point_.y()); | |
| 512 transform.Scale(x_scale, y_scale); | |
| 513 const gfx::Vector2dF rect_center_offset = | |
| 514 rect_layer_delegate_->GetCenteringOffset(); | |
| 515 transform.Translate(-rect_center_offset.x(), -rect_center_offset.y()); | |
| 516 return transform; | |
| 517 } | |
| 518 | |
| 520 void SquareInkDropRipple::GetCurrentTransforms( | 519 void SquareInkDropRipple::GetCurrentTransforms( |
| 521 InkDropTransforms* transforms_out) const { | 520 InkDropTransforms* transforms_out) const { |
| 522 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | 521 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) |
| 523 (*transforms_out)[i] = painted_layers_[i]->transform(); | 522 (*transforms_out)[i] = painted_layers_[i]->transform(); |
| 524 } | 523 } |
| 525 | 524 |
| 526 void SquareInkDropRipple::GetActivatedTargetTransforms( | 525 void SquareInkDropRipple::GetActivatedTargetTransforms( |
| 527 InkDropTransforms* transforms_out) const { | 526 InkDropTransforms* transforms_out) const { |
| 528 switch (activated_shape_) { | 527 switch (activated_shape_) { |
| 529 case CIRCLE: | 528 case CIRCLE: |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 575 layer->set_delegate(delegate); | 574 layer->set_delegate(delegate); |
| 576 layer->SetVisible(true); | 575 layer->SetVisible(true); |
| 577 layer->SetOpacity(1.0); | 576 layer->SetOpacity(1.0); |
| 578 layer->SetMasksToBounds(false); | 577 layer->SetMasksToBounds(false); |
| 579 layer->set_name("PAINTED_SHAPE_COUNT:" + ToLayerName(painted_shape)); | 578 layer->set_name("PAINTED_SHAPE_COUNT:" + ToLayerName(painted_shape)); |
| 580 | 579 |
| 581 painted_layers_[painted_shape].reset(layer); | 580 painted_layers_[painted_shape].reset(layer); |
| 582 } | 581 } |
| 583 | 582 |
| 584 } // namespace views | 583 } // namespace views |
| OLD | NEW |