Chromium Code Reviews| OLD | NEW |
|---|---|
| 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> // for std::max | 7 #include <algorithm> // for std::max |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "grit/ui_resources.h" | 10 #include "grit/ui_resources.h" |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 22 top(NULL), | 22 top(NULL), |
| 23 top_right(NULL), | 23 top_right(NULL), |
| 24 right(NULL), | 24 right(NULL), |
| 25 bottom_right(NULL), | 25 bottom_right(NULL), |
| 26 bottom(NULL), | 26 bottom(NULL), |
| 27 bottom_left(NULL), | 27 bottom_left(NULL), |
| 28 left_arrow(NULL), | 28 left_arrow(NULL), |
| 29 top_arrow(NULL), | 29 top_arrow(NULL), |
| 30 right_arrow(NULL), | 30 right_arrow(NULL), |
| 31 bottom_arrow(NULL), | 31 bottom_arrow(NULL), |
| 32 border_thickness(0) { | 32 left_border_padding(0), |
| 33 top_border_padding(0), | |
| 34 right_border_padding(0), | |
| 35 bottom_border_padding(0), | |
| 36 arrow_interior_height(0), | |
| 37 border_thickness(0), | |
| 38 corner_radius(0) { | |
| 33 } | 39 } |
| 34 | 40 |
| 35 gfx::ImageSkia* left; | 41 gfx::ImageSkia* left; |
| 36 gfx::ImageSkia* top_left; | 42 gfx::ImageSkia* top_left; |
| 37 gfx::ImageSkia* top; | 43 gfx::ImageSkia* top; |
| 38 gfx::ImageSkia* top_right; | 44 gfx::ImageSkia* top_right; |
| 39 gfx::ImageSkia* right; | 45 gfx::ImageSkia* right; |
| 40 gfx::ImageSkia* bottom_right; | 46 gfx::ImageSkia* bottom_right; |
| 41 gfx::ImageSkia* bottom; | 47 gfx::ImageSkia* bottom; |
| 42 gfx::ImageSkia* bottom_left; | 48 gfx::ImageSkia* bottom_left; |
| 49 | |
| 43 gfx::ImageSkia* left_arrow; | 50 gfx::ImageSkia* left_arrow; |
| 44 gfx::ImageSkia* top_arrow; | 51 gfx::ImageSkia* top_arrow; |
| 45 gfx::ImageSkia* right_arrow; | 52 gfx::ImageSkia* right_arrow; |
| 46 gfx::ImageSkia* bottom_arrow; | 53 gfx::ImageSkia* bottom_arrow; |
| 54 | |
| 55 // Offsets of where arrow tip pixel is in corresponding image assets. | |
|
msw
2012/09/18 19:33:42
nit: consider "Location of the arrow tip pixels in
xiyuan
2012/09/19 18:20:09
Done.
| |
| 56 gfx::Point left_arrow_tip; | |
|
msw
2012/09/18 19:33:42
We can derive the tip position from the image and
xiyuan
2012/09/19 18:20:09
Done.
| |
| 57 gfx::Point top_arrow_tip; | |
| 58 gfx::Point right_arrow_tip; | |
| 59 gfx::Point bottom_arrow_tip; | |
| 60 | |
| 61 // Padding pixels between border pixels and image bounds. | |
| 62 int left_border_padding; | |
|
msw
2012/09/18 19:33:42
We can derive the image padding from the image and
xiyuan
2012/09/19 18:20:09
Done.
| |
| 63 int top_border_padding; | |
| 64 int right_border_padding; | |
| 65 int bottom_border_padding; | |
| 66 | |
| 67 int arrow_interior_height; // The height inside the arrow image, in pixels. | |
| 47 int border_thickness; | 68 int border_thickness; |
| 69 int corner_radius; | |
| 48 }; | 70 }; |
| 49 | 71 |
| 50 // static | 72 // static |
| 51 struct BubbleBorder::BorderImages* BubbleBorder::normal_images_ = NULL; | 73 struct BubbleBorder::BorderImages* |
| 52 struct BubbleBorder::BorderImages* BubbleBorder::shadow_images_ = NULL; | 74 BubbleBorder::border_images_[SHADOW_COUNT] = { NULL }; |
| 53 | |
| 54 // The height inside the arrow image, in pixels. | |
| 55 static const int kArrowInteriorHeight = 7; | |
| 56 | 75 |
| 57 BubbleBorder::BubbleBorder(ArrowLocation arrow_location, Shadow shadow) | 76 BubbleBorder::BubbleBorder(ArrowLocation arrow_location, Shadow shadow) |
| 58 : override_arrow_offset_(0), | 77 : override_arrow_offset_(0), |
| 78 relative_arrow_offset_(0), | |
| 59 arrow_location_(arrow_location), | 79 arrow_location_(arrow_location), |
| 60 alignment_(ALIGN_ARROW_TO_MID_ANCHOR), | 80 alignment_(ALIGN_ARROW_TO_MID_ANCHOR), |
| 61 background_color_(SK_ColorWHITE) { | 81 background_color_(SK_ColorWHITE), |
| 82 center_arrow_(false) { | |
| 83 DCHECK(shadow < SHADOW_COUNT); | |
| 62 images_ = GetBorderImages(shadow); | 84 images_ = GetBorderImages(shadow); |
| 63 | 85 |
| 64 // Calculate horizontal and vertical insets for arrow by ensuring that | 86 // Calculate horizontal and vertical insets for arrow by ensuring that |
|
msw
2012/09/18 19:33:42
Should this be moved into CalculateArrowOffset?
xiyuan
2012/09/19 18:20:09
|arrow_offset_| is needed to get minimum bubble si
msw
2012/09/19 20:12:31
ok.
| |
| 65 // the widest arrow and corner images will have enough room to avoid overlap | 87 // the widest arrow and corner images will have enough room to avoid overlap |
| 66 int offset_x = | 88 int offset_x = |
| 67 (std::max(images_->top_arrow->width(), | 89 std::max(std::max(images_->top_arrow_tip.x(), |
|
msw
2012/09/18 19:33:42
It seems like you could assume that the arrow imag
xiyuan
2012/09/19 18:20:09
Done.
| |
| 68 images_->bottom_arrow->width()) / 2) + | 90 images_->top_arrow->width() - |
| 91 images_->top_arrow_tip.x()), | |
| 92 std::max(images_->bottom_arrow_tip.x(), | |
| 93 images_->bottom_arrow->width() - | |
| 94 images_->bottom_arrow_tip.x())) + | |
| 69 std::max(std::max(images_->top_left->width(), | 95 std::max(std::max(images_->top_left->width(), |
| 70 images_->top_right->width()), | 96 images_->top_right->width()), |
| 71 std::max(images_->bottom_left->width(), | 97 std::max(images_->bottom_left->width(), |
| 72 images_->bottom_right->width())); | 98 images_->bottom_right->width())); |
| 73 int offset_y = | 99 int offset_y = |
| 74 (std::max(images_->left_arrow->height(), | 100 std::max(std::max(images_->left_arrow_tip.y(), |
| 75 images_->right_arrow->height()) / 2) + | 101 images_->left_arrow->height() - |
| 102 images_->left_arrow_tip.y()), | |
| 103 std::max(images_->right_arrow_tip.y(), | |
| 104 images_->right_arrow->height() - | |
| 105 images_->right_arrow_tip.y())) + | |
| 76 std::max(std::max(images_->top_left->height(), | 106 std::max(std::max(images_->top_left->height(), |
| 77 images_->top_right->height()), | 107 images_->top_right->height()), |
| 78 std::max(images_->bottom_left->height(), | 108 std::max(images_->bottom_left->height(), |
| 79 images_->bottom_right->height())); | 109 images_->bottom_right->height())); |
| 80 arrow_offset_ = std::max(offset_x, offset_y); | 110 arrow_offset_ = std::max(offset_x, offset_y); |
| 81 } | 111 } |
| 82 | 112 |
| 83 gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to, | 113 gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to, |
| 84 const gfx::Size& contents_size) const { | 114 const gfx::Size& contents_size) const { |
| 85 // Desired size is size of contents enlarged by the size of the border images. | 115 // Desired size is size of contents enlarged by the size of the border images. |
| 86 gfx::Size border_size(contents_size); | 116 gfx::Size border_size(contents_size); |
| 87 gfx::Insets insets; | 117 gfx::Insets insets; |
| 88 GetInsets(&insets); | 118 GetInsets(&insets); |
| 89 border_size.Enlarge(insets.width(), insets.height()); | 119 border_size.Enlarge(insets.width(), insets.height()); |
| 90 | 120 |
| 91 // Ensure the bubble has a minimum size that draws arrows correctly. | 121 // Ensure the bubble has a minimum size that draws arrows correctly. |
| 92 if (is_arrow_on_horizontal(arrow_location_)) | 122 if (is_arrow_on_horizontal(arrow_location_)) |
| 93 border_size.set_width(std::max(border_size.width(), 2 * arrow_offset_)); | 123 border_size.set_width(std::max(border_size.width(), 2 * arrow_offset_)); |
| 94 else if (has_arrow(arrow_location_)) | 124 else if (has_arrow(arrow_location_)) |
| 95 border_size.set_height(std::max(border_size.height(), 2 * arrow_offset_)); | 125 border_size.set_height(std::max(border_size.height(), 2 * arrow_offset_)); |
| 96 | 126 |
| 97 // Screen position depends on the arrow location. | 127 // Screen position depends on the arrow location. |
| 98 // The arrow should overlap the target by some amount since there is space | 128 // The bubble should overlap the target by some amount since there is space |
| 99 // for shadow between arrow tip and image bounds. | 129 // for shadow between arrow tip/bubble border and image bounds. |
| 100 const int kArrowOverlap = 3; | |
| 101 int x = position_relative_to.x(); | 130 int x = position_relative_to.x(); |
| 102 int y = position_relative_to.y(); | 131 int y = position_relative_to.y(); |
| 103 int w = position_relative_to.width(); | 132 int w = position_relative_to.width(); |
| 104 int h = position_relative_to.height(); | 133 int h = position_relative_to.height(); |
| 105 int arrow_offset = override_arrow_offset_ ? override_arrow_offset_ : | 134 |
| 106 arrow_offset_; | 135 const int arrow_offset = CalculateArrowOffset(border_size); |
| 107 | 136 |
| 108 // Calculate bubble x coordinate. | 137 // Calculate bubble x coordinate. |
| 109 switch (arrow_location_) { | 138 switch (arrow_location_) { |
| 110 case TOP_LEFT: | 139 case TOP_LEFT: |
| 111 case BOTTOM_LEFT: | 140 case BOTTOM_LEFT: |
| 112 x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? w / 2 - arrow_offset : | 141 x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? w / 2 - arrow_offset : |
| 113 -kArrowOverlap; | 142 -images_->left_border_padding; |
| 114 break; | 143 break; |
| 115 | 144 |
| 116 case TOP_RIGHT: | 145 case TOP_RIGHT: |
| 117 case BOTTOM_RIGHT: | 146 case BOTTOM_RIGHT: |
| 118 x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? | 147 x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? |
| 119 w / 2 + arrow_offset - border_size.width() + 1 : | 148 w / 2 + arrow_offset - border_size.width() + 1 : |
| 120 w - border_size.width() + kArrowOverlap; | 149 w - border_size.width() + images_->right_border_padding; |
| 121 break; | 150 break; |
| 122 | 151 |
| 123 case LEFT_TOP: | 152 case LEFT_TOP: |
| 124 case LEFT_BOTTOM: | 153 case LEFT_BOTTOM: |
| 125 x += w - kArrowOverlap; | 154 x += w - images_->left_arrow_tip.x(); |
| 126 break; | 155 break; |
| 127 | 156 |
| 128 case RIGHT_TOP: | 157 case RIGHT_TOP: |
| 129 case RIGHT_BOTTOM: | 158 case RIGHT_BOTTOM: |
| 130 x += kArrowOverlap - border_size.width(); | 159 x += images_->right_arrow->width() - images_->right_arrow_tip.x() - |
| 160 border_size.width(); | |
| 131 break; | 161 break; |
| 132 | 162 |
| 133 case NONE: | 163 case NONE: |
| 134 case FLOAT: | 164 case FLOAT: |
| 135 x += w / 2 - border_size.width() / 2; | 165 x += w / 2 - border_size.width() / 2; |
| 136 break; | 166 break; |
| 137 } | 167 } |
| 138 | 168 |
| 139 // Calculate bubble y coordinate. | 169 // Calculate bubble y coordinate. |
| 140 switch (arrow_location_) { | 170 switch (arrow_location_) { |
| 141 case TOP_LEFT: | 171 case TOP_LEFT: |
| 142 case TOP_RIGHT: | 172 case TOP_RIGHT: |
| 143 y += h - kArrowOverlap; | 173 y += h - images_->top_arrow_tip.y(); |
| 144 break; | 174 break; |
| 145 | 175 |
| 146 case BOTTOM_LEFT: | 176 case BOTTOM_LEFT: |
| 147 case BOTTOM_RIGHT: | 177 case BOTTOM_RIGHT: |
| 148 y += kArrowOverlap - border_size.height(); | 178 y += images_->bottom_arrow->height() - images_->bottom_arrow_tip.y() - |
| 179 border_size.height(); | |
| 149 break; | 180 break; |
| 150 | 181 |
| 151 case LEFT_TOP: | 182 case LEFT_TOP: |
| 152 case RIGHT_TOP: | 183 case RIGHT_TOP: |
| 153 y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? h / 2 - arrow_offset : | 184 y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? h / 2 - arrow_offset : |
| 154 -kArrowOverlap; | 185 -images_->top_border_padding; |
| 155 break; | 186 break; |
| 156 | 187 |
| 157 case LEFT_BOTTOM: | 188 case LEFT_BOTTOM: |
| 158 case RIGHT_BOTTOM: | 189 case RIGHT_BOTTOM: |
| 159 y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? | 190 y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? |
| 160 h / 2 + arrow_offset - border_size.height() + 1 : | 191 h / 2 + arrow_offset - border_size.height() + 1 : |
| 161 h - border_size.height() + kArrowOverlap; | 192 h - border_size.height() + images_->bottom_border_padding; |
| 162 break; | 193 break; |
| 163 | 194 |
| 164 case NONE: | 195 case NONE: |
| 165 y += h; | 196 y += h; |
| 166 break; | 197 break; |
| 167 | 198 |
| 168 case FLOAT: | 199 case FLOAT: |
| 169 y += h / 2 - border_size.height() / 2; | 200 y += h / 2 - border_size.height() / 2; |
| 170 break; | 201 break; |
| 171 } | 202 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 209 // Nothing to do. | 240 // Nothing to do. |
| 210 break; | 241 break; |
| 211 } | 242 } |
| 212 insets->Set(top, left, bottom, right); | 243 insets->Set(top, left, bottom, right); |
| 213 } | 244 } |
| 214 | 245 |
| 215 int BubbleBorder::GetBorderThickness() const { | 246 int BubbleBorder::GetBorderThickness() const { |
| 216 return images_->border_thickness; | 247 return images_->border_thickness; |
| 217 } | 248 } |
| 218 | 249 |
| 250 int BubbleBorder::GetBorderCornerRadius() const { | |
| 251 return images_->corner_radius; | |
| 252 } | |
| 253 | |
| 219 int BubbleBorder::SetArrowOffset(int offset, const gfx::Size& contents_size) { | 254 int BubbleBorder::SetArrowOffset(int offset, const gfx::Size& contents_size) { |
| 220 gfx::Size border_size(contents_size); | 255 gfx::Size border_size(contents_size); |
| 221 gfx::Insets insets; | 256 gfx::Insets insets; |
| 222 GetInsets(&insets); | 257 GetInsets(&insets); |
| 223 border_size.Enlarge(insets.left() + insets.right(), | 258 border_size.Enlarge(insets.left() + insets.right(), |
| 224 insets.top() + insets.bottom()); | 259 insets.top() + insets.bottom()); |
| 225 offset = std::max(arrow_offset_, | 260 offset = SanitizeArrowOffset(offset, border_size); |
|
msw
2012/09/18 19:33:42
Nix this, its redundant with the call in Calculate
xiyuan
2012/09/19 18:20:09
Done. And made SetArrowOffset an inline accessor.
msw
2012/09/19 20:12:31
Nice.
| |
| 226 std::min(offset, (is_arrow_on_horizontal(arrow_location_) ? | |
| 227 border_size.width() : border_size.height()) - arrow_offset_)); | |
| 228 override_arrow_offset_ = offset; | 261 override_arrow_offset_ = offset; |
| 229 return override_arrow_offset_; | 262 return override_arrow_offset_; |
| 230 } | 263 } |
| 231 | 264 |
| 232 // static | 265 // static |
| 233 BubbleBorder::BorderImages* BubbleBorder::GetBorderImages(Shadow shadow) { | 266 BubbleBorder::BorderImages* BubbleBorder::GetBorderImages(Shadow shadow) { |
| 234 if (shadow == SHADOW && shadow_images_ == NULL) { | 267 DCHECK(shadow < SHADOW_COUNT); |
| 268 | |
| 269 struct BorderImages*& images = border_images_[shadow]; | |
| 270 if (images == NULL) { | |
|
msw
2012/09/18 19:33:42
Can you invert this check to make it an early retu
xiyuan
2012/09/19 18:20:09
Done.
| |
| 271 images = new BorderImages(); | |
| 272 | |
| 235 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 273 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 236 shadow_images_ = new BorderImages(); | 274 switch (shadow) { |
|
msw
2012/09/18 19:33:42
This is getting unwieldy, perhaps BorderImages nee
xiyuan
2012/09/19 18:20:09
Done. Added IDR arrays and pass it to BorderImage'
msw
2012/09/19 20:12:31
All excellent (though GetImageSkiaNamed was probab
| |
| 237 shadow_images_->left = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_L); | 275 case SHADOW: |
| 238 shadow_images_->top_left = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_TL); | 276 images->left = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_L); |
| 239 shadow_images_->top = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_T); | 277 images->top_left = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_TL); |
| 240 shadow_images_->top_right = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_TR); | 278 images->top = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_T); |
| 241 shadow_images_->right = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_R); | 279 images->top_right = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_TR); |
| 242 shadow_images_->bottom_right = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_BR); | 280 images->right = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_R); |
| 243 shadow_images_->bottom = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_B); | 281 images->bottom_right = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_BR); |
| 244 shadow_images_->bottom_left = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_BL); | 282 images->bottom = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_B); |
| 245 shadow_images_->left_arrow = new gfx::ImageSkia(); | 283 images->bottom_left = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_BL); |
| 246 shadow_images_->top_arrow = new gfx::ImageSkia(); | 284 images->left_arrow = new gfx::ImageSkia(); |
|
msw
2012/09/18 19:33:42
These seem to be leaked (prior to this CL, not you
xiyuan
2012/09/19 18:20:09
Resolved as we use ImageSkia object instead of poi
msw
2012/09/19 20:12:31
Great!
| |
| 247 shadow_images_->right_arrow = new gfx::ImageSkia(); | 285 images->top_arrow = new gfx::ImageSkia(); |
| 248 shadow_images_->bottom_arrow = new gfx::ImageSkia(); | 286 images->right_arrow = new gfx::ImageSkia(); |
| 249 shadow_images_->border_thickness = 10; | 287 images->bottom_arrow = new gfx::ImageSkia(); |
| 250 } else if (shadow == NO_SHADOW && normal_images_ == NULL) { | 288 images->arrow_interior_height = 7; |
|
msw
2012/09/18 19:33:42
This group has no arrow, why is arrow_interior_hei
xiyuan
2012/09/19 18:20:09
Removed since it's not used and we should be okay
| |
| 251 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 289 images->border_thickness = 10; |
| 252 normal_images_ = new BorderImages(); | 290 images->corner_radius = 4; |
| 253 normal_images_->left = rb.GetImageSkiaNamed(IDR_BUBBLE_L); | 291 break; |
| 254 normal_images_->top_left = rb.GetImageSkiaNamed(IDR_BUBBLE_TL); | 292 case NO_SHADOW: |
| 255 normal_images_->top = rb.GetImageSkiaNamed(IDR_BUBBLE_T); | 293 images->left = rb.GetImageSkiaNamed(IDR_BUBBLE_L); |
| 256 normal_images_->top_right = rb.GetImageSkiaNamed(IDR_BUBBLE_TR); | 294 images->top_left = rb.GetImageSkiaNamed(IDR_BUBBLE_TL); |
| 257 normal_images_->right = rb.GetImageSkiaNamed(IDR_BUBBLE_R); | 295 images->top = rb.GetImageSkiaNamed(IDR_BUBBLE_T); |
| 258 normal_images_->bottom_right = rb.GetImageSkiaNamed(IDR_BUBBLE_BR); | 296 images->top_right = rb.GetImageSkiaNamed(IDR_BUBBLE_TR); |
| 259 normal_images_->bottom = rb.GetImageSkiaNamed(IDR_BUBBLE_B); | 297 images->right = rb.GetImageSkiaNamed(IDR_BUBBLE_R); |
| 260 normal_images_->bottom_left = rb.GetImageSkiaNamed(IDR_BUBBLE_BL); | 298 images->bottom_right = rb.GetImageSkiaNamed(IDR_BUBBLE_BR); |
| 261 normal_images_->left_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_L_ARROW); | 299 images->bottom = rb.GetImageSkiaNamed(IDR_BUBBLE_B); |
| 262 normal_images_->top_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_T_ARROW); | 300 images->bottom_left = rb.GetImageSkiaNamed(IDR_BUBBLE_BL); |
| 263 normal_images_->right_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_R_ARROW); | 301 images->left_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_L_ARROW); |
| 264 normal_images_->bottom_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_B_ARROW); | 302 images->top_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_T_ARROW); |
| 265 normal_images_->border_thickness = 0; | 303 images->right_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_R_ARROW); |
| 304 images->bottom_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_B_ARROW); | |
| 305 images->left_arrow_tip = gfx::Point(3, 11); | |
| 306 images->top_arrow_tip = gfx::Point(9, 3); | |
| 307 images->right_arrow_tip = gfx::Point(9, 11); | |
| 308 images->bottom_arrow_tip = gfx::Point(9, 9); | |
| 309 images->left_border_padding = 3; | |
| 310 images->top_border_padding = 1; | |
| 311 images->right_border_padding = 3; | |
| 312 images->bottom_border_padding = 5; | |
| 313 images->arrow_interior_height = 7; | |
| 314 images->border_thickness = 0; | |
| 315 images->corner_radius = 4; | |
| 316 break; | |
| 317 #if defined(USE_AURA) | |
| 318 case BIG_SHADOW: | |
| 319 images->left = | |
| 320 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_BIG_LEFT); | |
| 321 images->top_left = | |
| 322 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_BIG_TOP_LEFT); | |
| 323 images->top = | |
| 324 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_BIG_TOP); | |
| 325 images->top_right = | |
| 326 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_BIG_TOP_RIGHT); | |
| 327 images->right = | |
| 328 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_BIG_RIGHT); | |
| 329 images->bottom_right = | |
| 330 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_BIG_BOTTOM_RIGHT); | |
| 331 images->bottom = | |
| 332 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_BIG_BOTTOM); | |
| 333 images->bottom_left = | |
| 334 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_BIG_BOTTOM_LEFT); | |
| 335 images->left_arrow = | |
| 336 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SPIKE_BIG_LEFT); | |
| 337 images->top_arrow = | |
| 338 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SPIKE_BIG_TOP); | |
| 339 images->right_arrow = | |
| 340 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SPIKE_BIG_RIGHT); | |
| 341 images->bottom_arrow = | |
| 342 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SPIKE_BIG_BOTTOM); | |
| 343 images->left_arrow_tip = gfx::Point(20, 16); | |
| 344 images->top_arrow_tip = gfx::Point(21, 20); | |
| 345 images->right_arrow_tip = gfx::Point(10, 16); | |
| 346 images->bottom_arrow_tip = gfx::Point(21, 10); | |
| 347 images->left_border_padding = 30; | |
| 348 images->top_border_padding = 30; | |
| 349 images->right_border_padding = 30; | |
| 350 images->bottom_border_padding = 30; | |
| 351 images->arrow_interior_height = 9; | |
| 352 images->border_thickness = 0; | |
| 353 images->corner_radius = 3; | |
| 354 break; | |
| 355 case SMALL_SHADOW: | |
| 356 images->left = | |
| 357 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_LEFT); | |
| 358 images->top_left = | |
| 359 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_TOP_LEFT); | |
| 360 images->top = | |
| 361 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_TOP); | |
| 362 images->top_right = | |
| 363 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_TOP_RIGHT); | |
| 364 images->right = | |
| 365 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_RIGHT); | |
| 366 images->bottom_right = | |
| 367 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_BOTTOM_RIGHT); | |
| 368 images->bottom = | |
| 369 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_BOTTOM); | |
| 370 images->bottom_left = | |
| 371 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SMALL_BOTTOM_LEFT); | |
| 372 images->left_arrow = | |
| 373 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SPIKE_SMALL_LEFT); | |
| 374 images->top_arrow = | |
| 375 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SPIKE_SMALL_TOP); | |
| 376 images->right_arrow = | |
| 377 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SPIKE_SMALL_RIGHT); | |
| 378 images->bottom_arrow = | |
| 379 rb.GetImageSkiaNamed(IDR_WINDOW_BUBBLE_SHADOW_SPIKE_SMALL_BOTTOM); | |
| 380 images->left_arrow_tip = gfx::Point(5, 9); | |
| 381 images->top_arrow_tip = gfx::Point(12, 5); | |
| 382 images->right_arrow_tip = gfx::Point(10, 9); | |
| 383 images->bottom_arrow_tip = gfx::Point(12, 10); | |
| 384 images->left_border_padding = 15; | |
| 385 images->top_border_padding = 15; | |
| 386 images->right_border_padding = 15; | |
| 387 images->bottom_border_padding = 15; | |
| 388 images->arrow_interior_height = 9; | |
| 389 images->border_thickness = 0; | |
| 390 images->corner_radius = 3; | |
| 391 break; | |
| 392 #endif | |
| 393 case SHADOW_COUNT: | |
|
msw
2012/09/18 19:33:42
Make this (or add a similar) default: case.
xiyuan
2012/09/19 18:20:09
Done.
I found not using "default" for enum based
msw
2012/09/19 20:12:31
Good point, feel free to switch it back; thanks fo
| |
| 394 NOTREACHED(); | |
| 395 break; | |
| 396 } | |
| 266 } | 397 } |
| 267 return shadow == SHADOW ? shadow_images_ : normal_images_; | 398 |
| 399 return images; | |
| 268 } | 400 } |
| 269 | 401 |
| 270 BubbleBorder::~BubbleBorder() {} | 402 BubbleBorder::~BubbleBorder() {} |
| 271 | 403 |
| 272 void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { | 404 void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { |
| 273 // Convenience shorthand variables. | 405 // Convenience shorthand variables. |
| 274 const int tl_width = images_->top_left->width(); | 406 const int tl_width = images_->top_left->width(); |
| 275 const int tl_height = images_->top_left->height(); | 407 const int tl_height = images_->top_left->height(); |
| 276 const int t_height = images_->top->height(); | 408 const int t_height = images_->top->height(); |
| 277 const int tr_width = images_->top_right->width(); | 409 const int tr_width = images_->top_right->width(); |
| 278 const int tr_height = images_->top_right->height(); | 410 const int tr_height = images_->top_right->height(); |
| 279 const int l_width = images_->left->width(); | 411 const int l_width = images_->left->width(); |
| 280 const int r_width = images_->right->width(); | 412 const int r_width = images_->right->width(); |
| 281 const int br_width = images_->bottom_right->width(); | 413 const int br_width = images_->bottom_right->width(); |
| 282 const int br_height = images_->bottom_right->height(); | 414 const int br_height = images_->bottom_right->height(); |
| 283 const int b_height = images_->bottom->height(); | 415 const int b_height = images_->bottom->height(); |
| 284 const int bl_width = images_->bottom_left->width(); | 416 const int bl_width = images_->bottom_left->width(); |
| 285 const int bl_height = images_->bottom_left->height(); | 417 const int bl_height = images_->bottom_left->height(); |
| 286 | 418 |
| 287 gfx::Insets insets; | 419 gfx::Insets insets; |
| 288 GetInsets(&insets); | 420 GetInsets(&insets); |
| 289 const int top = insets.top() - t_height; | 421 const int top = insets.top() - t_height; |
| 290 const int bottom = view.height() - insets.bottom() + b_height; | 422 const int bottom = view.height() - insets.bottom() + b_height; |
| 291 const int left = insets.left() - l_width; | 423 const int left = insets.left() - l_width; |
| 292 const int right = view.width() - insets.right() + r_width; | 424 const int right = view.width() - insets.right() + r_width; |
| 293 const int height = bottom - top; | 425 const int height = bottom - top; |
| 294 const int width = right - left; | 426 const int width = right - left; |
| 295 | 427 |
| 296 // |arrow_offset| is offset of arrow from the begining of the edge. | 428 // |arrow_offset| is offset of arrow from the beginning of the edge. |
| 297 int arrow_offset = arrow_offset_; | 429 int arrow_offset = CalculateArrowOffset(view.size()); |
| 298 if (override_arrow_offset_) | 430 if (is_arrow_on_horizontal(arrow_location_) && |
| 299 arrow_offset = override_arrow_offset_; | 431 !is_arrow_on_left(arrow_location_)) { |
| 300 else if (is_arrow_on_horizontal(arrow_location_) && | |
| 301 !is_arrow_on_left(arrow_location_)) { | |
| 302 arrow_offset = view.width() - arrow_offset - 1; | 432 arrow_offset = view.width() - arrow_offset - 1; |
| 303 } else if (!is_arrow_on_horizontal(arrow_location_) && | 433 } else if (!is_arrow_on_horizontal(arrow_location_) && |
| 304 !is_arrow_on_top(arrow_location_)) { | 434 !is_arrow_on_top(arrow_location_)) { |
| 305 arrow_offset = view.height() - arrow_offset - 1; | 435 arrow_offset = view.height() - arrow_offset - 1; |
| 306 } | 436 } |
| 307 | 437 |
| 308 // Left edge. | 438 // Left edge. |
| 309 if (arrow_location_ == LEFT_TOP || arrow_location_ == LEFT_BOTTOM) { | 439 if (arrow_location_ == LEFT_TOP || arrow_location_ == LEFT_BOTTOM) { |
| 310 int start_y = top + tl_height; | 440 int start_y = top + tl_height; |
| 311 int before_arrow = | 441 int before_arrow = |
| 312 arrow_offset - start_y - images_->left_arrow->height() / 2; | 442 arrow_offset - start_y - images_->left_arrow_tip.y(); |
| 313 int after_arrow = height - tl_height - bl_height - | 443 int after_arrow = height - tl_height - bl_height - |
| 314 images_->left_arrow->height() - before_arrow; | 444 images_->left_arrow->height() - before_arrow; |
| 315 // Shift tip coordinates half pixel so that skia draws the tip correctly. | 445 // Shift tip coordinates half pixel so that skia draws the tip correctly. |
| 316 DrawArrowInterior(canvas, | 446 DrawArrowInterior(canvas, |
| 317 images_->left_arrow->width() - kArrowInteriorHeight - 0.5f, | 447 images_->left_arrow->width() - images_->arrow_interior_height - 0.5f, |
| 318 start_y + before_arrow + images_->left_arrow->height() / 2 - 0.5f); | 448 start_y + before_arrow + images_->left_arrow_tip.y() - 0.5f); |
| 319 DrawEdgeWithArrow(canvas, | 449 DrawEdgeWithArrow(canvas, |
| 320 false, | 450 false, |
| 321 images_->left, | 451 images_->left, |
| 322 images_->left_arrow, | 452 images_->left_arrow, |
| 323 left, | 453 left, |
| 324 start_y, | 454 start_y, |
| 325 before_arrow, | 455 before_arrow, |
| 326 after_arrow, | 456 after_arrow, |
| 327 images_->left->width() - images_->left_arrow->width()); | 457 images_->left->width() - images_->left_arrow->width()); |
| 328 } else { | 458 } else { |
| 329 canvas->TileImageInt(*images_->left, left, top + tl_height, l_width, | 459 canvas->TileImageInt(*images_->left, left, top + tl_height, l_width, |
| 330 height - tl_height - bl_height); | 460 height - tl_height - bl_height); |
| 331 } | 461 } |
| 332 | 462 |
| 333 // Top left corner. | 463 // Top left corner. |
| 334 canvas->DrawImageInt(*images_->top_left, left, top); | 464 canvas->DrawImageInt(*images_->top_left, left, top); |
| 335 | 465 |
| 336 // Top edge. | 466 // Top edge. |
| 337 if (arrow_location_ == TOP_LEFT || arrow_location_ == TOP_RIGHT) { | 467 if (arrow_location_ == TOP_LEFT || arrow_location_ == TOP_RIGHT) { |
| 338 int start_x = left + tl_width; | 468 int start_x = left + tl_width; |
| 339 int before_arrow = arrow_offset - start_x - images_->top_arrow->width() / 2; | 469 int before_arrow = arrow_offset - start_x - images_->top_arrow_tip.x(); |
| 340 int after_arrow = width - tl_width - tr_width - | 470 int after_arrow = width - tl_width - tr_width - |
| 341 images_->top_arrow->width() - before_arrow; | 471 images_->top_arrow->width() - before_arrow; |
| 342 DrawArrowInterior(canvas, | 472 DrawArrowInterior(canvas, |
| 343 start_x + before_arrow + images_->top_arrow->width() / 2, | 473 start_x + before_arrow + images_->top_arrow_tip.x(), |
| 344 images_->top_arrow->height() - kArrowInteriorHeight); | 474 images_->top_arrow->height() - images_->arrow_interior_height); |
| 345 DrawEdgeWithArrow(canvas, | 475 DrawEdgeWithArrow(canvas, |
| 346 true, | 476 true, |
| 347 images_->top, | 477 images_->top, |
| 348 images_->top_arrow, | 478 images_->top_arrow, |
| 349 start_x, | 479 start_x, |
| 350 top, | 480 top, |
| 351 before_arrow, | 481 before_arrow, |
| 352 after_arrow, | 482 after_arrow, |
| 353 images_->top->height() - images_->top_arrow->height()); | 483 images_->top->height() - images_->top_arrow->height()); |
| 354 } else { | 484 } else { |
| 355 canvas->TileImageInt(*images_->top, left + tl_width, top, | 485 canvas->TileImageInt(*images_->top, left + tl_width, top, |
| 356 width - tl_width - tr_width, t_height); | 486 width - tl_width - tr_width, t_height); |
| 357 } | 487 } |
| 358 | 488 |
| 359 // Top right corner. | 489 // Top right corner. |
| 360 canvas->DrawImageInt(*images_->top_right, right - tr_width, top); | 490 canvas->DrawImageInt(*images_->top_right, right - tr_width, top); |
| 361 | 491 |
| 362 // Right edge. | 492 // Right edge. |
| 363 if (arrow_location_ == RIGHT_TOP || arrow_location_ == RIGHT_BOTTOM) { | 493 if (arrow_location_ == RIGHT_TOP || arrow_location_ == RIGHT_BOTTOM) { |
| 364 int start_y = top + tr_height; | 494 int start_y = top + tr_height; |
| 365 int before_arrow = | 495 int before_arrow = |
| 366 arrow_offset - start_y - images_->right_arrow->height() / 2; | 496 arrow_offset - start_y - images_->right_arrow_tip.y(); |
| 367 int after_arrow = height - tl_height - bl_height - | 497 int after_arrow = height - tl_height - bl_height - |
| 368 images_->right_arrow->height() - before_arrow; | 498 images_->right_arrow->height() - before_arrow; |
| 369 // Shift tip coordinates half pixel so that skia draws the tip correctly. | 499 // Shift tip coordinates half pixel so that skia draws the tip correctly. |
| 370 DrawArrowInterior(canvas, | 500 DrawArrowInterior(canvas, |
| 371 right - r_width + kArrowInteriorHeight - 0.5f, | 501 right - r_width + images_->arrow_interior_height - 0.5f, |
| 372 start_y + before_arrow + images_->right_arrow->height() / 2 - 0.5f); | 502 start_y + before_arrow + images_->right_arrow_tip.y() - 0.5f); |
| 373 DrawEdgeWithArrow(canvas, | 503 DrawEdgeWithArrow(canvas, |
| 374 false, | 504 false, |
| 375 images_->right, | 505 images_->right, |
| 376 images_->right_arrow, | 506 images_->right_arrow, |
| 377 right - r_width, | 507 right - r_width, |
| 378 start_y, | 508 start_y, |
| 379 before_arrow, | 509 before_arrow, |
| 380 after_arrow, | 510 after_arrow, |
| 381 0); | 511 0); |
| 382 } else { | 512 } else { |
| 383 canvas->TileImageInt(*images_->right, right - r_width, top + tr_height, | 513 canvas->TileImageInt(*images_->right, right - r_width, top + tr_height, |
| 384 r_width, height - tr_height - br_height); | 514 r_width, height - tr_height - br_height); |
| 385 } | 515 } |
| 386 | 516 |
| 387 // Bottom right corner. | 517 // Bottom right corner. |
| 388 canvas->DrawImageInt(*images_->bottom_right, | 518 canvas->DrawImageInt(*images_->bottom_right, |
| 389 right - br_width, | 519 right - br_width, |
| 390 bottom - br_height); | 520 bottom - br_height); |
| 391 | 521 |
| 392 // Bottom edge. | 522 // Bottom edge. |
| 393 if (arrow_location_ == BOTTOM_LEFT || arrow_location_ == BOTTOM_RIGHT) { | 523 if (arrow_location_ == BOTTOM_LEFT || arrow_location_ == BOTTOM_RIGHT) { |
| 394 int start_x = left + bl_width; | 524 int start_x = left + bl_width; |
| 395 int before_arrow = | 525 int before_arrow = |
| 396 arrow_offset - start_x - images_->bottom_arrow->width() / 2; | 526 arrow_offset - start_x - images_->bottom_arrow_tip.x(); |
| 397 int after_arrow = width - bl_width - br_width - | 527 int after_arrow = width - bl_width - br_width - |
| 398 images_->bottom_arrow->width() - before_arrow; | 528 images_->bottom_arrow->width() - before_arrow; |
| 399 DrawArrowInterior(canvas, | 529 DrawArrowInterior(canvas, |
| 400 start_x + before_arrow + images_->bottom_arrow->width() / 2, | 530 start_x + before_arrow + images_->bottom_arrow_tip.x(), |
| 401 bottom - b_height + kArrowInteriorHeight); | 531 bottom - b_height + images_->arrow_interior_height); |
| 402 DrawEdgeWithArrow(canvas, | 532 DrawEdgeWithArrow(canvas, |
| 403 true, | 533 true, |
| 404 images_->bottom, | 534 images_->bottom, |
| 405 images_->bottom_arrow, | 535 images_->bottom_arrow, |
| 406 start_x, | 536 start_x, |
| 407 bottom - b_height, | 537 bottom - b_height, |
| 408 before_arrow, | 538 before_arrow, |
| 409 after_arrow, | 539 after_arrow, |
| 410 0); | 540 0); |
| 411 } else { | 541 } else { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 } | 586 } |
| 457 } | 587 } |
| 458 | 588 |
| 459 void BubbleBorder::DrawArrowInterior(gfx::Canvas* canvas, | 589 void BubbleBorder::DrawArrowInterior(gfx::Canvas* canvas, |
| 460 float tip_x, | 590 float tip_x, |
| 461 float tip_y) const { | 591 float tip_y) const { |
| 462 const bool is_horizontal = is_arrow_on_horizontal(arrow_location_); | 592 const bool is_horizontal = is_arrow_on_horizontal(arrow_location_); |
| 463 const bool positive_offset = is_horizontal ? | 593 const bool positive_offset = is_horizontal ? |
| 464 is_arrow_on_top(arrow_location_) : is_arrow_on_left(arrow_location_); | 594 is_arrow_on_top(arrow_location_) : is_arrow_on_left(arrow_location_); |
| 465 const int offset_to_next_vertex = positive_offset ? | 595 const int offset_to_next_vertex = positive_offset ? |
| 466 kArrowInteriorHeight : -kArrowInteriorHeight; | 596 images_->arrow_interior_height : -images_->arrow_interior_height; |
| 467 | 597 |
| 468 SkPath path; | 598 SkPath path; |
| 469 path.incReserve(4); | 599 path.incReserve(4); |
| 470 path.moveTo(SkDoubleToScalar(tip_x), SkDoubleToScalar(tip_y)); | 600 path.moveTo(SkDoubleToScalar(tip_x), SkDoubleToScalar(tip_y)); |
| 471 path.lineTo(SkDoubleToScalar(tip_x + offset_to_next_vertex), | 601 path.lineTo(SkDoubleToScalar(tip_x + offset_to_next_vertex), |
| 472 SkDoubleToScalar(tip_y + offset_to_next_vertex)); | 602 SkDoubleToScalar(tip_y + offset_to_next_vertex)); |
| 473 if (is_horizontal) { | 603 if (is_horizontal) { |
| 474 path.lineTo(SkDoubleToScalar(tip_x - offset_to_next_vertex), | 604 path.lineTo(SkDoubleToScalar(tip_x - offset_to_next_vertex), |
| 475 SkDoubleToScalar(tip_y + offset_to_next_vertex)); | 605 SkDoubleToScalar(tip_y + offset_to_next_vertex)); |
| 476 } else { | 606 } else { |
| 477 path.lineTo(SkDoubleToScalar(tip_x + offset_to_next_vertex), | 607 path.lineTo(SkDoubleToScalar(tip_x + offset_to_next_vertex), |
| 478 SkDoubleToScalar(tip_y - offset_to_next_vertex)); | 608 SkDoubleToScalar(tip_y - offset_to_next_vertex)); |
| 479 } | 609 } |
| 480 path.close(); | 610 path.close(); |
| 481 | 611 |
| 482 SkPaint paint; | 612 SkPaint paint; |
| 483 paint.setStyle(SkPaint::kFill_Style); | 613 paint.setStyle(SkPaint::kFill_Style); |
| 484 paint.setColor(background_color_); | 614 paint.setColor(background_color_); |
| 485 | 615 |
| 486 canvas->DrawPath(path, paint); | 616 canvas->DrawPath(path, paint); |
| 487 } | 617 } |
| 488 | 618 |
| 619 int BubbleBorder::SanitizeArrowOffset(int arrow_offset, | |
|
msw
2012/09/18 19:33:42
After removing the call in SetArrowOffset, inline
xiyuan
2012/09/19 18:20:09
Done.
| |
| 620 const gfx::Size& border_size) const { | |
| 621 return std::max(arrow_offset_, | |
| 622 std::min(arrow_offset, (is_arrow_on_horizontal(arrow_location_) ? | |
| 623 border_size.width() : border_size.height()) - arrow_offset_)); | |
| 624 } | |
| 625 | |
| 626 int BubbleBorder::CalculateArrowOffset(const gfx::Size& border_size) const { | |
| 627 int arrow_offset = arrow_offset_; | |
| 628 if (override_arrow_offset_) | |
|
msw
2012/09/18 19:33:42
Add braces here to match the else case.
xiyuan
2012/09/19 18:20:09
Done.
| |
| 629 arrow_offset = override_arrow_offset_; | |
| 630 else if (center_arrow_) { | |
| 631 if (is_arrow_on_horizontal(arrow_location_)) | |
| 632 arrow_offset = border_size.width() / 2; | |
| 633 else if (has_arrow(arrow_location_)) | |
| 634 arrow_offset = border_size.height() / 2; | |
| 635 } | |
| 636 | |
| 637 arrow_offset += relative_arrow_offset_; | |
| 638 return SanitizeArrowOffset(arrow_offset, border_size); | |
| 639 } | |
| 640 | |
| 489 ///////////////////////// | 641 ///////////////////////// |
| 490 | 642 |
| 491 void BubbleBackground::Paint(gfx::Canvas* canvas, views::View* view) const { | 643 void BubbleBackground::Paint(gfx::Canvas* canvas, views::View* view) const { |
| 492 // Clip out the client bounds to prevent overlapping transparent widgets. | 644 // Clip out the client bounds to prevent overlapping transparent widgets. |
| 493 if (!border_->client_bounds().IsEmpty()) { | 645 if (!border_->client_bounds().IsEmpty()) { |
| 494 SkRect client_rect(gfx::RectToSkRect(border_->client_bounds())); | 646 SkRect client_rect(gfx::RectToSkRect(border_->client_bounds())); |
| 495 canvas->sk_canvas()->clipRect(client_rect, SkRegion::kDifference_Op); | 647 canvas->sk_canvas()->clipRect(client_rect, SkRegion::kDifference_Op); |
| 496 } | 648 } |
| 497 | 649 |
| 498 // The border of this view creates an anti-aliased round-rect region for the | 650 // The border of this view creates an anti-aliased round-rect region for the |
| 499 // contents, which we need to fill with the background color. | 651 // contents, which we need to fill with the background color. |
| 500 // NOTE: This doesn't handle an arrow location of "NONE", which has square top | 652 // NOTE: This doesn't handle an arrow location of "NONE", which has square top |
| 501 // corners. | 653 // corners. |
| 502 SkPaint paint; | 654 SkPaint paint; |
| 503 paint.setAntiAlias(true); | 655 paint.setAntiAlias(true); |
| 504 paint.setStyle(SkPaint::kFill_Style); | 656 paint.setStyle(SkPaint::kFill_Style); |
| 505 paint.setColor(border_->background_color()); | 657 paint.setColor(border_->background_color()); |
| 506 SkPath path; | 658 SkPath path; |
| 507 gfx::Rect bounds(view->GetContentsBounds()); | 659 gfx::Rect bounds(view->GetContentsBounds()); |
| 508 bounds.Inset(-border_->GetBorderThickness(), -border_->GetBorderThickness()); | 660 bounds.Inset(-border_->GetBorderThickness(), -border_->GetBorderThickness()); |
| 509 SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius()); | 661 SkScalar radius = SkIntToScalar(border_->GetBorderCornerRadius()); |
| 510 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius); | 662 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius); |
| 511 canvas->DrawPath(path, paint); | 663 canvas->DrawPath(path, paint); |
| 512 } | 664 } |
| 513 | 665 |
| 514 } // namespace views | 666 } // namespace views |
| OLD | NEW |