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" |
| 11 #include "ui/base/resource/resource_bundle.h" | 11 #include "ui/base/resource/resource_bundle.h" |
| 12 #include "ui/gfx/canvas.h" | 12 #include "ui/gfx/canvas.h" |
| 13 #include "ui/gfx/image/image_skia.h" | 13 #include "ui/gfx/image/image_skia.h" |
| 14 #include "ui/gfx/skia_util.h" | 14 #include "ui/gfx/skia_util.h" |
| 15 | 15 |
| 16 namespace { | |
| 17 | |
| 18 // Stroke size in pixels of borders in image assets. | |
| 19 const int kBorderStrokeSize = 1; | |
| 20 | |
| 21 // Border image resource ids. | |
| 22 const int kShadowImages[] = { | |
| 23 IDR_BUBBLE_SHADOW_L, | |
| 24 IDR_BUBBLE_SHADOW_TL, | |
| 25 IDR_BUBBLE_SHADOW_T, | |
| 26 IDR_BUBBLE_SHADOW_TR, | |
| 27 IDR_BUBBLE_SHADOW_R, | |
| 28 IDR_BUBBLE_SHADOW_BR, | |
| 29 IDR_BUBBLE_SHADOW_B, | |
| 30 IDR_BUBBLE_SHADOW_BL, | |
| 31 }; | |
| 32 | |
| 33 const int kNoShadowImages[] = { | |
| 34 IDR_BUBBLE_L, | |
| 35 IDR_BUBBLE_TL, | |
| 36 IDR_BUBBLE_T, | |
| 37 IDR_BUBBLE_TR, | |
| 38 IDR_BUBBLE_R, | |
| 39 IDR_BUBBLE_BR, | |
| 40 IDR_BUBBLE_B, | |
| 41 IDR_BUBBLE_BL, | |
| 42 IDR_BUBBLE_L_ARROW, | |
| 43 IDR_BUBBLE_T_ARROW, | |
| 44 IDR_BUBBLE_R_ARROW, | |
| 45 IDR_BUBBLE_B_ARROW, | |
| 46 }; | |
| 47 | |
| 48 #if defined(USE_AURA) | |
| 49 const int kBigShadowImages[] = { | |
| 50 IDR_WINDOW_BUBBLE_SHADOW_BIG_LEFT, | |
| 51 IDR_WINDOW_BUBBLE_SHADOW_BIG_TOP_LEFT, | |
| 52 IDR_WINDOW_BUBBLE_SHADOW_BIG_TOP, | |
| 53 IDR_WINDOW_BUBBLE_SHADOW_BIG_TOP_RIGHT, | |
| 54 IDR_WINDOW_BUBBLE_SHADOW_BIG_RIGHT, | |
| 55 IDR_WINDOW_BUBBLE_SHADOW_BIG_BOTTOM_RIGHT, | |
| 56 IDR_WINDOW_BUBBLE_SHADOW_BIG_BOTTOM, | |
| 57 IDR_WINDOW_BUBBLE_SHADOW_BIG_BOTTOM_LEFT, | |
| 58 IDR_WINDOW_BUBBLE_SHADOW_SPIKE_BIG_LEFT, | |
| 59 IDR_WINDOW_BUBBLE_SHADOW_SPIKE_BIG_TOP, | |
| 60 IDR_WINDOW_BUBBLE_SHADOW_SPIKE_BIG_RIGHT, | |
| 61 IDR_WINDOW_BUBBLE_SHADOW_SPIKE_BIG_BOTTOM, | |
| 62 }; | |
| 63 | |
| 64 const int kSmallShadowImages[] = { | |
| 65 IDR_WINDOW_BUBBLE_SHADOW_SMALL_LEFT, | |
| 66 IDR_WINDOW_BUBBLE_SHADOW_SMALL_TOP_LEFT, | |
| 67 IDR_WINDOW_BUBBLE_SHADOW_SMALL_TOP, | |
| 68 IDR_WINDOW_BUBBLE_SHADOW_SMALL_TOP_RIGHT, | |
| 69 IDR_WINDOW_BUBBLE_SHADOW_SMALL_RIGHT, | |
| 70 IDR_WINDOW_BUBBLE_SHADOW_SMALL_BOTTOM_RIGHT, | |
| 71 IDR_WINDOW_BUBBLE_SHADOW_SMALL_BOTTOM, | |
| 72 IDR_WINDOW_BUBBLE_SHADOW_SMALL_BOTTOM_LEFT, | |
| 73 IDR_WINDOW_BUBBLE_SHADOW_SPIKE_SMALL_LEFT, | |
| 74 IDR_WINDOW_BUBBLE_SHADOW_SPIKE_SMALL_TOP, | |
| 75 IDR_WINDOW_BUBBLE_SHADOW_SPIKE_SMALL_RIGHT, | |
| 76 IDR_WINDOW_BUBBLE_SHADOW_SPIKE_SMALL_BOTTOM, | |
| 77 }; | |
| 78 #endif | |
| 79 | |
| 80 } // namespace | |
| 81 | |
| 16 namespace views { | 82 namespace views { |
| 17 | 83 |
| 18 struct BubbleBorder::BorderImages { | 84 struct BubbleBorder::BorderImages { |
| 19 BorderImages() | 85 BorderImages(const int image_ids[], |
| 20 : left(NULL), | 86 size_t image_ids_size, |
| 21 top_left(NULL), | 87 int arrow_interior_height, |
| 22 top(NULL), | 88 int border_thickness, |
| 23 top_right(NULL), | 89 int corner_radius) |
| 24 right(NULL), | 90 : arrow_interior_height(arrow_interior_height), |
| 25 bottom_right(NULL), | 91 border_thickness(border_thickness), |
| 26 bottom(NULL), | 92 corner_radius(corner_radius) { |
| 27 bottom_left(NULL), | 93 // Only two possible sizes of image ids array. |
| 28 left_arrow(NULL), | 94 DCHECK(image_ids_size == 12 || image_ids_size == 8); |
| 29 top_arrow(NULL), | 95 |
| 30 right_arrow(NULL), | 96 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 31 bottom_arrow(NULL), | 97 |
| 32 border_thickness(0) { | 98 left = *rb.GetImageNamed(image_ids[0]).ToImageSkia(); |
|
msw
2012/09/20 17:03:34
I know the ResourceBundle header says GetImageName
xiyuan
2012/09/20 17:30:56
Aha... Thanks for the tip. Reverted back to use Ge
msw
2012/09/20 17:40:09
np, I'm updating the ambiguous comment at https://
| |
| 99 top_left = *rb.GetImageNamed(image_ids[1]).ToImageSkia(); | |
| 100 top = *rb.GetImageNamed(image_ids[2]).ToImageSkia(); | |
| 101 top_right = *rb.GetImageNamed(image_ids[3]).ToImageSkia(); | |
| 102 right = *rb.GetImageNamed(image_ids[4]).ToImageSkia(); | |
| 103 bottom_right = *rb.GetImageNamed(image_ids[5]).ToImageSkia(); | |
| 104 bottom = *rb.GetImageNamed(image_ids[6]).ToImageSkia(); | |
| 105 bottom_left = *rb.GetImageNamed(image_ids[7]).ToImageSkia(); | |
| 106 | |
| 107 if (image_ids_size > 8) { | |
| 108 left_arrow = *rb.GetImageNamed(image_ids[8]).ToImageSkia(); | |
| 109 top_arrow = *rb.GetImageNamed(image_ids[9]).ToImageSkia(); | |
| 110 right_arrow = *rb.GetImageNamed(image_ids[10]).ToImageSkia(); | |
| 111 bottom_arrow = *rb.GetImageNamed(image_ids[11]).ToImageSkia(); | |
| 112 } | |
| 33 } | 113 } |
| 34 | 114 |
| 35 gfx::ImageSkia* left; | 115 gfx::ImageSkia left; |
| 36 gfx::ImageSkia* top_left; | 116 gfx::ImageSkia top_left; |
| 37 gfx::ImageSkia* top; | 117 gfx::ImageSkia top; |
| 38 gfx::ImageSkia* top_right; | 118 gfx::ImageSkia top_right; |
| 39 gfx::ImageSkia* right; | 119 gfx::ImageSkia right; |
| 40 gfx::ImageSkia* bottom_right; | 120 gfx::ImageSkia bottom_right; |
| 41 gfx::ImageSkia* bottom; | 121 gfx::ImageSkia bottom; |
| 42 gfx::ImageSkia* bottom_left; | 122 gfx::ImageSkia bottom_left; |
| 43 gfx::ImageSkia* left_arrow; | 123 |
| 44 gfx::ImageSkia* top_arrow; | 124 gfx::ImageSkia left_arrow; |
| 45 gfx::ImageSkia* right_arrow; | 125 gfx::ImageSkia top_arrow; |
| 46 gfx::ImageSkia* bottom_arrow; | 126 gfx::ImageSkia right_arrow; |
| 127 gfx::ImageSkia bottom_arrow; | |
| 128 | |
| 129 int arrow_interior_height; // The height inside the arrow image, in pixels. | |
| 47 int border_thickness; | 130 int border_thickness; |
| 131 int corner_radius; | |
| 48 }; | 132 }; |
| 49 | 133 |
| 50 // static | 134 // static |
| 51 struct BubbleBorder::BorderImages* BubbleBorder::normal_images_ = NULL; | 135 struct BubbleBorder::BorderImages* |
| 52 struct BubbleBorder::BorderImages* BubbleBorder::shadow_images_ = NULL; | 136 BubbleBorder::border_images_[SHADOW_COUNT] = { NULL }; |
| 53 | |
| 54 // The height inside the arrow image, in pixels. | |
| 55 static const int kArrowInteriorHeight = 7; | |
| 56 | 137 |
| 57 BubbleBorder::BubbleBorder(ArrowLocation arrow_location, Shadow shadow) | 138 BubbleBorder::BubbleBorder(ArrowLocation arrow_location, Shadow shadow) |
| 58 : override_arrow_offset_(0), | 139 : override_arrow_offset_(0), |
| 59 arrow_location_(arrow_location), | 140 arrow_location_(arrow_location), |
| 60 alignment_(ALIGN_ARROW_TO_MID_ANCHOR), | 141 alignment_(ALIGN_ARROW_TO_MID_ANCHOR), |
| 61 background_color_(SK_ColorWHITE) { | 142 background_color_(SK_ColorWHITE) { |
| 143 DCHECK(shadow < SHADOW_COUNT); | |
| 62 images_ = GetBorderImages(shadow); | 144 images_ = GetBorderImages(shadow); |
| 63 | 145 |
| 64 // Calculate horizontal and vertical insets for arrow by ensuring that | 146 // Calculate horizontal and vertical insets for arrow by ensuring that |
| 65 // the widest arrow and corner images will have enough room to avoid overlap | 147 // the widest arrow and corner images will have enough room to avoid overlap |
| 66 int offset_x = | 148 int offset_x = |
| 67 (std::max(images_->top_arrow->width(), | 149 (std::max(images_->top_arrow.width(), |
| 68 images_->bottom_arrow->width()) / 2) + | 150 images_->bottom_arrow.width()) / 2) + |
| 69 std::max(std::max(images_->top_left->width(), | 151 std::max(std::max(images_->top_left.width(), |
| 70 images_->top_right->width()), | 152 images_->top_right.width()), |
| 71 std::max(images_->bottom_left->width(), | 153 std::max(images_->bottom_left.width(), |
| 72 images_->bottom_right->width())); | 154 images_->bottom_right.width())); |
| 73 int offset_y = | 155 int offset_y = |
| 74 (std::max(images_->left_arrow->height(), | 156 (std::max(images_->left_arrow.height(), |
| 75 images_->right_arrow->height()) / 2) + | 157 images_->right_arrow.height()) / 2) + |
| 76 std::max(std::max(images_->top_left->height(), | 158 std::max(std::max(images_->top_left.height(), |
| 77 images_->top_right->height()), | 159 images_->top_right.height()), |
| 78 std::max(images_->bottom_left->height(), | 160 std::max(images_->bottom_left.height(), |
| 79 images_->bottom_right->height())); | 161 images_->bottom_right.height())); |
| 80 arrow_offset_ = std::max(offset_x, offset_y); | 162 arrow_offset_ = std::max(offset_x, offset_y); |
| 81 } | 163 } |
| 82 | 164 |
| 83 gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to, | 165 gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to, |
| 84 const gfx::Size& contents_size) const { | 166 const gfx::Size& contents_size) const { |
| 85 // Desired size is size of contents enlarged by the size of the border images. | 167 // Desired size is size of contents enlarged by the size of the border images. |
| 86 gfx::Size border_size(contents_size); | 168 gfx::Size border_size(contents_size); |
| 87 gfx::Insets insets; | 169 gfx::Insets insets; |
| 88 GetInsets(&insets); | 170 GetInsets(&insets); |
| 89 border_size.Enlarge(insets.width(), insets.height()); | 171 border_size.Enlarge(insets.width(), insets.height()); |
| 90 | 172 |
| 91 // Ensure the bubble has a minimum size that draws arrows correctly. | 173 // Ensure the bubble has a minimum size that draws arrows correctly. |
| 92 if (is_arrow_on_horizontal(arrow_location_)) | 174 if (is_arrow_on_horizontal(arrow_location_)) |
| 93 border_size.set_width(std::max(border_size.width(), 2 * arrow_offset_)); | 175 border_size.set_width(std::max(border_size.width(), 2 * arrow_offset_)); |
| 94 else if (has_arrow(arrow_location_)) | 176 else if (has_arrow(arrow_location_)) |
| 95 border_size.set_height(std::max(border_size.height(), 2 * arrow_offset_)); | 177 border_size.set_height(std::max(border_size.height(), 2 * arrow_offset_)); |
| 96 | 178 |
| 97 // Screen position depends on the arrow location. | 179 // Screen position depends on the arrow location. |
| 98 // The arrow should overlap the target by some amount since there is space | 180 // The bubble should overlap the target by some amount since there is space |
| 99 // for shadow between arrow tip and image bounds. | 181 // for shadow between arrow tip/bubble border and image bounds. |
| 100 const int kArrowOverlap = 3; | |
| 101 int x = position_relative_to.x(); | 182 int x = position_relative_to.x(); |
| 102 int y = position_relative_to.y(); | 183 int y = position_relative_to.y(); |
| 103 int w = position_relative_to.width(); | 184 int w = position_relative_to.width(); |
| 104 int h = position_relative_to.height(); | 185 int h = position_relative_to.height(); |
| 105 int arrow_offset = override_arrow_offset_ ? override_arrow_offset_ : | 186 |
| 106 arrow_offset_; | 187 const int arrow_size = images_->arrow_interior_height + kBorderStrokeSize; |
| 188 const int arrow_offset = GetArrowOffset(border_size); | |
| 107 | 189 |
| 108 // Calculate bubble x coordinate. | 190 // Calculate bubble x coordinate. |
| 109 switch (arrow_location_) { | 191 switch (arrow_location_) { |
| 110 case TOP_LEFT: | 192 case TOP_LEFT: |
| 111 case BOTTOM_LEFT: | 193 case BOTTOM_LEFT: |
| 112 x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? w / 2 - arrow_offset : | 194 x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? w / 2 - arrow_offset : |
| 113 -kArrowOverlap; | 195 -(images_->left.width() - kBorderStrokeSize); |
| 114 break; | 196 break; |
| 115 | 197 |
| 116 case TOP_RIGHT: | 198 case TOP_RIGHT: |
| 117 case BOTTOM_RIGHT: | 199 case BOTTOM_RIGHT: |
| 118 x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? | 200 x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? |
| 119 w / 2 + arrow_offset - border_size.width() + 1 : | 201 w / 2 + arrow_offset - border_size.width() + 1 : |
| 120 w - border_size.width() + kArrowOverlap; | 202 w - border_size.width() + images_->right.width() - kBorderStrokeSize; |
| 121 break; | 203 break; |
| 122 | 204 |
| 123 case LEFT_TOP: | 205 case LEFT_TOP: |
| 206 case LEFT_CENTER: | |
| 124 case LEFT_BOTTOM: | 207 case LEFT_BOTTOM: |
| 125 x += w - kArrowOverlap; | 208 x += w - (images_->left_arrow.width() - arrow_size); |
| 126 break; | 209 break; |
| 127 | 210 |
| 128 case RIGHT_TOP: | 211 case RIGHT_TOP: |
| 212 case RIGHT_CENTER: | |
| 129 case RIGHT_BOTTOM: | 213 case RIGHT_BOTTOM: |
| 130 x += kArrowOverlap - border_size.width(); | 214 x += images_->right_arrow.width() - arrow_size - border_size.width(); |
| 215 break; | |
| 216 | |
| 217 case TOP_CENTER: | |
| 218 case BOTTOM_CENTER: | |
| 219 x += w / 2 - arrow_offset; | |
| 131 break; | 220 break; |
| 132 | 221 |
| 133 case NONE: | 222 case NONE: |
| 134 case FLOAT: | 223 case FLOAT: |
| 135 x += w / 2 - border_size.width() / 2; | 224 x += w / 2 - border_size.width() / 2; |
| 136 break; | 225 break; |
| 137 } | 226 } |
| 138 | 227 |
| 139 // Calculate bubble y coordinate. | 228 // Calculate bubble y coordinate. |
| 140 switch (arrow_location_) { | 229 switch (arrow_location_) { |
| 141 case TOP_LEFT: | 230 case TOP_LEFT: |
| 231 case TOP_CENTER: | |
| 142 case TOP_RIGHT: | 232 case TOP_RIGHT: |
| 143 y += h - kArrowOverlap; | 233 y += h - (images_->top_arrow.height() - arrow_size); |
| 144 break; | 234 break; |
| 145 | 235 |
| 146 case BOTTOM_LEFT: | 236 case BOTTOM_LEFT: |
| 237 case BOTTOM_CENTER: | |
| 147 case BOTTOM_RIGHT: | 238 case BOTTOM_RIGHT: |
| 148 y += kArrowOverlap - border_size.height(); | 239 y += images_->bottom_arrow.height() - arrow_size - |
| 240 border_size.height(); | |
| 149 break; | 241 break; |
| 150 | 242 |
| 151 case LEFT_TOP: | 243 case LEFT_TOP: |
| 152 case RIGHT_TOP: | 244 case RIGHT_TOP: |
| 153 y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? h / 2 - arrow_offset : | 245 y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? h / 2 - arrow_offset : |
| 154 -kArrowOverlap; | 246 -(images_->top.height() - kBorderStrokeSize); |
| 155 break; | 247 break; |
| 156 | 248 |
| 157 case LEFT_BOTTOM: | 249 case LEFT_BOTTOM: |
| 158 case RIGHT_BOTTOM: | 250 case RIGHT_BOTTOM: |
| 159 y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? | 251 y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? |
| 160 h / 2 + arrow_offset - border_size.height() + 1 : | 252 h / 2 + arrow_offset - border_size.height() + 1 : |
| 161 h - border_size.height() + kArrowOverlap; | 253 h - border_size.height() + images_->bottom.height() - |
| 254 kBorderStrokeSize; | |
| 255 break; | |
| 256 | |
| 257 case LEFT_CENTER: | |
| 258 case RIGHT_CENTER: | |
| 259 y += h / 2 - arrow_offset; | |
| 162 break; | 260 break; |
| 163 | 261 |
| 164 case NONE: | 262 case NONE: |
| 165 y += h; | 263 y += h; |
| 166 break; | 264 break; |
| 167 | 265 |
| 168 case FLOAT: | 266 case FLOAT: |
| 169 y += h / 2 - border_size.height() / 2; | 267 y += h / 2 - border_size.height() / 2; |
| 170 break; | 268 break; |
| 171 } | 269 } |
| 172 | 270 |
| 173 return gfx::Rect(x, y, border_size.width(), border_size.height()); | 271 return gfx::Rect(x, y, border_size.width(), border_size.height()); |
| 174 } | 272 } |
| 175 | 273 |
| 176 void BubbleBorder::GetInsets(gfx::Insets* insets) const { | 274 void BubbleBorder::GetInsets(gfx::Insets* insets) const { |
| 177 return GetInsetsForArrowLocation(insets, arrow_location()); | 275 return GetInsetsForArrowLocation(insets, arrow_location()); |
| 178 } | 276 } |
| 179 | 277 |
| 180 void BubbleBorder::GetInsetsForArrowLocation(gfx::Insets* insets, | 278 void BubbleBorder::GetInsetsForArrowLocation(gfx::Insets* insets, |
| 181 ArrowLocation arrow_loc) const { | 279 ArrowLocation arrow_loc) const { |
| 182 int top = images_->top->height(); | 280 int top = images_->top.height(); |
| 183 int bottom = images_->bottom->height(); | 281 int bottom = images_->bottom.height(); |
| 184 int left = images_->left->width(); | 282 int left = images_->left.width(); |
| 185 int right = images_->right->width(); | 283 int right = images_->right.width(); |
| 186 switch (arrow_loc) { | 284 switch (arrow_loc) { |
| 187 case TOP_LEFT: | 285 case TOP_LEFT: |
| 286 case TOP_CENTER: | |
| 188 case TOP_RIGHT: | 287 case TOP_RIGHT: |
| 189 top = std::max(top, images_->top_arrow->height()); | 288 top = std::max(top, images_->top_arrow.height()); |
| 190 break; | 289 break; |
| 191 | 290 |
| 192 case BOTTOM_LEFT: | 291 case BOTTOM_LEFT: |
| 292 case BOTTOM_CENTER: | |
| 193 case BOTTOM_RIGHT: | 293 case BOTTOM_RIGHT: |
| 194 bottom = std::max(bottom, images_->bottom_arrow->height()); | 294 bottom = std::max(bottom, images_->bottom_arrow.height()); |
| 195 break; | 295 break; |
| 196 | 296 |
| 197 case LEFT_TOP: | 297 case LEFT_TOP: |
| 298 case LEFT_CENTER: | |
| 198 case LEFT_BOTTOM: | 299 case LEFT_BOTTOM: |
| 199 left = std::max(left, images_->left_arrow->width()); | 300 left = std::max(left, images_->left_arrow.width()); |
| 200 break; | 301 break; |
| 201 | 302 |
| 202 case RIGHT_TOP: | 303 case RIGHT_TOP: |
| 304 case RIGHT_CENTER: | |
| 203 case RIGHT_BOTTOM: | 305 case RIGHT_BOTTOM: |
| 204 right = std::max(right, images_->right_arrow->width()); | 306 right = std::max(right, images_->right_arrow.width()); |
| 205 break; | 307 break; |
| 206 | 308 |
| 207 case NONE: | 309 case NONE: |
| 208 case FLOAT: | 310 case FLOAT: |
| 209 // Nothing to do. | 311 // Nothing to do. |
| 210 break; | 312 break; |
| 211 } | 313 } |
| 212 insets->Set(top, left, bottom, right); | 314 insets->Set(top, left, bottom, right); |
| 213 } | 315 } |
| 214 | 316 |
| 215 int BubbleBorder::GetBorderThickness() const { | 317 int BubbleBorder::GetBorderThickness() const { |
| 216 return images_->border_thickness; | 318 return images_->border_thickness; |
| 217 } | 319 } |
| 218 | 320 |
| 219 int BubbleBorder::SetArrowOffset(int offset, const gfx::Size& contents_size) { | 321 int BubbleBorder::GetBorderCornerRadius() const { |
| 220 gfx::Size border_size(contents_size); | 322 return images_->corner_radius; |
| 221 gfx::Insets insets; | 323 } |
| 222 GetInsets(&insets); | 324 |
| 223 border_size.Enlarge(insets.left() + insets.right(), | 325 int BubbleBorder::GetArrowOffset(const gfx::Size& border_size) const { |
| 224 insets.top() + insets.bottom()); | 326 int arrow_offset = arrow_offset_; |
| 225 offset = std::max(arrow_offset_, | 327 if (override_arrow_offset_) { |
| 226 std::min(offset, (is_arrow_on_horizontal(arrow_location_) ? | 328 arrow_offset = override_arrow_offset_; |
| 329 } else if (is_arrow_at_center(arrow_location_)) { | |
| 330 if (is_arrow_on_horizontal(arrow_location_)) | |
| 331 arrow_offset = border_size.width() / 2; | |
| 332 else | |
| 333 arrow_offset = border_size.height() / 2; | |
| 334 } | |
| 335 | |
| 336 // |arrow_offset_| contains the minimum offset required to draw border images | |
| 337 // correctly. It's defined in terms of number of pixels from the beginning of | |
| 338 // the edge. The maximum arrow offset is the edge size - |arrow_offset_|. The | |
| 339 // following statement clamps the calculated arrow offset within that range. | |
| 340 return std::max(arrow_offset_, | |
| 341 std::min(arrow_offset, (is_arrow_on_horizontal(arrow_location_) ? | |
| 227 border_size.width() : border_size.height()) - arrow_offset_)); | 342 border_size.width() : border_size.height()) - arrow_offset_)); |
| 228 override_arrow_offset_ = offset; | |
| 229 return override_arrow_offset_; | |
| 230 } | 343 } |
| 231 | 344 |
| 232 // static | 345 // static |
| 233 BubbleBorder::BorderImages* BubbleBorder::GetBorderImages(Shadow shadow) { | 346 BubbleBorder::BorderImages* BubbleBorder::GetBorderImages(Shadow shadow) { |
| 234 if (shadow == SHADOW && shadow_images_ == NULL) { | 347 CHECK_LT(shadow, SHADOW_COUNT); |
| 235 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 348 |
| 236 shadow_images_ = new BorderImages(); | 349 struct BorderImages*& images = border_images_[shadow]; |
| 237 shadow_images_->left = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_L); | 350 if (images) |
| 238 shadow_images_->top_left = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_TL); | 351 return images; |
| 239 shadow_images_->top = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_T); | 352 |
| 240 shadow_images_->top_right = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_TR); | 353 switch (shadow) { |
| 241 shadow_images_->right = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_R); | 354 case SHADOW: |
| 242 shadow_images_->bottom_right = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_BR); | 355 images = new BorderImages(kShadowImages, |
| 243 shadow_images_->bottom = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_B); | 356 arraysize(kShadowImages), |
| 244 shadow_images_->bottom_left = rb.GetImageSkiaNamed(IDR_BUBBLE_SHADOW_BL); | 357 0, 10, 4); |
| 245 shadow_images_->left_arrow = new gfx::ImageSkia(); | 358 break; |
| 246 shadow_images_->top_arrow = new gfx::ImageSkia(); | 359 case NO_SHADOW: |
| 247 shadow_images_->right_arrow = new gfx::ImageSkia(); | 360 images = new BorderImages(kNoShadowImages, |
| 248 shadow_images_->bottom_arrow = new gfx::ImageSkia(); | 361 arraysize(kNoShadowImages), |
| 249 shadow_images_->border_thickness = 10; | 362 7, 0, 4); |
| 250 } else if (shadow == NO_SHADOW && normal_images_ == NULL) { | 363 break; |
| 251 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 364 #if defined(USE_AURA) |
| 252 normal_images_ = new BorderImages(); | 365 case BIG_SHADOW: |
| 253 normal_images_->left = rb.GetImageSkiaNamed(IDR_BUBBLE_L); | 366 images = new BorderImages(kBigShadowImages, |
| 254 normal_images_->top_left = rb.GetImageSkiaNamed(IDR_BUBBLE_TL); | 367 arraysize(kBigShadowImages), |
| 255 normal_images_->top = rb.GetImageSkiaNamed(IDR_BUBBLE_T); | 368 9, 0, 3); |
| 256 normal_images_->top_right = rb.GetImageSkiaNamed(IDR_BUBBLE_TR); | 369 break; |
| 257 normal_images_->right = rb.GetImageSkiaNamed(IDR_BUBBLE_R); | 370 case SMALL_SHADOW: |
| 258 normal_images_->bottom_right = rb.GetImageSkiaNamed(IDR_BUBBLE_BR); | 371 images = new BorderImages(kSmallShadowImages, |
| 259 normal_images_->bottom = rb.GetImageSkiaNamed(IDR_BUBBLE_B); | 372 arraysize(kSmallShadowImages), |
| 260 normal_images_->bottom_left = rb.GetImageSkiaNamed(IDR_BUBBLE_BL); | 373 9, 0, 3); |
| 261 normal_images_->left_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_L_ARROW); | 374 break; |
| 262 normal_images_->top_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_T_ARROW); | 375 #endif |
| 263 normal_images_->right_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_R_ARROW); | 376 case SHADOW_COUNT: |
| 264 normal_images_->bottom_arrow = rb.GetImageSkiaNamed(IDR_BUBBLE_B_ARROW); | 377 NOTREACHED(); |
| 265 normal_images_->border_thickness = 0; | 378 break; |
| 266 } | 379 } |
| 267 return shadow == SHADOW ? shadow_images_ : normal_images_; | 380 |
| 381 return images; | |
| 268 } | 382 } |
| 269 | 383 |
| 270 BubbleBorder::~BubbleBorder() {} | 384 BubbleBorder::~BubbleBorder() {} |
| 271 | 385 |
| 272 void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { | 386 void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { |
| 273 // Convenience shorthand variables. | 387 // Convenience shorthand variables. |
| 274 const int tl_width = images_->top_left->width(); | 388 const int tl_width = images_->top_left.width(); |
| 275 const int tl_height = images_->top_left->height(); | 389 const int tl_height = images_->top_left.height(); |
| 276 const int t_height = images_->top->height(); | 390 const int t_height = images_->top.height(); |
| 277 const int tr_width = images_->top_right->width(); | 391 const int tr_width = images_->top_right.width(); |
| 278 const int tr_height = images_->top_right->height(); | 392 const int tr_height = images_->top_right.height(); |
| 279 const int l_width = images_->left->width(); | 393 const int l_width = images_->left.width(); |
| 280 const int r_width = images_->right->width(); | 394 const int r_width = images_->right.width(); |
| 281 const int br_width = images_->bottom_right->width(); | 395 const int br_width = images_->bottom_right.width(); |
| 282 const int br_height = images_->bottom_right->height(); | 396 const int br_height = images_->bottom_right.height(); |
| 283 const int b_height = images_->bottom->height(); | 397 const int b_height = images_->bottom.height(); |
| 284 const int bl_width = images_->bottom_left->width(); | 398 const int bl_width = images_->bottom_left.width(); |
| 285 const int bl_height = images_->bottom_left->height(); | 399 const int bl_height = images_->bottom_left.height(); |
| 286 | 400 |
| 287 gfx::Insets insets; | 401 gfx::Insets insets; |
| 288 GetInsets(&insets); | 402 GetInsets(&insets); |
| 289 const int top = insets.top() - t_height; | 403 const int top = insets.top() - t_height; |
| 290 const int bottom = view.height() - insets.bottom() + b_height; | 404 const int bottom = view.height() - insets.bottom() + b_height; |
| 291 const int left = insets.left() - l_width; | 405 const int left = insets.left() - l_width; |
| 292 const int right = view.width() - insets.right() + r_width; | 406 const int right = view.width() - insets.right() + r_width; |
| 293 const int height = bottom - top; | 407 const int height = bottom - top; |
| 294 const int width = right - left; | 408 const int width = right - left; |
| 295 | 409 |
| 296 // |arrow_offset| is offset of arrow from the begining of the edge. | 410 // |arrow_offset| is offset of arrow from the beginning of the edge. |
| 297 int arrow_offset = arrow_offset_; | 411 int arrow_offset = GetArrowOffset(view.size()); |
| 298 if (override_arrow_offset_) | 412 if (!is_arrow_at_center(arrow_location_)) { |
| 299 arrow_offset = override_arrow_offset_; | 413 if (is_arrow_on_horizontal(arrow_location_) && |
| 300 else if (is_arrow_on_horizontal(arrow_location_) && | 414 !is_arrow_on_left(arrow_location_)) { |
|
msw
2012/09/20 00:07:23
nit: indent one more space.
xiyuan
2012/09/20 16:56:51
Done.
| |
| 301 !is_arrow_on_left(arrow_location_)) { | 415 arrow_offset = view.width() - arrow_offset - 1; |
| 302 arrow_offset = view.width() - arrow_offset - 1; | 416 } else if (!is_arrow_on_horizontal(arrow_location_) && |
| 303 } else if (!is_arrow_on_horizontal(arrow_location_) && | 417 !is_arrow_on_top(arrow_location_)) { |
| 304 !is_arrow_on_top(arrow_location_)) { | 418 arrow_offset = view.height() - arrow_offset - 1; |
| 305 arrow_offset = view.height() - arrow_offset - 1; | 419 } |
| 306 } | 420 } |
| 307 | 421 |
| 308 // Left edge. | 422 // Left edge. |
| 309 if (arrow_location_ == LEFT_TOP || arrow_location_ == LEFT_BOTTOM) { | 423 if (arrow_location_ == LEFT_TOP || |
| 424 arrow_location_ == LEFT_CENTER || | |
| 425 arrow_location_ == LEFT_BOTTOM) { | |
| 310 int start_y = top + tl_height; | 426 int start_y = top + tl_height; |
| 311 int before_arrow = | 427 int before_arrow = |
| 312 arrow_offset - start_y - images_->left_arrow->height() / 2; | 428 arrow_offset - start_y - images_->left_arrow.height() / 2; |
| 313 int after_arrow = height - tl_height - bl_height - | 429 int after_arrow = height - tl_height - bl_height - |
| 314 images_->left_arrow->height() - before_arrow; | 430 images_->left_arrow.height() - before_arrow; |
| 315 // Shift tip coordinates half pixel so that skia draws the tip correctly. | 431 // Shift tip coordinates half pixel so that skia draws the tip correctly. |
| 316 DrawArrowInterior(canvas, | 432 DrawArrowInterior(canvas, |
| 317 images_->left_arrow->width() - kArrowInteriorHeight - 0.5f, | 433 images_->left_arrow.width() - images_->arrow_interior_height - 0.5f, |
| 318 start_y + before_arrow + images_->left_arrow->height() / 2 - 0.5f); | 434 start_y + before_arrow + images_->left_arrow.height() / 2 - 0.5f); |
| 319 DrawEdgeWithArrow(canvas, | 435 DrawEdgeWithArrow(canvas, |
| 320 false, | 436 false, |
| 321 images_->left, | 437 images_->left, |
| 322 images_->left_arrow, | 438 images_->left_arrow, |
| 323 left, | 439 left, |
| 324 start_y, | 440 start_y, |
| 325 before_arrow, | 441 before_arrow, |
| 326 after_arrow, | 442 after_arrow, |
| 327 images_->left->width() - images_->left_arrow->width()); | 443 images_->left.width() - images_->left_arrow.width()); |
| 328 } else { | 444 } else { |
| 329 canvas->TileImageInt(*images_->left, left, top + tl_height, l_width, | 445 canvas->TileImageInt(images_->left, left, top + tl_height, l_width, |
| 330 height - tl_height - bl_height); | 446 height - tl_height - bl_height); |
| 331 } | 447 } |
| 332 | 448 |
| 333 // Top left corner. | 449 // Top left corner. |
| 334 canvas->DrawImageInt(*images_->top_left, left, top); | 450 canvas->DrawImageInt(images_->top_left, left, top); |
| 335 | 451 |
| 336 // Top edge. | 452 // Top edge. |
| 337 if (arrow_location_ == TOP_LEFT || arrow_location_ == TOP_RIGHT) { | 453 if (arrow_location_ == TOP_LEFT || |
| 454 arrow_location_ == TOP_CENTER || | |
| 455 arrow_location_ == TOP_RIGHT) { | |
| 338 int start_x = left + tl_width; | 456 int start_x = left + tl_width; |
| 339 int before_arrow = arrow_offset - start_x - images_->top_arrow->width() / 2; | 457 int before_arrow = arrow_offset - start_x - images_->top_arrow.width() / 2; |
| 340 int after_arrow = width - tl_width - tr_width - | 458 int after_arrow = width - tl_width - tr_width - |
| 341 images_->top_arrow->width() - before_arrow; | 459 images_->top_arrow.width() - before_arrow; |
| 342 DrawArrowInterior(canvas, | 460 DrawArrowInterior(canvas, |
| 343 start_x + before_arrow + images_->top_arrow->width() / 2, | 461 start_x + before_arrow + images_->top_arrow.width() / 2, |
| 344 images_->top_arrow->height() - kArrowInteriorHeight); | 462 images_->top_arrow.height() - images_->arrow_interior_height); |
| 345 DrawEdgeWithArrow(canvas, | 463 DrawEdgeWithArrow(canvas, |
| 346 true, | 464 true, |
| 347 images_->top, | 465 images_->top, |
| 348 images_->top_arrow, | 466 images_->top_arrow, |
| 349 start_x, | 467 start_x, |
| 350 top, | 468 top, |
| 351 before_arrow, | 469 before_arrow, |
| 352 after_arrow, | 470 after_arrow, |
| 353 images_->top->height() - images_->top_arrow->height()); | 471 images_->top.height() - images_->top_arrow.height()); |
| 354 } else { | 472 } else { |
| 355 canvas->TileImageInt(*images_->top, left + tl_width, top, | 473 canvas->TileImageInt(images_->top, left + tl_width, top, |
| 356 width - tl_width - tr_width, t_height); | 474 width - tl_width - tr_width, t_height); |
| 357 } | 475 } |
| 358 | 476 |
| 359 // Top right corner. | 477 // Top right corner. |
| 360 canvas->DrawImageInt(*images_->top_right, right - tr_width, top); | 478 canvas->DrawImageInt(images_->top_right, right - tr_width, top); |
| 361 | 479 |
| 362 // Right edge. | 480 // Right edge. |
| 363 if (arrow_location_ == RIGHT_TOP || arrow_location_ == RIGHT_BOTTOM) { | 481 if (arrow_location_ == RIGHT_TOP || |
| 482 arrow_location_ == RIGHT_CENTER || | |
| 483 arrow_location_ == RIGHT_BOTTOM) { | |
| 364 int start_y = top + tr_height; | 484 int start_y = top + tr_height; |
| 365 int before_arrow = | 485 int before_arrow = |
| 366 arrow_offset - start_y - images_->right_arrow->height() / 2; | 486 arrow_offset - start_y - images_->right_arrow.height() / 2; |
| 367 int after_arrow = height - tl_height - bl_height - | 487 int after_arrow = height - tl_height - bl_height - |
| 368 images_->right_arrow->height() - before_arrow; | 488 images_->right_arrow.height() - before_arrow; |
| 369 // Shift tip coordinates half pixel so that skia draws the tip correctly. | 489 // Shift tip coordinates half pixel so that skia draws the tip correctly. |
| 370 DrawArrowInterior(canvas, | 490 DrawArrowInterior(canvas, |
| 371 right - r_width + kArrowInteriorHeight - 0.5f, | 491 right - r_width + images_->arrow_interior_height - 0.5f, |
| 372 start_y + before_arrow + images_->right_arrow->height() / 2 - 0.5f); | 492 start_y + before_arrow + images_->right_arrow.height() / 2 - 0.5f); |
| 373 DrawEdgeWithArrow(canvas, | 493 DrawEdgeWithArrow(canvas, |
| 374 false, | 494 false, |
| 375 images_->right, | 495 images_->right, |
| 376 images_->right_arrow, | 496 images_->right_arrow, |
| 377 right - r_width, | 497 right - r_width, |
| 378 start_y, | 498 start_y, |
| 379 before_arrow, | 499 before_arrow, |
| 380 after_arrow, | 500 after_arrow, |
| 381 0); | 501 0); |
| 382 } else { | 502 } else { |
| 383 canvas->TileImageInt(*images_->right, right - r_width, top + tr_height, | 503 canvas->TileImageInt(images_->right, right - r_width, top + tr_height, |
| 384 r_width, height - tr_height - br_height); | 504 r_width, height - tr_height - br_height); |
| 385 } | 505 } |
| 386 | 506 |
| 387 // Bottom right corner. | 507 // Bottom right corner. |
| 388 canvas->DrawImageInt(*images_->bottom_right, | 508 canvas->DrawImageInt(images_->bottom_right, |
| 389 right - br_width, | 509 right - br_width, |
| 390 bottom - br_height); | 510 bottom - br_height); |
| 391 | 511 |
| 392 // Bottom edge. | 512 // Bottom edge. |
| 393 if (arrow_location_ == BOTTOM_LEFT || arrow_location_ == BOTTOM_RIGHT) { | 513 if (arrow_location_ == BOTTOM_LEFT || |
| 514 arrow_location_ == BOTTOM_CENTER || | |
| 515 arrow_location_ == BOTTOM_RIGHT) { | |
| 394 int start_x = left + bl_width; | 516 int start_x = left + bl_width; |
| 395 int before_arrow = | 517 int before_arrow = |
| 396 arrow_offset - start_x - images_->bottom_arrow->width() / 2; | 518 arrow_offset - start_x - images_->bottom_arrow.width() / 2; |
| 397 int after_arrow = width - bl_width - br_width - | 519 int after_arrow = width - bl_width - br_width - |
| 398 images_->bottom_arrow->width() - before_arrow; | 520 images_->bottom_arrow.width() - before_arrow; |
| 399 DrawArrowInterior(canvas, | 521 DrawArrowInterior(canvas, |
| 400 start_x + before_arrow + images_->bottom_arrow->width() / 2, | 522 start_x + before_arrow + images_->bottom_arrow.width() / 2, |
| 401 bottom - b_height + kArrowInteriorHeight); | 523 bottom - b_height + images_->arrow_interior_height); |
| 402 DrawEdgeWithArrow(canvas, | 524 DrawEdgeWithArrow(canvas, |
| 403 true, | 525 true, |
| 404 images_->bottom, | 526 images_->bottom, |
| 405 images_->bottom_arrow, | 527 images_->bottom_arrow, |
| 406 start_x, | 528 start_x, |
| 407 bottom - b_height, | 529 bottom - b_height, |
| 408 before_arrow, | 530 before_arrow, |
| 409 after_arrow, | 531 after_arrow, |
| 410 0); | 532 0); |
| 411 } else { | 533 } else { |
| 412 canvas->TileImageInt(*images_->bottom, left + bl_width, bottom - b_height, | 534 canvas->TileImageInt(images_->bottom, left + bl_width, bottom - b_height, |
| 413 width - bl_width - br_width, b_height); | 535 width - bl_width - br_width, b_height); |
| 414 } | 536 } |
| 415 | 537 |
| 416 // Bottom left corner. | 538 // Bottom left corner. |
| 417 canvas->DrawImageInt(*images_->bottom_left, left, bottom - bl_height); | 539 canvas->DrawImageInt(images_->bottom_left, left, bottom - bl_height); |
| 418 } | 540 } |
| 419 | 541 |
| 420 void BubbleBorder::DrawEdgeWithArrow(gfx::Canvas* canvas, | 542 void BubbleBorder::DrawEdgeWithArrow(gfx::Canvas* canvas, |
| 421 bool is_horizontal, | 543 bool is_horizontal, |
| 422 gfx::ImageSkia* edge, | 544 const gfx::ImageSkia& edge, |
| 423 gfx::ImageSkia* arrow, | 545 const gfx::ImageSkia& arrow, |
| 424 int start_x, | 546 int start_x, |
| 425 int start_y, | 547 int start_y, |
| 426 int before_arrow, | 548 int before_arrow, |
| 427 int after_arrow, | 549 int after_arrow, |
| 428 int offset) const { | 550 int offset) const { |
| 429 /* Here's what the parameters mean: | 551 /* Here's what the parameters mean: |
| 430 * start_x | 552 * start_x |
| 431 * . | 553 * . |
| 432 * . ┌───┐ ┬ offset | 554 * . ┌───┐ ┬ offset |
| 433 * start_y..........┌────┬────────┤ ▲ ├────────┬────┐ | 555 * start_y..........┌────┬────────┤ ▲ ├────────┬────┐ |
| 434 * │ / │--------│∙ ∙│--------│ \ │ | 556 * │ / │--------│∙ ∙│--------│ \ │ |
| 435 * │ / ├────────┴───┴────────┤ \ │ | 557 * │ / ├────────┴───┴────────┤ \ │ |
| 436 * ├───┬┘ └┬───┤ | 558 * ├───┬┘ └┬───┤ |
| 437 * └───┬────┘ └───┬────┘ | 559 * └───┬────┘ └───┬────┘ |
| 438 * before_arrow ─┘ └─ after_arrow | 560 * before_arrow ─┘ └─ after_arrow |
| 439 */ | 561 */ |
| 440 if (before_arrow) { | 562 if (before_arrow) { |
| 441 canvas->TileImageInt(*edge, start_x, start_y, | 563 canvas->TileImageInt(edge, start_x, start_y, |
| 442 is_horizontal ? before_arrow : edge->width(), | 564 is_horizontal ? before_arrow : edge.width(), |
| 443 is_horizontal ? edge->height() : before_arrow); | 565 is_horizontal ? edge.height() : before_arrow); |
| 444 } | 566 } |
| 445 | 567 |
| 446 canvas->DrawImageInt(*arrow, | 568 canvas->DrawImageInt(arrow, |
| 447 start_x + (is_horizontal ? before_arrow : offset), | 569 start_x + (is_horizontal ? before_arrow : offset), |
| 448 start_y + (is_horizontal ? offset : before_arrow)); | 570 start_y + (is_horizontal ? offset : before_arrow)); |
| 449 | 571 |
| 450 if (after_arrow) { | 572 if (after_arrow) { |
| 451 start_x += (is_horizontal ? before_arrow + arrow->width() : 0); | 573 start_x += (is_horizontal ? before_arrow + arrow.width() : 0); |
| 452 start_y += (is_horizontal ? 0 : before_arrow + arrow->height()); | 574 start_y += (is_horizontal ? 0 : before_arrow + arrow.height()); |
| 453 canvas->TileImageInt(*edge, start_x, start_y, | 575 canvas->TileImageInt(edge, start_x, start_y, |
| 454 is_horizontal ? after_arrow : edge->width(), | 576 is_horizontal ? after_arrow : edge.width(), |
| 455 is_horizontal ? edge->height() : after_arrow); | 577 is_horizontal ? edge.height() : after_arrow); |
| 456 } | 578 } |
| 457 } | 579 } |
| 458 | 580 |
| 459 void BubbleBorder::DrawArrowInterior(gfx::Canvas* canvas, | 581 void BubbleBorder::DrawArrowInterior(gfx::Canvas* canvas, |
| 460 float tip_x, | 582 float tip_x, |
| 461 float tip_y) const { | 583 float tip_y) const { |
| 462 const bool is_horizontal = is_arrow_on_horizontal(arrow_location_); | 584 const bool is_horizontal = is_arrow_on_horizontal(arrow_location_); |
| 463 const bool positive_offset = is_horizontal ? | 585 const bool positive_offset = is_horizontal ? |
| 464 is_arrow_on_top(arrow_location_) : is_arrow_on_left(arrow_location_); | 586 is_arrow_on_top(arrow_location_) : is_arrow_on_left(arrow_location_); |
| 465 const int offset_to_next_vertex = positive_offset ? | 587 const int offset_to_next_vertex = positive_offset ? |
| 466 kArrowInteriorHeight : -kArrowInteriorHeight; | 588 images_->arrow_interior_height : -images_->arrow_interior_height; |
| 467 | 589 |
| 468 SkPath path; | 590 SkPath path; |
| 469 path.incReserve(4); | 591 path.incReserve(4); |
| 470 path.moveTo(SkDoubleToScalar(tip_x), SkDoubleToScalar(tip_y)); | 592 path.moveTo(SkDoubleToScalar(tip_x), SkDoubleToScalar(tip_y)); |
| 471 path.lineTo(SkDoubleToScalar(tip_x + offset_to_next_vertex), | 593 path.lineTo(SkDoubleToScalar(tip_x + offset_to_next_vertex), |
| 472 SkDoubleToScalar(tip_y + offset_to_next_vertex)); | 594 SkDoubleToScalar(tip_y + offset_to_next_vertex)); |
| 473 if (is_horizontal) { | 595 if (is_horizontal) { |
| 474 path.lineTo(SkDoubleToScalar(tip_x - offset_to_next_vertex), | 596 path.lineTo(SkDoubleToScalar(tip_x - offset_to_next_vertex), |
| 475 SkDoubleToScalar(tip_y + offset_to_next_vertex)); | 597 SkDoubleToScalar(tip_y + offset_to_next_vertex)); |
| 476 } else { | 598 } else { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 499 // contents, which we need to fill with the background color. | 621 // 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 | 622 // NOTE: This doesn't handle an arrow location of "NONE", which has square top |
| 501 // corners. | 623 // corners. |
| 502 SkPaint paint; | 624 SkPaint paint; |
| 503 paint.setAntiAlias(true); | 625 paint.setAntiAlias(true); |
| 504 paint.setStyle(SkPaint::kFill_Style); | 626 paint.setStyle(SkPaint::kFill_Style); |
| 505 paint.setColor(border_->background_color()); | 627 paint.setColor(border_->background_color()); |
| 506 SkPath path; | 628 SkPath path; |
| 507 gfx::Rect bounds(view->GetContentsBounds()); | 629 gfx::Rect bounds(view->GetContentsBounds()); |
| 508 bounds.Inset(-border_->GetBorderThickness(), -border_->GetBorderThickness()); | 630 bounds.Inset(-border_->GetBorderThickness(), -border_->GetBorderThickness()); |
| 509 SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius()); | 631 SkScalar radius = SkIntToScalar(border_->GetBorderCornerRadius()); |
| 510 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius); | 632 path.addRoundRect(gfx::RectToSkRect(bounds), radius, radius); |
| 511 canvas->DrawPath(path, paint); | 633 canvas->DrawPath(path, paint); |
| 512 } | 634 } |
| 513 | 635 |
| 514 } // namespace views | 636 } // namespace views |
| OLD | NEW |