From aa7aee7ab3c63baec2e27823a33d32311bb4d206 Mon Sep 17 00:00:00 2001 From: "varunjain@chromium.org" <varunjain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> Date: Fri, 15 Mar 2013 07:30:39 +0000 Subject: [PATCH] A couple of fixes to bubble view: 1. Mirror arrow location even for centered arrows if the bubble is offscreen 2. Apply insets to |anchor_point|. This give the user the ability to specify a generic "anchor_rect" (as a combination of center point and insets) instead of either a |anchor_point| or an |anchor_view|. BUG=none Review URL: https://chromiumcodereview.appspot.com/12545040 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188285 0039d316-1c4b-4281-b951-d872f2087c98 --- ui/views/bubble/bubble_delegate.cc | 5 +-- ui/views/bubble/bubble_frame_view.cc | 5 +++ ui/views/bubble/bubble_frame_view_unittest.cc | 38 +++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/ui/views/bubble/bubble_delegate.cc b/ui/views/bubble/bubble_delegate.cc index ecee2a0589ff0..21ccd1e38c887 100644 --- a/ui/views/bubble/bubble_delegate.cc +++ b/ui/views/bubble/bubble_delegate.cc @@ -231,9 +231,8 @@ void BubbleDelegateView::OnWidgetBoundsChanged(Widget* widget, } gfx::Rect BubbleDelegateView::GetAnchorRect() { - if (!anchor_view()) - return gfx::Rect(anchor_point_, gfx::Size()); - gfx::Rect anchor_bounds = anchor_view()->GetBoundsInScreen(); + gfx::Rect anchor_bounds = anchor_view() ? anchor_view()->GetBoundsInScreen() : + gfx::Rect(anchor_point_, gfx::Size()); anchor_bounds.Inset(anchor_insets_); return anchor_bounds; } diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc index c7efa375752b4..c8e8cdafdade1 100644 --- a/ui/views/bubble/bubble_frame_view.cc +++ b/ui/views/bubble/bubble_frame_view.cc @@ -184,6 +184,11 @@ gfx::Rect BubbleFrameView::GetUpdatedWindowBounds(const gfx::Rect& anchor_rect, MirrorArrowIfOffScreen(true, anchor_rect, client_size); MirrorArrowIfOffScreen(false, anchor_rect, client_size); } else { + // Mirror as needed vertically if the arrow is on a horizontal edge and + // vice-versa. + MirrorArrowIfOffScreen(BubbleBorder::is_arrow_on_horizontal(arrow), + anchor_rect, + client_size); OffsetArrowIfOffScreen(anchor_rect, client_size); } } diff --git a/ui/views/bubble/bubble_frame_view_unittest.cc b/ui/views/bubble/bubble_frame_view_unittest.cc index 602d79f9de45a..b90615a6a5e81 100644 --- a/ui/views/bubble/bubble_frame_view_unittest.cc +++ b/ui/views/bubble/bubble_frame_view_unittest.cc @@ -228,6 +228,44 @@ TEST_F(BubbleFrameViewTest, GetUpdatedWindowBoundsMirroringFails) { EXPECT_EQ(BubbleBorder::TOP_LEFT, frame.bubble_border()->arrow_location()); } +TEST_F(BubbleFrameViewTest, TestMirroringForCenteredArrow) { + TestBubbleFrameView frame; + + // Test bubble not fitting above the anchor. + frame.bubble_border()->set_arrow_location(BubbleBorder::BOTTOM_CENTER); + gfx::Rect window_bounds = frame.GetUpdatedWindowBounds( + gfx::Rect(100, 100, 50, 50), // |anchor_rect| + gfx::Size(500, 700), // |client_size| + true); // |adjust_if_offscreen| + EXPECT_EQ(BubbleBorder::TOP_CENTER, frame.bubble_border()->arrow_location()); + + // Test bubble not fitting below the anchor. + frame.bubble_border()->set_arrow_location(BubbleBorder::TOP_CENTER); + window_bounds = frame.GetUpdatedWindowBounds( + gfx::Rect(300, 800, 50, 50), // |anchor_rect| + gfx::Size(500, 200), // |client_size| + true); // |adjust_if_offscreen| + EXPECT_EQ(BubbleBorder::BOTTOM_CENTER, + frame.bubble_border()->arrow_location()); + + // Test bubble not fitting to the right of the anchor. + frame.bubble_border()->set_arrow_location(BubbleBorder::LEFT_CENTER); + window_bounds = frame.GetUpdatedWindowBounds( + gfx::Rect(800, 300, 50, 50), // |anchor_rect| + gfx::Size(200, 500), // |client_size| + true); // |adjust_if_offscreen| + EXPECT_EQ(BubbleBorder::RIGHT_CENTER, + frame.bubble_border()->arrow_location()); + + // Test bubble not fitting to the left of the anchor. + frame.bubble_border()->set_arrow_location(BubbleBorder::RIGHT_CENTER); + window_bounds = frame.GetUpdatedWindowBounds( + gfx::Rect(100, 300, 50, 50), // |anchor_rect| + gfx::Size(500, 500), // |client_size| + true); // |adjust_if_offscreen| + EXPECT_EQ(BubbleBorder::LEFT_CENTER, frame.bubble_border()->arrow_location()); +} + // Test that the arrow will not be mirrored when |adjust_if_offscreen| is false. TEST_F(BubbleFrameViewTest, GetUpdatedWindowBoundsDontTryMirror) { TestBubbleFrameView frame;