blob: 117f723c648ad609f0b5928b343fc67b7e03c152 [file] [log] [blame] [edit]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/wm/splitview/split_view_utils.h"
#include "ash/wm/splitview/split_view_constants.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
namespace ash {
namespace {
// The animation speed at which the highlights fade in or out.
constexpr base::TimeDelta kHighlightsFadeInOutMs =
base::TimeDelta::FromMilliseconds(250);
// The animation speed which the other highlight fades in or out.
constexpr base::TimeDelta kOtherFadeInOutMs =
base::TimeDelta::FromMilliseconds(133);
// The delay before the other highlight starts fading in or out.
constexpr base::TimeDelta kOtherFadeOutDelayMs =
base::TimeDelta::FromMilliseconds(117);
// The animation speed for any animation on the indicator labels.
constexpr base::TimeDelta kLabelAnimationMs =
base::TimeDelta::FromMilliseconds(83);
// The delay before the indicator labels start animating.
constexpr base::TimeDelta kLabelAnimationDelayMs =
base::TimeDelta::FromMilliseconds(167);
// The time duration for the window transformation animations.
constexpr base::TimeDelta kWindowTransformMs =
base::TimeDelta::FromMilliseconds(250);
constexpr float kHighlightOpacity = 0.3f;
constexpr float kPreviewAreaHighlightOpacity = 0.18f;
// Gets the duration, tween type and delay before animation based on |type|.
void GetAnimationValuesForType(
SplitviewAnimationType type,
base::TimeDelta* out_duration,
gfx::Tween::Type* out_tween_type,
ui::LayerAnimator::PreemptionStrategy* out_preemption_strategy,
base::TimeDelta* out_delay) {
*out_preemption_strategy = ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET;
switch (type) {
case SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_IN:
case SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_OUT:
case SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_IN:
case SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_OUT:
case SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_IN:
case SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_OUT:
case SPLITVIEW_ANIMATION_TEXT_FADE_IN_WITH_HIGHLIGHT:
case SPLITVIEW_ANIMATION_TEXT_FADE_OUT_WITH_HIGHLIGHT:
case SPLITVIEW_ANIMATION_PREVIEW_AREA_SLIDE_IN_OUT:
*out_duration = kHighlightsFadeInOutMs;
*out_tween_type = gfx::Tween::FAST_OUT_SLOW_IN;
return;
case SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_IN:
case SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_SLIDE_IN:
*out_duration = kOtherFadeInOutMs;
*out_tween_type = gfx::Tween::LINEAR_OUT_SLOW_IN;
return;
case SPLITVIEW_ANIMATION_TEXT_FADE_IN:
case SPLITVIEW_ANIMATION_TEXT_FADE_OUT:
case SPLITVIEW_ANIMATION_TEXT_SLIDE_IN:
case SPLITVIEW_ANIMATION_TEXT_SLIDE_OUT:
if (type == SPLITVIEW_ANIMATION_TEXT_SLIDE_IN)
*out_delay = kLabelAnimationDelayMs;
*out_duration = kLabelAnimationMs;
*out_tween_type = gfx::Tween::LINEAR_OUT_SLOW_IN;
return;
case SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_OUT:
case SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_SLIDE_OUT:
*out_delay = kOtherFadeOutDelayMs;
*out_duration = kOtherFadeInOutMs;
*out_tween_type = gfx::Tween::LINEAR_OUT_SLOW_IN;
return;
case SPLITVIEW_ANIMATION_SET_WINDOW_TRANSFORM:
*out_duration = kWindowTransformMs;
*out_tween_type = gfx::Tween::FAST_OUT_SLOW_IN;
*out_preemption_strategy =
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET;
return;
}
NOTREACHED();
}
// Helper function to apply animation values to |settings|.
void ApplyAnimationSettings(
ui::ScopedLayerAnimationSettings* settings,
ui::LayerAnimator* animator,
base::TimeDelta duration,
gfx::Tween::Type tween,
ui::LayerAnimator::PreemptionStrategy preemption_strategy,
base::TimeDelta delay) {
DCHECK_EQ(settings->GetAnimator(), animator);
settings->SetTransitionDuration(duration);
settings->SetTweenType(tween);
settings->SetPreemptionStrategy(preemption_strategy);
if (!delay.is_zero()) {
settings->SetPreemptionStrategy(
ui::LayerAnimator::REPLACE_QUEUED_ANIMATIONS);
animator->SchedulePauseForProperties(
delay, ui::LayerAnimationElement::OPACITY |
ui::LayerAnimationElement::TRANSFORM);
}
}
} // namespace
void DoSplitviewOpacityAnimation(ui::Layer* layer,
SplitviewAnimationType type) {
float target_opacity = 0.f;
switch (type) {
case SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_OUT:
case SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_OUT:
case SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_OUT:
case SPLITVIEW_ANIMATION_TEXT_FADE_OUT:
case SPLITVIEW_ANIMATION_TEXT_FADE_OUT_WITH_HIGHLIGHT:
target_opacity = 0.f;
break;
case SPLITVIEW_ANIMATION_HIGHLIGHT_FADE_IN:
case SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_FADE_IN:
case SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_IN:
target_opacity = kPreviewAreaHighlightOpacity;
break;
case SPLITVIEW_ANIMATION_PREVIEW_AREA_FADE_OUT:
target_opacity = kHighlightOpacity;
break;
case SPLITVIEW_ANIMATION_SELECTOR_ITEM_FADE_IN:
case SPLITVIEW_ANIMATION_TEXT_FADE_IN:
case SPLITVIEW_ANIMATION_TEXT_FADE_IN_WITH_HIGHLIGHT:
target_opacity = 1.f;
break;
default:
NOTREACHED() << "Not a valid split view opacity animation type.";
return;
}
if (layer->GetTargetOpacity() == target_opacity)
return;
base::TimeDelta duration;
gfx::Tween::Type tween;
ui::LayerAnimator::PreemptionStrategy preemption_strategy;
base::TimeDelta delay;
GetAnimationValuesForType(type, &duration, &tween, &preemption_strategy,
&delay);
ui::LayerAnimator* animator = layer->GetAnimator();
ui::ScopedLayerAnimationSettings settings(animator);
ApplyAnimationSettings(&settings, animator, duration, tween,
preemption_strategy, delay);
layer->SetOpacity(target_opacity);
}
void DoSplitviewTransformAnimation(ui::Layer* layer,
SplitviewAnimationType type,
const gfx::Transform& target_transform) {
if (layer->GetTargetTransform() == target_transform)
return;
switch (type) {
case SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_SLIDE_IN:
case SPLITVIEW_ANIMATION_OTHER_HIGHLIGHT_SLIDE_OUT:
case SPLITVIEW_ANIMATION_PREVIEW_AREA_SLIDE_IN_OUT:
case SPLITVIEW_ANIMATION_SET_WINDOW_TRANSFORM:
case SPLITVIEW_ANIMATION_TEXT_SLIDE_IN:
case SPLITVIEW_ANIMATION_TEXT_SLIDE_OUT:
break;
default:
NOTREACHED() << "Not a valid split view transform type.";
return;
}
base::TimeDelta duration;
gfx::Tween::Type tween;
ui::LayerAnimator::PreemptionStrategy preemption_strategy;
base::TimeDelta delay;
GetAnimationValuesForType(type, &duration, &tween, &preemption_strategy,
&delay);
ui::LayerAnimator* animator = layer->GetAnimator();
ui::ScopedLayerAnimationSettings settings(animator);
ApplyAnimationSettings(&settings, animator, duration, tween,
preemption_strategy, delay);
layer->SetTransform(target_transform);
}
} // namespace ash