summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/animation/scrollbar_animation_controller.h1
-rw-r--r--cc/animation/scrollbar_animation_controller_linear_fade.cc5
-rw-r--r--cc/animation/scrollbar_animation_controller_linear_fade.h1
-rw-r--r--cc/animation/scrollbar_animation_controller_thinning.cc16
-rw-r--r--cc/animation/scrollbar_animation_controller_thinning.h2
-rw-r--r--cc/animation/scrollbar_animation_controller_thinning_unittest.cc41
-rw-r--r--cc/trees/layer_tree_host_impl.cc74
-rw-r--r--cc/trees/layer_tree_host_impl.h13
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc11
9 files changed, 144 insertions, 20 deletions
diff --git a/cc/animation/scrollbar_animation_controller.h b/cc/animation/scrollbar_animation_controller.h
index d0794a2..ecef4fb 100644
--- a/cc/animation/scrollbar_animation_controller.h
+++ b/cc/animation/scrollbar_animation_controller.h
@@ -24,6 +24,7 @@ class CC_EXPORT ScrollbarAnimationController {
virtual bool Animate(base::TimeTicks now) = 0;
virtual void DidScrollGestureBegin() = 0;
virtual void DidScrollGestureEnd(base::TimeTicks now) = 0;
+ virtual void DidMouseMoveOffScrollbar(base::TimeTicks now) = 0;
// Returns true if we should start an animation.
virtual bool DidScrollUpdate(base::TimeTicks now) = 0;
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade.cc b/cc/animation/scrollbar_animation_controller_linear_fade.cc
index 451c45d..0690498 100644
--- a/cc/animation/scrollbar_animation_controller_linear_fade.cc
+++ b/cc/animation/scrollbar_animation_controller_linear_fade.cc
@@ -65,6 +65,11 @@ void ScrollbarAnimationControllerLinearFade::DidScrollGestureEnd(
scroll_gesture_in_progress_ = false;
}
+void ScrollbarAnimationControllerLinearFade::DidMouseMoveOffScrollbar(
+ base::TimeTicks now) {
+ // Ignore mouse move events.
+}
+
bool ScrollbarAnimationControllerLinearFade::DidScrollUpdate(
base::TimeTicks now) {
ApplyOpacityToScrollbars(1.0f);
diff --git a/cc/animation/scrollbar_animation_controller_linear_fade.h b/cc/animation/scrollbar_animation_controller_linear_fade.h
index b490f2e..85cdada 100644
--- a/cc/animation/scrollbar_animation_controller_linear_fade.h
+++ b/cc/animation/scrollbar_animation_controller_linear_fade.h
@@ -29,6 +29,7 @@ class CC_EXPORT ScrollbarAnimationControllerLinearFade
virtual bool Animate(base::TimeTicks now) OVERRIDE;
virtual void DidScrollGestureBegin() OVERRIDE;
virtual void DidScrollGestureEnd(base::TimeTicks now) OVERRIDE;
+ virtual void DidMouseMoveOffScrollbar(base::TimeTicks now) OVERRIDE;
virtual bool DidScrollUpdate(base::TimeTicks now) OVERRIDE;
virtual bool DidMouseMoveNear(base::TimeTicks now, float distance) OVERRIDE;
diff --git a/cc/animation/scrollbar_animation_controller_thinning.cc b/cc/animation/scrollbar_animation_controller_thinning.cc
index e439daf..ce196fb 100644
--- a/cc/animation/scrollbar_animation_controller_thinning.cc
+++ b/cc/animation/scrollbar_animation_controller_thinning.cc
@@ -34,6 +34,7 @@ ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning(
: ScrollbarAnimationController(),
scroll_layer_(scroll_layer),
scroll_gesture_in_progress_(false),
+ mouse_is_over_scrollbar_(false),
animation_delay_(animation_delay),
animation_duration_(animation_duration),
mouse_move_distance_to_trigger_animation_(100.f) {}
@@ -53,6 +54,10 @@ base::TimeDelta ScrollbarAnimationControllerThinning::DelayBeforeStart(
}
bool ScrollbarAnimationControllerThinning::Animate(base::TimeTicks now) {
+ if (mouse_is_over_scrollbar_) {
+ ApplyOpacityAndThumbThicknessScale(1, 1);
+ return false;
+ }
float progress = AnimationProgressAtTime(now);
float opacity = OpacityAtAnimationProgress(progress);
float thumb_thickness_scale = ThumbThicknessScaleAtAnimationProgress(
@@ -75,6 +80,12 @@ void ScrollbarAnimationControllerThinning::DidScrollGestureEnd(
scroll_gesture_in_progress_ = false;
}
+void ScrollbarAnimationControllerThinning::DidMouseMoveOffScrollbar(
+ base::TimeTicks now) {
+ mouse_is_over_scrollbar_ = false;
+ DidScrollUpdate(now);
+}
+
bool ScrollbarAnimationControllerThinning::DidScrollUpdate(
base::TimeTicks now) {
ApplyOpacityAndThumbThicknessScale(1, 1);
@@ -85,6 +96,11 @@ bool ScrollbarAnimationControllerThinning::DidScrollUpdate(
bool ScrollbarAnimationControllerThinning::DidMouseMoveNear(
base::TimeTicks now, float distance) {
+ if (distance == 0.0) {
+ mouse_is_over_scrollbar_ = true;
+ return false;
+ }
+
if (distance < mouse_move_distance_to_trigger_animation_)
return DidScrollUpdate(now);
diff --git a/cc/animation/scrollbar_animation_controller_thinning.h b/cc/animation/scrollbar_animation_controller_thinning.h
index 1f0d41d..8038745 100644
--- a/cc/animation/scrollbar_animation_controller_thinning.h
+++ b/cc/animation/scrollbar_animation_controller_thinning.h
@@ -37,6 +37,7 @@ class CC_EXPORT ScrollbarAnimationControllerThinning
virtual bool Animate(base::TimeTicks now) OVERRIDE;
virtual void DidScrollGestureBegin() OVERRIDE;
virtual void DidScrollGestureEnd(base::TimeTicks now) OVERRIDE;
+ virtual void DidMouseMoveOffScrollbar(base::TimeTicks now) OVERRIDE;
virtual bool DidScrollUpdate(base::TimeTicks now) OVERRIDE;
virtual bool DidMouseMoveNear(base::TimeTicks now, float distance) OVERRIDE;
@@ -58,6 +59,7 @@ class CC_EXPORT ScrollbarAnimationControllerThinning
base::TimeTicks last_awaken_time_;
bool scroll_gesture_in_progress_;
+ bool mouse_is_over_scrollbar_;
base::TimeDelta animation_delay_;
base::TimeDelta animation_duration_;
diff --git a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
index c83bdc8..7bb5076 100644
--- a/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
+++ b/cc/animation/scrollbar_animation_controller_thinning_unittest.cc
@@ -181,5 +181,46 @@ TEST_F(ScrollbarAnimationControllerThinningTest, AwakenByProgrammaticScroll) {
EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
}
+TEST_F(ScrollbarAnimationControllerThinningTest, MouseOverAndOut) {
+ base::TimeTicks time;
+ time += base::TimeDelta::FromSeconds(1);
+ EXPECT_TRUE(scrollbar_controller_->DidScrollUpdate(time));
+ EXPECT_TRUE(scrollbar_controller_->IsAnimating());
+ EXPECT_EQ(2, scrollbar_controller_->DelayBeforeStart(time).InSeconds());
+ scrollbar_controller_->Animate(time);
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+
+ time += base::TimeDelta::FromSeconds(4);
+ scrollbar_controller_->Animate(time);
+ EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor());
+
+ scrollbar_controller_->DidMouseMoveNear(time, 0);
+ scrollbar_controller_->Animate(time);
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+
+ time += base::TimeDelta::FromSeconds(4);
+ scrollbar_controller_->Animate(time);
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+
+ scrollbar_controller_->DidMouseMoveOffScrollbar(time);
+ scrollbar_controller_->Animate(time);
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor());
+
+ time += base::TimeDelta::FromSeconds(4);
+ scrollbar_controller_->Animate(time);
+ EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor());
+
+ time += base::TimeDelta::FromSeconds(1);
+ scrollbar_controller_->Animate(time);
+ EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->opacity());
+ EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor());
+}
+
} // namespace
} // namespace cc
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index a764372..281fa5b 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -198,6 +198,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(
did_lock_scrolling_layer_(false),
should_bubble_scrolls_(false),
wheel_scrolling_(false),
+ scroll_layer_id_when_mouse_over_scrollbar_(0),
tile_priorities_dirty_(false),
root_layer_scroll_offset_delegate_(NULL),
settings_(settings),
@@ -1904,19 +1905,11 @@ static LayerImpl* NextScrollLayer(LayerImpl* layer) {
return layer->parent();
}
-LayerImpl* LayerTreeHostImpl::FindScrollLayerForViewportPoint(
- gfx::Point viewport_point, InputHandler::ScrollInputType type,
- bool* scroll_on_main_thread) {
+LayerImpl* LayerTreeHostImpl::FindScrollLayerForDeviceViewportPoint(
+ gfx::PointF device_viewport_point, InputHandler::ScrollInputType type,
+ LayerImpl* layer_impl, bool* scroll_on_main_thread) {
DCHECK(scroll_on_main_thread);
- gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
- device_scale_factor_);
-
- // First find out which layer was hit from the saved list of visible layers
- // in the most recent frame.
- LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
- device_viewport_point, active_tree_->RenderSurfaceLayerList());
-
// Walk up the hierarchy and look for a scrollable layer.
LayerImpl* potentially_scrolling_layer_impl = 0;
for (; layer_impl; layer_impl = NextScrollLayer(layer_impl)) {
@@ -1968,9 +1961,15 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
if (!EnsureRenderSurfaceLayerList())
return ScrollIgnored;
+ gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
+ device_scale_factor_);
+ LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
+ device_viewport_point,
+ active_tree_->RenderSurfaceLayerList());
bool scroll_on_main_thread = false;
- LayerImpl* potentially_scrolling_layer_impl = FindScrollLayerForViewportPoint(
- viewport_point, type, &scroll_on_main_thread);
+ LayerImpl* potentially_scrolling_layer_impl =
+ FindScrollLayerForDeviceViewportPoint(device_viewport_point, type,
+ layer_impl, &scroll_on_main_thread);
if (scroll_on_main_thread) {
rendering_stats_instrumentation_->IncrementMainThreadScrolls();
@@ -2296,10 +2295,32 @@ void LayerTreeHostImpl::MouseMoveAt(gfx::Point viewport_point) {
if (!EnsureRenderSurfaceLayerList())
return;
- // TODO(tony): What should happen if the mouse cursor is over the scrollbar?
+ gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
+ device_scale_factor_);
+
+ LayerImpl* layer_impl = LayerTreeHostCommon::FindLayerThatIsHitByPoint(
+ device_viewport_point,
+ active_tree_->RenderSurfaceLayerList());
+ if (HandleMouseOverScrollbar(layer_impl, device_viewport_point))
+ return;
+
+ if (scroll_layer_id_when_mouse_over_scrollbar_) {
+ LayerImpl* scroll_layer_impl = active_tree_->LayerById(
+ scroll_layer_id_when_mouse_over_scrollbar_);
+
+ ScrollbarAnimationController* animation_controller =
+ scroll_layer_impl->scrollbar_animation_controller();
+ if (animation_controller) {
+ animation_controller->DidMouseMoveOffScrollbar(
+ CurrentPhysicalTimeTicks());
+ StartScrollbarAnimation();
+ }
+ scroll_layer_id_when_mouse_over_scrollbar_ = 0;
+ }
+
bool scroll_on_main_thread = false;
- LayerImpl* scroll_layer_impl = FindScrollLayerForViewportPoint(
- viewport_point, InputHandler::Gesture,
+ LayerImpl* scroll_layer_impl = FindScrollLayerForDeviceViewportPoint(
+ device_viewport_point, InputHandler::Gesture, layer_impl,
&scroll_on_main_thread);
if (scroll_on_main_thread || !scroll_layer_impl)
return;
@@ -2309,8 +2330,6 @@ void LayerTreeHostImpl::MouseMoveAt(gfx::Point viewport_point) {
if (!animation_controller)
return;
- gfx::PointF device_viewport_point = gfx::ScalePoint(viewport_point,
- device_scale_factor_);
float distance_to_scrollbar = std::min(
DeviceSpaceDistanceToLayer(device_viewport_point,
scroll_layer_impl->horizontal_scrollbar_layer()),
@@ -2325,6 +2344,25 @@ void LayerTreeHostImpl::MouseMoveAt(gfx::Point viewport_point) {
}
}
+bool LayerTreeHostImpl::HandleMouseOverScrollbar(LayerImpl* layer_impl,
+ gfx::PointF device_viewport_point) {
+ if (layer_impl && layer_impl->ToScrollbarLayer()) {
+ int scroll_layer_id = layer_impl->ToScrollbarLayer()->ScrollLayerId();
+ layer_impl = active_tree_->LayerById(scroll_layer_id);
+ if (layer_impl && layer_impl->scrollbar_animation_controller()) {
+ scroll_layer_id_when_mouse_over_scrollbar_ = scroll_layer_id;
+ layer_impl->scrollbar_animation_controller()->DidMouseMoveNear(
+ CurrentPhysicalTimeTicks(), 0);
+ } else {
+ scroll_layer_id_when_mouse_over_scrollbar_ = 0;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
void LayerTreeHostImpl::PinchGestureBegin() {
pinch_gesture_active_ = true;
previous_pinch_anchor_ = gfx::Point();
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index d71a0aa..aabd0b5 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -278,6 +278,10 @@ class CC_EXPORT LayerTreeHostImpl
LayerImpl* RootScrollLayer() const;
LayerImpl* CurrentlyScrollingLayer() const;
+ int scroll_layer_id_when_mouse_over_scrollbar() {
+ return scroll_layer_id_when_mouse_over_scrollbar_;
+ }
+
virtual void SetVisible(bool visible);
bool visible() const { return visible_; }
@@ -456,14 +460,18 @@ class CC_EXPORT LayerTreeHostImpl
bool EnsureRenderSurfaceLayerList();
void ClearCurrentlyScrollingLayer();
+ bool HandleMouseOverScrollbar(LayerImpl* layer_impl,
+ gfx::PointF device_viewport_point);
+
void AnimateScrollbarsRecursive(LayerImpl* layer,
base::TimeTicks time);
void UpdateCurrentFrameTime(base::TimeTicks* ticks, base::Time* now) const;
- LayerImpl* FindScrollLayerForViewportPoint(
- gfx::Point viewport_point,
+ LayerImpl* FindScrollLayerForDeviceViewportPoint(
+ gfx::PointF device_viewport_point,
InputHandler::ScrollInputType type,
+ LayerImpl* layer_hit_by_point,
bool* scroll_on_main_thread);
float DeviceSpaceDistanceToLayer(gfx::PointF device_viewport_point,
LayerImpl* layer_impl);
@@ -511,6 +519,7 @@ class CC_EXPORT LayerTreeHostImpl
bool did_lock_scrolling_layer_;
bool should_bubble_scrolls_;
bool wheel_scrolling_;
+ int scroll_layer_id_when_mouse_over_scrollbar_;
bool tile_priorities_dirty_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 5f2eaf7..2ddd544 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -1259,6 +1259,8 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
// The scrollbar is on the right side.
scoped_ptr<PaintedScrollbarLayerImpl> scrollbar =
PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), 5, VERTICAL);
+ scrollbar->SetDrawsContent(true);
+ scrollbar->SetBounds(gfx::Size(15, viewport_size.height()));
scrollbar->SetContentBounds(gfx::Size(15, viewport_size.height()));
scrollbar->SetPosition(gfx::Point(285, 0));
scroll->SetVerticalScrollbarLayer(scrollbar.get());
@@ -1293,6 +1295,15 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
did_request_redraw_ = false;
host_impl_->MouseMoveAt(gfx::Point(184, 100));
EXPECT_TRUE(did_request_redraw_);
+
+ did_request_redraw_ = false;
+ EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
+ host_impl_->MouseMoveAt(gfx::Point(290, 100));
+ EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
+ host_impl_->MouseMoveAt(gfx::Point(290, 120));
+ EXPECT_EQ(2, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
+ host_impl_->MouseMoveAt(gfx::Point(150, 120));
+ EXPECT_EQ(0, host_impl_->scroll_layer_id_when_mouse_over_scrollbar());
}
TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) {