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

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

Issue 454173002: Fixed BubbleBorder sizing problems & added unit tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed construction order of the TrayBubbleView/TrayBubbleWrapper in WebNotificationBubbleWrapper co… Created 6 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
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_border.h" 5 #include "ui/views/bubble/bubble_border.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "ui/base/resource/resource_bundle.h" 10 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/gfx/canvas.h" 11 #include "ui/gfx/canvas.h"
13 #include "ui/gfx/image/image_skia.h"
14 #include "ui/gfx/rect.h" 12 #include "ui/gfx/rect.h"
15 #include "ui/gfx/skia_util.h" 13 #include "ui/gfx/skia_util.h"
16 #include "ui/resources/grit/ui_resources.h" 14 #include "ui/resources/grit/ui_resources.h"
17 #include "ui/views/painter.h" 15 #include "ui/views/painter.h"
18 #include "ui/views/view.h" 16 #include "ui/views/view.h"
19 17
20 namespace views { 18 namespace views {
21 19
22 namespace internal { 20 namespace internal {
23 21
24 // A helper that combines each border image-set painter with arrows and metrics.
25 struct BorderImages {
26 BorderImages(const int border_image_ids[],
27 const int arrow_image_ids[],
28 int border_interior_thickness,
29 int arrow_interior_thickness,
30 int corner_radius);
31
32 scoped_ptr<Painter> border_painter;
33 gfx::ImageSkia left_arrow;
34 gfx::ImageSkia top_arrow;
35 gfx::ImageSkia right_arrow;
36 gfx::ImageSkia bottom_arrow;
37
38 // The thickness of border and arrow images and their interior areas.
39 // Thickness is the width of left/right and the height of top/bottom images.
40 // The interior is measured without including stroke or shadow pixels.
41 int border_thickness;
42 int border_interior_thickness;
43 int arrow_thickness;
44 int arrow_interior_thickness;
45 // The corner radius of the bubble's rounded-rect interior area.
46 int corner_radius;
47 };
48
49 BorderImages::BorderImages(const int border_image_ids[], 22 BorderImages::BorderImages(const int border_image_ids[],
50 const int arrow_image_ids[], 23 const int arrow_image_ids[],
51 int border_interior_thickness, 24 int border_interior_thickness,
52 int arrow_interior_thickness, 25 int arrow_interior_thickness,
53 int corner_radius) 26 int corner_radius)
54 : border_painter(Painter::CreateImageGridPainter(border_image_ids)), 27 : border_painter(Painter::CreateImageGridPainter(border_image_ids)),
55 border_thickness(0), 28 border_thickness(0),
56 border_interior_thickness(border_interior_thickness), 29 border_interior_thickness(border_interior_thickness),
57 arrow_thickness(0), 30 arrow_thickness(0),
58 arrow_interior_thickness(arrow_interior_thickness), 31 arrow_interior_thickness(arrow_interior_thickness),
59 corner_radius(corner_radius) { 32 corner_radius(corner_radius) {
60 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 33 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
61 border_thickness = rb.GetImageSkiaNamed(border_image_ids[0])->width(); 34 border_thickness = rb.GetImageSkiaNamed(border_image_ids[0])->width();
62 if (arrow_image_ids[0] != 0) { 35 if (arrow_image_ids[0] != 0) {
63 left_arrow = *rb.GetImageSkiaNamed(arrow_image_ids[0]); 36 left_arrow = *rb.GetImageSkiaNamed(arrow_image_ids[0]);
64 top_arrow = *rb.GetImageSkiaNamed(arrow_image_ids[1]); 37 top_arrow = *rb.GetImageSkiaNamed(arrow_image_ids[1]);
65 right_arrow = *rb.GetImageSkiaNamed(arrow_image_ids[2]); 38 right_arrow = *rb.GetImageSkiaNamed(arrow_image_ids[2]);
66 bottom_arrow = *rb.GetImageSkiaNamed(arrow_image_ids[3]); 39 bottom_arrow = *rb.GetImageSkiaNamed(arrow_image_ids[3]);
67 arrow_thickness = top_arrow.height(); 40 arrow_thickness = top_arrow.height();
68 } 41 }
69 } 42 }
70 43
44 BorderImages::~BorderImages() {}
45
71 } // namespace internal 46 } // namespace internal
72 47
73 namespace { 48 namespace {
74 49
75 // The border and arrow stroke size used in image assets, in pixels.
76 const int kStroke = 1;
77
78 // Bubble border and arrow image resource ids. They don't use the IMAGE_GRID 50 // Bubble border and arrow image resource ids. They don't use the IMAGE_GRID
79 // macro because there is no center image. 51 // macro because there is no center image.
80 const int kNoShadowImages[] = { 52 const int kNoShadowImages[] = {
81 IDR_BUBBLE_TL, IDR_BUBBLE_T, IDR_BUBBLE_TR, 53 IDR_BUBBLE_TL, IDR_BUBBLE_T, IDR_BUBBLE_TR,
82 IDR_BUBBLE_L, 0, IDR_BUBBLE_R, 54 IDR_BUBBLE_L, 0, IDR_BUBBLE_R,
83 IDR_BUBBLE_BL, IDR_BUBBLE_B, IDR_BUBBLE_BR }; 55 IDR_BUBBLE_BL, IDR_BUBBLE_B, IDR_BUBBLE_BR };
84 const int kNoShadowArrows[] = { 56 const int kNoShadowArrows[] = {
85 IDR_BUBBLE_L_ARROW, IDR_BUBBLE_T_ARROW, 57 IDR_BUBBLE_L_ARROW, IDR_BUBBLE_T_ARROW,
86 IDR_BUBBLE_R_ARROW, IDR_BUBBLE_B_ARROW, }; 58 IDR_BUBBLE_R_ARROW, IDR_BUBBLE_B_ARROW, };
87 59
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 case BubbleBorder::SHADOW_COUNT: 115 case BubbleBorder::SHADOW_COUNT:
144 NOTREACHED(); 116 NOTREACHED();
145 break; 117 break;
146 } 118 }
147 119
148 return set; 120 return set;
149 } 121 }
150 122
151 } // namespace 123 } // namespace
152 124
125 const int BubbleBorder::kStroke = 1;
126
153 BubbleBorder::BubbleBorder(Arrow arrow, Shadow shadow, SkColor color) 127 BubbleBorder::BubbleBorder(Arrow arrow, Shadow shadow, SkColor color)
154 : arrow_(arrow), 128 : arrow_(arrow),
155 arrow_offset_(0), 129 arrow_offset_(0),
156 arrow_paint_type_(PAINT_NORMAL), 130 arrow_paint_type_(PAINT_NORMAL),
157 alignment_(ALIGN_ARROW_TO_MID_ANCHOR), 131 alignment_(ALIGN_ARROW_TO_MID_ANCHOR),
158 shadow_(shadow), 132 shadow_(shadow),
159 background_color_(color), 133 background_color_(color),
160 use_theme_background_color_(false) { 134 use_theme_background_color_(false) {
161 DCHECK(shadow < SHADOW_COUNT); 135 DCHECK(shadow < SHADOW_COUNT);
162 images_ = GetBorderImages(shadow); 136 images_ = GetBorderImages(shadow);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 const gfx::Insets insets = GetInsets(); 245 const gfx::Insets insets = GetInsets();
272 size.Enlarge(insets.width(), insets.height()); 246 size.Enlarge(insets.width(), insets.height());
273 247
274 // Ensure the bubble is large enough to not overlap border and arrow images. 248 // Ensure the bubble is large enough to not overlap border and arrow images.
275 const int min = 2 * images_->border_thickness; 249 const int min = 2 * images_->border_thickness;
276 const int min_with_arrow_width = min + images_->top_arrow.width(); 250 const int min_with_arrow_width = min + images_->top_arrow.width();
277 const int min_with_arrow_thickness = images_->border_thickness + 251 const int min_with_arrow_thickness = images_->border_thickness +
278 std::max(images_->arrow_thickness + images_->border_interior_thickness, 252 std::max(images_->arrow_thickness + images_->border_interior_thickness,
279 images_->border_thickness); 253 images_->border_thickness);
280 // Only take arrow image sizes into account when the bubble tip is shown. 254 // Only take arrow image sizes into account when the bubble tip is shown.
281 if (arrow_paint_type_ == PAINT_TRANSPARENT || !has_arrow(arrow_)) 255 if (arrow_paint_type_ == PAINT_NONE || !has_arrow(arrow_))
282 size.SetToMax(gfx::Size(min, min)); 256 size.SetToMax(gfx::Size(min, min));
283 else if (is_arrow_on_horizontal(arrow_)) 257 else if (is_arrow_on_horizontal(arrow_))
284 size.SetToMax(gfx::Size(min_with_arrow_width, min_with_arrow_thickness)); 258 size.SetToMax(gfx::Size(min_with_arrow_width, min_with_arrow_thickness));
285 else 259 else
286 size.SetToMax(gfx::Size(min_with_arrow_thickness, min_with_arrow_width)); 260 size.SetToMax(gfx::Size(min_with_arrow_thickness, min_with_arrow_width));
287 return size; 261 return size;
288 } 262 }
289 263
290 gfx::ImageSkia* BubbleBorder::GetArrowImage() const { 264 gfx::ImageSkia* BubbleBorder::GetArrowImage() const {
291 if (!has_arrow(arrow_)) 265 if (!has_arrow(arrow_))
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 SkDoubleToScalar(tip_y + multiplier * offset_to_next_vertex)); 327 SkDoubleToScalar(tip_y + multiplier * offset_to_next_vertex));
354 path.close(); 328 path.close();
355 329
356 SkPaint paint; 330 SkPaint paint;
357 paint.setStyle(SkPaint::kFill_Style); 331 paint.setStyle(SkPaint::kFill_Style);
358 paint.setColor(background_color_); 332 paint.setColor(background_color_);
359 333
360 canvas->DrawPath(path, paint); 334 canvas->DrawPath(path, paint);
361 } 335 }
362 336
337 internal::BorderImages* BubbleBorder::GetImagesForTest() const {
338 return images_;
339 }
340
363 void BubbleBackground::Paint(gfx::Canvas* canvas, views::View* view) const { 341 void BubbleBackground::Paint(gfx::Canvas* canvas, views::View* view) const {
364 if (border_->shadow() == BubbleBorder::NO_SHADOW_OPAQUE_BORDER) 342 if (border_->shadow() == BubbleBorder::NO_SHADOW_OPAQUE_BORDER)
365 canvas->DrawColor(border_->background_color()); 343 canvas->DrawColor(border_->background_color());
366 344
367 // Fill the contents with a round-rect region to match the border images. 345 // Fill the contents with a round-rect region to match the border images.
368 SkPaint paint; 346 SkPaint paint;
369 paint.setAntiAlias(true); 347 paint.setAntiAlias(true);
370 paint.setStyle(SkPaint::kFill_Style); 348 paint.setStyle(SkPaint::kFill_Style);
371 paint.setColor(border_->background_color()); 349 paint.setColor(border_->background_color());
372 SkPath path; 350 SkPath path;
373 gfx::Rect bounds(view->GetLocalBounds()); 351 gfx::Rect bounds(view->GetLocalBounds());
374 bounds.Inset(border_->GetInsets()); 352 bounds.Inset(border_->GetInsets());
375 353
376 SkScalar radius = SkIntToScalar(border_->GetBorderCornerRadius()); 354 SkScalar radius = SkIntToScalar(border_->GetBorderCornerRadius());
377 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius); 355 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius);
378 canvas->DrawPath(path, paint); 356 canvas->DrawPath(path, paint);
379 } 357 }
380 358
381 } // namespace views 359 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698