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 = ...@@ -40,8 +40,12 @@ constexpr int kArrowButtonGroupWidth =
kArrowButtonSize + kArrowButtonEndPadding + kDistanceToArrowButton; kArrowButtonSize + kArrowButtonEndPadding + kDistanceToArrowButton;
// The gesture fling event with the velocity smaller than the threshold will be // The gesture fling event with the velocity smaller than the threshold will be
// neglected. // ignored.
constexpr int kFlingVelocityThreshold = 1000; 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. // Horizontal size of the tap areafor the overflow arrow button.
constexpr int kArrowButtonTapAreaHorizontal = 32; constexpr int kArrowButtonTapAreaHorizontal = 32;
...@@ -592,6 +596,11 @@ void ScrollableShelfView::ChildPreferredSizeChanged(views::View* child) { ...@@ -592,6 +596,11 @@ void ScrollableShelfView::ChildPreferredSizeChanged(views::View* child) {
} }
void ScrollableShelfView::OnMouseEvent(ui::MouseEvent* event) { 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 // The mouse event's location may be outside of ShelfView but within the
// bounds of the ScrollableShelfView. Meanwhile, ScrollableShelfView should // bounds of the ScrollableShelfView. Meanwhile, ScrollableShelfView should
// handle the mouse event consistently with ShelfView. To achieve this, // handle the mouse event consistently with ShelfView. To achieve this,
...@@ -844,15 +853,16 @@ bool ScrollableShelfView::ProcessGestureEvent(const ui::GestureEvent& event) { ...@@ -844,15 +853,16 @@ bool ScrollableShelfView::ProcessGestureEvent(const ui::GestureEvent& event) {
if (event.type() == ui::ET_SCROLL_FLING_START) { if (event.type() == ui::ET_SCROLL_FLING_START) {
const bool is_horizontal_alignment = GetShelf()->IsHorizontalAlignment(); const bool is_horizontal_alignment = GetShelf()->IsHorizontalAlignment();
if (!ShouldHandleScroll(gfx::Vector2dF(event.details().velocity_x(),
int scroll_velocity = is_horizontal_alignment event.details().velocity_y()),
? event.details().velocity_x() /*is_gesture_fling=*/true)) {
: event.details().velocity_y();
if (abs(scroll_velocity) < kFlingVelocityThreshold)
return false; return false;
}
layout_strategy_ = layout_strategy_before_main_axis_scrolling_; 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 = float page_scrolling_offset =
CalculatePageScrollingOffset(scroll_velocity < 0); CalculatePageScrollingOffset(scroll_velocity < 0);
if (is_horizontal_alignment) { if (is_horizontal_alignment) {
...@@ -878,6 +888,35 @@ bool ScrollableShelfView::ProcessGestureEvent(const ui::GestureEvent& event) { ...@@ -878,6 +888,35 @@ bool ScrollableShelfView::ProcessGestureEvent(const ui::GestureEvent& event) {
return true; 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) { void ScrollableShelfView::ScrollByXOffset(float x_offset, bool animating) {
ScrollToXOffset(scroll_offset_.x() + x_offset, animating); ScrollToXOffset(scroll_offset_.x() + x_offset, animating);
} }
...@@ -1065,4 +1104,14 @@ bool ScrollableShelfView::CanFitAllAppsWithoutScrolling() const { ...@@ -1065,4 +1104,14 @@ bool ScrollableShelfView::CanFitAllAppsWithoutScrolling() const {
return available_length >= preferred_length; 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 } // namespace ash
...@@ -188,6 +188,8 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -188,6 +188,8 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// consumed. // consumed.
bool ProcessGestureEvent(const ui::GestureEvent& event); bool ProcessGestureEvent(const ui::GestureEvent& event);
void HandleMouseWheelEvent(ui::MouseWheelEvent* event);
// Scrolls the view by distance of |x_offset| or |y_offset|. |animating| // Scrolls the view by distance of |x_offset| or |y_offset|. |animating|
// indicates whether the animation displays. |x_offset| or |y_offset| has to // indicates whether the animation displays. |x_offset| or |y_offset| has to
// be float. Otherwise the slow gesture drag is neglected. // be float. Otherwise the slow gesture drag is neglected.
...@@ -230,6 +232,12 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView, ...@@ -230,6 +232,12 @@ class ASH_EXPORT ScrollableShelfView : public views::AccessiblePaneView,
// Returns whether there is available space to accommodate all shelf icons. // Returns whether there is available space to accommodate all shelf icons.
bool CanFitAllAppsWithoutScrolling() const; 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; LayoutStrategy layout_strategy_ = kNotShowArrowButtons;
// Child views Owned by views hierarchy. // Child views Owned by views hierarchy.
......
...@@ -289,8 +289,9 @@ void Shelf::ProcessMouseEvent(const ui::MouseEvent& event) { ...@@ -289,8 +289,9 @@ void Shelf::ProcessMouseEvent(const ui::MouseEvent& event) {
shelf_layout_manager_->ProcessMouseEventFromShelf(event); shelf_layout_manager_->ProcessMouseEventFromShelf(event);
} }
void Shelf::ProcessMouseWheelEvent(const ui::MouseWheelEvent& event) { void Shelf::ProcessMouseWheelEvent(ui::MouseWheelEvent* event) {
Shell::Get()->app_list_controller()->ProcessMouseWheelEvent(event); event->SetHandled();
Shell::Get()->app_list_controller()->ProcessMouseWheelEvent(*event);
} }
void Shelf::AddObserver(ShelfObserver* observer) { void Shelf::AddObserver(ShelfObserver* observer) {
......
...@@ -138,7 +138,7 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver { ...@@ -138,7 +138,7 @@ class ASH_EXPORT Shelf : public ShelfLayoutManagerObserver {
void ProcessMouseEvent(const ui::MouseEvent& event); void ProcessMouseEvent(const ui::MouseEvent& event);
// Handles a mousewheel scroll event coming from the shelf. // 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 AddObserver(ShelfObserver* observer);
void RemoveObserver(ShelfObserver* observer); void RemoveObserver(ShelfObserver* observer);
......
...@@ -611,8 +611,7 @@ void ShelfView::OnMouseEvent(ui::MouseEvent* event) { ...@@ -611,8 +611,7 @@ void ShelfView::OnMouseEvent(ui::MouseEvent* event) {
switch (event->type()) { switch (event->type()) {
case ui::ET_MOUSEWHEEL: case ui::ET_MOUSEWHEEL:
event->SetHandled(); // The mouse wheel event is handled by ScrollableShelfView.
shelf_->ProcessMouseWheelEvent(*event->AsMouseWheelEvent());
break; break;
case ui::ET_MOUSE_PRESSED: case ui::ET_MOUSE_PRESSED:
if (!event->IsOnlyLeftMouseButton()) { 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