| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/bubble/bubble_border.h" | 5 #include "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 "grit/ui_resources_standard.h" | 11 #include "grit/ui_resources_standard.h" |
| 12 #include "third_party/skia/include/core/SkBitmap.h" | 12 #include "third_party/skia/include/core/SkBitmap.h" |
| 13 #include "ui/base/resource/resource_bundle.h" | 13 #include "ui/base/resource/resource_bundle.h" |
| 14 #include "ui/gfx/canvas_skia.h" | 14 #include "ui/gfx/canvas_skia.h" |
| 15 #include "ui/gfx/path.h" | 15 #include "ui/gfx/path.h" |
| 16 | 16 |
| 17 namespace views { | 17 namespace views { |
| 18 | 18 |
| 19 // static | 19 struct BubbleBorder::BorderImages { |
| 20 SkBitmap* BubbleBorder::left_ = NULL; | 20 BorderImages() |
| 21 SkBitmap* BubbleBorder::top_left_ = NULL; | 21 : left(NULL), |
| 22 SkBitmap* BubbleBorder::top_ = NULL; | 22 top_left(NULL), |
| 23 SkBitmap* BubbleBorder::top_right_ = NULL; | 23 top(NULL), |
| 24 SkBitmap* BubbleBorder::right_ = NULL; | 24 top_right(NULL), |
| 25 SkBitmap* BubbleBorder::bottom_right_ = NULL; | 25 right(NULL), |
| 26 SkBitmap* BubbleBorder::bottom_ = NULL; | 26 bottom_right(NULL), |
| 27 SkBitmap* BubbleBorder::bottom_left_ = NULL; | 27 bottom(NULL), |
| 28 SkBitmap* BubbleBorder::top_arrow_ = NULL; | 28 bottom_left(NULL), |
| 29 SkBitmap* BubbleBorder::bottom_arrow_ = NULL; | 29 left_arrow(NULL), |
| 30 SkBitmap* BubbleBorder::left_arrow_ = NULL; | 30 top_arrow(NULL), |
| 31 SkBitmap* BubbleBorder::right_arrow_ = NULL; | 31 right_arrow(NULL), |
| 32 bottom_arrow(NULL) { |
| 33 } |
| 34 |
| 35 SkBitmap* left; |
| 36 SkBitmap* top_left; |
| 37 SkBitmap* top; |
| 38 SkBitmap* top_right; |
| 39 SkBitmap* right; |
| 40 SkBitmap* bottom_right; |
| 41 SkBitmap* bottom; |
| 42 SkBitmap* bottom_left; |
| 43 SkBitmap* left_arrow; |
| 44 SkBitmap* top_arrow; |
| 45 SkBitmap* right_arrow; |
| 46 SkBitmap* bottom_arrow; |
| 47 }; |
| 32 | 48 |
| 33 // static | 49 // static |
| 34 int BubbleBorder::arrow_offset_; | 50 struct BubbleBorder::BorderImages* BubbleBorder::normal_images_ = NULL; |
| 51 struct BubbleBorder::BorderImages* BubbleBorder::shadow_images_ = NULL; |
| 52 |
| 35 | 53 |
| 36 // The height inside the arrow image, in pixels. | 54 // The height inside the arrow image, in pixels. |
| 37 static const int kArrowInteriorHeight = 7; | 55 static const int kArrowInteriorHeight = 7; |
| 38 | 56 |
| 57 BubbleBorder::BubbleBorder(ArrowLocation arrow_location, Shadow shadow) |
| 58 : override_arrow_offset_(0), |
| 59 arrow_location_(arrow_location), |
| 60 alignment_(ALIGN_ARROW_TO_MID_ANCHOR), |
| 61 background_color_(SK_ColorWHITE) { |
| 62 images_ = GetBorderImages(shadow); |
| 63 |
| 64 // Calculate horizontal and vertical insets for arrow by ensuring that |
| 65 // the widest arrow and corner images will have enough room to avoid overlap |
| 66 int offset_x = |
| 67 (std::max(images_->top_arrow->width(), |
| 68 images_->bottom_arrow->width()) / 2) + |
| 69 std::max(std::max(images_->top_left->width(), |
| 70 images_->top_right->width()), |
| 71 std::max(images_->bottom_left->width(), |
| 72 images_->bottom_right->width())); |
| 73 int offset_y = |
| 74 (std::max(images_->left_arrow->height(), |
| 75 images_->right_arrow->height()) / 2) + |
| 76 std::max(std::max(images_->top_left->height(), |
| 77 images_->top_right->height()), |
| 78 std::max(images_->bottom_left->height(), |
| 79 images_->bottom_right->height())); |
| 80 arrow_offset_ = std::max(offset_x, offset_y); |
| 81 } |
| 82 |
| 39 gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to, | 83 gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to, |
| 40 const gfx::Size& contents_size) const { | 84 const gfx::Size& contents_size) const { |
| 41 // Desired size is size of contents enlarged by the size of the border images. | 85 // Desired size is size of contents enlarged by the size of the border images. |
| 42 gfx::Size border_size(contents_size); | 86 gfx::Size border_size(contents_size); |
| 43 gfx::Insets insets; | 87 gfx::Insets insets; |
| 44 GetInsets(&insets); | 88 GetInsets(&insets); |
| 45 border_size.Enlarge(insets.left() + insets.right(), | 89 border_size.Enlarge(insets.left() + insets.right(), |
| 46 insets.top() + insets.bottom()); | 90 insets.top() + insets.bottom()); |
| 47 | 91 |
| 48 // Screen position depends on the arrow location. | 92 // Screen position depends on the arrow location. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 | 162 |
| 119 case FLOAT: | 163 case FLOAT: |
| 120 y += h / 2 - border_size.height() / 2; | 164 y += h / 2 - border_size.height() / 2; |
| 121 break; | 165 break; |
| 122 } | 166 } |
| 123 | 167 |
| 124 return gfx::Rect(x, y, border_size.width(), border_size.height()); | 168 return gfx::Rect(x, y, border_size.width(), border_size.height()); |
| 125 } | 169 } |
| 126 | 170 |
| 127 void BubbleBorder::GetInsets(gfx::Insets* insets) const { | 171 void BubbleBorder::GetInsets(gfx::Insets* insets) const { |
| 128 int top = top_->height(); | 172 int top = images_->top->height(); |
| 129 int bottom = bottom_->height(); | 173 int bottom = images_->bottom->height(); |
| 130 int left = left_->width(); | 174 int left = images_->left->width(); |
| 131 int right = right_->width(); | 175 int right = images_->right->width(); |
| 132 switch (arrow_location_) { | 176 switch (arrow_location_) { |
| 133 case TOP_LEFT: | 177 case TOP_LEFT: |
| 134 case TOP_RIGHT: | 178 case TOP_RIGHT: |
| 135 top = std::max(top, top_arrow_->height()); | 179 top = std::max(top, images_->top_arrow->height()); |
| 136 break; | 180 break; |
| 137 | 181 |
| 138 case BOTTOM_LEFT: | 182 case BOTTOM_LEFT: |
| 139 case BOTTOM_RIGHT: | 183 case BOTTOM_RIGHT: |
| 140 bottom = std::max(bottom, bottom_arrow_->height()); | 184 bottom = std::max(bottom, images_->bottom_arrow->height()); |
| 141 break; | 185 break; |
| 142 | 186 |
| 143 case LEFT_TOP: | 187 case LEFT_TOP: |
| 144 case LEFT_BOTTOM: | 188 case LEFT_BOTTOM: |
| 145 left = std::max(left, left_arrow_->width()); | 189 left = std::max(left, images_->left_arrow->width()); |
| 146 break; | 190 break; |
| 147 | 191 |
| 148 case RIGHT_TOP: | 192 case RIGHT_TOP: |
| 149 case RIGHT_BOTTOM: | 193 case RIGHT_BOTTOM: |
| 150 right = std::max(right, right_arrow_->width()); | 194 right = std::max(right, images_->right_arrow->width()); |
| 151 break; | 195 break; |
| 152 | 196 |
| 153 case NONE: | 197 case NONE: |
| 154 case FLOAT: | 198 case FLOAT: |
| 155 // Nothing to do. | 199 // Nothing to do. |
| 156 break; | 200 break; |
| 157 } | 201 } |
| 158 insets->Set(top, left, bottom, right); | 202 insets->Set(top, left, bottom, right); |
| 159 } | 203 } |
| 160 | 204 |
| 161 int BubbleBorder::SetArrowOffset(int offset, const gfx::Size& contents_size) { | 205 int BubbleBorder::SetArrowOffset(int offset, const gfx::Size& contents_size) { |
| 162 gfx::Size border_size(contents_size); | 206 gfx::Size border_size(contents_size); |
| 163 gfx::Insets insets; | 207 gfx::Insets insets; |
| 164 GetInsets(&insets); | 208 GetInsets(&insets); |
| 165 border_size.Enlarge(insets.left() + insets.right(), | 209 border_size.Enlarge(insets.left() + insets.right(), |
| 166 insets.top() + insets.bottom()); | 210 insets.top() + insets.bottom()); |
| 167 offset = std::max(arrow_offset_, | 211 offset = std::max(arrow_offset_, |
| 168 std::min(offset, (is_arrow_on_horizontal(arrow_location_) ? | 212 std::min(offset, (is_arrow_on_horizontal(arrow_location_) ? |
| 169 border_size.width() : border_size.height()) - arrow_offset_)); | 213 border_size.width() : border_size.height()) - arrow_offset_)); |
| 170 override_arrow_offset_ = offset; | 214 override_arrow_offset_ = offset; |
| 171 return override_arrow_offset_; | 215 return override_arrow_offset_; |
| 172 } | 216 } |
| 173 | 217 |
| 174 // static | 218 // static |
| 175 void BubbleBorder::InitClass() { | 219 BubbleBorder::BorderImages* BubbleBorder::GetBorderImages(Shadow shadow) { |
| 176 static bool initialized = false; | 220 if (shadow == SHADOW && shadow_images_ == NULL) { |
| 177 if (!initialized) { | |
| 178 // Load images. | |
| 179 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 221 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 180 left_ = rb.GetBitmapNamed(IDR_BUBBLE_L); | 222 shadow_images_ = new BorderImages(); |
| 181 top_left_ = rb.GetBitmapNamed(IDR_BUBBLE_TL); | 223 shadow_images_->left = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_L); |
| 182 top_ = rb.GetBitmapNamed(IDR_BUBBLE_T); | 224 shadow_images_->top_left = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_TL); |
| 183 top_right_ = rb.GetBitmapNamed(IDR_BUBBLE_TR); | 225 shadow_images_->top = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_T); |
| 184 right_ = rb.GetBitmapNamed(IDR_BUBBLE_R); | 226 shadow_images_->top_right = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_TR); |
| 185 bottom_right_ = rb.GetBitmapNamed(IDR_BUBBLE_BR); | 227 shadow_images_->right = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_R); |
| 186 bottom_ = rb.GetBitmapNamed(IDR_BUBBLE_B); | 228 shadow_images_->bottom_right = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_BR); |
| 187 bottom_left_ = rb.GetBitmapNamed(IDR_BUBBLE_BL); | 229 shadow_images_->bottom = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_B); |
| 188 left_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_L_ARROW); | 230 shadow_images_->bottom_left = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_BL); |
| 189 top_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_T_ARROW); | 231 shadow_images_->left_arrow = new SkBitmap(); |
| 190 right_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_R_ARROW); | 232 shadow_images_->top_arrow = new SkBitmap(); |
| 191 bottom_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_B_ARROW); | 233 shadow_images_->right_arrow = new SkBitmap(); |
| 192 | 234 shadow_images_->bottom_arrow = new SkBitmap(); |
| 193 // Calculate horizontal and vertical insets for arrow by ensuring that | 235 } else if (shadow == NO_SHADOW && normal_images_ == NULL) { |
| 194 // the widest arrow and corner images will have enough room to avoid overlap | 236 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 195 int offset_x = | 237 normal_images_ = new BorderImages(); |
| 196 (std::max(top_arrow_->width(), bottom_arrow_->width()) / 2) + | 238 normal_images_->left = rb.GetBitmapNamed(IDR_BUBBLE_L); |
| 197 std::max(std::max(top_left_->width(), top_right_->width()), | 239 normal_images_->top_left = rb.GetBitmapNamed(IDR_BUBBLE_TL); |
| 198 std::max(bottom_left_->width(), bottom_right_->width())); | 240 normal_images_->top = rb.GetBitmapNamed(IDR_BUBBLE_T); |
| 199 int offset_y = | 241 normal_images_->top_right = rb.GetBitmapNamed(IDR_BUBBLE_TR); |
| 200 (std::max(left_arrow_->height(), right_arrow_->height()) / 2) + | 242 normal_images_->right = rb.GetBitmapNamed(IDR_BUBBLE_R); |
| 201 std::max(std::max(top_left_->height(), top_right_->height()), | 243 normal_images_->bottom_right = rb.GetBitmapNamed(IDR_BUBBLE_BR); |
| 202 std::max(bottom_left_->height(), bottom_right_->height())); | 244 normal_images_->bottom = rb.GetBitmapNamed(IDR_BUBBLE_B); |
| 203 arrow_offset_ = std::max(offset_x, offset_y); | 245 normal_images_->bottom_left = rb.GetBitmapNamed(IDR_BUBBLE_BL); |
| 204 | 246 normal_images_->left_arrow = rb.GetBitmapNamed(IDR_BUBBLE_L_ARROW); |
| 205 initialized = true; | 247 normal_images_->top_arrow = rb.GetBitmapNamed(IDR_BUBBLE_T_ARROW); |
| 248 normal_images_->right_arrow = rb.GetBitmapNamed(IDR_BUBBLE_R_ARROW); |
| 249 normal_images_->bottom_arrow = rb.GetBitmapNamed(IDR_BUBBLE_B_ARROW); |
| 206 } | 250 } |
| 251 return shadow == SHADOW ? shadow_images_ : normal_images_; |
| 207 } | 252 } |
| 208 | 253 |
| 209 BubbleBorder::~BubbleBorder() {} | 254 BubbleBorder::~BubbleBorder() {} |
| 210 | 255 |
| 211 void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { | 256 void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { |
| 212 // Convenience shorthand variables. | 257 // Convenience shorthand variables. |
| 213 const int tl_width = top_left_->width(); | 258 const int tl_width = images_->top_left->width(); |
| 214 const int tl_height = top_left_->height(); | 259 const int tl_height = images_->top_left->height(); |
| 215 const int t_height = top_->height(); | 260 const int t_height = images_->top->height(); |
| 216 const int tr_width = top_right_->width(); | 261 const int tr_width = images_->top_right->width(); |
| 217 const int tr_height = top_right_->height(); | 262 const int tr_height = images_->top_right->height(); |
| 218 const int l_width = left_->width(); | 263 const int l_width = images_->left->width(); |
| 219 const int r_width = right_->width(); | 264 const int r_width = images_->right->width(); |
| 220 const int br_width = bottom_right_->width(); | 265 const int br_width = images_->bottom_right->width(); |
| 221 const int br_height = bottom_right_->height(); | 266 const int br_height = images_->bottom_right->height(); |
| 222 const int b_height = bottom_->height(); | 267 const int b_height = images_->bottom->height(); |
| 223 const int bl_width = bottom_left_->width(); | 268 const int bl_width = images_->bottom_left->width(); |
| 224 const int bl_height = bottom_left_->height(); | 269 const int bl_height = images_->bottom_left->height(); |
| 225 | 270 |
| 226 gfx::Insets insets; | 271 gfx::Insets insets; |
| 227 GetInsets(&insets); | 272 GetInsets(&insets); |
| 228 const int top = insets.top() - t_height; | 273 const int top = insets.top() - t_height; |
| 229 const int bottom = view.height() - insets.bottom() + b_height; | 274 const int bottom = view.height() - insets.bottom() + b_height; |
| 230 const int left = insets.left() - l_width; | 275 const int left = insets.left() - l_width; |
| 231 const int right = view.width() - insets.right() + r_width; | 276 const int right = view.width() - insets.right() + r_width; |
| 232 const int height = bottom - top; | 277 const int height = bottom - top; |
| 233 const int width = right - left; | 278 const int width = right - left; |
| 234 | 279 |
| 235 // |arrow_offset| is offset of arrow from the begining of the edge. | 280 // |arrow_offset| is offset of arrow from the begining of the edge. |
| 236 int arrow_offset = arrow_offset_; | 281 int arrow_offset = arrow_offset_; |
| 237 if (override_arrow_offset_) | 282 if (override_arrow_offset_) |
| 238 arrow_offset = override_arrow_offset_; | 283 arrow_offset = override_arrow_offset_; |
| 239 else if (is_arrow_on_horizontal(arrow_location_) && | 284 else if (is_arrow_on_horizontal(arrow_location_) && |
| 240 !is_arrow_on_left(arrow_location_)) { | 285 !is_arrow_on_left(arrow_location_)) { |
| 241 arrow_offset = view.width() - arrow_offset - 1; | 286 arrow_offset = view.width() - arrow_offset - 1; |
| 242 } else if (!is_arrow_on_horizontal(arrow_location_) && | 287 } else if (!is_arrow_on_horizontal(arrow_location_) && |
| 243 !is_arrow_on_top(arrow_location_)) { | 288 !is_arrow_on_top(arrow_location_)) { |
| 244 arrow_offset = view.height() - arrow_offset - 1; | 289 arrow_offset = view.height() - arrow_offset - 1; |
| 245 } | 290 } |
| 246 | 291 |
| 247 // Left edge. | 292 // Left edge. |
| 248 if (arrow_location_ == LEFT_TOP || arrow_location_ == LEFT_BOTTOM) { | 293 if (arrow_location_ == LEFT_TOP || arrow_location_ == LEFT_BOTTOM) { |
| 249 int start_y = top + tl_height; | 294 int start_y = top + tl_height; |
| 250 int before_arrow = arrow_offset - start_y - left_arrow_->height() / 2; | 295 int before_arrow = |
| 251 int after_arrow = | 296 arrow_offset - start_y - images_->left_arrow->height() / 2; |
| 252 height - tl_height - bl_height - left_arrow_->height() - before_arrow; | 297 int after_arrow = height - tl_height - bl_height - |
| 298 images_->left_arrow->height() - before_arrow; |
| 299 int tip_y = start_y + before_arrow + images_->left_arrow->height() / 2; |
| 253 DrawArrowInterior(canvas, | 300 DrawArrowInterior(canvas, |
| 254 false, | 301 false, |
| 255 left_arrow_->width() - kArrowInteriorHeight, | 302 images_->left_arrow->width() - kArrowInteriorHeight, |
| 256 start_y + before_arrow + left_arrow_->height() / 2, | 303 tip_y, |
| 257 kArrowInteriorHeight, | 304 kArrowInteriorHeight, |
| 258 left_arrow_->height() / 2 - 1); | 305 images_->left_arrow->height() / 2 - 1); |
| 259 DrawEdgeWithArrow(canvas, | 306 DrawEdgeWithArrow(canvas, |
| 260 false, | 307 false, |
| 261 left_, | 308 images_->left, |
| 262 left_arrow_, | 309 images_->left_arrow, |
| 263 left, | 310 left, |
| 264 start_y, | 311 start_y, |
| 265 before_arrow, | 312 before_arrow, |
| 266 after_arrow, | 313 after_arrow, |
| 267 left_->width() - left_arrow_->width()); | 314 images_->left->width() - images_->left_arrow->width()); |
| 268 } else { | 315 } else { |
| 269 canvas->TileImageInt(*left_, left, top + tl_height, l_width, | 316 canvas->TileImageInt(*images_->left, left, top + tl_height, l_width, |
| 270 height - tl_height - bl_height); | 317 height - tl_height - bl_height); |
| 271 } | 318 } |
| 272 | 319 |
| 273 // Top left corner. | 320 // Top left corner. |
| 274 canvas->DrawBitmapInt(*top_left_, left, top); | 321 canvas->DrawBitmapInt(*images_->top_left, left, top); |
| 275 | 322 |
| 276 // Top edge. | 323 // Top edge. |
| 277 if (arrow_location_ == TOP_LEFT || arrow_location_ == TOP_RIGHT) { | 324 if (arrow_location_ == TOP_LEFT || arrow_location_ == TOP_RIGHT) { |
| 278 int start_x = left + tl_width; | 325 int start_x = left + tl_width; |
| 279 int before_arrow = arrow_offset - start_x - top_arrow_->width() / 2; | 326 int before_arrow = arrow_offset - start_x - images_->top_arrow->width() / 2; |
| 280 int after_arrow = | 327 int after_arrow = width - tl_width - tr_width - |
| 281 width - tl_width - tr_width - top_arrow_->width() - before_arrow; | 328 images_->top_arrow->width() - before_arrow; |
| 282 DrawArrowInterior(canvas, | 329 DrawArrowInterior(canvas, |
| 283 true, | 330 true, |
| 284 start_x + before_arrow + top_arrow_->width() / 2, | 331 start_x + before_arrow + images_->top_arrow->width() / 2, |
| 285 top_arrow_->height() - kArrowInteriorHeight, | 332 images_->top_arrow->height() - kArrowInteriorHeight, |
| 286 1 - top_arrow_->width() / 2, | 333 1 - images_->top_arrow->width() / 2, |
| 287 kArrowInteriorHeight); | 334 kArrowInteriorHeight); |
| 288 DrawEdgeWithArrow(canvas, | 335 DrawEdgeWithArrow(canvas, |
| 289 true, | 336 true, |
| 290 top_, | 337 images_->top, |
| 291 top_arrow_, | 338 images_->top_arrow, |
| 292 start_x, | 339 start_x, |
| 293 top, | 340 top, |
| 294 before_arrow, | 341 before_arrow, |
| 295 after_arrow, | 342 after_arrow, |
| 296 top_->height() - top_arrow_->height()); | 343 images_->top->height() - images_->top_arrow->height()); |
| 297 } else { | 344 } else { |
| 298 canvas->TileImageInt(*top_, left + tl_width, top, | 345 canvas->TileImageInt(*images_->top, left + tl_width, top, |
| 299 width - tl_width - tr_width, t_height); | 346 width - tl_width - tr_width, t_height); |
| 300 } | 347 } |
| 301 | 348 |
| 302 // Top right corner. | 349 // Top right corner. |
| 303 canvas->DrawBitmapInt(*top_right_, right - tr_width, top); | 350 canvas->DrawBitmapInt(*images_->top_right, right - tr_width, top); |
| 304 | 351 |
| 305 // Right edge. | 352 // Right edge. |
| 306 if (arrow_location_ == RIGHT_TOP || arrow_location_ == RIGHT_BOTTOM) { | 353 if (arrow_location_ == RIGHT_TOP || arrow_location_ == RIGHT_BOTTOM) { |
| 307 int start_y = top + tr_height; | 354 int start_y = top + tr_height; |
| 308 int before_arrow = arrow_offset - start_y - right_arrow_->height() / 2; | 355 int before_arrow = |
| 356 arrow_offset - start_y - images_->right_arrow->height() / 2; |
| 309 int after_arrow = height - tl_height - bl_height - | 357 int after_arrow = height - tl_height - bl_height - |
| 310 right_arrow_->height() - before_arrow; | 358 images_->right_arrow->height() - before_arrow; |
| 359 int tip_y = start_y + before_arrow + images_->right_arrow->height() / 2; |
| 311 DrawArrowInterior(canvas, | 360 DrawArrowInterior(canvas, |
| 312 false, | 361 false, |
| 313 right - r_width + kArrowInteriorHeight, | 362 right - r_width + kArrowInteriorHeight, |
| 314 start_y + before_arrow + right_arrow_->height() / 2, | 363 tip_y, |
| 315 -kArrowInteriorHeight, | 364 -kArrowInteriorHeight, |
| 316 right_arrow_->height() / 2 - 1); | 365 images_->right_arrow->height() / 2 - 1); |
| 317 DrawEdgeWithArrow(canvas, | 366 DrawEdgeWithArrow(canvas, |
| 318 false, | 367 false, |
| 319 right_, | 368 images_->right, |
| 320 right_arrow_, | 369 images_->right_arrow, |
| 321 right - r_width, | 370 right - r_width, |
| 322 start_y, | 371 start_y, |
| 323 before_arrow, | 372 before_arrow, |
| 324 after_arrow, | 373 after_arrow, |
| 325 0); | 374 0); |
| 326 } else { | 375 } else { |
| 327 canvas->TileImageInt(*right_, right - r_width, top + tr_height, r_width, | 376 canvas->TileImageInt(*images_->right, right - r_width, top + tr_height, |
| 328 height - tr_height - br_height); | 377 r_width, height - tr_height - br_height); |
| 329 } | 378 } |
| 330 | 379 |
| 331 // Bottom right corner. | 380 // Bottom right corner. |
| 332 canvas->DrawBitmapInt(*bottom_right_, right - br_width, bottom - br_height); | 381 canvas->DrawBitmapInt(*images_->bottom_right, |
| 382 right - br_width, |
| 383 bottom - br_height); |
| 333 | 384 |
| 334 // Bottom edge. | 385 // Bottom edge. |
| 335 if (arrow_location_ == BOTTOM_LEFT || arrow_location_ == BOTTOM_RIGHT) { | 386 if (arrow_location_ == BOTTOM_LEFT || arrow_location_ == BOTTOM_RIGHT) { |
| 336 int start_x = left + bl_width; | 387 int start_x = left + bl_width; |
| 337 int before_arrow = arrow_offset - start_x - bottom_arrow_->width() / 2; | 388 int before_arrow = |
| 338 int after_arrow = | 389 arrow_offset - start_x - images_->bottom_arrow->width() / 2; |
| 339 width - bl_width - br_width - bottom_arrow_->width() - before_arrow; | 390 int after_arrow = width - bl_width - br_width - |
| 391 images_->bottom_arrow->width() - before_arrow; |
| 392 int tip_x = start_x + before_arrow + images_->bottom_arrow->width() / 2; |
| 340 DrawArrowInterior(canvas, | 393 DrawArrowInterior(canvas, |
| 341 true, | 394 true, |
| 342 start_x + before_arrow + bottom_arrow_->width() / 2, | 395 tip_x, |
| 343 bottom - b_height + kArrowInteriorHeight, | 396 bottom - b_height + kArrowInteriorHeight, |
| 344 1 - bottom_arrow_->width() / 2, | 397 1 - images_->bottom_arrow->width() / 2, |
| 345 -kArrowInteriorHeight); | 398 -kArrowInteriorHeight); |
| 346 DrawEdgeWithArrow(canvas, | 399 DrawEdgeWithArrow(canvas, |
| 347 true, | 400 true, |
| 348 bottom_, | 401 images_->bottom, |
| 349 bottom_arrow_, | 402 images_->bottom_arrow, |
| 350 start_x, | 403 start_x, |
| 351 bottom - b_height, | 404 bottom - b_height, |
| 352 before_arrow, | 405 before_arrow, |
| 353 after_arrow, | 406 after_arrow, |
| 354 0); | 407 0); |
| 355 } else { | 408 } else { |
| 356 canvas->TileImageInt(*bottom_, left + bl_width, bottom - b_height, | 409 canvas->TileImageInt(*images_->bottom, left + bl_width, bottom - b_height, |
| 357 width - bl_width - br_width, b_height); | 410 width - bl_width - br_width, b_height); |
| 358 } | 411 } |
| 359 | 412 |
| 360 // Bottom left corner. | 413 // Bottom left corner. |
| 361 canvas->DrawBitmapInt(*bottom_left_, left, bottom - bl_height); | 414 canvas->DrawBitmapInt(*images_->bottom_left, left, bottom - bl_height); |
| 362 } | 415 } |
| 363 | 416 |
| 364 void BubbleBorder::DrawEdgeWithArrow(gfx::Canvas* canvas, | 417 void BubbleBorder::DrawEdgeWithArrow(gfx::Canvas* canvas, |
| 365 bool is_horizontal, | 418 bool is_horizontal, |
| 366 SkBitmap* edge, | 419 SkBitmap* edge, |
| 367 SkBitmap* arrow, | 420 SkBitmap* arrow, |
| 368 int start_x, | 421 int start_x, |
| 369 int start_y, | 422 int start_y, |
| 370 int before_arrow, | 423 int before_arrow, |
| 371 int after_arrow, | 424 int after_arrow, |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 gfx::Rect bounds(view->GetContentsBounds()); | 502 gfx::Rect bounds(view->GetContentsBounds()); |
| 450 SkRect rect; | 503 SkRect rect; |
| 451 rect.set(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()), | 504 rect.set(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()), |
| 452 SkIntToScalar(bounds.right()), SkIntToScalar(bounds.bottom())); | 505 SkIntToScalar(bounds.right()), SkIntToScalar(bounds.bottom())); |
| 453 SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius()); | 506 SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius()); |
| 454 path.addRoundRect(rect, radius, radius); | 507 path.addRoundRect(rect, radius, radius); |
| 455 canvas->GetSkCanvas()->drawPath(path, paint); | 508 canvas->GetSkCanvas()->drawPath(path, paint); |
| 456 } | 509 } |
| 457 | 510 |
| 458 } // namespace views | 511 } // namespace views |
| OLD | NEW |