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 |