Commit d9de59b3 authored by Andrew Xu's avatar Andrew Xu Committed by Commit Bot

[scrollable shelf] Implement the mouse wheel event handler

This CL enables the scrollable shelf to handle the mouse wheel event.

Bug: 1005002
Change-Id: I25914f3591f40e560a681cc41bedcfaa0ee35f68
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1822357Reviewed-by: default avatarManu Cornet <manucornet@chromium.org>
Commit-Queue: Andrew Xu <andrewxu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#699558}
parent 4699d649
......@@ -40,8 +40,12 @@ constexpr int kArrowButtonGroupWidth =
kArrowButtonSize + kArrowButtonEndPadding + kDistanceToArrowButton;
// The gesture fling event with the velocity smaller than the threshold will be
// neglected.
constexpr int kFlingVelocityThreshold = 1000;
// ignored.
constexpr int kGestureFlingVelocityThreshold = 1000;
// The mouse wheel event (including touchpad scrolling) with the main axis
// offset smaller than the threshold will be ignored.
constexpr int KScrollOffsetThreshold = 20;
// Horizontal size of the tap areafor the overflow arrow button.
constexpr int kArrowButtonTapAreaHorizontal = 32;
......@@ -592,6 +596,11 @@ void ScrollableShelfView::ChildPreferredSizeChanged(views::View* child) {
}
void ScrollableShelfView::OnMouseEvent(ui::MouseEvent* event) {
if (event->IsMouseWheelEvent()) {
HandleMouseWheelEvent(event->AsMouseWheelEvent());
return;
}
// The mouse event's location may be outside of ShelfView but within the
// bounds of the ScrollableShelfView. Meanwhile, ScrollableShelfView should
// handle the mouse event consistently with ShelfView. To achieve this,
......@@ -844,15 +853,16 @@ bool ScrollableShelfView::ProcessGestureEvent(const ui::GestureEvent& event) {
if (event.type() == ui::ET_SCROLL_FLING_START) {
const bool is_horizontal_alignment = GetShelf()->IsHorizontalAlignment();
int scroll_velocity = is_horizontal_alignment
? event.details().velocity_x()
: event.details().velocity_y();
if (abs(scroll_velocity) < kFlingVelocityThreshold)
if (!ShouldHandleScroll(gfx::Vector2dF(event.details().velocity_x(),
event.details().velocity_y()),
/*is_gesture_fling=*/true)) {
return false;
}
layout_strategy_ = layout_strategy_before_main_axis_scrolling_;
const int scroll_velocity = is_horizontal_alignment
? event.details().velocity_x()
: event.details().velocity_y();
float page_scrolling_offset =
CalculatePageScrollingOffset(scroll_velocity < 0);
if (is_horizontal_alignment) {
......@@ -878,6 +888,35 @@ bool ScrollableShelfView::ProcessGestureEvent(const ui::GestureEvent& event) {
return true;
}
void ScrollableShelfView::HandleMouseWheelEvent(ui::MouseWheelEvent* event) {
// Note that the scrolling from touchpad is propagated as mouse wheel event.
// When shelf is horizontally aligned, the mouse wheel event may be handled
// by AppList.
if (!ShouldHandleScroll(gfx::Vector2dF(event->x_offset(), event->y_offset()),
/*is_gesture_fling=*/false) &&
GetShelf()->IsHorizontalAlignment()) {
GetShelf()->ProcessMouseWheelEvent(event);
return;
}
event->SetHandled();
// Scrolling the mouse wheel may create multiple mouse wheel events at the
// same time. If the scrollable shelf view is during scrolling animation at
// this moment, do not handle the mouse wheel event.
if (shelf_view_->layer()->GetAnimator()->is_animating())
return;
if (GetShelf()->IsHorizontalAlignment()) {
ScrollByXOffset(CalculatePageScrollingOffset(event->x_offset() < 0),
/*animating=*/true);
} else {
ScrollByYOffset(CalculatePageScrollingOffset(event->y_offset() < 0),
/*animating=*/true);
}
}
void ScrollableShelfView::ScrollByXOffset(float x_offset, bool animating) {
ScrollToXOffset(scroll_offset_.x() + x_offset, animating);
}
......@@ -1065,4 +1104,14 @@ bool ScrollableShelfView::CanFitAllAppsWithoutScrolling() const {
return available_length >= preferred_length;
}
bool ScrollableShelfView::ShouldHandleScroll(const gfx::Vector2dF& offset,
bool is_gesture_scrolling) const {
const float main_axis_offset =
GetShelf()->IsHorizontalAlignment() ? offset.x() : offset.y();
const int threshold = is_gesture_scrolling ? kGestureFlingVelocityThreshold
: KScrollOffsetThreshold;
return abs(main_axis_offset) > threshold;
}
} // namespace ash
......@@ -188,6 +188,8 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// consumed.
bool ProcessGestureEvent(const ui::GestureEvent& event);
void HandleMouseWheelEvent(ui::MouseWheelEvent* event);
// Scrolls the view by distance of |x_offset| or |y_offset|. |animating|
// indicates whether the animation displays. |x_offset| or |y_offset| has to
// be float. Otherwise the slow gesture drag is neglected.
......@@ -230,6 +232,12 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// Returns whether there is available space to accommodate all shelf icons.
bool CanFitAllAppsWithoutScrolling() const;
// Returns whether scrolling should be handled. |is_gesture_fling| is true
// when the scrolling is triggered by gesture fling event; when it is false,
// the scrolling is triggered by touch pad or mouse wheel event.
bool ShouldHandleScroll(const gfx::Vector2dF& offset,
bool is_gesture_fling) const;
LayoutStrategy layout_strategy_ = kNotShowArrowButtons;
// Child views Owned by views hierarchy.
......
......@@ -289,8 +289,9 @@ void Shelf::ProcessMouseEvent(const ui::MouseEvent& event) {
shelf_layout_manager_->ProcessMouseEventFromShelf(event);
}
void Shelf::ProcessMouseWheelEvent(const ui::MouseWheelEvent& event) {
Shell::Get()->app_list_controller()->ProcessMouseWheelEvent(event);
void Shelf::ProcessMouseWheelEvent(ui::MouseWheelEvent* event) {
event->SetHandled();
Shell::Get()->app_list_controller()->ProcessMouseWheelEvent(*event);
}
void Shelf::AddObserver(ShelfObserver* observer) {
......
......@@ -138,7 +138,7 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
void ProcessMouseEvent(const ui::MouseEvent& event);
// Handles a mousewheel scroll event coming from the shelf.
void ProcessMouseWheelEvent(const ui::MouseWheelEvent& event);
void ProcessMouseWheelEvent(ui::MouseWheelEvent* event);
void AddObserver(ShelfObserver* observer);
void RemoveObserver(ShelfObserver* observer);
......
......@@ -611,8 +611,7 @@ void ShelfView::OnMouseEvent(ui::MouseEvent* event) {
switch (event->type()) {
case ui::ET_MOUSEWHEEL:
event->SetHandled();
shelf_->ProcessMouseWheelEvent(*event->AsMouseWheelEvent());
// The mouse wheel event is handled by ScrollableShelfView.
break;
case ui::ET_MOUSE_PRESSED:
if (!event->IsOnlyLeftMouseButton()) {
......
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