Commit 2aaa0faa authored by Katie D's avatar Katie D Committed by Commit Bot

Fix autoclick scroll bubble's jumpy animation to position.

The autoclick scroll bubble animation was jumpy because the arrow
and anchor rect changes both kicked off animations. This gives
subclasses of BubbleDialogDelegateView the option to set the arrow
without creating an animation, in order to fix the visual bug.

Bug: 978163
Change-Id: Id4feb50e35a3945c24e5759d953261a02dd4970c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1691549
Commit-Queue: Katie Dektar <katie@chromium.org>
Reviewed-by: default avatarBret Sepulveda <bsep@chromium.org>
Reviewed-by: default avatarTetsui Ohkubo <tetsui@chromium.org>
Cr-Commit-Position: refs/heads/master@{#676211}
parent 3c775c28
...@@ -52,8 +52,7 @@ void AutoclickScrollBubbleController::UpdateAnchorRect( ...@@ -52,8 +52,7 @@ void AutoclickScrollBubbleController::UpdateAnchorRect(
menu_bubble_alignment_ = alignment; menu_bubble_alignment_ = alignment;
if (set_scroll_rect_) if (set_scroll_rect_)
return; return;
bubble_view_->SetArrow(alignment); bubble_view_->UpdateAnchorRect(rect, alignment);
bubble_view_->UpdateAnchorRect(rect);
} }
void AutoclickScrollBubbleController::SetScrollPosition( void AutoclickScrollBubbleController::SetScrollPosition(
...@@ -78,8 +77,8 @@ void AutoclickScrollBubbleController::SetScrollPosition( ...@@ -78,8 +77,8 @@ void AutoclickScrollBubbleController::SetScrollPosition(
// Buffer around the point so that the scroll bubble does not overlap it. // Buffer around the point so that the scroll bubble does not overlap it.
// ScrollBubbleController will automatically layout to avoid edges. // ScrollBubbleController will automatically layout to avoid edges.
anchor.Inset(-kScrollPointBufferDips, -kScrollPointBufferDips); anchor.Inset(-kScrollPointBufferDips, -kScrollPointBufferDips);
bubble_view_->SetArrow(views::BubbleBorder::Arrow::LEFT_CENTER); bubble_view_->UpdateAnchorRect(anchor,
bubble_view_->UpdateAnchorRect(anchor); views::BubbleBorder::Arrow::LEFT_CENTER);
return; return;
} }
...@@ -152,17 +151,18 @@ void AutoclickScrollBubbleController::SetScrollPosition( ...@@ -152,17 +151,18 @@ void AutoclickScrollBubbleController::SetScrollPosition(
std::stable_sort(positions.begin(), positions.end(), comparePositions); std::stable_sort(positions.begin(), positions.end(), comparePositions);
// Position on the optimal side depending on the shortest distance. // Position on the optimal side depending on the shortest distance.
bubble_view_->SetArrow(positions.front().arrow);
if (positions.front().is_horizontal) { if (positions.front().is_horizontal) {
// Center it vertically on the scroll point. // Center it vertically on the scroll point.
bubble_view_->UpdateAnchorRect(gfx::Rect(scroll_bounds_in_dips.x(), bubble_view_->UpdateAnchorRect(
scroll_point_in_dips.y(), gfx::Rect(scroll_bounds_in_dips.x(), scroll_point_in_dips.y(),
scroll_bounds_in_dips.width(), 0)); scroll_bounds_in_dips.width(), 0),
positions.at(0).arrow);
} else { } else {
// Center horizontally on scroll point. // Center horizontally on scroll point.
bubble_view_->UpdateAnchorRect(gfx::Rect(scroll_point_in_dips.x(), bubble_view_->UpdateAnchorRect(
scroll_bounds_in_dips.y(), 0, gfx::Rect(scroll_point_in_dips.x(), scroll_bounds_in_dips.y(), 0,
scroll_bounds_in_dips.height())); scroll_bounds_in_dips.height()),
positions.at(0).arrow);
} }
} }
......
...@@ -327,11 +327,16 @@ AutoclickScrollBubbleView::AutoclickScrollBubbleView( ...@@ -327,11 +327,16 @@ AutoclickScrollBubbleView::AutoclickScrollBubbleView(
AutoclickScrollBubbleView::~AutoclickScrollBubbleView() {} AutoclickScrollBubbleView::~AutoclickScrollBubbleView() {}
void AutoclickScrollBubbleView::UpdateAnchorRect(const gfx::Rect& rect) { void AutoclickScrollBubbleView::UpdateAnchorRect(
const gfx::Rect& rect,
views::BubbleBorder::Arrow arrow) {
ui::ScopedLayerAnimationSettings settings( ui::ScopedLayerAnimationSettings settings(
GetWidget()->GetLayer()->GetAnimator()); GetWidget()->GetLayer()->GetAnimator());
settings.SetPreemptionStrategy( settings.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET); ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
// SetAnchorRect will resize, so set the arrow without reizing to avoid a
// double animation.
SetArrowWithoutResizing(arrow);
SetAnchorRect(rect); SetAnchorRect(rect);
} }
......
...@@ -21,7 +21,8 @@ class AutoclickScrollBubbleView : public TrayBubbleView { ...@@ -21,7 +21,8 @@ class AutoclickScrollBubbleView : public TrayBubbleView {
explicit AutoclickScrollBubbleView(TrayBubbleView::InitParams init_params); explicit AutoclickScrollBubbleView(TrayBubbleView::InitParams init_params);
~AutoclickScrollBubbleView() override; ~AutoclickScrollBubbleView() override;
void UpdateAnchorRect(const gfx::Rect& rect); void UpdateAnchorRect(const gfx::Rect& rect,
views::BubbleBorder::Arrow arrow);
// TrayBubbleView: // TrayBubbleView:
bool IsAnchoredToStatusArea() const override; bool IsAnchoredToStatusArea() const override;
......
...@@ -265,6 +265,15 @@ void BubbleDialogDelegateView::SetHighlightedButton( ...@@ -265,6 +265,15 @@ void BubbleDialogDelegateView::SetHighlightedButton(
} }
void BubbleDialogDelegateView::SetArrow(BubbleBorder::Arrow arrow) { void BubbleDialogDelegateView::SetArrow(BubbleBorder::Arrow arrow) {
SetArrowWithoutResizing(arrow);
// If SetArrow() is called before CreateWidget(), there's no need to update
// the BubbleFrameView.
if (GetBubbleFrameView())
SizeToContents();
}
void BubbleDialogDelegateView::SetArrowWithoutResizing(
BubbleBorder::Arrow arrow) {
if (base::i18n::IsRTL()) if (base::i18n::IsRTL())
arrow = BubbleBorder::horizontal_mirror(arrow); arrow = BubbleBorder::horizontal_mirror(arrow);
if (arrow_ == arrow) if (arrow_ == arrow)
...@@ -273,10 +282,8 @@ void BubbleDialogDelegateView::SetArrow(BubbleBorder::Arrow arrow) { ...@@ -273,10 +282,8 @@ void BubbleDialogDelegateView::SetArrow(BubbleBorder::Arrow arrow) {
// If SetArrow() is called before CreateWidget(), there's no need to update // If SetArrow() is called before CreateWidget(), there's no need to update
// the BubbleFrameView. // the BubbleFrameView.
if (GetBubbleFrameView()) { if (GetBubbleFrameView())
GetBubbleFrameView()->SetArrow(arrow); GetBubbleFrameView()->SetArrow(arrow);
SizeToContents();
}
} }
gfx::Rect BubbleDialogDelegateView::GetAnchorRect() const { gfx::Rect BubbleDialogDelegateView::GetAnchorRect() const {
......
...@@ -79,9 +79,19 @@ class VIEWS_EXPORT BubbleDialogDelegateView : public DialogDelegateView, ...@@ -79,9 +79,19 @@ class VIEWS_EXPORT BubbleDialogDelegateView : public DialogDelegateView,
// The anchor rect is used in the absence of an assigned anchor view. // The anchor rect is used in the absence of an assigned anchor view.
const gfx::Rect& anchor_rect() const { return anchor_rect_; } const gfx::Rect& anchor_rect() const { return anchor_rect_; }
// Set the desired arrow for the bubble. The arrow will be mirrored for RTL. // Set the desired arrow for the bubble and updates the bubble's bounds
// accordingly. The arrow will be mirrored for RTL.
void SetArrow(BubbleBorder::Arrow arrow); void SetArrow(BubbleBorder::Arrow arrow);
// Sets the arrow without recaluclating or updating bounds. This could be used
// proceeding another function call which also sets bounds, so that bounds are
// not set multiple times in a row. When animating bounds changes, setting
// bounds twice in a row can make the widget position jump.
// TODO(crbug.com/982880) It would be good to be able to re-target the
// animation rather than expet callers to use SetArrowWithoutResizing if they
// are also changing the anchor rect, or similar.
void SetArrowWithoutResizing(BubbleBorder::Arrow arrow);
BubbleBorder::Shadow GetShadow() const; BubbleBorder::Shadow GetShadow() const;
void set_shadow(BubbleBorder::Shadow shadow) { shadow_ = shadow; } void set_shadow(BubbleBorder::Shadow shadow) { shadow_ = shadow; }
......
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