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

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

Issue 12096084: Cleanup BubbleFrameView and BubbleBorder construction. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Additional refactoring and cleanup. Created 7 years, 10 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/tray_bubble_view.h" 5 #include "ui/views/bubble/tray_bubble_view.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "third_party/skia/include/core/SkCanvas.h" 9 #include "third_party/skia/include/core/SkCanvas.h"
10 #include "third_party/skia/include/core/SkColor.h" 10 #include "third_party/skia/include/core/SkColor.h"
(...skipping 21 matching lines...) Expand all
32 const int kBubbleSpacing = 20; 32 const int kBubbleSpacing = 20;
33 33
34 } // namespace 34 } // namespace
35 35
36 namespace views { 36 namespace views {
37 37
38 namespace internal { 38 namespace internal {
39 39
40 // Custom border for TrayBubbleView. Contains special logic for GetBounds() 40 // Custom border for TrayBubbleView. Contains special logic for GetBounds()
41 // to stack bubbles with no arrows correctly. Also calculates the arrow offset. 41 // to stack bubbles with no arrows correctly. Also calculates the arrow offset.
42 class TrayBubbleBorder : public views::BubbleBorder { 42 class TrayBubbleBorder : public BubbleBorder {
43 public: 43 public:
44 TrayBubbleBorder(views::View* owner, 44 TrayBubbleBorder(View* owner,
45 views::View* anchor, 45 View* anchor,
46 TrayBubbleView::InitParams params) 46 TrayBubbleView::InitParams params)
47 : views::BubbleBorder(params.arrow_location, params.shadow), 47 : BubbleBorder(params.arrow_location, params.shadow, params.arrow_color),
48 owner_(owner), 48 owner_(owner),
49 anchor_(anchor), 49 anchor_(anchor),
50 tray_arrow_offset_(params.arrow_offset) { 50 tray_arrow_offset_(params.arrow_offset) {
51 set_alignment(params.arrow_alignment); 51 set_alignment(params.arrow_alignment);
52 set_background_color(params.arrow_color); 52 set_background_color(params.arrow_color);
53 set_paint_arrow(!params.hide_arrow); 53 set_paint_arrow(!params.hide_arrow);
54 } 54 }
55 55
56 virtual ~TrayBubbleBorder() {} 56 virtual ~TrayBubbleBorder() {}
57 57
58 // Overridden from views::BubbleBorder. 58 // Overridden from BubbleBorder.
59 // Override views::BubbleBorder to set the bubble on top of the anchor when 59 // Sets the bubble on top of the anchor when it has no arrow.
60 // it has no arrow.
61 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to, 60 virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to,
62 const gfx::Size& contents_size) const OVERRIDE { 61 const gfx::Size& contents_size) const OVERRIDE {
63 if (has_arrow(arrow_location())) { 62 if (has_arrow(arrow_location()))
64 return views::BubbleBorder::GetBounds(position_relative_to, 63 return BubbleBorder::GetBounds(position_relative_to, contents_size);
65 contents_size);
66 }
67 64
68 gfx::Size border_size(contents_size); 65 gfx::Size border_size(contents_size);
69 gfx::Insets insets = GetInsets(); 66 gfx::Insets insets = GetInsets();
70 border_size.Enlarge(insets.width(), insets.height()); 67 border_size.Enlarge(insets.width(), insets.height());
71 68
72 const int x = position_relative_to.x() + 69 const int x = position_relative_to.x() +
73 position_relative_to.width() / 2 - border_size.width() / 2; 70 position_relative_to.width() / 2 - border_size.width() / 2;
74 // Position the bubble on top of the anchor. 71 // Position the bubble on top of the anchor.
75 const int y = position_relative_to.y() - border_size.height() 72 const int y = position_relative_to.y() - border_size.height()
76 + insets.height() - kBubbleSpacing; 73 + insets.height() - kBubbleSpacing;
77 return gfx::Rect(x, y, border_size.width(), border_size.height()); 74 return gfx::Rect(x, y, border_size.width(), border_size.height());
78 } 75 }
79 76
80 void UpdateArrowOffset() { 77 void UpdateArrowOffset() {
81 int arrow_offset = 0; 78 int arrow_offset = 0;
82 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT || 79 if (arrow_location() == BubbleBorder::BOTTOM_RIGHT ||
83 arrow_location() == views::BubbleBorder::BOTTOM_LEFT) { 80 arrow_location() == BubbleBorder::BOTTOM_LEFT) {
84 // Note: tray_arrow_offset_ is relative to the anchor widget. 81 // Note: tray_arrow_offset_ is relative to the anchor widget.
85 if (tray_arrow_offset_ == 82 if (tray_arrow_offset_ ==
86 TrayBubbleView::InitParams::kArrowDefaultOffset) { 83 TrayBubbleView::InitParams::kArrowDefaultOffset) {
87 arrow_offset = kArrowMinOffset; 84 arrow_offset = kArrowMinOffset;
88 } else { 85 } else {
89 const int width = owner_->GetWidget()->GetContentsView()->width(); 86 const int width = owner_->GetWidget()->GetContentsView()->width();
90 gfx::Point pt(tray_arrow_offset_, 0); 87 gfx::Point pt(tray_arrow_offset_, 0);
91 views::View::ConvertPointToScreen( 88 View::ConvertPointToScreen(anchor_->GetWidget()->GetRootView(), &pt);
92 anchor_->GetWidget()->GetRootView(), &pt); 89 View::ConvertPointFromScreen(owner_->GetWidget()->GetRootView(), &pt);
93 views::View::ConvertPointFromScreen(
94 owner_->GetWidget()->GetRootView(), &pt);
95 arrow_offset = pt.x(); 90 arrow_offset = pt.x();
96 if (arrow_location() == views::BubbleBorder::BOTTOM_RIGHT) 91 if (arrow_location() == BubbleBorder::BOTTOM_RIGHT)
97 arrow_offset = width - arrow_offset; 92 arrow_offset = width - arrow_offset;
98 arrow_offset = std::max(arrow_offset, kArrowMinOffset); 93 arrow_offset = std::max(arrow_offset, kArrowMinOffset);
99 } 94 }
100 } else { 95 } else {
101 if (tray_arrow_offset_ == 96 if (tray_arrow_offset_ ==
102 TrayBubbleView::InitParams::kArrowDefaultOffset) { 97 TrayBubbleView::InitParams::kArrowDefaultOffset) {
103 arrow_offset = kArrowMinOffset; 98 arrow_offset = kArrowMinOffset;
104 } else { 99 } else {
105 gfx::Point pt(0, tray_arrow_offset_); 100 gfx::Point pt(0, tray_arrow_offset_);
106 views::View::ConvertPointToScreen( 101 View::ConvertPointToScreen(anchor_->GetWidget()->GetRootView(), &pt);
107 anchor_->GetWidget()->GetRootView(), &pt); 102 View::ConvertPointFromScreen(owner_->GetWidget()->GetRootView(), &pt);
108 views::View::ConvertPointFromScreen(
109 owner_->GetWidget()->GetRootView(), &pt);
110 arrow_offset = pt.y(); 103 arrow_offset = pt.y();
111 arrow_offset = std::max(arrow_offset, kArrowMinOffset); 104 arrow_offset = std::max(arrow_offset, kArrowMinOffset);
112 } 105 }
113 } 106 }
114 set_arrow_offset(arrow_offset); 107 set_arrow_offset(arrow_offset);
115 } 108 }
116 109
117 private: 110 private:
118 views::View* owner_; 111 View* owner_;
119 views::View* anchor_; 112 View* anchor_;
120 const int tray_arrow_offset_; 113 const int tray_arrow_offset_;
121 114
122 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder); 115 DISALLOW_COPY_AND_ASSIGN(TrayBubbleBorder);
123 }; 116 };
124 117
125 // This mask layer clips the bubble's content so that it does not overwrite the 118 // This mask layer clips the bubble's content so that it does not overwrite the
126 // rounded bubble corners. 119 // rounded bubble corners.
127 // TODO(miket): This does not work on Windows. Implement layer masking or 120 // TODO(miket): This does not work on Windows. Implement layer masking or
128 // alternate solutions if the TrayBubbleView is needed there in the future. 121 // alternate solutions if the TrayBubbleView is needed there in the future.
129 class TrayBubbleContentMask : public ui::LayerDelegate { 122 class TrayBubbleContentMask : public ui::LayerDelegate {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 float device_scale_factor) { 162 float device_scale_factor) {
170 // Redrawing will take care of scale factor change. 163 // Redrawing will take care of scale factor change.
171 } 164 }
172 165
173 base::Closure TrayBubbleContentMask::PrepareForLayerBoundsChange() { 166 base::Closure TrayBubbleContentMask::PrepareForLayerBoundsChange() {
174 return base::Closure(); 167 return base::Closure();
175 } 168 }
176 169
177 // Custom layout for the bubble-view. Does the default box-layout if there is 170 // Custom layout for the bubble-view. Does the default box-layout if there is
178 // enough height. Otherwise, makes sure the bottom rows are visible. 171 // enough height. Otherwise, makes sure the bottom rows are visible.
179 class BottomAlignedBoxLayout : public views::BoxLayout { 172 class BottomAlignedBoxLayout : public BoxLayout {
180 public: 173 public:
181 explicit BottomAlignedBoxLayout(TrayBubbleView* bubble_view) 174 explicit BottomAlignedBoxLayout(TrayBubbleView* bubble_view)
182 : views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0), 175 : BoxLayout(BoxLayout::kVertical, 0, 0, 0),
183 bubble_view_(bubble_view) { 176 bubble_view_(bubble_view) {
184 } 177 }
185 178
186 virtual ~BottomAlignedBoxLayout() {} 179 virtual ~BottomAlignedBoxLayout() {}
187 180
188 private: 181 private:
189 virtual void Layout(views::View* host) OVERRIDE { 182 virtual void Layout(View* host) OVERRIDE {
190 if (host->height() >= host->GetPreferredSize().height() || 183 if (host->height() >= host->GetPreferredSize().height() ||
191 !bubble_view_->is_gesture_dragging()) { 184 !bubble_view_->is_gesture_dragging()) {
192 views::BoxLayout::Layout(host); 185 BoxLayout::Layout(host);
193 return; 186 return;
194 } 187 }
195 188
196 int consumed_height = 0; 189 int consumed_height = 0;
197 for (int i = host->child_count() - 1; 190 for (int i = host->child_count() - 1;
198 i >= 0 && consumed_height < host->height(); --i) { 191 i >= 0 && consumed_height < host->height(); --i) {
199 views::View* child = host->child_at(i); 192 View* child = host->child_at(i);
200 if (!child->visible()) 193 if (!child->visible())
201 continue; 194 continue;
202 gfx::Size size = child->GetPreferredSize(); 195 gfx::Size size = child->GetPreferredSize();
203 child->SetBounds(0, host->height() - consumed_height - size.height(), 196 child->SetBounds(0, host->height() - consumed_height - size.height(),
204 host->width(), size.height()); 197 host->width(), size.height());
205 consumed_height += size.height(); 198 consumed_height += size.height();
206 } 199 }
207 } 200 }
208 201
209 TrayBubbleView* bubble_view_; 202 TrayBubbleView* bubble_view_;
(...skipping 15 matching lines...) Expand all
225 int min_width, 218 int min_width,
226 int max_width) 219 int max_width)
227 : anchor_type(anchor_type), 220 : anchor_type(anchor_type),
228 anchor_alignment(anchor_alignment), 221 anchor_alignment(anchor_alignment),
229 min_width(min_width), 222 min_width(min_width),
230 max_width(max_width), 223 max_width(max_width),
231 max_height(0), 224 max_height(0),
232 can_activate(false), 225 can_activate(false),
233 close_on_deactivate(true), 226 close_on_deactivate(true),
234 arrow_color(SK_ColorBLACK), 227 arrow_color(SK_ColorBLACK),
235 arrow_location(views::BubbleBorder::NONE), 228 arrow_location(BubbleBorder::NONE),
236 arrow_offset(kArrowDefaultOffset), 229 arrow_offset(kArrowDefaultOffset),
237 hide_arrow(false), 230 hide_arrow(false),
238 shadow(views::BubbleBorder::BIG_SHADOW), 231 shadow(BubbleBorder::BIG_SHADOW),
239 arrow_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE) { 232 arrow_alignment(BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE) {
240 } 233 }
241 234
242 // static 235 // static
243 TrayBubbleView* TrayBubbleView::Create(gfx::NativeView parent_window, 236 TrayBubbleView* TrayBubbleView::Create(gfx::NativeView parent_window,
244 views::View* anchor, 237 View* anchor,
245 Delegate* delegate, 238 Delegate* delegate,
246 InitParams* init_params) { 239 InitParams* init_params) {
247 // Set arrow_location here so that it can be passed correctly to the 240 // Set arrow_location here so that it can be passed correctly to the
248 // BubbleView constructor. 241 // BubbleView constructor.
249 if (init_params->anchor_type == ANCHOR_TYPE_TRAY) { 242 if (init_params->anchor_type == ANCHOR_TYPE_TRAY) {
250 if (init_params->anchor_alignment == ANCHOR_ALIGNMENT_BOTTOM) { 243 if (init_params->anchor_alignment == ANCHOR_ALIGNMENT_BOTTOM) {
251 init_params->arrow_location = base::i18n::IsRTL() ? 244 init_params->arrow_location = base::i18n::IsRTL() ?
252 views::BubbleBorder::BOTTOM_LEFT : views::BubbleBorder::BOTTOM_RIGHT; 245 BubbleBorder::BOTTOM_LEFT : BubbleBorder::BOTTOM_RIGHT;
253 } else if (init_params->anchor_alignment == ANCHOR_ALIGNMENT_TOP) { 246 } else if (init_params->anchor_alignment == ANCHOR_ALIGNMENT_TOP) {
254 init_params->arrow_location = views::BubbleBorder::TOP_LEFT; 247 init_params->arrow_location = BubbleBorder::TOP_LEFT;
255 } else if (init_params->anchor_alignment == ANCHOR_ALIGNMENT_LEFT) { 248 } else if (init_params->anchor_alignment == ANCHOR_ALIGNMENT_LEFT) {
256 init_params->arrow_location = views::BubbleBorder::LEFT_BOTTOM; 249 init_params->arrow_location = BubbleBorder::LEFT_BOTTOM;
257 } else { 250 } else {
258 init_params->arrow_location = views::BubbleBorder::RIGHT_BOTTOM; 251 init_params->arrow_location = BubbleBorder::RIGHT_BOTTOM;
259 } 252 }
260 } else { 253 } else {
261 init_params->arrow_location = views::BubbleBorder::NONE; 254 init_params->arrow_location = BubbleBorder::NONE;
262 } 255 }
263 256
264 return new TrayBubbleView(parent_window, anchor, delegate, *init_params); 257 return new TrayBubbleView(parent_window, anchor, delegate, *init_params);
265 } 258 }
266 259
267 TrayBubbleView::TrayBubbleView(gfx::NativeView parent_window, 260 TrayBubbleView::TrayBubbleView(gfx::NativeView parent_window,
268 views::View* anchor, 261 View* anchor,
269 Delegate* delegate, 262 Delegate* delegate,
270 const InitParams& init_params) 263 const InitParams& init_params)
271 : views::BubbleDelegateView(anchor, init_params.arrow_location), 264 : BubbleDelegateView(anchor, init_params.arrow_location),
272 params_(init_params), 265 params_(init_params),
273 delegate_(delegate), 266 delegate_(delegate),
274 preferred_width_(init_params.min_width), 267 preferred_width_(init_params.min_width),
275 bubble_border_(NULL), 268 bubble_border_(NULL),
276 is_gesture_dragging_(false) { 269 is_gesture_dragging_(false) {
277 set_parent_window(parent_window); 270 set_parent_window(parent_window);
278 set_notify_enter_exit_on_child(true); 271 set_notify_enter_exit_on_child(true);
279 set_close_on_deactivate(init_params.close_on_deactivate); 272 set_close_on_deactivate(init_params.close_on_deactivate);
280 set_margins(gfx::Insets()); 273 set_margins(gfx::Insets());
281 bubble_border_ = new TrayBubbleBorder(this, anchor_view(), params_); 274 bubble_border_ = new TrayBubbleBorder(this, anchor_view(), params_);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 323
331 void TrayBubbleView::SetPaintArrow(bool paint_arrow) { 324 void TrayBubbleView::SetPaintArrow(bool paint_arrow) {
332 bubble_border_->set_paint_arrow(paint_arrow && !params_.hide_arrow); 325 bubble_border_->set_paint_arrow(paint_arrow && !params_.hide_arrow);
333 } 326 }
334 327
335 gfx::Insets TrayBubbleView::GetBorderInsets() const { 328 gfx::Insets TrayBubbleView::GetBorderInsets() const {
336 return bubble_border_->GetInsets(); 329 return bubble_border_->GetInsets();
337 } 330 }
338 331
339 void TrayBubbleView::Init() { 332 void TrayBubbleView::Init() {
340 views::BoxLayout* layout = new BottomAlignedBoxLayout(this); 333 BoxLayout* layout = new BottomAlignedBoxLayout(this);
341 layout->set_spread_blank_space(true); 334 layout->set_spread_blank_space(true);
342 SetLayoutManager(layout); 335 SetLayoutManager(layout);
343 } 336 }
344 337
345 gfx::Rect TrayBubbleView::GetAnchorRect() { 338 gfx::Rect TrayBubbleView::GetAnchorRect() {
346 if (!delegate_) 339 if (!delegate_)
347 return gfx::Rect(); 340 return gfx::Rect();
348 return delegate_->GetAnchorRect(anchor_widget(), 341 return delegate_->GetAnchorRect(anchor_widget(),
349 params_.anchor_type, 342 params_.anchor_type,
350 params_.anchor_alignment); 343 params_.anchor_alignment);
351 } 344 }
352 345
353 bool TrayBubbleView::CanActivate() const { 346 bool TrayBubbleView::CanActivate() const {
354 return params_.can_activate; 347 return params_.can_activate;
355 } 348 }
356 349
357 // Overridden to create BubbleFrameView and set a custom border. 350 NonClientFrameView* TrayBubbleView::CreateNonClientFrameView(Widget* widget) {
358 views::NonClientFrameView* TrayBubbleView::CreateNonClientFrameView( 351 BubbleFrameView* frame = new BubbleFrameView(margins());
359 views::Widget* widget) { 352 frame->SetBubbleBorder(bubble_border_);
360 views::BubbleFrameView* bubble_frame_view = 353 return frame;
361 new views::BubbleFrameView(margins(), bubble_border_);
362 return bubble_frame_view;
363 } 354 }
364 355
365 bool TrayBubbleView::WidgetHasHitTestMask() const { 356 bool TrayBubbleView::WidgetHasHitTestMask() const {
366 return true; 357 return true;
367 } 358 }
368 359
369 void TrayBubbleView::GetWidgetHitTestMask(gfx::Path* mask) const { 360 void TrayBubbleView::GetWidgetHitTestMask(gfx::Path* mask) const {
370 DCHECK(mask); 361 DCHECK(mask);
371 mask->addRect(gfx::RectToSkRect(GetBubbleFrameView()->GetContentsBounds())); 362 mask->addRect(gfx::RectToSkRect(GetBubbleFrameView()->GetContentsBounds()));
372 } 363 }
373 364
374 gfx::Size TrayBubbleView::GetPreferredSize() { 365 gfx::Size TrayBubbleView::GetPreferredSize() {
375 gfx::Size size = views::BubbleDelegateView::GetPreferredSize(); 366 gfx::Size size = BubbleDelegateView::GetPreferredSize();
376 int height = size.height(); 367 int height = size.height();
377 if (params_.max_height != 0 && height > params_.max_height) 368 if (params_.max_height != 0 && height > params_.max_height)
378 height = params_.max_height; 369 height = params_.max_height;
379 return gfx::Size(preferred_width_, height); 370 return gfx::Size(preferred_width_, height);
380 } 371 }
381 372
382 gfx::Size TrayBubbleView::GetMaximumSize() { 373 gfx::Size TrayBubbleView::GetMaximumSize() {
383 gfx::Size size = GetPreferredSize(); 374 gfx::Size size = GetPreferredSize();
384 size.set_width(params_.max_width); 375 size.set_width(params_.max_width);
385 return size; 376 return size;
(...skipping 14 matching lines...) Expand all
400 state->role = ui::AccessibilityTypes::ROLE_WINDOW; 391 state->role = ui::AccessibilityTypes::ROLE_WINDOW;
401 state->name = delegate_->GetAccessibleNameForBubble(); 392 state->name = delegate_->GetAccessibleNameForBubble();
402 } 393 }
403 } 394 }
404 395
405 void TrayBubbleView::ChildPreferredSizeChanged(View* child) { 396 void TrayBubbleView::ChildPreferredSizeChanged(View* child) {
406 SizeToContents(); 397 SizeToContents();
407 } 398 }
408 399
409 void TrayBubbleView::ViewHierarchyChanged(bool is_add, 400 void TrayBubbleView::ViewHierarchyChanged(bool is_add,
410 views::View* parent, 401 View* parent,
411 views::View* child) { 402 View* child) {
412 if (get_use_acceleration_when_possible() && is_add && child == this) { 403 if (get_use_acceleration_when_possible() && is_add && child == this) {
413 parent->SetPaintToLayer(true); 404 parent->SetPaintToLayer(true);
414 parent->SetFillsBoundsOpaquely(true); 405 parent->SetFillsBoundsOpaquely(true);
415 parent->layer()->SetMasksToBounds(true); 406 parent->layer()->SetMasksToBounds(true);
416 } 407 }
417 } 408 }
418 409
419 } // namespace views 410 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698