summaryrefslogtreecommitdiff
path: root/chromium/cc/input
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@theqtcompany.com>2015-06-18 14:10:49 +0200
committerOswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>2015-06-18 13:53:24 +0000
commit813fbf95af77a531c57a8c497345ad2c61d475b3 (patch)
tree821b2c8de8365f21b6c9ba17a236fb3006a1d506 /chromium/cc/input
parentaf6588f8d723931a298c995fa97259bb7f7deb55 (diff)
downloadqtwebengine-chromium-813fbf95af77a531c57a8c497345ad2c61d475b3.tar.gz
BASELINE: Update chromium to 44.0.2403.47
Change-Id: Ie056fedba95cf5e5c76b30c4b2c80fca4764aa2f Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'chromium/cc/input')
-rw-r--r--chromium/cc/input/input_handler.h38
-rw-r--r--chromium/cc/input/layer_selection_bound.h3
-rw-r--r--chromium/cc/input/page_scale_animation.h19
-rw-r--r--chromium/cc/input/scroll_elasticity_helper.cc91
-rw-r--r--chromium/cc/input/scroll_elasticity_helper.h73
-rw-r--r--chromium/cc/input/selection.h38
-rw-r--r--chromium/cc/input/top_controls_manager.cc172
-rw-r--r--chromium/cc/input/top_controls_manager.h34
-rw-r--r--chromium/cc/input/top_controls_manager_client.h5
-rw-r--r--chromium/cc/input/top_controls_manager_unittest.cc286
10 files changed, 536 insertions, 223 deletions
diff --git a/chromium/cc/input/input_handler.h b/chromium/cc/input/input_handler.h
index 7a9c9919687..81d91b87143 100644
--- a/chromium/cc/input/input_handler.h
+++ b/chromium/cc/input/input_handler.h
@@ -9,8 +9,8 @@
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "cc/base/cc_export.h"
-#include "cc/base/swap_promise_monitor.h"
#include "cc/input/scrollbar.h"
+#include "cc/trees/swap_promise_monitor.h"
namespace gfx {
class Point;
@@ -24,6 +24,7 @@ namespace ui { struct LatencyInfo; }
namespace cc {
class LayerScrollOffsetDelegate;
+class ScrollElasticityHelper;
struct CC_EXPORT InputHandlerScrollResult {
InputHandlerScrollResult();
@@ -47,6 +48,7 @@ class CC_EXPORT InputHandlerClient {
virtual void WillShutdown() = 0;
virtual void Animate(base::TimeTicks time) = 0;
virtual void MainThreadHasStoppedFlinging() = 0;
+ virtual void ReconcileElasticOverscrollAndRootScroll() = 0;
protected:
InputHandlerClient() {}
@@ -64,14 +66,14 @@ class CC_EXPORT InputHandler {
// Note these are used in a histogram. Do not reorder or delete existing
// entries.
enum ScrollStatus {
- ScrollOnMainThread = 0,
- ScrollStarted,
- ScrollIgnored,
- ScrollUnknown,
+ SCROLL_ON_MAIN_THREAD = 0,
+ SCROLL_STARTED,
+ SCROLL_IGNORED,
+ SCROLL_UNKNOWN,
// This must be the last entry.
ScrollStatusCount
};
- enum ScrollInputType { Gesture, Wheel, NonBubblingGesture };
+ enum ScrollInputType { GESTURE, WHEEL, NON_BUBBLING_GESTURE };
// Binds a client to this handler to receive notifications. Only one client
// can be bound to an InputHandler. The client must live at least until the
@@ -79,10 +81,10 @@ class CC_EXPORT InputHandler {
virtual void BindToClient(InputHandlerClient* client) = 0;
// Selects a layer to be scrolled at a given point in viewport (logical
- // pixel) coordinates. Returns ScrollStarted if the layer at the coordinates
- // can be scrolled, ScrollOnMainThread if the scroll event should instead be
- // delegated to the main thread, or ScrollIgnored if there is nothing to be
- // scrolled at the given coordinates.
+ // pixel) coordinates. Returns SCROLL_STARTED if the layer at the coordinates
+ // can be scrolled, SCROLL_ON_MAIN_THREAD if the scroll event should instead
+ // be delegated to the main thread, or SCROLL_IGNORED if there is nothing to
+ // be scrolled at the given coordinates.
virtual ScrollStatus ScrollBegin(const gfx::Point& viewport_point,
ScrollInputType type) = 0;
@@ -100,7 +102,7 @@ class CC_EXPORT InputHandler {
// If the scroll delta hits the root layer, and the layer can no longer move,
// the root overscroll accumulated within this ScrollBegin() scope is reported
// in the return value's |accumulated_overscroll| field.
- // Should only be called if ScrollBegin() returned ScrollStarted.
+ // Should only be called if ScrollBegin() returned SCROLL_STARTED.
virtual InputHandlerScrollResult ScrollBy(
const gfx::Point& viewport_point,
const gfx::Vector2dF& scroll_delta) = 0;
@@ -108,14 +110,14 @@ class CC_EXPORT InputHandler {
virtual bool ScrollVerticallyByPage(const gfx::Point& viewport_point,
ScrollDirection direction) = 0;
- // Returns ScrollStarted if a layer was being actively being scrolled,
- // ScrollIgnored if not.
+ // Returns SCROLL_STARTED if a layer was being actively being scrolled,
+ // SCROLL_IGNORED if not.
virtual ScrollStatus FlingScrollBegin() = 0;
virtual void MouseMoveAt(const gfx::Point& mouse_position) = 0;
// Stop scrolling the selected layer. Should only be called if ScrollBegin()
- // returned ScrollStarted.
+ // returned SCROLL_STARTED.
virtual void ScrollEnd() = 0;
virtual void SetRootLayerScrollOffsetDelegate(
@@ -140,7 +142,11 @@ class CC_EXPORT InputHandler {
virtual bool IsCurrentlyScrollingLayerAt(const gfx::Point& viewport_point,
ScrollInputType type) = 0;
- virtual bool HaveTouchEventHandlersAt(const gfx::Point& viewport_point) = 0;
+ virtual bool HaveWheelEventHandlersAt(const gfx::Point& viewport_point) = 0;
+
+ // Whether the page should be given the opportunity to suppress scrolling by
+ // consuming touch events that started at |viewport_point|.
+ virtual bool DoTouchEventsBlockScrollAt(const gfx::Point& viewport_point) = 0;
// Calling CreateLatencyInfoSwapPromiseMonitor() to get a scoped
// LatencyInfoSwapPromiseMonitor. During the life time of the
@@ -150,6 +156,8 @@ class CC_EXPORT InputHandler {
virtual scoped_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor(
ui::LatencyInfo* latency) = 0;
+ virtual ScrollElasticityHelper* CreateScrollElasticityHelper() = 0;
+
protected:
InputHandler() {}
virtual ~InputHandler() {}
diff --git a/chromium/cc/input/layer_selection_bound.h b/chromium/cc/input/layer_selection_bound.h
index 21d52849cf3..10b14d904d2 100644
--- a/chromium/cc/input/layer_selection_bound.h
+++ b/chromium/cc/input/layer_selection_bound.h
@@ -6,6 +6,7 @@
#define CC_INPUT_LAYER_SELECTION_BOUND_H_
#include "cc/base/cc_export.h"
+#include "cc/input/selection.h"
#include "cc/input/selection_bound_type.h"
#include "ui/gfx/geometry/point_f.h"
@@ -25,6 +26,8 @@ struct CC_EXPORT LayerSelectionBound {
bool operator==(const LayerSelectionBound& lhs, const LayerSelectionBound& rhs);
bool operator!=(const LayerSelectionBound& lhs, const LayerSelectionBound& rhs);
+typedef Selection<LayerSelectionBound> LayerSelection;
+
} // namespace cc
#endif // CC_INPUT_LAYER_SELECTION_BOUND_H_
diff --git a/chromium/cc/input/page_scale_animation.h b/chromium/cc/input/page_scale_animation.h
index ce13dcf8ba7..0e430c212fe 100644
--- a/chromium/cc/input/page_scale_animation.h
+++ b/chromium/cc/input/page_scale_animation.h
@@ -10,12 +10,31 @@
#include "base/time/time.h"
#include "cc/base/cc_export.h"
#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/geometry/vector2d_f.h"
namespace cc {
class TimingFunction;
+// Used in the CC to pass around a scale animation that hasn't yet been
+// initialized.
+struct PendingPageScaleAnimation {
+ PendingPageScaleAnimation(
+ const gfx::Vector2d _target_offset,
+ bool _use_anchor,
+ float _scale,
+ const base::TimeDelta& _duration)
+ : target_offset(_target_offset),
+ use_anchor(_use_anchor),
+ scale(_scale),
+ duration(_duration) {}
+ gfx::Vector2d target_offset;
+ bool use_anchor;
+ float scale;
+ base::TimeDelta duration;
+};
+
// A small helper class that does the math for zoom animations, primarily for
// double-tap zoom. Initialize it with starting and ending scroll/page scale
// positions and an animation length time, then call ...AtTime() at every frame
diff --git a/chromium/cc/input/scroll_elasticity_helper.cc b/chromium/cc/input/scroll_elasticity_helper.cc
new file mode 100644
index 00000000000..1c496d90531
--- /dev/null
+++ b/chromium/cc/input/scroll_elasticity_helper.cc
@@ -0,0 +1,91 @@
+// Copyright 2014 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 "cc/input/scroll_elasticity_helper.h"
+
+#include "cc/layers/layer_impl.h"
+#include "cc/trees/layer_tree_host_impl.h"
+#include "cc/trees/layer_tree_impl.h"
+
+namespace cc {
+
+class ScrollElasticityHelperImpl : public ScrollElasticityHelper {
+ public:
+ explicit ScrollElasticityHelperImpl(LayerTreeHostImpl* layer_tree_host_impl);
+ ~ScrollElasticityHelperImpl() override;
+
+ bool IsUserScrollable() const override;
+ gfx::Vector2dF StretchAmount() const override;
+ void SetStretchAmount(const gfx::Vector2dF& stretch_amount) override;
+ gfx::ScrollOffset ScrollOffset() const override;
+ gfx::ScrollOffset MaxScrollOffset() const override;
+ void ScrollBy(const gfx::Vector2dF& delta) override;
+ void RequestAnimate() override;
+
+ private:
+ LayerTreeHostImpl* layer_tree_host_impl_;
+};
+
+ScrollElasticityHelperImpl::ScrollElasticityHelperImpl(
+ LayerTreeHostImpl* layer_tree)
+ : layer_tree_host_impl_(layer_tree) {
+}
+
+ScrollElasticityHelperImpl::~ScrollElasticityHelperImpl() {
+}
+
+bool ScrollElasticityHelperImpl::IsUserScrollable() const {
+ LayerImpl* layer = layer_tree_host_impl_->OuterViewportScrollLayer();
+ if (!layer)
+ return false;
+ return layer->user_scrollable_horizontal() ||
+ layer->user_scrollable_vertical();
+}
+
+gfx::Vector2dF ScrollElasticityHelperImpl::StretchAmount() const {
+ return layer_tree_host_impl_->active_tree()->elastic_overscroll()->Current(
+ true);
+}
+
+void ScrollElasticityHelperImpl::SetStretchAmount(
+ const gfx::Vector2dF& stretch_amount) {
+ if (stretch_amount == StretchAmount())
+ return;
+
+ layer_tree_host_impl_->active_tree()->elastic_overscroll()->SetCurrent(
+ stretch_amount);
+ layer_tree_host_impl_->active_tree()->set_needs_update_draw_properties();
+ layer_tree_host_impl_->SetNeedsCommit();
+ layer_tree_host_impl_->SetNeedsRedraw();
+ layer_tree_host_impl_->SetFullRootLayerDamage();
+}
+
+gfx::ScrollOffset ScrollElasticityHelperImpl::ScrollOffset() const {
+ return layer_tree_host_impl_->active_tree()->TotalScrollOffset();
+}
+
+gfx::ScrollOffset ScrollElasticityHelperImpl::MaxScrollOffset() const {
+ return layer_tree_host_impl_->active_tree()->TotalMaxScrollOffset();
+}
+
+void ScrollElasticityHelperImpl::ScrollBy(const gfx::Vector2dF& delta) {
+ LayerImpl* root_scroll_layer =
+ layer_tree_host_impl_->OuterViewportScrollLayer()
+ ? layer_tree_host_impl_->OuterViewportScrollLayer()
+ : layer_tree_host_impl_->InnerViewportScrollLayer();
+ if (root_scroll_layer)
+ root_scroll_layer->ScrollBy(delta);
+}
+
+void ScrollElasticityHelperImpl::RequestAnimate() {
+ layer_tree_host_impl_->SetNeedsAnimate();
+}
+
+// static
+ScrollElasticityHelper* ScrollElasticityHelper::CreateForLayerTreeHostImpl(
+ LayerTreeHostImpl* layer_tree_host_impl) {
+ return new ScrollElasticityHelperImpl(layer_tree_host_impl);
+}
+
+} // namespace cc
diff --git a/chromium/cc/input/scroll_elasticity_helper.h b/chromium/cc/input/scroll_elasticity_helper.h
new file mode 100644
index 00000000000..a2bdbfe709f
--- /dev/null
+++ b/chromium/cc/input/scroll_elasticity_helper.h
@@ -0,0 +1,73 @@
+// Copyright 2014 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.
+
+#ifndef CC_INPUT_SCROLL_ELASTICITY_HELPER_H_
+#define CC_INPUT_SCROLL_ELASTICITY_HELPER_H_
+
+#include "base/time/time.h"
+#include "cc/base/cc_export.h"
+#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
+
+namespace cc {
+
+class LayerTreeHostImpl;
+
+// ScrollElasticityHelper is based on
+// WebKit/Source/platform/mac/ScrollElasticityController.h
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Interface between a LayerTreeHostImpl and the ScrollElasticityController. It
+// would be possible, in principle, for LayerTreeHostImpl to implement this
+// interface itself. This artificial boundary is introduced to reduce the amount
+// of logic and state held directly inside LayerTreeHostImpl.
+class CC_EXPORT ScrollElasticityHelper {
+ public:
+ static ScrollElasticityHelper* CreateForLayerTreeHostImpl(
+ LayerTreeHostImpl* layer_tree_host_impl);
+
+ virtual ~ScrollElasticityHelper() {}
+
+ virtual bool IsUserScrollable() const = 0;
+
+ // The amount that the view is stretched past the normal allowable bounds.
+ virtual gfx::Vector2dF StretchAmount() const = 0;
+ virtual void SetStretchAmount(const gfx::Vector2dF& stretch_amount) = 0;
+
+ // Functions for the scrolling of the root scroll layer.
+ virtual gfx::ScrollOffset ScrollOffset() const = 0;
+ virtual gfx::ScrollOffset MaxScrollOffset() const = 0;
+ virtual void ScrollBy(const gfx::Vector2dF& delta) = 0;
+
+ // Request that the controller have its Animate method called for the next
+ // frame.
+ virtual void RequestAnimate() = 0;
+};
+
+} // namespace cc
+
+#endif // CC_INPUT_SCROLL_ELASTICITY_HELPER_H_
diff --git a/chromium/cc/input/selection.h b/chromium/cc/input/selection.h
new file mode 100644
index 00000000000..1f3c6ebac05
--- /dev/null
+++ b/chromium/cc/input/selection.h
@@ -0,0 +1,38 @@
+// Copyright 2014 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.
+
+#ifndef CC_INPUT_SELECTION_H_
+#define CC_INPUT_SELECTION_H_
+
+#include "cc/base/cc_export.h"
+
+namespace cc {
+
+template <typename BoundType>
+struct CC_EXPORT Selection {
+ Selection() : is_editable(false), is_empty_text_form_control(false) {}
+ ~Selection() {}
+
+ BoundType start, end;
+ bool is_editable;
+ bool is_empty_text_form_control;
+};
+
+template <typename BoundType>
+inline bool operator==(const Selection<BoundType>& lhs,
+ const Selection<BoundType>& rhs) {
+ return lhs.start == rhs.start && lhs.end == rhs.end &&
+ lhs.is_editable == rhs.is_editable &&
+ lhs.is_empty_text_form_control == rhs.is_empty_text_form_control;
+}
+
+template <typename BoundType>
+inline bool operator!=(const Selection<BoundType>& lhs,
+ const Selection<BoundType>& rhs) {
+ return !(lhs == rhs);
+}
+
+} // namespace cc
+
+#endif // CC_INPUT_SELECTION_H_
diff --git a/chromium/cc/input/top_controls_manager.cc b/chromium/cc/input/top_controls_manager.cc
index cd3534c1764..c8bd5348721 100644
--- a/chromium/cc/input/top_controls_manager.cc
+++ b/chromium/cc/input/top_controls_manager.cc
@@ -26,29 +26,23 @@ const int64 kShowHideMaxDurationMs = 200;
// static
scoped_ptr<TopControlsManager> TopControlsManager::Create(
TopControlsManagerClient* client,
- float top_controls_height,
float top_controls_show_threshold,
float top_controls_hide_threshold) {
return make_scoped_ptr(new TopControlsManager(client,
- top_controls_height,
top_controls_show_threshold,
top_controls_hide_threshold));
}
TopControlsManager::TopControlsManager(TopControlsManagerClient* client,
- float top_controls_height,
float top_controls_show_threshold,
float top_controls_hide_threshold)
: client_(client),
animation_direction_(NO_ANIMATION),
permitted_state_(BOTH),
- top_controls_height_(top_controls_height),
- current_scroll_delta_(0.f),
- controls_scroll_begin_offset_(0.f),
- top_controls_show_height_(
- top_controls_height * top_controls_hide_threshold),
- top_controls_hide_height_(
- top_controls_height * (1.f - top_controls_show_threshold)),
+ accumulated_scroll_delta_(0.f),
+ baseline_content_offset_(0.f),
+ top_controls_show_threshold_(top_controls_hide_threshold),
+ top_controls_hide_threshold_(top_controls_show_threshold),
pinch_gesture_active_(false) {
CHECK(client_);
}
@@ -56,12 +50,20 @@ TopControlsManager::TopControlsManager(TopControlsManagerClient* client,
TopControlsManager::~TopControlsManager() {
}
-float TopControlsManager::ControlsTopOffset() {
- return client_->ControlsTopOffset();
+float TopControlsManager::ControlsTopOffset() const {
+ return ContentTopOffset() - TopControlsHeight();
}
-float TopControlsManager::ContentTopOffset() {
- return client_->ControlsTopOffset() + top_controls_height_;
+float TopControlsManager::ContentTopOffset() const {
+ return TopControlsShownRatio() * TopControlsHeight();
+}
+
+float TopControlsManager::TopControlsShownRatio() const {
+ return client_->CurrentTopControlsShownRatio();
+}
+
+float TopControlsManager::TopControlsHeight() const {
+ return client_->TopControlsHeight();
}
void TopControlsManager::UpdateTopControlsState(TopControlsState constraints,
@@ -77,35 +79,31 @@ void TopControlsManager::UpdateTopControlsState(TopControlsState constraints,
return;
// Don't do anything if there is no change in offset.
- float final_controls_position = 0.f;
- if (constraints == HIDDEN || current == HIDDEN) {
- final_controls_position = -top_controls_height_;
- }
- if (final_controls_position == client_->ControlsTopOffset()) {
+ float final_shown_ratio = 1.f;
+ if (constraints == HIDDEN || current == HIDDEN)
+ final_shown_ratio = 0.f;
+ if (final_shown_ratio == TopControlsShownRatio())
return;
- }
- AnimationDirection animation_direction = SHOWING_CONTROLS;
- if (constraints == HIDDEN || current == HIDDEN)
- animation_direction = HIDING_CONTROLS;
- ResetAnimations();
if (animate) {
- SetupAnimation(animation_direction);
+ SetupAnimation(final_shown_ratio ? SHOWING_CONTROLS : HIDING_CONTROLS);
} else {
- client_->SetControlsTopOffset(final_controls_position);
+ ResetAnimations();
+ client_->SetCurrentTopControlsShownRatio(final_shown_ratio);
}
- client_->DidChangeTopControlsPosition();
}
void TopControlsManager::ScrollBegin() {
DCHECK(!pinch_gesture_active_);
ResetAnimations();
- current_scroll_delta_ = 0.f;
- controls_scroll_begin_offset_ = client_->ControlsTopOffset();
+ ResetBaseline();
}
gfx::Vector2dF TopControlsManager::ScrollBy(
const gfx::Vector2dF& pending_delta) {
+ if (!TopControlsHeight())
+ return pending_delta;
+
if (pinch_gesture_active_)
return pending_delta;
@@ -114,21 +112,21 @@ gfx::Vector2dF TopControlsManager::ScrollBy(
else if (permitted_state_ == HIDDEN && pending_delta.y() < 0)
return pending_delta;
- current_scroll_delta_ += pending_delta.y();
+ accumulated_scroll_delta_ += pending_delta.y();
- float old_offset = client_->ControlsTopOffset();
- SetControlsTopOffset(controls_scroll_begin_offset_ - current_scroll_delta_);
+ float old_offset = ContentTopOffset();
+ client_->SetCurrentTopControlsShownRatio(
+ (baseline_content_offset_ - accumulated_scroll_delta_) /
+ TopControlsHeight());
// If the controls are fully visible, treat the current position as the
// new baseline even if the gesture didn't end.
- if (client_->ControlsTopOffset() == 0.f) {
- current_scroll_delta_ = 0.f;
- controls_scroll_begin_offset_ = 0.f;
- }
+ if (TopControlsShownRatio() == 1.f)
+ ResetBaseline();
ResetAnimations();
- gfx::Vector2dF applied_delta(0.f, old_offset - client_->ControlsTopOffset());
+ gfx::Vector2dF applied_delta(0.f, old_offset - ContentTopOffset());
return pending_delta - applied_delta;
}
@@ -151,31 +149,24 @@ void TopControlsManager::PinchEnd() {
ScrollBegin();
}
-void TopControlsManager::SetControlsTopOffset(float controls_top_offset) {
- controls_top_offset = std::max(controls_top_offset, -top_controls_height_);
- controls_top_offset = std::min(controls_top_offset, 0.f);
-
- if (client_->ControlsTopOffset() == controls_top_offset)
- return;
-
- client_->SetControlsTopOffset(controls_top_offset);
-
- client_->DidChangeTopControlsPosition();
+void TopControlsManager::MainThreadHasStoppedFlinging() {
+ StartAnimationIfNecessary();
}
gfx::Vector2dF TopControlsManager::Animate(base::TimeTicks monotonic_time) {
if (!top_controls_animation_ || !client_->HaveRootScrollLayer())
return gfx::Vector2dF();
- double time = (monotonic_time - base::TimeTicks()).InMillisecondsF();
+ base::TimeDelta time = monotonic_time - base::TimeTicks();
- float old_offset = client_->ControlsTopOffset();
- SetControlsTopOffset(top_controls_animation_->GetValue(time));
+ float old_offset = ContentTopOffset();
+ client_->SetCurrentTopControlsShownRatio(
+ top_controls_animation_->GetValue(time));
if (IsAnimationCompleteAtTime(monotonic_time))
ResetAnimations();
- gfx::Vector2dF scroll_delta(0.f, client_->ControlsTopOffset() - old_offset);
+ gfx::Vector2dF scroll_delta(0.f, ContentTopOffset() - old_offset);
return scroll_delta;
}
@@ -185,55 +176,48 @@ void TopControlsManager::ResetAnimations() {
}
void TopControlsManager::SetupAnimation(AnimationDirection direction) {
- DCHECK(direction != NO_ANIMATION);
+ DCHECK_NE(NO_ANIMATION, direction);
+ DCHECK_IMPLIES(direction == HIDING_CONTROLS, TopControlsShownRatio() > 0.f);
+ DCHECK_IMPLIES(direction == SHOWING_CONTROLS, TopControlsShownRatio() < 1.f);
- if (direction == SHOWING_CONTROLS && client_->ControlsTopOffset() == 0)
+ if (top_controls_animation_ && animation_direction_ == direction)
return;
- if (direction == HIDING_CONTROLS &&
- client_->ControlsTopOffset() == -top_controls_height_) {
+ if (!TopControlsHeight()) {
+ client_->SetCurrentTopControlsShownRatio(
+ direction == HIDING_CONTROLS ? 0.f : 1.f);
return;
}
- if (top_controls_animation_ && animation_direction_ == direction)
- return;
-
top_controls_animation_ = KeyframedFloatAnimationCurve::Create();
- double start_time =
- (gfx::FrameTime::Now() - base::TimeTicks()).InMillisecondsF();
- top_controls_animation_->AddKeyframe(
- FloatKeyframe::Create(start_time, client_->ControlsTopOffset(), nullptr));
- float max_ending_offset =
- (direction == SHOWING_CONTROLS ? 1 : -1) * top_controls_height_;
+ base::TimeDelta start_time = gfx::FrameTime::Now() - base::TimeTicks();
top_controls_animation_->AddKeyframe(
- FloatKeyframe::Create(start_time + kShowHideMaxDurationMs,
- client_->ControlsTopOffset() + max_ending_offset,
- EaseTimingFunction::Create()));
+ FloatKeyframe::Create(start_time, TopControlsShownRatio(), nullptr));
+ float max_ending_ratio = (direction == SHOWING_CONTROLS ? 1 : -1);
+ top_controls_animation_->AddKeyframe(FloatKeyframe::Create(
+ start_time + base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs),
+ TopControlsShownRatio() + max_ending_ratio,
+ EaseTimingFunction::Create()));
animation_direction_ = direction;
client_->DidChangeTopControlsPosition();
}
void TopControlsManager::StartAnimationIfNecessary() {
- if (client_->ControlsTopOffset() != 0
- && client_->ControlsTopOffset() != -top_controls_height_) {
- AnimationDirection show_controls = NO_ANIMATION;
-
- if (client_->ControlsTopOffset() >= -top_controls_show_height_) {
- // If we're showing so much that the hide threshold won't trigger, show.
- show_controls = SHOWING_CONTROLS;
- } else if (client_->ControlsTopOffset() <= -top_controls_hide_height_) {
- // If we're showing so little that the show threshold won't trigger, hide.
- show_controls = HIDING_CONTROLS;
- } else {
- // If we could be either showing or hiding, we determine which one to
- // do based on whether or not the total scroll delta was moving up or
- // down.
- show_controls = current_scroll_delta_ <= 0.f ?
- SHOWING_CONTROLS : HIDING_CONTROLS;
- }
-
- if (show_controls != NO_ANIMATION)
- SetupAnimation(show_controls);
+ if (TopControlsShownRatio() == 0.f || TopControlsShownRatio() == 1.f)
+ return;
+
+ if (TopControlsShownRatio() >= 1.f - top_controls_hide_threshold_) {
+ // If we're showing so much that the hide threshold won't trigger, show.
+ SetupAnimation(SHOWING_CONTROLS);
+ } else if (TopControlsShownRatio() <= top_controls_show_threshold_) {
+ // If we're showing so little that the show threshold won't trigger, hide.
+ SetupAnimation(HIDING_CONTROLS);
+ } else {
+ // If we could be either showing or hiding, we determine which one to
+ // do based on whether or not the total scroll delta was moving up or
+ // down.
+ SetupAnimation(accumulated_scroll_delta_ <= 0.f ? SHOWING_CONTROLS
+ : HIDING_CONTROLS);
}
}
@@ -241,15 +225,19 @@ bool TopControlsManager::IsAnimationCompleteAtTime(base::TimeTicks time) {
if (!top_controls_animation_)
return true;
- double time_ms = (time - base::TimeTicks()).InMillisecondsF();
- float new_offset = top_controls_animation_->GetValue(time_ms);
+ base::TimeDelta animation_time = time - base::TimeTicks();
+ float new_ratio = top_controls_animation_->GetValue(animation_time);
- if ((animation_direction_ == SHOWING_CONTROLS && new_offset >= 0) ||
- (animation_direction_ == HIDING_CONTROLS
- && new_offset <= -top_controls_height_)) {
+ if ((animation_direction_ == SHOWING_CONTROLS && new_ratio >= 1.f) ||
+ (animation_direction_ == HIDING_CONTROLS && new_ratio <= 0.f)) {
return true;
}
return false;
}
+void TopControlsManager::ResetBaseline() {
+ accumulated_scroll_delta_ = 0.f;
+ baseline_content_offset_ = ContentTopOffset();
+}
+
} // namespace cc
diff --git a/chromium/cc/input/top_controls_manager.h b/chromium/cc/input/top_controls_manager.h
index a90d33d3e4a..fc40378f5f8 100644
--- a/chromium/cc/input/top_controls_manager.h
+++ b/chromium/cc/input/top_controls_manager.h
@@ -34,14 +34,14 @@ class CC_EXPORT TopControlsManager
static scoped_ptr<TopControlsManager> Create(
TopControlsManagerClient* client,
- float top_controls_height,
float top_controls_show_threshold,
float top_controls_hide_threshold);
virtual ~TopControlsManager();
- float controls_height() { return top_controls_height_; }
- float ControlsTopOffset();
- float ContentTopOffset();
+ float ControlsTopOffset() const;
+ float ContentTopOffset() const;
+ float TopControlsShownRatio() const;
+ float TopControlsHeight() const;
KeyframedFloatAnimationCurve* animation() {
return top_controls_animation_.get();
@@ -61,13 +61,12 @@ class CC_EXPORT TopControlsManager
void PinchBegin();
void PinchEnd();
+ void MainThreadHasStoppedFlinging();
+
gfx::Vector2dF Animate(base::TimeTicks monotonic_time);
- void SetControlsTopOffset(float offset);
- float top_controls_height() { return top_controls_height_; }
protected:
TopControlsManager(TopControlsManagerClient* client,
- float top_controls_height,
float top_controls_show_threshold,
float top_controls_hide_threshold);
@@ -76,6 +75,7 @@ class CC_EXPORT TopControlsManager
void SetupAnimation(AnimationDirection direction);
void StartAnimationIfNecessary();
bool IsAnimationCompleteAtTime(base::TimeTicks time);
+ void ResetBaseline();
TopControlsManagerClient* client_; // The client manages the lifecycle of
// this.
@@ -83,18 +83,20 @@ class CC_EXPORT TopControlsManager
scoped_ptr<KeyframedFloatAnimationCurve> top_controls_animation_;
AnimationDirection animation_direction_;
TopControlsState permitted_state_;
- float top_controls_height_;
- float current_scroll_delta_;
- float controls_scroll_begin_offset_;
+ // Accumulated scroll delta since last baseline reset
+ float accumulated_scroll_delta_;
+
+ // Content offset when last baseline reset occurred
+ float baseline_content_offset_;
- // The height of the visible top control such that it must be shown when
- // the user stops the scroll.
- float top_controls_show_height_;
+ // The percent height of the visible top control such that it must be shown
+ // when the user stops the scroll.
+ float top_controls_show_threshold_;
- // The height of the visible top control such that it must be hidden when
- // the user stops the scroll.
- float top_controls_hide_height_;
+ // The percent height of the visible top control such that it must be hidden
+ // when the user stops the scroll.
+ float top_controls_hide_threshold_;
bool pinch_gesture_active_;
diff --git a/chromium/cc/input/top_controls_manager_client.h b/chromium/cc/input/top_controls_manager_client.h
index 53b5978f097..a0f2f5b16ca 100644
--- a/chromium/cc/input/top_controls_manager_client.h
+++ b/chromium/cc/input/top_controls_manager_client.h
@@ -11,8 +11,9 @@ class LayerTreeImpl;
class CC_EXPORT TopControlsManagerClient {
public:
- virtual void SetControlsTopOffset(float offset) = 0;
- virtual float ControlsTopOffset() const = 0;
+ virtual float TopControlsHeight() const = 0;
+ virtual void SetCurrentTopControlsShownRatio(float ratio) = 0;
+ virtual float CurrentTopControlsShownRatio() const = 0;
virtual void DidChangeTopControlsPosition() = 0;
virtual bool HaveRootScrollLayer() const = 0;
diff --git a/chromium/cc/input/top_controls_manager_unittest.cc b/chromium/cc/input/top_controls_manager_unittest.cc
index 77b40c9de05..52e46e674ed 100644
--- a/chromium/cc/input/top_controls_manager_unittest.cc
+++ b/chromium/cc/input/top_controls_manager_unittest.cc
@@ -4,6 +4,10 @@
#include "cc/input/top_controls_manager.h"
+#include <algorithm>
+#include <cmath>
+
+#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "cc/input/top_controls_manager_client.h"
@@ -11,6 +15,7 @@
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/test_shared_bitmap_manager.h"
+#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_impl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/frame_time.h"
@@ -19,19 +24,21 @@
namespace cc {
namespace {
-static const float kTopControlsHeight = 100;
-
class MockTopControlsManagerClient : public TopControlsManagerClient {
public:
- MockTopControlsManagerClient(float top_controls_show_threshold,
+ MockTopControlsManagerClient(float top_controls_height,
+ float top_controls_show_threshold,
float top_controls_hide_threshold)
- : host_impl_(&proxy_, &shared_bitmap_manager_),
+ : host_impl_(&proxy_, &shared_bitmap_manager_, &task_graph_runner_),
redraw_needed_(false),
update_draw_properties_needed_(false),
- top_controls_top_offset_(0.f),
+ top_controls_shown_ratio_(1.f),
+ top_controls_height_(top_controls_height),
top_controls_show_threshold_(top_controls_show_threshold),
top_controls_hide_threshold_(top_controls_hide_threshold) {
- active_tree_ = LayerTreeImpl::create(&host_impl_);
+ active_tree_ = LayerTreeImpl::create(
+ &host_impl_, new SyncedProperty<ScaleGroup>, new SyncedTopControls,
+ new SyncedElasticOverscroll);
root_scroll_layer_ = LayerImpl::Create(active_tree_.get(), 1);
}
@@ -44,11 +51,20 @@ class MockTopControlsManagerClient : public TopControlsManagerClient {
bool HaveRootScrollLayer() const override { return true; }
- void SetControlsTopOffset(float offset) override {
- top_controls_top_offset_ = offset;
+ float TopControlsHeight() const override { return top_controls_height_; }
+
+ void SetCurrentTopControlsShownRatio(float ratio) override {
+ ASSERT_FALSE(std::isnan(ratio));
+ ASSERT_FALSE(ratio == std::numeric_limits<float>::infinity());
+ ASSERT_FALSE(ratio == -std::numeric_limits<float>::infinity());
+ ratio = std::max(ratio, 0.f);
+ ratio = std::min(ratio, 1.f);
+ top_controls_shown_ratio_ = ratio;
}
- float ControlsTopOffset() const override { return top_controls_top_offset_; }
+ float CurrentTopControlsShownRatio() const override {
+ return top_controls_shown_ratio_;
+ }
LayerImpl* rootScrollLayer() {
return root_scroll_layer_.get();
@@ -57,16 +73,18 @@ class MockTopControlsManagerClient : public TopControlsManagerClient {
TopControlsManager* manager() {
if (!manager_) {
manager_ = TopControlsManager::Create(this,
- kTopControlsHeight,
top_controls_show_threshold_,
top_controls_hide_threshold_);
}
return manager_.get();
}
+ void SetTopControlsHeight(float height) { top_controls_height_ = height; }
+
private:
FakeImplProxy proxy_;
TestSharedBitmapManager shared_bitmap_manager_;
+ TestTaskGraphRunner task_graph_runner_;
FakeLayerTreeHostImpl host_impl_;
scoped_ptr<LayerTreeImpl> active_tree_;
scoped_ptr<LayerImpl> root_scroll_layer_;
@@ -74,263 +92,264 @@ class MockTopControlsManagerClient : public TopControlsManagerClient {
bool redraw_needed_;
bool update_draw_properties_needed_;
- float top_controls_top_offset_;
+ float top_controls_shown_ratio_;
+ float top_controls_height_;
float top_controls_show_threshold_;
float top_controls_hide_threshold_;
};
TEST(TopControlsManagerTest, EnsureScrollThresholdApplied) {
- MockTopControlsManagerClient client(0.5f, 0.5f);
+ MockTopControlsManagerClient client(100.f, 0.5f, 0.5f);
TopControlsManager* manager = client.manager();
manager->ScrollBegin();
// Scroll down to hide the controls entirely.
manager->ScrollBy(gfx::Vector2dF(0.f, 30.f));
- EXPECT_EQ(-30.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-30.f, manager->ControlsTopOffset());
manager->ScrollBy(gfx::Vector2dF(0.f, 30.f));
- EXPECT_EQ(-60.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-60.f, manager->ControlsTopOffset());
manager->ScrollBy(gfx::Vector2dF(0.f, 100.f));
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
// Scroll back up a bit and ensure the controls don't move until we cross
// the threshold.
manager->ScrollBy(gfx::Vector2dF(0.f, -10.f));
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
manager->ScrollBy(gfx::Vector2dF(0.f, -50.f));
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
// After hitting the threshold, further scrolling up should result in the top
// controls showing.
manager->ScrollBy(gfx::Vector2dF(0.f, -10.f));
- EXPECT_EQ(-90.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-90.f, manager->ControlsTopOffset());
manager->ScrollBy(gfx::Vector2dF(0.f, -50.f));
- EXPECT_EQ(-40.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-40.f, manager->ControlsTopOffset());
// Reset the scroll threshold by going further up the page than the initial
// threshold.
manager->ScrollBy(gfx::Vector2dF(0.f, -100.f));
- EXPECT_EQ(0.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
// See that scrolling down the page now will result in the controls hiding.
manager->ScrollBy(gfx::Vector2dF(0.f, 20.f));
- EXPECT_EQ(-20.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-20.f, manager->ControlsTopOffset());
manager->ScrollEnd();
}
TEST(TopControlsManagerTest, PartialShownHideAnimation) {
- MockTopControlsManagerClient client(0.5f, 0.5f);
+ MockTopControlsManagerClient client(100.f, 0.5f, 0.5f);
TopControlsManager* manager = client.manager();
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
- EXPECT_EQ(0.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
manager->ScrollEnd();
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
- EXPECT_EQ(-85.f, manager->ControlsTopOffset());
- EXPECT_EQ(15.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-85.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(15.f, manager->ContentTopOffset());
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
base::TimeTicks time = gfx::FrameTime::Now();
- float previous_offset = manager->ControlsTopOffset();
+ float previous;
while (manager->animation()) {
+ previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
- EXPECT_LT(manager->ControlsTopOffset(), previous_offset);
- previous_offset = manager->ControlsTopOffset();
+ EXPECT_LT(manager->TopControlsShownRatio(), previous);
}
EXPECT_FALSE(manager->animation());
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
- EXPECT_EQ(0.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
}
TEST(TopControlsManagerTest, PartialShownShowAnimation) {
- MockTopControlsManagerClient client(0.5f, 0.5f);
+ MockTopControlsManagerClient client(100.f, 0.5f, 0.5f);
TopControlsManager* manager = client.manager();
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
- EXPECT_EQ(0.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
manager->ScrollEnd();
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, -70.f));
- EXPECT_EQ(-30.f, manager->ControlsTopOffset());
- EXPECT_EQ(70.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-30.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(70.f, manager->ContentTopOffset());
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
base::TimeTicks time = gfx::FrameTime::Now();
- float previous_offset = manager->ControlsTopOffset();
+ float previous;
while (manager->animation()) {
+ previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
- EXPECT_GT(manager->ControlsTopOffset(), previous_offset);
- previous_offset = manager->ControlsTopOffset();
+ EXPECT_GT(manager->TopControlsShownRatio(), previous);
}
EXPECT_FALSE(manager->animation());
- EXPECT_EQ(0.f, manager->ControlsTopOffset());
- EXPECT_EQ(100.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset());
}
TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdShows) {
- MockTopControlsManagerClient client(0.25f, 0.25f);
+ MockTopControlsManagerClient client(100.f, 0.25f, 0.25f);
TopControlsManager* manager = client.manager();
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, 20.f));
- EXPECT_EQ(-20.f, manager->ControlsTopOffset());
- EXPECT_EQ(80.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-20.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(80.f, manager->ContentTopOffset());
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
base::TimeTicks time = gfx::FrameTime::Now();
- float previous_offset = manager->ControlsTopOffset();
+ float previous;
while (manager->animation()) {
+ previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
- EXPECT_GT(manager->ControlsTopOffset(), previous_offset);
- previous_offset = manager->ControlsTopOffset();
+ EXPECT_GT(manager->TopControlsShownRatio(), previous);
}
EXPECT_FALSE(manager->animation());
- EXPECT_EQ(0.f, manager->ControlsTopOffset());
- EXPECT_EQ(100.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset());
}
TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdHides) {
- MockTopControlsManagerClient client(0.25f, 0.25f);
+ MockTopControlsManagerClient client(100.f, 0.25f, 0.25f);
TopControlsManager* manager = client.manager();
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, 30.f));
- EXPECT_EQ(-30.f, manager->ControlsTopOffset());
- EXPECT_EQ(70.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-30.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(70.f, manager->ContentTopOffset());
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
base::TimeTicks time = gfx::FrameTime::Now();
- float previous_offset = manager->ControlsTopOffset();
+ float previous;
while (manager->animation()) {
+ previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
- EXPECT_LT(manager->ControlsTopOffset(), previous_offset);
- previous_offset = manager->ControlsTopOffset();
+ EXPECT_LT(manager->TopControlsShownRatio(), previous);
}
EXPECT_FALSE(manager->animation());
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
- EXPECT_EQ(0.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
}
TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdHides) {
- MockTopControlsManagerClient client(0.25f, 0.25f);
+ MockTopControlsManagerClient client(100.f, 0.25f, 0.25f);
TopControlsManager* manager = client.manager();
manager->ScrollBy(gfx::Vector2dF(0.f, 200.f));
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
- EXPECT_EQ(0.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, -20.f));
- EXPECT_EQ(-80.f, manager->ControlsTopOffset());
- EXPECT_EQ(20.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-80.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(20.f, manager->ContentTopOffset());
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
base::TimeTicks time = gfx::FrameTime::Now();
- float previous_offset = manager->ControlsTopOffset();
+ float previous;
while (manager->animation()) {
+ previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
- EXPECT_LT(manager->ControlsTopOffset(), previous_offset);
- previous_offset = manager->ControlsTopOffset();
+ EXPECT_LT(manager->TopControlsShownRatio(), previous);
}
EXPECT_FALSE(manager->animation());
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
- EXPECT_EQ(0.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
}
TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdShows) {
- MockTopControlsManagerClient client(0.25f, 0.25f);
+ MockTopControlsManagerClient client(100.f, 0.25f, 0.25f);
TopControlsManager* manager = client.manager();
manager->ScrollBy(gfx::Vector2dF(0.f, 200.f));
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
- EXPECT_EQ(0.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, -30.f));
- EXPECT_EQ(-70.f, manager->ControlsTopOffset());
- EXPECT_EQ(30.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-70.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(30.f, manager->ContentTopOffset());
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
base::TimeTicks time = gfx::FrameTime::Now();
- float previous_offset = manager->ControlsTopOffset();
+ float previous;
while (manager->animation()) {
+ previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
- EXPECT_GT(manager->ControlsTopOffset(), previous_offset);
- previous_offset = manager->ControlsTopOffset();
+ EXPECT_GT(manager->TopControlsShownRatio(), previous);
}
EXPECT_FALSE(manager->animation());
- EXPECT_EQ(0.f, manager->ControlsTopOffset());
- EXPECT_EQ(100.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset());
}
TEST(TopControlsManagerTest, PinchIgnoresScroll) {
- MockTopControlsManagerClient client(0.5f, 0.5f);
+ MockTopControlsManagerClient client(100.f, 0.5f, 0.5f);
TopControlsManager* manager = client.manager();
// Hide the controls.
manager->ScrollBegin();
- EXPECT_EQ(0.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
manager->PinchBegin();
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
// Scrolls are ignored during pinch.
manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
manager->PinchEnd();
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
// Scrolls should no long be ignored.
manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
- EXPECT_EQ(-85.f, manager->ControlsTopOffset());
- EXPECT_EQ(15.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-85.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(15.f, manager->ContentTopOffset());
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
}
TEST(TopControlsManagerTest, PinchBeginStartsAnimationIfNecessary) {
- MockTopControlsManagerClient client(0.5f, 0.5f);
+ MockTopControlsManagerClient client(100.f, 0.5f, 0.5f);
TopControlsManager* manager = client.manager();
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
- EXPECT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
manager->PinchBegin();
EXPECT_FALSE(manager->animation());
@@ -339,19 +358,19 @@ TEST(TopControlsManagerTest, PinchBeginStartsAnimationIfNecessary) {
EXPECT_FALSE(manager->animation());
manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
- EXPECT_EQ(-85.f, manager->ControlsTopOffset());
- EXPECT_EQ(15.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-85.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(15.f, manager->ContentTopOffset());
manager->PinchBegin();
EXPECT_TRUE(manager->animation());
base::TimeTicks time = base::TimeTicks::Now();
- float previous_offset = manager->ControlsTopOffset();
+ float previous;
while (manager->animation()) {
+ previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
- EXPECT_LT(manager->ControlsTopOffset(), previous_offset);
- previous_offset = manager->ControlsTopOffset();
+ EXPECT_LT(manager->TopControlsShownRatio(), previous);
}
EXPECT_FALSE(manager->animation());
@@ -359,24 +378,95 @@ TEST(TopControlsManagerTest, PinchBeginStartsAnimationIfNecessary) {
EXPECT_FALSE(manager->animation());
manager->ScrollBy(gfx::Vector2dF(0.f, -55.f));
- EXPECT_EQ(-45.f, manager->ControlsTopOffset());
- EXPECT_EQ(55.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(-45.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(55.f, manager->ContentTopOffset());
EXPECT_FALSE(manager->animation());
manager->ScrollEnd();
EXPECT_TRUE(manager->animation());
time = base::TimeTicks::Now();
- previous_offset = manager->ControlsTopOffset();
while (manager->animation()) {
+ previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
- EXPECT_GT(manager->ControlsTopOffset(), previous_offset);
- previous_offset = manager->ControlsTopOffset();
+ EXPECT_GT(manager->TopControlsShownRatio(), previous);
}
EXPECT_FALSE(manager->animation());
- EXPECT_EQ(0.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
+}
+
+TEST(TopControlsManagerTest, HeightChangeMaintainsFullyVisibleControls) {
+ MockTopControlsManagerClient client(0.f, 0.5f, 0.5f);
+ TopControlsManager* manager = client.manager();
+
+ EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
+
+ client.SetTopControlsHeight(100.f);
+ EXPECT_FALSE(manager->animation());
+ EXPECT_FLOAT_EQ(100.f, manager->TopControlsHeight());
+ EXPECT_FLOAT_EQ(0, manager->ControlsTopOffset());
+
+ client.SetTopControlsHeight(50.f);
+ EXPECT_FALSE(manager->animation());
+ EXPECT_FLOAT_EQ(50.f, manager->TopControlsHeight());
+ EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
+}
+
+TEST(TopControlsManagerTest, GrowingHeightKeepsTopControlsHidden) {
+ MockTopControlsManagerClient client(0.f, 0.5f, 0.5f);
+ TopControlsManager* manager = client.manager();
+ client.SetTopControlsHeight(1.f);
+ manager->UpdateTopControlsState(HIDDEN, HIDDEN, false);
+ EXPECT_EQ(-1.f, manager->ControlsTopOffset());
+ EXPECT_EQ(0.f, manager->ContentTopOffset());
+
+ client.SetTopControlsHeight(50.f);
+ EXPECT_FALSE(manager->animation());
+ EXPECT_EQ(-50.f, manager->ControlsTopOffset());
+ EXPECT_EQ(0.f, manager->ContentTopOffset());
+
+ client.SetTopControlsHeight(100.f);
+ EXPECT_FALSE(manager->animation());
+ EXPECT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_EQ(0.f, manager->ContentTopOffset());
+}
+
+TEST(TopControlsManagerTest, ShrinkingHeightKeepsTopControlsHidden) {
+ MockTopControlsManagerClient client(100.f, 0.5f, 0.5f);
+ TopControlsManager* manager = client.manager();
+
+ manager->ScrollBegin();
+ manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
+ EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
+ manager->ScrollEnd();
+
+ client.SetTopControlsHeight(50.f);
+ EXPECT_FALSE(manager->animation());
+ EXPECT_FLOAT_EQ(-50.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
+
+ client.SetTopControlsHeight(0.f);
+ EXPECT_FALSE(manager->animation());
+ EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
+}
+
+TEST(TopControlsManagerTest, ScrollByWithZeroHeightControlsIsNoop) {
+ MockTopControlsManagerClient client(0.f, 0.5f, 0.5f);
+ TopControlsManager* manager = client.manager();
+ manager->UpdateTopControlsState(BOTH, BOTH, false);
+
+ manager->ScrollBegin();
+ gfx::Vector2dF pending = manager->ScrollBy(gfx::Vector2dF(0.f, 20.f));
+ EXPECT_FLOAT_EQ(20.f, pending.y());
+ EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
+ EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
+ EXPECT_FLOAT_EQ(1.f, client.CurrentTopControlsShownRatio());
+ manager->ScrollEnd();
}
+
} // namespace
} // namespace cc