 Chromium Code Reviews
 Chromium Code Reviews Issue 1280953003:
  Enhance the material design ripple API so the ripple's state can be controlled by it's owning View.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1280953003:
  Enhance the material design ripple API so the ripple's state can be controlled by it's owning View.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| Index: ui/views/animation/ink_drop_animation_controller_impl.cc | 
| diff --git a/ui/views/animation/ink_drop_animation_controller.cc b/ui/views/animation/ink_drop_animation_controller_impl.cc | 
| similarity index 62% | 
| rename from ui/views/animation/ink_drop_animation_controller.cc | 
| rename to ui/views/animation/ink_drop_animation_controller_impl.cc | 
| index bfe459dd8fa1e60cc39ca51b63158023407b5902..6e8fef0cdc690575365f5d5ea7c552b02a137129 100644 | 
| --- a/ui/views/animation/ink_drop_animation_controller.cc | 
| +++ b/ui/views/animation/ink_drop_animation_controller_impl.cc | 
| @@ -2,7 +2,7 @@ | 
| // Use of this source code is governed by a BSD-style license that can be | 
| // found in the LICENSE file. | 
| -#include "ui/views/animation/ink_drop_animation_controller.h" | 
| +#include "ui/views/animation/ink_drop_animation_controller_impl.h" | 
| #include "base/command_line.h" | 
| #include "ui/base/ui_base_switches.h" | 
| @@ -13,6 +13,9 @@ | 
| #include "ui/compositor/scoped_layer_animation_settings.h" | 
| #include "ui/events/event.h" | 
| #include "ui/gfx/canvas.h" | 
| +#include "ui/gfx/geometry/size.h" | 
| +#include "ui/views/animation/ink_drop_delegate.h" | 
| +#include "ui/views/animation/ink_drop_host.h" | 
| #include "ui/views/view.h" | 
| namespace { | 
| @@ -113,8 +116,7 @@ class AppearAnimationObserver : public ui::LayerAnimationObserver { | 
| }; | 
| AppearAnimationObserver::AppearAnimationObserver(ui::Layer* layer, bool hide) | 
| - : layer_(layer), background_layer_(nullptr), hide_(hide) { | 
| -} | 
| + : layer_(layer), background_layer_(nullptr), hide_(hide) {} | 
| AppearAnimationObserver::~AppearAnimationObserver() { | 
| StopObserving(); | 
| @@ -182,98 +184,78 @@ bool AppearAnimationObserver::RequiresNotificationWhenAnimatorDestroyed() | 
| return true; | 
| } | 
| -// Renders the visual feedback. Will render a circle if |circle_| is true, | 
| -// otherwise renders a rounded rectangle. | 
| -class InkDropDelegate : public ui::LayerDelegate { | 
| - public: | 
| - InkDropDelegate(ui::Layer* layer, SkColor color); | 
| - ~InkDropDelegate() override; | 
| - | 
| - // Sets the visual style of the feedback. | 
| - void set_should_render_circle(bool should_render_circle) { | 
| - should_render_circle_ = should_render_circle; | 
| - } | 
| - | 
| - // ui::LayerDelegate: | 
| - void OnPaintLayer(const ui::PaintContext& context) override; | 
| - void OnDelegatedFrameDamage(const gfx::Rect& damage_rect_in_dip) override; | 
| - void OnDeviceScaleFactorChanged(float device_scale_factor) override; | 
| - base::Closure PrepareForLayerBoundsChange() override; | 
| - | 
| - private: | 
| - // The ui::Layer being rendered to. | 
| - ui::Layer* layer_; | 
| - | 
| - // The color to paint. | 
| - SkColor color_; | 
| - | 
| - // When true renders a circle, otherwise renders a rounded rectangle. | 
| - bool should_render_circle_; | 
| +InkDropAnimationControllerImpl::InkDropAnimationControllerImpl( | 
| + InkDropHost* ink_drop_host) | 
| + : ink_drop_host_(ink_drop_host), | 
| + appear_animation_observer_(nullptr), | 
| + long_press_animation_observer_(nullptr), | 
| + ink_drop_bounds_(0, 0, 0, 0) { | 
| + root_layer_owner_.SetLayer(new ui::Layer(ui::LAYER_NOT_DRAWN)); | 
| + ink_drop_layer_owner_.SetLayer(new ui::Layer()); | 
| + long_press_layer_owner_.SetLayer(new ui::Layer()); | 
| + | 
| + ink_drop_delegate_.reset(new InkDropDelegate(ink_drop_layer_owner_.layer(), | 
| + kInkDropColor, kCircleRadius, | 
| + kRoundedRectCorners)); | 
| + long_press_delegate_.reset( | 
| + new InkDropDelegate(long_press_layer_owner_.layer(), kLongPressColor, | 
| + kCircleRadius, kRoundedRectCorners)); | 
| + | 
| + SetupAnimationLayer(long_press_layer_owner_.layer(), | 
| + long_press_delegate_.get()); | 
| + SetupAnimationLayer(ink_drop_layer_owner_.layer(), ink_drop_delegate_.get()); | 
| - DISALLOW_COPY_AND_ASSIGN(InkDropDelegate); | 
| -}; | 
| + root_layer_owner_.layer()->Add(ink_drop_layer_owner_.layer()); | 
| + root_layer_owner_.layer()->Add(long_press_layer_owner_.layer()); | 
| -InkDropDelegate::InkDropDelegate(ui::Layer* layer, SkColor color) | 
| - : layer_(layer), color_(color), should_render_circle_(true) { | 
| + ink_drop_host_->AddInkDropLayer(root_layer_owner_.layer()); | 
| 
sadrul
2015/08/18 19:52:39
Add a TODO and refer to 522175
 
bruthig
2015/08/18 20:58:04
Done.
 | 
| } | 
| -InkDropDelegate::~InkDropDelegate() { | 
| +InkDropAnimationControllerImpl::~InkDropAnimationControllerImpl() { | 
| + // TODO(bruthig): Change this to be called when the ink drop becomes hidden. | 
| + // See www.crbug.com/522175. | 
| + ink_drop_host_->RemoveInkDropLayer(root_layer_owner_.layer()); | 
| } | 
| -void InkDropDelegate::OnPaintLayer(const ui::PaintContext& context) { | 
| - SkPaint paint; | 
| - paint.setColor(color_); | 
| - paint.setFlags(SkPaint::kAntiAlias_Flag); | 
| - paint.setStyle(SkPaint::kFill_Style); | 
| - | 
| - gfx::Rect bounds = layer_->bounds(); | 
| - | 
| - ui::PaintRecorder recorder(context, layer_->size()); | 
| - gfx::Canvas* canvas = recorder.canvas(); | 
| - if (should_render_circle_) { | 
| - gfx::Point midpoint(bounds.width() * 0.5f, bounds.height() * 0.5f); | 
| - canvas->DrawCircle(midpoint, kCircleRadius, paint); | 
| - } else { | 
| - canvas->DrawRoundRect(bounds, kRoundedRectCorners, paint); | 
| +void InkDropAnimationControllerImpl::AnimateToState(InkDropState state) { | 
| + // TODO(bruthig): Do not transition if we are already in |state| and restrict | 
| + // any state transition that don't make sense or wouldn't look visually | 
| + // appealing. | 
| + switch (state) { | 
| + case InkDropState::HIDDEN: | 
| + AnimateHide(); | 
| + break; | 
| + case InkDropState::ACTION_PENDING: | 
| + AnimateTapDown(); | 
| + break; | 
| + case InkDropState::QUICK_ACTION: | 
| + AnimateTapDown(); | 
| + AnimateHide(); | 
| + break; | 
| + case InkDropState::SLOW_ACTION: | 
| + AnimateLongPress(); | 
| + break; | 
| + case InkDropState::ACTIVATED: | 
| + AnimateLongPress(); | 
| + break; | 
| } | 
| } | 
| -void InkDropDelegate::OnDelegatedFrameDamage( | 
| - const gfx::Rect& damage_rect_in_dip) { | 
| -} | 
| - | 
| -void InkDropDelegate::OnDeviceScaleFactorChanged(float device_scale_factor) { | 
| -} | 
| - | 
| -base::Closure InkDropDelegate::PrepareForLayerBoundsChange() { | 
| - return base::Closure(); | 
| +void InkDropAnimationControllerImpl::SetInkDropSize(const gfx::Size& size) { | 
| + SetInkDropBounds(gfx::Rect(ink_drop_bounds_.origin(), size)); | 
| } | 
| -InkDropAnimationController::InkDropAnimationController(views::View* view) | 
| - : ink_drop_layer_(new ui::Layer()), | 
| - ink_drop_delegate_( | 
| - new InkDropDelegate(ink_drop_layer_.get(), kInkDropColor)), | 
| - appear_animation_observer_(nullptr), | 
| - long_press_layer_(new ui::Layer()), | 
| - long_press_delegate_( | 
| - new InkDropDelegate(long_press_layer_.get(), kLongPressColor)), | 
| - long_press_animation_observer_(nullptr), | 
| - view_(view) { | 
| - view_->SetPaintToLayer(true); | 
| - view_->AddPreTargetHandler(this); | 
| - ui::Layer* layer = view_->layer(); | 
| - layer->SetMasksToBounds(!UseCircularFeedback()); | 
| - SetupAnimationLayer(layer, long_press_layer_.get(), | 
| - long_press_delegate_.get()); | 
| - SetupAnimationLayer(layer, ink_drop_layer_.get(), ink_drop_delegate_.get()); | 
| - ink_drop_delegate_->set_should_render_circle(UseCircularFeedback()); | 
| +gfx::Rect InkDropAnimationControllerImpl::GetInkDropBounds() const { | 
| + return ink_drop_bounds_; | 
| } | 
| -InkDropAnimationController::~InkDropAnimationController() { | 
| - view_->RemovePreTargetHandler(this); | 
| +void InkDropAnimationControllerImpl::SetInkDropBounds(const gfx::Rect& bounds) { | 
| + ink_drop_bounds_ = bounds; | 
| + SetLayerBounds(ink_drop_layer_owner_.layer()); | 
| + SetLayerBounds(long_press_layer_owner_.layer()); | 
| } | 
| -void InkDropAnimationController::AnimateTapDown() { | 
| +void InkDropAnimationControllerImpl::AnimateTapDown() { | 
| if ((appear_animation_observer_ && | 
| appear_animation_observer_->IsAnimationActive()) || | 
| (long_press_animation_observer_ && | 
| @@ -283,20 +265,23 @@ void InkDropAnimationController::AnimateTapDown() { | 
| return; | 
| } | 
| appear_animation_observer_.reset( | 
| - new AppearAnimationObserver(ink_drop_layer_.get(), false)); | 
| - AnimateShow(ink_drop_layer_.get(), appear_animation_observer_.get(), | 
| - UseCircularFeedback(), | 
| + new AppearAnimationObserver(ink_drop_layer_owner_.layer(), false)); | 
| + AnimateShow(ink_drop_layer_owner_.layer(), appear_animation_observer_.get(), | 
| base::TimeDelta::FromMilliseconds( | 
| (UseFastAnimations() ? kShowInkDropAnimationDurationFastMs | 
| : kShowInkDropAnimationDurationSlowMs))); | 
| } | 
| -void InkDropAnimationController::AnimateHide() { | 
| - if (appear_animation_observer_) | 
| +void InkDropAnimationControllerImpl::AnimateHide() { | 
| + if (appear_animation_observer_ && | 
| + appear_animation_observer_->IsAnimationActive()) { | 
| appear_animation_observer_->HideNowIfDoneOrOnceCompleted(); | 
| + } else if (long_press_animation_observer_) { | 
| + long_press_animation_observer_->HideNowIfDoneOrOnceCompleted(); | 
| + } | 
| } | 
| -void InkDropAnimationController::AnimateLongPress() { | 
| +void InkDropAnimationControllerImpl::AnimateLongPress() { | 
| // Only one animation at a time. Subsequent long presses are ignored until the | 
| // current animation completes. | 
| if (long_press_animation_observer_ && | 
| @@ -305,25 +290,27 @@ void InkDropAnimationController::AnimateLongPress() { | 
| } | 
| appear_animation_observer_.reset(); | 
| long_press_animation_observer_.reset( | 
| - new AppearAnimationObserver(long_press_layer_.get(), true)); | 
| - long_press_animation_observer_->SetBackgroundToHide(ink_drop_layer_.get()); | 
| - AnimateShow(long_press_layer_.get(), long_press_animation_observer_.get(), | 
| - true, | 
| + new AppearAnimationObserver(long_press_layer_owner_.layer(), false)); | 
| + long_press_animation_observer_->SetBackgroundToHide( | 
| + ink_drop_layer_owner_.layer()); | 
| + AnimateShow(long_press_layer_owner_.layer(), | 
| + long_press_animation_observer_.get(), | 
| base::TimeDelta::FromMilliseconds( | 
| UseFastAnimations() ? kShowLongPressAnimationDurationFastMs | 
| : kShowLongPressAnimationDurationSlowMs)); | 
| } | 
| -void InkDropAnimationController::AnimateShow(ui::Layer* layer, | 
| - AppearAnimationObserver* observer, | 
| - bool circle, | 
| - base::TimeDelta duration) { | 
| - SetLayerBounds(layer, circle, view_->width(), view_->height()); | 
| +void InkDropAnimationControllerImpl::AnimateShow( | 
| + ui::Layer* layer, | 
| + AppearAnimationObserver* observer, | 
| + base::TimeDelta duration) { | 
| layer->SetVisible(true); | 
| layer->SetOpacity(1.0f); | 
| - float start_x = layer->bounds().width() * kMinimumScaleCenteringOffset; | 
| - float start_y = layer->bounds().height() * kMinimumScaleCenteringOffset; | 
| + float start_x = ink_drop_bounds_.x() + | 
| + layer->bounds().width() * kMinimumScaleCenteringOffset; | 
| + float start_y = ink_drop_bounds_.y() + | 
| + layer->bounds().height() * kMinimumScaleCenteringOffset; | 
| gfx::Transform initial_transform; | 
| initial_transform.Translate(start_x, start_y); | 
| @@ -335,9 +322,10 @@ void InkDropAnimationController::AnimateShow(ui::Layer* layer, | 
| animation.SetPreemptionStrategy( | 
| ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); | 
| - gfx::Transform identity_transform; | 
| + gfx::Transform target_transform; | 
| + target_transform.Translate(ink_drop_bounds_.x(), ink_drop_bounds_.y()); | 
| ui::LayerAnimationElement* element = | 
| - ui::LayerAnimationElement::CreateTransformElement(identity_transform, | 
| + ui::LayerAnimationElement::CreateTransformElement(target_transform, | 
| duration); | 
| ui::LayerAnimationSequence* sequence = | 
| new ui::LayerAnimationSequence(element); | 
| @@ -345,48 +333,24 @@ void InkDropAnimationController::AnimateShow(ui::Layer* layer, | 
| animator->StartAnimation(sequence); | 
| } | 
| -void InkDropAnimationController::SetLayerBounds(ui::Layer* layer, | 
| - bool circle, | 
| - int width, | 
| - int height) { | 
| - float circle_width = circle ? 2.0f * kCircleRadius : width; | 
| - float circle_height = circle ? 2.0f * kCircleRadius : height; | 
| - float circle_x = circle ? (width - circle_width) * 0.5f : 0; | 
| - float circle_y = circle ? (height - circle_height) * 0.5f : 0; | 
| +void InkDropAnimationControllerImpl::SetLayerBounds(ui::Layer* layer) { | 
| + bool circle = UseCircularFeedback(); | 
| + gfx::Size size = ink_drop_bounds_.size(); | 
| + float circle_width = circle ? 2.0f * kCircleRadius : size.width(); | 
| + float circle_height = circle ? 2.0f * kCircleRadius : size.height(); | 
| + float circle_x = circle ? (size.width() - circle_width) * 0.5f : 0; | 
| + float circle_y = circle ? (size.height() - circle_height) * 0.5f : 0; | 
| layer->SetBounds(gfx::Rect(circle_x, circle_y, circle_width, circle_height)); | 
| } | 
| -void InkDropAnimationController::SetupAnimationLayer( | 
| - ui::Layer* parent, | 
| +void InkDropAnimationControllerImpl::SetupAnimationLayer( | 
| ui::Layer* layer, | 
| InkDropDelegate* delegate) { | 
| layer->SetFillsBoundsOpaquely(false); | 
| layer->set_delegate(delegate); | 
| layer->SetVisible(false); | 
| layer->SetBounds(gfx::Rect()); | 
| - parent->Add(layer); | 
| - parent->StackAtBottom(layer); | 
| -} | 
| - | 
| -void InkDropAnimationController::OnGestureEvent(ui::GestureEvent* event) { | 
| - if (event->target() != view_) | 
| - return; | 
| - | 
| - switch (event->type()) { | 
| - case ui::ET_GESTURE_TAP_DOWN: | 
| - AnimateTapDown(); | 
| - break; | 
| - case ui::ET_GESTURE_LONG_PRESS: | 
| - AnimateLongPress(); | 
| - break; | 
| - case ui::ET_GESTURE_END: | 
| - case ui::ET_GESTURE_TAP_CANCEL: | 
| - case ui::ET_GESTURE_TAP: | 
| - AnimateHide(); | 
| - break; | 
| - default: | 
| - break; | 
| - } | 
| + delegate->set_should_render_circle(UseCircularFeedback()); | 
| } | 
| } // namespace views |