Commit 5cab33d1 authored by Tommy C. Li's avatar Tommy C. Li Committed by Commit Bot

Omnibox UI Refresh: Implement popup open and close opacity animations.

This eases in and out the Omnibox popup opacity over 82ms as it opens
and closes. This matches the animation spec provided by UX.

Bug: 823535
Change-Id: Ic2add1f57f63ae6d043812f2bd5a766f84d302c9
Reviewed-on: https://chromium-review.googlesource.com/1081198
Commit-Queue: Tommy Li <tommycli@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarAli Juma <ajuma@chromium.org>
Cr-Commit-Position: refs/heads/master@{#564295}
parent ade42bd2
......@@ -29,7 +29,9 @@
#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/theme_provider.h"
#include "ui/compositor/clip_recorder.h"
#include "ui/compositor/closure_animation_observer.h"
#include "ui/compositor/paint_recorder.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/canvas.h"
......@@ -194,7 +196,65 @@ class OmniboxPopupContentsView::AutocompletePopupWidget
SetBounds(bounds);
}
void ShowAnimated() {
if (!LocationBarView::IsRounded()) {
ShowInactive();
return;
}
// Set the initial opacity to 0 and ease into fully opaque.
GetLayer()->SetOpacity(0.0);
ShowInactive();
auto scoped_settings = GetScopedAnimationSettings();
GetLayer()->SetOpacity(1.0);
}
void CloseAnimated() {
if (!LocationBarView::IsRounded()) {
// NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack
// triggered by the popup receiving a message (e.g. LBUTTONUP), and
// destroying the popup would cause us to read garbage when we unwind back
// to that level.
Close();
return;
}
// If the opening or shrinking animations still running, abort them, as the
// popup is closing. This is an edge case for superhumanly fast users.
GetLayer()->GetAnimator()->AbortAllAnimations();
auto scoped_settings = GetScopedAnimationSettings();
GetLayer()->SetOpacity(0.0);
// Destroy the popup when done. The observer deletes itself on completion.
scoped_settings->AddObserver(new ui::ClosureAnimationObserver(
base::BindOnce(&AutocompletePopupWidget::Close, AsWeakPtr())));
}
void OnNativeWidgetDestroying() override {
// End all our animations immediately, as our closing animation may trigger
// a Close call which will be invalid once the native widget is gone.
GetLayer()->GetAnimator()->AbortAllAnimations();
ThemeCopyingWidget::OnNativeWidgetDestroying();
}
private:
std::unique_ptr<ui::ScopedLayerAnimationSettings>
GetScopedAnimationSettings() {
auto settings = std::make_unique<ui::ScopedLayerAnimationSettings>(
GetLayer()->GetAnimator());
settings->SetTweenType(gfx::Tween::Type::FAST_OUT_SLOW_IN);
constexpr base::TimeDelta kPopupOpacityAnimationDuration =
base::TimeDelta::FromMilliseconds(82);
settings->SetTransitionDuration(kPopupOpacityAnimationDuration);
return settings;
}
std::unique_ptr<WidgetShrinkAnimation> animator_;
DISALLOW_COPY_AND_ASSIGN(AutocompletePopupWidget);
......@@ -318,11 +378,7 @@ void OmniboxPopupContentsView::UpdatePopupAppearance() {
// the omnibox popup window. Close any existing popup.
if (popup_) {
NotifyAccessibilityEvent(ax::mojom::Event::kExpandedChanged, true);
// NOTE: Do NOT use CloseNow() here, as we may be deep in a callstack
// triggered by the popup receiving a message (e.g. LBUTTONUP), and
// destroying the popup would cause us to read garbage when we unwind back
// to that level.
popup_->Close(); // This will eventually delete the popup.
popup_->CloseAnimated(); // This will eventually delete the popup.
popup_.reset();
}
return;
......@@ -378,7 +434,7 @@ void OmniboxPopupContentsView::UpdatePopupAppearance() {
if (!popup_)
return;
popup_->ShowInactive();
popup_->ShowAnimated();
// Popup is now expanded and first item will be selected.
NotifyAccessibilityEvent(ax::mojom::Event::kExpandedChanged, true);
......
......@@ -29,6 +29,7 @@
#include "components/omnibox/browser/omnibox_popup_model.h"
#include "content/public/test/test_utils.h"
#include "ui/base/ui_base_switches.h"
#include "ui/compositor/layer_animator.h"
#include "ui/events/test/event_generator.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
......@@ -412,6 +413,9 @@ IN_PROC_BROWSER_TEST_P(RoundedOmniboxPopupContentsViewTest,
generator.ClickLeftButton();
ASSERT_TRUE(GetPopupWidget());
// Instantly finish all queued animations.
GetPopupWidget()->GetLayer()->GetAnimator()->StopAnimating();
EXPECT_TRUE(GetPopupWidget()->IsClosed());
}
......
......@@ -6,8 +6,8 @@
namespace ui {
ClosureAnimationObserver::ClosureAnimationObserver(const base::Closure& closure)
: closure_(closure) {
ClosureAnimationObserver::ClosureAnimationObserver(base::OnceClosure closure)
: closure_(std::move(closure)) {
DCHECK(!closure_.is_null());
}
......@@ -15,7 +15,7 @@ ClosureAnimationObserver::~ClosureAnimationObserver() {
}
void ClosureAnimationObserver::OnImplicitAnimationsCompleted() {
closure_.Run();
std::move(closure_).Run();
delete this;
}
......
......@@ -17,7 +17,7 @@ namespace ui {
class COMPOSITOR_EXPORT ClosureAnimationObserver
: public ImplicitAnimationObserver {
public:
explicit ClosureAnimationObserver(const base::Closure& closure);
explicit ClosureAnimationObserver(base::OnceClosure closure);
private:
~ClosureAnimationObserver() override;
......@@ -25,7 +25,7 @@ class COMPOSITOR_EXPORT ClosureAnimationObserver
// ImplicitAnimationObserver:
void OnImplicitAnimationsCompleted() override;
const base::Closure closure_;
base::OnceClosure closure_;
DISALLOW_COPY_AND_ASSIGN(ClosureAnimationObserver);
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment