| Index: ui/compositor/overscroll/ui_input_handler.cc
|
| diff --git a/ui/compositor/overscroll/ui_input_handler.cc b/ui/compositor/overscroll/ui_input_handler.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4e55f22bf08e4ac1182a4ecb4eab24e2c3db8666
|
| --- /dev/null
|
| +++ b/ui/compositor/overscroll/ui_input_handler.cc
|
| @@ -0,0 +1,150 @@
|
| +// Copyright 2016 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 "ui/compositor/overscroll/ui_input_handler.h"
|
| +
|
| +#include "base/logging.h"
|
| +#include "cc/trees/layer_tree_impl.h"
|
| +#include "cc/trees/scroll_node.h"
|
| +#include "ui/events/event.h"
|
| +
|
| +namespace ui {
|
| +
|
| +namespace {
|
| +
|
| +// Creates a cc::ScrollState from a ui::ScrollEvent, populating fields general
|
| +// to all event phases. Take care not to put deltas on beginning/end updates,
|
| +// since InputHandler will DCHECK if they're present.
|
| +cc::ScrollState CreateScrollState(const ScrollEvent& scroll,
|
| + bool is_begin,
|
| + bool is_end) {
|
| + cc::ScrollStateData scroll_state_data;
|
| + scroll_state_data.position_x = scroll.x();
|
| + scroll_state_data.position_y = scroll.y();
|
| + if (!is_begin && !is_end) {
|
| + scroll_state_data.delta_x = -scroll.x_offset_ordinal();
|
| + scroll_state_data.delta_y = -scroll.y_offset_ordinal();
|
| + }
|
| + scroll_state_data.is_in_inertial_phase =
|
| + scroll.momentum_phase() == EventMomentumPhase::INERTIAL_UPDATE;
|
| + scroll_state_data.is_beginning = is_begin;
|
| + scroll_state_data.is_ending = is_end;
|
| + return cc::ScrollState(scroll_state_data);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +UIInputHandler::UIInputHandler(
|
| + const base::WeakPtr<cc::InputHandler>& input_handler)
|
| + : input_handler_(input_handler.get()) {
|
| + input_handler_->BindToClient(this);
|
| +}
|
| +
|
| +UIInputHandler::~UIInputHandler() {
|
| + DCHECK(!input_handler_);
|
| +}
|
| +
|
| +void UIInputHandler::WillShutdown() {
|
| + input_handler_ = nullptr;
|
| +}
|
| +
|
| +void UIInputHandler::Animate(base::TimeTicks time) {
|
| + scroll_elasticity_controller_.Animate(time);
|
| +}
|
| +
|
| +void UIInputHandler::MainThreadHasStoppedFlinging() {}
|
| +
|
| +void UIInputHandler::ReconcileElasticOverscrollAndRootScroll() {
|
| + scroll_elasticity_controller_.ReconcileStretchAndScroll();
|
| +}
|
| +
|
| +void UIInputHandler::UpdateRootLayerStateForSynchronousInputHandler(
|
| + const gfx::ScrollOffset& total_scroll_offset,
|
| + const gfx::ScrollOffset& max_scroll_offset,
|
| + const gfx::SizeF& scrollable_size,
|
| + float page_scale_factor,
|
| + float min_page_scale_factor,
|
| + float max_page_scale_factor) {}
|
| +
|
| +cc::ElementId UIInputHandler::HandleScrollBegin(const ScrollEvent& scroll) {
|
| + // TODO(tapted): Handle cancelling any fling or elasticity animation,
|
| + // ScrollUnits::Page, viewport targeting, smooth-scrolling animations. These
|
| + // are not currently needed for UI scrolling on Mac.
|
| +
|
| + cc::ScrollState scroll_state = CreateScrollState(scroll, true, false);
|
| + cc::InputHandler::ScrollStatus scroll_status =
|
| + input_handler_->ScrollBegin(&scroll_state, cc::InputHandler::WHEEL);
|
| +
|
| + switch (scroll_status.thread) {
|
| + case cc::InputHandler::SCROLL_ON_MAIN_THREAD:
|
| + // Main thread means "not here", but this should only happen if the
|
| + // scroll status has already entered this mode, or the scrolling layer has
|
| + // set main_thread_scrolling_reasons to something. Neither of which should
|
| + // occur for UI scrolling.
|
| + NOTREACHED();
|
| + return cc::ElementId();
|
| + case cc::InputHandler::SCROLL_UNKNOWN:
|
| + // Unknown usually means a failed hit test. Did not handle.
|
| + return cc::ElementId();
|
| + case cc::InputHandler::SCROLL_IGNORED:
|
| + // Something hit, but it wasn't scrollable. Ignored.
|
| + return cc::ElementId();
|
| + case cc::InputHandler::SCROLL_ON_IMPL_THREAD:
|
| + break;
|
| + }
|
| +
|
| + if (!scroll_state.layer_tree_impl()) {
|
| + LOG(ERROR) << "layer_tree_impl not set - figure out why.";
|
| + return cc::ElementId();
|
| + }
|
| +
|
| + // InputHandler::ScrollBegin() doesn't set the element ID in ScrollState. That
|
| + // might be nicer than reaching into LayerTreeImpl.
|
| + cc::LayerImpl* layer =
|
| + scroll_state.layer_tree_impl()->CurrentlyScrollingLayer();
|
| + DCHECK(layer);
|
| +
|
| + // The event may be the start of a momentum portion of touchpad event stream.
|
| + // The input handler needs to resume scrolling, but elasticity doesn't change.
|
| + if ((scroll.momentum_phase() == EventMomentumPhase::MAY_BEGIN) == 0)
|
| + return layer->element_id();
|
| +
|
| + // Lock scrolling to the thing that was hit.
|
| + scroll_elasticity_controller_.SetActiveHelper(
|
| + input_handler_->ScrollElasticityHelperForScrollingLayer());
|
| +
|
| + // The elasticity controller doesn't reset when observing event streams that
|
| + // can't result in momentum, but that's handled above by
|
| + // EventMomentumPhase::MAY_BEGIN. So |leave_momentum| is just the inverse of
|
| + // |enter_momentum|.
|
| + bool has_momentum = scroll_state.is_in_inertial_phase();
|
| + scroll_elasticity_controller_.ObserveRealScrollBegin(has_momentum,
|
| + !has_momentum);
|
| + return layer->element_id();
|
| +}
|
| +
|
| +void UIInputHandler::HandleScrollUpdate(const ScrollEvent& scroll,
|
| + cc::ElementId element) {
|
| + // TODO(tapted): Manage animations, handle pinning a fling curve to an
|
| + // overscroll direction, handle did_overscroll_root. Most of these don't apply
|
| + // for Mac events.
|
| + cc::ScrollState scroll_state = CreateScrollState(scroll, false, false);
|
| + scroll_state.data()->set_current_native_scrolling_element(element);
|
| + cc::InputHandlerScrollResult result = input_handler_->ScrollBy(&scroll_state);
|
| +
|
| + gfx::Vector2dF event_delta(scroll_state.delta_x(), scroll_state.delta_y());
|
| + scroll_elasticity_controller_.ObserveScrollUpdate(
|
| + event_delta, result.unused_scroll_delta, scroll.time_stamp(),
|
| + scroll_state.is_in_inertial_phase());
|
| +}
|
| +
|
| +void UIInputHandler::HandleScrollEnd(const ScrollEvent& scroll) {
|
| + // TODO(tapted): Handle smooth scrolling / animations (i.e. ignore event for
|
| + // these cases).
|
| + cc::ScrollState scroll_state = CreateScrollState(scroll, false, true);
|
| + input_handler_->ScrollEnd(&scroll_state);
|
| + scroll_elasticity_controller_.ObserveRealScrollEnd(scroll.time_stamp());
|
| +}
|
| +
|
| +} // namespace ui
|
|
|