Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(315)

Side by Side Diff: ui/views/bubble/bubble_frame_view.cc

Issue 10905311: Consolidate bubble border code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: for comments in #3 Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/bubble/bubble_frame_view.h" 5 #include "ui/views/bubble/bubble_frame_view.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "ui/gfx/screen.h" 9 #include "ui/gfx/screen.h"
10 #include "ui/views/bubble/bubble_border.h" 10 #include "ui/views/bubble/bubble_border.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 return GetWidget()->client_view()->NonClientHitTest(point); 67 return GetWidget()->client_view()->NonClientHitTest(point);
68 } 68 }
69 69
70 gfx::Size BubbleFrameView::GetPreferredSize() { 70 gfx::Size BubbleFrameView::GetPreferredSize() {
71 gfx::Size client_size(GetWidget()->client_view()->GetPreferredSize()); 71 gfx::Size client_size(GetWidget()->client_view()->GetPreferredSize());
72 return GetUpdatedWindowBounds(gfx::Rect(), client_size, false).size(); 72 return GetUpdatedWindowBounds(gfx::Rect(), client_size, false).size();
73 } 73 }
74 74
75 gfx::Rect BubbleFrameView::GetUpdatedWindowBounds(const gfx::Rect& anchor_rect, 75 gfx::Rect BubbleFrameView::GetUpdatedWindowBounds(const gfx::Rect& anchor_rect,
76 gfx::Size client_size, 76 gfx::Size client_size,
77 bool try_mirroring_arrow) { 77 bool adjust_if_offscreen) {
78 // Give the contents a margin. 78 // Give the contents a margin.
79 client_size.Enlarge(content_margins_.width(), content_margins_.height()); 79 client_size.Enlarge(content_margins_.width(), content_margins_.height());
80 80
81 if (try_mirroring_arrow) { 81 const BubbleBorder::ArrowLocation arrow = bubble_border_->arrow_location();
82 // Try to mirror the anchoring if the bubble does not fit on the screen. 82 if (adjust_if_offscreen && BubbleBorder::has_arrow(arrow)) {
83 MirrorArrowIfOffScreen(true, anchor_rect, client_size); 83 if (!bubble_border_->is_arrow_at_center(arrow)) {
84 MirrorArrowIfOffScreen(false, anchor_rect, client_size); 84 // Try to mirror the anchoring if the bubble does not fit on the screen.
85 MirrorArrowIfOffScreen(true, anchor_rect, client_size);
86 MirrorArrowIfOffScreen(false, anchor_rect, client_size);
87 } else {
88 OffsetArrowIfOffScreen(anchor_rect, client_size);
89 }
85 } 90 }
86 91
87 // Calculate the bounds with the arrow in its updated location. 92 // Calculate the bounds with the arrow in its updated location and offset.
88 return bubble_border_->GetBounds(anchor_rect, client_size); 93 return bubble_border_->GetBounds(anchor_rect, client_size);
89 } 94 }
90 95
91 void BubbleFrameView::SetBubbleBorder(BubbleBorder* border) { 96 void BubbleFrameView::SetBubbleBorder(BubbleBorder* border) {
92 bubble_border_ = border; 97 bubble_border_ = border;
93 set_border(bubble_border_); 98 set_border(bubble_border_);
94 99
95 // Update the background, which relies on the border. 100 // Update the background, which relies on the border.
96 set_background(new views::BubbleBackground(border)); 101 set_background(new views::BubbleBackground(border));
97 } 102 }
(...skipping 19 matching lines...) Expand all
117 bubble_border_->GetBounds(anchor_rect, client_size); 122 bubble_border_->GetBounds(anchor_rect, client_size);
118 // Restore the original arrow if mirroring doesn't show more of the bubble. 123 // Restore the original arrow if mirroring doesn't show more of the bubble.
119 if (GetOffScreenLength(monitor_rect, mirror_bounds, vertical) >= 124 if (GetOffScreenLength(monitor_rect, mirror_bounds, vertical) >=
120 GetOffScreenLength(monitor_rect, window_bounds, vertical)) 125 GetOffScreenLength(monitor_rect, window_bounds, vertical))
121 bubble_border_->set_arrow_location(arrow); 126 bubble_border_->set_arrow_location(arrow);
122 else 127 else
123 SchedulePaint(); 128 SchedulePaint();
124 } 129 }
125 } 130 }
126 131
132 void BubbleFrameView::OffsetArrowIfOffScreen(const gfx::Rect& anchor_rect,
133 const gfx::Size& client_size) {
134 BubbleBorder::ArrowLocation arrow = bubble_border()->arrow_location();
135 DCHECK(BubbleBorder::has_arrow(arrow));
136
137 // Get the desired bubble bounds without adjustment.
138 bubble_border_->set_arrow_offset(0);
139 gfx::Rect window_bounds(bubble_border_->GetBounds(anchor_rect, client_size));
140
141 gfx::Rect monitor_rect(GetMonitorBounds(anchor_rect));
142 if (monitor_rect.IsEmpty() || monitor_rect.Contains(window_bounds))
143 return;
144
145 // Calculate off-screen adjustment.
146 const bool is_horizontal = BubbleBorder::is_arrow_on_horizontal(arrow);
147 int offscreen_adjust = 0;
148 if (is_horizontal) {
149 if (window_bounds.x() < monitor_rect.x())
150 offscreen_adjust = monitor_rect.x() - window_bounds.x();
151 else if (window_bounds.right() > monitor_rect.right())
152 offscreen_adjust = monitor_rect.right() - window_bounds.right();
153 } else {
154 if (window_bounds.y() < monitor_rect.y())
155 offscreen_adjust = monitor_rect.y() - window_bounds.y();
156 else if (window_bounds.bottom() > monitor_rect.bottom())
157 offscreen_adjust = monitor_rect.bottom() - window_bounds.bottom();
158 }
159
160 if (BubbleBorder::is_arrow_at_center(arrow) ||
msw 2012/09/19 20:12:32 After diagramming some cases I think |offscreen_ad
xiyuan 2012/09/19 22:51:36 Since we only run this function for center arrows,
msw 2012/09/20 00:07:23 Ahhh, I mistakenly thought the offset always used
xiyuan 2012/09/20 16:56:51 I'll keep it as it is now. I have a DCHECK at the
161 (is_horizontal && BubbleBorder::is_arrow_on_left(arrow)) ||
162 (!is_horizontal && BubbleBorder::is_arrow_on_top(arrow))) {
163 // For left/top/center arrow, arrow moves closer to starting edge for
164 // positive adjustment (i.e. negative arrow offset adjustment). Similarly,
165 // negative adjustment (bubble right edge offscreen) means arrow should
166 // move further from starting edge (i.e. positive arrow offset adjustment).
167 offscreen_adjust = -offscreen_adjust;
168 }
169
170 int arrow_offset = bubble_border_->GetArrowOffset(window_bounds.size()) +
msw 2012/09/19 20:12:32 nit: send the result to set_arrow_offset directly;
xiyuan 2012/09/19 22:51:36 Done.
171 offscreen_adjust;
172 bubble_border_->set_arrow_offset(arrow_offset);
173 if (offscreen_adjust != 0)
174 SchedulePaint();
175 }
176
127 } // namespace views 177 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698