Commit 842373f4 authored by Melissa Zhang's avatar Melissa Zhang Committed by Commit Bot

[Sharesheet] Animate sharesheet open and close.

This CL adds animation to Sharesheet appear and disappear.
Appear has a opacity fade in from 0 - 100 in 100ms with linear curve
and scale fade in 80-100% in 150ms with curve (0.4,0,0.2,1).
Disappear is a 100-0 in 80ms linear opacity fade out.

In this CL we also disable sharesheet close on deactivate
when ShareActions have been selected.

Bug: 1148692
Change-Id: Id6a360438271ad62f5911ed97984c3230a448332
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2537502
Commit-Queue: Maggie Cai <mxcai@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828107}
parent a84b61ba
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/i18n/rtl.h" #include "base/i18n/rtl.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/time/time.h"
#include "chrome/app/vector_icons/vector_icons.h" #include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sharesheet/sharesheet_metrics.h" #include "chrome/browser/sharesheet/sharesheet_metrics.h"
...@@ -24,11 +25,15 @@ ...@@ -24,11 +25,15 @@
#include "ui/accessibility/ax_enums.mojom-forward.h" #include "ui/accessibility/ax_enums.mojom-forward.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/compositor/closure_animation_observer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/color_palette.h" #include "ui/gfx/color_palette.h"
#include "ui/gfx/font_list.h" #include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image_skia.h" #include "ui/gfx/image/image_skia.h"
#include "ui/gfx/transform_util.h"
#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/bubble/bubble_border.h" #include "ui/views/bubble/bubble_border.h"
#include "ui/views/bubble/bubble_frame_view.h" #include "ui/views/bubble/bubble_frame_view.h"
...@@ -72,6 +77,9 @@ constexpr int kShortSpacing = 20; ...@@ -72,6 +77,9 @@ constexpr int kShortSpacing = 20;
constexpr int kSpacing = 24; constexpr int kSpacing = 24;
constexpr int kTitleLineHeight = 24; constexpr int kTitleLineHeight = 24;
constexpr float kSharesheetOpacityTranslucent = 0.0f;
constexpr float kSharesheetOpacityOpaque = 1.0f;
constexpr char kTitleFont[] = "GoogleSans, Medium, 16px"; constexpr char kTitleFont[] = "GoogleSans, Medium, 16px";
constexpr char kExpandViewTitleFont[] = "Roboto, Medium, 15px"; constexpr char kExpandViewTitleFont[] = "Roboto, Medium, 15px";
...@@ -162,9 +170,9 @@ void SharesheetBubbleView::ShowBubble( ...@@ -162,9 +170,9 @@ void SharesheetBubbleView::ShowBubble(
main_view_->RequestFocus(); main_view_->RequestFocus();
main_view_->GetViewAccessibility().OverrideName( main_view_->GetViewAccessibility().OverrideName(
l10n_util::GetStringUTF16(IDS_SHARESHEET_TITLE_LABEL)); l10n_util::GetStringUTF16(IDS_SHARESHEET_TITLE_LABEL));
views::Widget* widget = views::BubbleDialogDelegateView::CreateBubble(this); views::BubbleDialogDelegateView::CreateBubble(this);
GetWidget()->GetRootView()->Layout(); GetWidget()->GetRootView()->Layout();
widget->Show(); ShowWidgetWithAnimateFadeIn();
if (expanded_view_ == nullptr || expanded_view_->children().size() > 1) { if (expanded_view_ == nullptr || expanded_view_->children().size() > 1) {
SetToDefaultBubbleSizing(); SetToDefaultBubbleSizing();
...@@ -290,20 +298,18 @@ void SharesheetBubbleView::ResizeBubble(const int& width, const int& height) { ...@@ -290,20 +298,18 @@ void SharesheetBubbleView::ResizeBubble(const int& width, const int& height) {
UpdateAnchorPosition(); UpdateAnchorPosition();
} }
// This function is called from a ShareAction or after an app launches.
void SharesheetBubbleView::CloseBubble() { void SharesheetBubbleView::CloseBubble() {
views::Widget* widget = View::GetWidget(); CloseWidgetWithAnimateFadeOut(
widget->CloseWithReason(views::Widget::ClosedReason::kAcceptButtonClicked); views::Widget::ClosedReason::kAcceptButtonClicked);
// Reset all bubble values.
active_target_ = base::string16();
intent_.reset();
keyboard_highlighted_target_ = 0;
SetToDefaultBubbleSizing();
} }
void SharesheetBubbleView::OnKeyEvent(ui::KeyEvent* event) { void SharesheetBubbleView::OnKeyEvent(ui::KeyEvent* event) {
// Ignore key press if bubble is closing.
// TODO(crbug.com/1141741) Update to OnKeyPressed. // TODO(crbug.com/1141741) Update to OnKeyPressed.
if (!IsKeyboardCodeArrow(event->key_code()) || if (!IsKeyboardCodeArrow(event->key_code()) ||
event->type() != ui::ET_KEY_RELEASED || default_view_ == nullptr) { event->type() != ui::ET_KEY_RELEASED || default_view_ == nullptr ||
is_bubble_closing_) {
return; return;
} }
...@@ -368,21 +374,23 @@ gfx::Size SharesheetBubbleView::CalculatePreferredSize() const { ...@@ -368,21 +374,23 @@ gfx::Size SharesheetBubbleView::CalculatePreferredSize() const {
return gfx::Size(width_, height_); return gfx::Size(width_, height_);
} }
void SharesheetBubbleView::OnWidgetDestroyed(views::Widget* widget) { void SharesheetBubbleView::OnWidgetActivationChanged(views::Widget* widget,
// If there is no active_target_ value, the user cancelled without making a bool active) {
// selection and we will record this. // Catch widgets that are closing due to the user clicking out of the bubble.
if (user_cancelled_) { // If |user_selection_made_| we should not close the bubble here as it will be
// closed in a different code path.
if (!active && !user_selection_made_) {
if (close_callback_) {
std::move(close_callback_).Run(sharesheet::SharesheetResult::kCancel);
}
sharesheet::SharesheetMetrics::RecordSharesheetActionMetrics( sharesheet::SharesheetMetrics::RecordSharesheetActionMetrics(
sharesheet::SharesheetMetrics::UserAction::kCancelled); sharesheet::SharesheetMetrics::UserAction::kCancelled);
} CloseWidgetWithAnimateFadeOut(views::Widget::ClosedReason::kLostFocus);
delegate_->OnBubbleClosed(active_target_);
if (close_callback_) {
std::move(close_callback_).Run(sharesheet::SharesheetResult::kCancel);
} }
} }
void SharesheetBubbleView::CreateBubble() { void SharesheetBubbleView::CreateBubble() {
set_close_on_deactivate(true); set_close_on_deactivate(false);
SetButtons(ui::DIALOG_BUTTON_NONE); SetButtons(ui::DIALOG_BUTTON_NONE);
SetLayoutManager(std::make_unique<views::BoxLayout>( SetLayoutManager(std::make_unique<views::BoxLayout>(
...@@ -418,6 +426,7 @@ void SharesheetBubbleView::ExpandButtonPressed() { ...@@ -418,6 +426,7 @@ void SharesheetBubbleView::ExpandButtonPressed() {
} }
void SharesheetBubbleView::TargetButtonPressed(TargetInfo target) { void SharesheetBubbleView::TargetButtonPressed(TargetInfo target) {
user_selection_made_ = true;
auto type = target.type; auto type = target.type;
if (type == sharesheet::TargetType::kAction) if (type == sharesheet::TargetType::kAction)
active_target_ = target.launch_name; active_target_ = target.launch_name;
...@@ -426,7 +435,6 @@ void SharesheetBubbleView::TargetButtonPressed(TargetInfo target) { ...@@ -426,7 +435,6 @@ void SharesheetBubbleView::TargetButtonPressed(TargetInfo target) {
delegate_->OnTargetSelected(target.launch_name, type, std::move(intent_), delegate_->OnTargetSelected(target.launch_name, type, std::move(intent_),
share_action_view_); share_action_view_);
intent_.reset(); intent_.reset();
user_cancelled_ = false;
if (close_callback_) if (close_callback_)
std::move(close_callback_).Run(sharesheet::SharesheetResult::kSuccess); std::move(close_callback_).Run(sharesheet::SharesheetResult::kSuccess);
} }
...@@ -454,3 +462,61 @@ void SharesheetBubbleView::SetToDefaultBubbleSizing() { ...@@ -454,3 +462,61 @@ void SharesheetBubbleView::SetToDefaultBubbleSizing() {
width_ = kDefaultBubbleWidth; width_ = kDefaultBubbleWidth;
height_ = kDefaultBubbleHeight; height_ = kDefaultBubbleHeight;
} }
void SharesheetBubbleView::ShowWidgetWithAnimateFadeIn() {
constexpr float kSharesheetScaleUpFactor = 0.8f;
constexpr base::TimeDelta kSharesheetScaleUpTime =
base::TimeDelta::FromMilliseconds(150);
constexpr base::TimeDelta kSharesheetOpacityFadeInTime =
base::TimeDelta::FromMilliseconds(100);
views::Widget* widget = View::GetWidget();
ui::Layer* layer = widget->GetLayer();
layer->SetOpacity(kSharesheetOpacityTranslucent);
widget->ShowInactive();
gfx::Transform transform = gfx::GetScaleTransform(
gfx::Rect(layer->size()).CenterPoint(), kSharesheetScaleUpFactor);
layer->SetTransform(transform);
auto scoped_settings =
std::make_unique<ui::ScopedLayerAnimationSettings>(layer->GetAnimator());
scoped_settings->SetTransitionDuration(kSharesheetScaleUpTime);
scoped_settings->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN);
layer->SetTransform(gfx::Transform());
scoped_settings->SetTransitionDuration(kSharesheetOpacityFadeInTime);
scoped_settings->SetTweenType(gfx::Tween::Type::LINEAR);
layer->SetOpacity(kSharesheetOpacityOpaque);
widget->Activate();
}
void SharesheetBubbleView::CloseWidgetWithAnimateFadeOut(
views::Widget::ClosedReason closed_reason) {
constexpr base::TimeDelta kSharesheetOpacityFadeOutTime =
base::TimeDelta::FromMilliseconds(80);
is_bubble_closing_ = true;
ui::Layer* layer = View::GetWidget()->GetLayer();
// If open animation is still running, abort it as we are now closing.
layer->GetAnimator()->AbortAllAnimations();
auto scoped_settings =
std::make_unique<ui::ScopedLayerAnimationSettings>(layer->GetAnimator());
scoped_settings->SetTweenType(gfx::Tween::Type::LINEAR);
scoped_settings->SetTransitionDuration(kSharesheetOpacityFadeOutTime);
layer->SetOpacity(kSharesheetOpacityTranslucent);
// We are closing the native widget during the close animation which results
// in destroying the layer and the animation and the observer not calling
// back. Thus it is safe to use base::Unretained here.
scoped_settings->AddObserver(new ui::ClosureAnimationObserver(
base::BindOnce(&SharesheetBubbleView::CloseWidgetWithReason,
base::Unretained(this), closed_reason)));
}
void SharesheetBubbleView::CloseWidgetWithReason(
views::Widget::ClosedReason closed_reason) {
View::GetWidget()->CloseWithReason(closed_reason);
// Bubble is deleted here.
delegate_->OnBubbleClosed(active_target_);
}
...@@ -57,7 +57,7 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView { ...@@ -57,7 +57,7 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView {
// views::BubbleDialogDelegateView: // views::BubbleDialogDelegateView:
gfx::Size CalculatePreferredSize() const override; gfx::Size CalculatePreferredSize() const override;
void OnWidgetDestroyed(views::Widget* widget) override; void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
void CreateBubble(); void CreateBubble();
std::unique_ptr<views::View> MakeScrollableTargetView( std::unique_ptr<views::View> MakeScrollableTargetView(
...@@ -69,6 +69,9 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView { ...@@ -69,6 +69,9 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView {
void TargetButtonPressed(TargetInfo target); void TargetButtonPressed(TargetInfo target);
void UpdateAnchorPosition(); void UpdateAnchorPosition();
void SetToDefaultBubbleSizing(); void SetToDefaultBubbleSizing();
void ShowWidgetWithAnimateFadeIn();
void CloseWidgetWithAnimateFadeOut(views::Widget::ClosedReason closed_reason);
void CloseWidgetWithReason(views::Widget::ClosedReason closed_reason);
// Owns this class. // Owns this class.
sharesheet::SharesheetServiceDelegate* delegate_; sharesheet::SharesheetServiceDelegate* delegate_;
...@@ -78,8 +81,9 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView { ...@@ -78,8 +81,9 @@ class SharesheetBubbleView : public views::BubbleDialogDelegateView {
int width_ = 0; int width_ = 0;
int height_ = 0; int height_ = 0;
bool user_cancelled_ = true;
bool show_expanded_view_ = false; bool show_expanded_view_ = false;
bool is_bubble_closing_ = false;
bool user_selection_made_ = false;
size_t keyboard_highlighted_target_ = 0; size_t keyboard_highlighted_target_ = 0;
......
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