Chromium Code Reviews| Index: ui/views/bubble/bubble_frame_view.cc |
| diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc |
| index 9ae1f8d5862799a76d3239555054824cbd076af1..55010e4c79ff7f52a5ffbc9d74d08389f14aa744 100644 |
| --- a/ui/views/bubble/bubble_frame_view.cc |
| +++ b/ui/views/bubble/bubble_frame_view.cc |
| @@ -74,17 +74,22 @@ gfx::Size BubbleFrameView::GetPreferredSize() { |
| gfx::Rect BubbleFrameView::GetUpdatedWindowBounds(const gfx::Rect& anchor_rect, |
| gfx::Size client_size, |
| - bool try_mirroring_arrow) { |
| + bool try_fit_bubble) { |
| // Give the contents a margin. |
| client_size.Enlarge(content_margins_.width(), content_margins_.height()); |
| - if (try_mirroring_arrow) { |
| - // Try to mirror the anchoring if the bubble does not fit on the screen. |
| - MirrorArrowIfOffScreen(true, anchor_rect, client_size); |
| - MirrorArrowIfOffScreen(false, anchor_rect, client_size); |
| + if (try_fit_bubble && |
| + BubbleBorder::has_arrow(bubble_border_->arrow_location())) { |
| + if (!bubble_border_->center_arrow()) { |
| + // Try to mirror the anchoring if the bubble does not fit on the screen. |
| + MirrorArrowIfOffScreen(true, anchor_rect, client_size); |
| + MirrorArrowIfOffScreen(false, anchor_rect, client_size); |
| + } |
| + |
| + OffsetArrowIfOffScreen(anchor_rect, client_size); |
|
msw
2012/09/18 19:33:42
This is only useful for centered arrows, right? Li
xiyuan
2012/09/19 18:20:09
Done.
|
| } |
| - // Calculate the bounds with the arrow in its updated location. |
| + // Calculate the bounds with the arrow in its updated location and offset. |
| return bubble_border_->GetBounds(anchor_rect, client_size); |
| } |
| @@ -124,4 +129,47 @@ void BubbleFrameView::MirrorArrowIfOffScreen( |
| } |
| } |
| +void BubbleFrameView::OffsetArrowIfOffScreen(const gfx::Rect& anchor_rect, |
| + const gfx::Size& client_size) { |
| + BubbleBorder::ArrowLocation arrow = bubble_border()->arrow_location(); |
| + DCHECK(BubbleBorder::has_arrow(arrow)); |
| + |
| + // Get desired bubble bounds without adjustment. |
|
msw
2012/09/18 19:33:42
grammar nit: "Get the..."
xiyuan
2012/09/19 18:20:09
Done.
|
| + const int old_adjust = bubble_border_->relative_arrow_offset(); |
|
msw
2012/09/18 19:33:42
Use the existing |override_arrow_offset_|; nix new
xiyuan
2012/09/19 18:20:09
Done.
|
| + bubble_border_->set_relative_arrow_offset(0); |
| + gfx::Rect window_bounds(bubble_border_->GetBounds(anchor_rect, client_size)); |
| + |
| + gfx::Rect monitor_rect(GetMonitorBounds(anchor_rect)); |
| + if (monitor_rect.IsEmpty() || monitor_rect.Contains(window_bounds)) |
| + return; |
| + |
| + // Calculate off screen adjustment |
|
msw
2012/09/18 19:33:42
nit: hyphen off-screen or single word; add a perio
xiyuan
2012/09/19 18:20:09
Done.
|
| + const bool is_horizontal = BubbleBorder::is_arrow_on_horizontal(arrow); |
| + int offscreen_adjust = 0; |
| + if (is_horizontal) { |
| + if (window_bounds.x() < monitor_rect.x()) |
| + offscreen_adjust = monitor_rect.x() - window_bounds.x(); |
| + else if (window_bounds.right() > monitor_rect.right()) |
| + offscreen_adjust = monitor_rect.right() - window_bounds.right(); |
| + } else { |
| + if (window_bounds.y() < monitor_rect.y()) |
| + offscreen_adjust = monitor_rect.y() - window_bounds.y(); |
| + else if (window_bounds.bottom() > monitor_rect.bottom()) |
| + offscreen_adjust = monitor_rect.bottom() - window_bounds.bottom(); |
| + } |
| + |
| + if ((is_horizontal && BubbleBorder::is_arrow_on_left(arrow)) || |
| + (!is_horizontal && BubbleBorder::is_arrow_on_top(arrow))) { |
| + // For left and top arrow, arrow moves closer to starting edge for positive |
| + // adjustment (i.e. negative arrow offset adjustment). Similarly, negative |
| + // adjustment (bubble right edge offscreen) means arrow should move further |
| + // from starting edge (i.e. positive arrow offset adjustment). |
| + offscreen_adjust = -offscreen_adjust; |
| + } |
| + |
| + bubble_border_->set_relative_arrow_offset(offscreen_adjust); |
| + if (old_adjust != offscreen_adjust) |
| + SchedulePaint(); |
| +} |
| + |
| } // namespace views |