Commit 39dfb7b5 authored by Dana Fried's avatar Dana Fried Committed by Commit Bot

Mohnstrudel: Base animation type and duration off of user gesture.

As per request from UX, we are using:
- linear-in for fling animations
- shorter time for fling animations based on the amount of distance to
  the end of the animation

TODO: consider basing animation time on fling speed, but fling speed
seems to be highly unreliable and dependent on system event handling.

Bug: 1116651
Change-Id: Ie768e83463532de841a4b80abb80a4d5ff9afedd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2368106
Commit-Queue: Dana Fried <dfried@chromium.org>
Reviewed-by: default avatarCharlene Yan <cyan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#800711}
parent bac1febe
...@@ -81,8 +81,80 @@ ...@@ -81,8 +81,80 @@
// can use it in module local methods. // can use it in module local methods.
enum class WebUITabStripDragDirection { kUp, kDown }; enum class WebUITabStripDragDirection { kUp, kDown };
// Represents which type of event is causing the WebUI tab strip to open or
// close. Note that currently |kDragRelease| and |kOther| behave the same but
// they're conceptually different and could use different logic in the future.
enum class WebUITabStripOpenCloseReason {
// User drags the toolbar up or down and releases it partway.
kDragRelease,
// User flings, flicks, or swipes the toolbar up or down (possibly during a
// drag).
kFling,
// The tabstrip is opened or closed as the result of some other action or
// event not tied to the user directly manipulating the toolbar.
kOther
};
namespace { namespace {
// Returns the animation curve to use for different types of events that could
// cause the tabstrip to be revealed or hidden.
gfx::Tween::Type GetTweenTypeForTabstripOpenClose(
WebUITabStripOpenCloseReason reason) {
switch (reason) {
case WebUITabStripOpenCloseReason::kDragRelease:
// case falls through
case WebUITabStripOpenCloseReason::kOther:
return gfx::Tween::FAST_OUT_SLOW_IN;
case WebUITabStripOpenCloseReason::kFling:
return gfx::Tween::LINEAR_OUT_SLOW_IN;
}
}
// Returns the base duration of the animation used to open or close the
// tabstrip, before changes are made for shade positioning, gesture velocity,
// etc.
base::TimeDelta GetBaseTabstripOpenCloseAnimationDuration(
WebUITabStripDragDirection direction) {
// These values were determined by UX; in the future we may want to change
// values for fling animations to be consistent for both open and close
// gestures.
constexpr base::TimeDelta kHideAnimationDuration =
base::TimeDelta::FromMilliseconds(200);
constexpr base::TimeDelta kShowAnimationDuration =
base::TimeDelta::FromMilliseconds(250);
switch (direction) {
case WebUITabStripDragDirection::kUp:
return kHideAnimationDuration;
case WebUITabStripDragDirection::kDown:
return kShowAnimationDuration;
}
}
// Returns the actual duration of the animation used to open or close the
// tabstrip based on open/close reason, movement direction, and the current
// position of the toolbar.
base::TimeDelta GetTimeDeltaForTabstripOpenClose(
WebUITabStripOpenCloseReason reason,
WebUITabStripDragDirection direction,
double percent_remaining) {
base::TimeDelta duration =
GetBaseTabstripOpenCloseAnimationDuration(direction);
// Fling gestures get shortened based on how little space is left for the
// toolbar to move. Ideally we'd base it on fling velocity instead but (a) the
// animation is already very fast, and (b) the event reporting around drag vs.
// fling is not granular enough to give consistent results.
if (reason == WebUITabStripOpenCloseReason::kFling) {
constexpr base::TimeDelta kMinimumAnimationDuration =
base::TimeDelta::FromMilliseconds(75);
duration =
std::max(kMinimumAnimationDuration, duration * percent_remaining);
}
return duration;
}
// Converts a y-delta to a drag direction. // Converts a y-delta to a drag direction.
WebUITabStripDragDirection DragDirectionFromDelta(float delta) { WebUITabStripDragDirection DragDirectionFromDelta(float delta) {
DCHECK(delta != 0.0f); DCHECK(delta != 0.0f);
...@@ -455,7 +527,6 @@ WebUITabStripContainerView::WebUITabStripContainerView( ...@@ -455,7 +527,6 @@ WebUITabStripContainerView::WebUITabStripContainerView(
browser_view->feature_promo_controller())) { browser_view->feature_promo_controller())) {
TRACE_EVENT0("ui", "WebUITabStripContainerView.Init"); TRACE_EVENT0("ui", "WebUITabStripContainerView.Init");
DCHECK(UseTouchableTabStrip(browser_)); DCHECK(UseTouchableTabStrip(browser_));
animation_.SetTweenType(gfx::Tween::Type::FAST_OUT_SLOW_IN);
SetVisible(false); SetVisible(false);
animation_.Reset(0.0); animation_.Reset(0.0);
...@@ -547,7 +618,7 @@ void WebUITabStripContainerView::OpenForTabDrag() { ...@@ -547,7 +618,7 @@ void WebUITabStripContainerView::OpenForTabDrag() {
return; return;
RecordTabStripUIOpenHistogram(TabStripUIOpenAction::kTabDraggedIntoWindow); RecordTabStripUIOpenHistogram(TabStripUIOpenAction::kTabDraggedIntoWindow);
SetContainerTargetVisibility(true); SetContainerTargetVisibility(true, WebUITabStripOpenCloseReason::kOther);
} }
views::NativeViewHost* WebUITabStripContainerView::GetNativeViewHost() { views::NativeViewHost* WebUITabStripContainerView::GetNativeViewHost() {
...@@ -569,7 +640,7 @@ std::unique_ptr<views::View> WebUITabStripContainerView::CreateTabCounter() { ...@@ -569,7 +640,7 @@ std::unique_ptr<views::View> WebUITabStripContainerView::CreateTabCounter() {
} }
void WebUITabStripContainerView::SetVisibleForTesting(bool visible) { void WebUITabStripContainerView::SetVisibleForTesting(bool visible) {
SetContainerTargetVisibility(visible); SetContainerTargetVisibility(visible, WebUITabStripOpenCloseReason::kOther);
FinishAnimationForTesting(); FinishAnimationForTesting();
} }
...@@ -588,7 +659,7 @@ WebUITabStripContainerView::GetAcceleratorProvider() const { ...@@ -588,7 +659,7 @@ WebUITabStripContainerView::GetAcceleratorProvider() const {
} }
void WebUITabStripContainerView::CloseContainer() { void WebUITabStripContainerView::CloseContainer() {
SetContainerTargetVisibility(false); SetContainerTargetVisibility(false, WebUITabStripOpenCloseReason::kOther);
iph_controller_->NotifyClosed(); iph_controller_->NotifyClosed();
} }
...@@ -643,11 +714,15 @@ void WebUITabStripContainerView::EndDragToOpen( ...@@ -643,11 +714,15 @@ void WebUITabStripContainerView::EndDragToOpen(
} }
animation_.Reset(open_proportion); animation_.Reset(open_proportion);
SetContainerTargetVisibility(opening); SetContainerTargetVisibility(
opening, fling_direction.has_value()
? WebUITabStripOpenCloseReason::kFling
: WebUITabStripOpenCloseReason::kDragRelease);
} }
void WebUITabStripContainerView::SetContainerTargetVisibility( void WebUITabStripContainerView::SetContainerTargetVisibility(
bool target_visible) { bool target_visible,
WebUITabStripOpenCloseReason reason) {
if (target_visible) { if (target_visible) {
immersive_revealed_lock_.reset( immersive_revealed_lock_.reset(
BrowserView::GetBrowserViewForBrowser(browser_) BrowserView::GetBrowserViewForBrowser(browser_)
...@@ -656,8 +731,12 @@ void WebUITabStripContainerView::SetContainerTargetVisibility( ...@@ -656,8 +731,12 @@ void WebUITabStripContainerView::SetContainerTargetVisibility(
SetVisible(true); SetVisible(true);
PreferredSizeChanged(); PreferredSizeChanged();
if (animation_.GetCurrentValue() < 1.0) { const double current_value = animation_.GetCurrentValue();
animation_.SetSlideDuration(base::TimeDelta::FromMilliseconds(250)); if (current_value < 1.0) {
animation_.SetSlideDuration(GetTimeDeltaForTabstripOpenClose(
reason, WebUITabStripDragDirection::kDown,
/* percent_remaining */ 1.0 - current_value));
animation_.SetTweenType(GetTweenTypeForTabstripOpenClose(reason));
animation_.Show(); animation_.Show();
} }
...@@ -678,8 +757,12 @@ void WebUITabStripContainerView::SetContainerTargetVisibility( ...@@ -678,8 +757,12 @@ void WebUITabStripContainerView::SetContainerTargetVisibility(
time_at_open_ = base::nullopt; time_at_open_ = base::nullopt;
} }
if (animation_.GetCurrentValue() > 0.0) { const double current_value = animation_.GetCurrentValue();
animation_.SetSlideDuration(base::TimeDelta::FromMilliseconds(200)); if (current_value > 0.0) {
animation_.SetSlideDuration(GetTimeDeltaForTabstripOpenClose(
reason, WebUITabStripDragDirection::kUp,
/* percent_remaining */ current_value));
animation_.SetTweenType(GetTweenTypeForTabstripOpenClose(reason));
animation_.Hide(); animation_.Hide();
} else { } else {
PreferredSizeChanged(); PreferredSizeChanged();
...@@ -697,7 +780,7 @@ void WebUITabStripContainerView::CloseForEventOutsideTabStrip( ...@@ -697,7 +780,7 @@ void WebUITabStripContainerView::CloseForEventOutsideTabStrip(
TabStripUICloseAction reason) { TabStripUICloseAction reason) {
RecordTabStripUICloseHistogram(reason); RecordTabStripUICloseHistogram(reason);
iph_controller_->NotifyClosed(); iph_controller_->NotifyClosed();
SetContainerTargetVisibility(false); SetContainerTargetVisibility(false, WebUITabStripOpenCloseReason::kOther);
} }
void WebUITabStripContainerView::AnimationEnded( void WebUITabStripContainerView::AnimationEnded(
...@@ -784,7 +867,8 @@ void WebUITabStripContainerView::ButtonPressed(views::Button* sender, ...@@ -784,7 +867,8 @@ void WebUITabStripContainerView::ButtonPressed(views::Button* sender,
iph_controller_->NotifyClosed(); iph_controller_->NotifyClosed();
} }
SetContainerTargetVisibility(new_visibility); SetContainerTargetVisibility(new_visibility,
WebUITabStripOpenCloseReason::kOther);
if (GetVisible() && sender->HasFocus()) { if (GetVisible() && sender->HasFocus()) {
// Automatically move focus to the tab strip WebUI if the focus is // Automatically move focus to the tab strip WebUI if the focus is
......
...@@ -40,6 +40,7 @@ class WebView; ...@@ -40,6 +40,7 @@ class WebView;
class Browser; class Browser;
class BrowserView; class BrowserView;
enum class WebUITabStripDragDirection; enum class WebUITabStripDragDirection;
enum class WebUITabStripOpenCloseReason;
class ImmersiveRevealedLock; class ImmersiveRevealedLock;
class WebUITabStripContainerView : public TabStripUIEmbedder, class WebUITabStripContainerView : public TabStripUIEmbedder,
...@@ -96,7 +97,8 @@ class WebUITabStripContainerView : public TabStripUIEmbedder, ...@@ -96,7 +97,8 @@ class WebUITabStripContainerView : public TabStripUIEmbedder,
void EndDragToOpen(base::Optional<WebUITabStripDragDirection> void EndDragToOpen(base::Optional<WebUITabStripDragDirection>
fling_direction = base::nullopt); fling_direction = base::nullopt);
void SetContainerTargetVisibility(bool target_visible); void SetContainerTargetVisibility(bool target_visible,
WebUITabStripOpenCloseReason reason);
// Passed to the AutoCloser to handle closing. // Passed to the AutoCloser to handle closing.
void CloseForEventOutsideTabStrip(TabStripUICloseAction reason); void CloseForEventOutsideTabStrip(TabStripUICloseAction reason);
......
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