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/app_list/app_list_bubble_border.h" | 5 #include "ui/views/bubble/bubble_border_geometric.h" |
6 | 6 |
7 #include "third_party/skia/include/core/SkPath.h" | 7 #include <algorithm> // for std::max |
8 #include "third_party/skia/include/core/SkPaint.h" | 8 |
9 #include "third_party/skia/include/effects/SkGradientShader.h" | 9 #include "base/logging.h" |
10 #include "ui/gfx/canvas.h" | 10 #include "ui/gfx/canvas.h" |
11 #include "ui/gfx/path.h" | 11 #include "ui/gfx/path.h" |
12 #include "ui/gfx/rect.h" | |
13 #include "ui/gfx/screen.h" | |
12 #include "ui/gfx/skia_util.h" | 14 #include "ui/gfx/skia_util.h" |
13 | 15 |
14 namespace { | 16 namespace { |
15 | 17 |
16 // Bubble border corner radius. | 18 // Bubble border corner radius. |
17 const int kCornerRadius = 2; | 19 const int kCornerRadius = 2; |
18 | 20 |
19 // Arrow width and height. | 21 // Arrow width and height. |
20 const int kArrowHeight = 10; | 22 const int kArrowHeight = 10; |
21 const int kArrowWidth = 20; | 23 const int kArrowWidth = 20; |
22 | 24 |
23 // Bubble border color and width. | 25 const int kBorderSize = 1; |
24 const SkColor kBorderColor = SkColorSetARGB(0x26, 0, 0, 0); | 26 const SkColor kBorderColor = SkColorSetARGB(0x26, 0, 0, 0); |
25 const int kBorderSize = 1; | 27 const SkColor kBackgroundColor = SK_ColorWHITE; |
26 | 28 |
27 const SkColor kSearchBoxBackground = SK_ColorWHITE; | 29 const gfx::Point kShadowOffset(0, 5); |
msw
2012/08/03 18:08:26
Don't static init objects, use ints kShadowOffsetX
varunjain
2012/08/03 18:22:42
Done.
| |
28 const SkColor kContentsBackground = SkColorSetRGB(0xFC, 0xFC, 0xFC); | 30 const double kShadowBlur = 30; |
29 | 31 const SkColor kShadowColor = SkColorSetARGB(0x72, 0, 0, 0); |
30 // Colors and sizes of top separator between searchbox and grid view. | |
31 const SkColor kTopSeparatorColor = SkColorSetRGB(0xF0, 0xF0, 0xF0); | |
32 const int kTopSeparatorSize = 1; | |
33 | 32 |
34 // Builds a bubble shape for given |bounds|. | 33 // Builds a bubble shape for given |bounds|. |
35 void BuildShape(const gfx::Rect& bounds, | 34 void BuildShape(const gfx::Rect& bounds, |
36 views::BubbleBorder::ArrowLocation arrow_location, | 35 views::BubbleBorder::ArrowLocation arrow_location, |
37 SkScalar arrow_offset, | 36 SkScalar arrow_offset, |
38 SkScalar padding, | 37 SkScalar padding, |
39 SkPath* path) { | 38 SkPath* path, |
40 const SkScalar corner_radius = SkIntToScalar(kCornerRadius); | 39 int corner_radius_int, |
40 int arrow_height_int, | |
41 int arrow_width_int) { | |
42 const SkScalar corner_radius = SkIntToScalar(corner_radius_int); | |
41 | 43 |
42 const SkScalar left = SkIntToScalar(bounds.x()) + padding; | 44 const SkScalar left = SkIntToScalar(bounds.x()) + padding; |
43 const SkScalar top = SkIntToScalar(bounds.y()) + padding; | 45 const SkScalar top = SkIntToScalar(bounds.y()) + padding; |
44 const SkScalar right = SkIntToScalar(bounds.right()) - padding; | 46 const SkScalar right = SkIntToScalar(bounds.right()) - padding; |
45 const SkScalar bottom = SkIntToScalar(bounds.bottom()) - padding; | 47 const SkScalar bottom = SkIntToScalar(bounds.bottom()) - padding; |
46 | 48 |
47 const SkScalar center_x = SkIntToScalar((bounds.x() + bounds.right()) / 2); | 49 const SkScalar center_x = SkIntToScalar((bounds.x() + bounds.right()) / 2); |
48 const SkScalar center_y = SkIntToScalar((bounds.y() + bounds.bottom()) / 2); | 50 const SkScalar center_y = SkIntToScalar((bounds.y() + bounds.bottom()) / 2); |
49 | 51 |
50 const SkScalar half_arrow_width = (SkIntToScalar(kArrowWidth) - padding) / 2; | 52 const SkScalar half_arrow_width = |
51 const SkScalar arrow_height = SkIntToScalar(kArrowHeight) - padding; | 53 (SkIntToScalar(arrow_width_int) - padding) / 2; |
54 const SkScalar arrow_height = SkIntToScalar(arrow_height_int) - padding; | |
52 | 55 |
53 path->reset(); | 56 path->reset(); |
54 path->incReserve(12); | 57 path->incReserve(12); |
55 | 58 |
56 switch (arrow_location) { | 59 switch (arrow_location) { |
57 case views::BubbleBorder::TOP_LEFT: | 60 case views::BubbleBorder::TOP_LEFT: |
58 case views::BubbleBorder::TOP_RIGHT: | 61 case views::BubbleBorder::TOP_RIGHT: |
59 path->moveTo(center_x, bottom); | 62 path->moveTo(center_x, bottom); |
60 path->arcTo(right, bottom, right, center_y, corner_radius); | 63 path->arcTo(right, bottom, right, center_y, corner_radius); |
61 path->arcTo(right, top, center_x - half_arrow_width, top, | 64 path->arcTo(right, top, center_x - half_arrow_width, top, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 corner_radius, | 112 corner_radius, |
110 corner_radius); | 113 corner_radius); |
111 break; | 114 break; |
112 } | 115 } |
113 | 116 |
114 path->close(); | 117 path->close(); |
115 } | 118 } |
116 | 119 |
117 } // namespace | 120 } // namespace |
118 | 121 |
119 namespace app_list { | 122 namespace views { |
120 | 123 |
121 AppListBubbleBorder::AppListBubbleBorder(views::View* app_list_view, | 124 BubbleBorderGeometric::BubbleBorderGeometric(ArrowLocation arrow_location) |
122 views::View* search_box_view) | 125 : BubbleBorder(arrow_location, views::BubbleBorder::NO_SHADOW), |
123 : views::BubbleBorder(views::BubbleBorder::BOTTOM_RIGHT, | 126 corner_radius_(kCornerRadius), |
124 views::BubbleBorder::NO_SHADOW), | 127 border_size_(kBorderSize), |
125 app_list_view_(app_list_view), | 128 arrow_height_(kArrowHeight), |
126 search_box_view_(search_box_view) { | 129 arrow_width_(kArrowWidth), |
127 const gfx::ShadowValue kShadows[] = { | 130 background_color_(kBackgroundColor), |
128 // Offset (0, 5), blur=30, color=0.36 black | 131 border_color_(kBorderColor), |
129 gfx::ShadowValue(gfx::Point(0, 5), 30, SkColorSetARGB(0x72, 0, 0, 0)), | 132 anchor_edge_offset_(0) { |
130 }; | 133 SetShadow(gfx::ShadowValue(kShadowOffset, kShadowBlur, kShadowColor)); |
131 shadows_.assign(kShadows, kShadows + arraysize(kShadows)); | |
132 } | 134 } |
133 | 135 |
134 AppListBubbleBorder::~AppListBubbleBorder() { | 136 BubbleBorderGeometric::~BubbleBorderGeometric() {} |
137 | |
138 gfx::Rect BubbleBorderGeometric::ComputeOffsetAndUpdateBubbleRect( | |
139 gfx::Rect bubble_rect, | |
140 const gfx::Rect& anchor_view_rect) { | |
141 offset_ = gfx::Point(); | |
142 | |
143 gfx::Rect monitor_rect = gfx::Screen::GetDisplayNearestPoint( | |
144 anchor_view_rect.CenterPoint()).bounds(); | |
145 if (monitor_rect.IsEmpty() || monitor_rect.Contains(bubble_rect)) | |
146 return bubble_rect; | |
147 | |
148 gfx::Point offset; | |
149 | |
150 if (has_arrow(arrow_location())) { | |
151 if (is_arrow_on_horizontal(arrow_location())) { | |
152 if (bubble_rect.x() < monitor_rect.x()) | |
153 offset.set_x(monitor_rect.x() - bubble_rect.x()); | |
154 else if (bubble_rect.right() > monitor_rect.right()) | |
155 offset.set_x(monitor_rect.right() - bubble_rect.right()); | |
156 } else { | |
157 if (bubble_rect.y() < monitor_rect.y()) | |
158 offset.set_y(monitor_rect.y() - bubble_rect.y()); | |
159 else if (bubble_rect.bottom() > monitor_rect.bottom()) | |
160 offset.set_y(monitor_rect.bottom() - bubble_rect.bottom()); | |
161 } | |
162 } | |
163 | |
164 bubble_rect.Offset(offset); | |
165 set_offset(offset); | |
166 | |
167 return bubble_rect; | |
135 } | 168 } |
136 | 169 |
137 bool AppListBubbleBorder::ArrowAtTopOrBottom() const { | 170 void BubbleBorderGeometric::GetMask(const gfx::Rect& bounds, |
138 return arrow_location() == views::BubbleBorder::TOP_LEFT || | 171 gfx::Path* mask) const { |
139 arrow_location() == views::BubbleBorder::TOP_RIGHT || | |
140 arrow_location() == views::BubbleBorder::BOTTOM_LEFT || | |
141 arrow_location() == views::BubbleBorder::BOTTOM_RIGHT; | |
142 } | |
143 | |
144 bool AppListBubbleBorder::ArrowOnLeftOrRight() const { | |
145 return arrow_location() == views::BubbleBorder::LEFT_TOP || | |
146 arrow_location() == views::BubbleBorder::LEFT_BOTTOM || | |
147 arrow_location() == views::BubbleBorder::RIGHT_TOP || | |
148 arrow_location() == views::BubbleBorder::RIGHT_BOTTOM; | |
149 } | |
150 | |
151 void AppListBubbleBorder::GetMask(const gfx::Rect& bounds, | |
152 gfx::Path* mask) const { | |
153 gfx::Insets insets; | 172 gfx::Insets insets; |
154 GetInsets(&insets); | 173 GetInsets(&insets); |
155 | 174 |
156 gfx::Rect content_bounds(bounds); | 175 gfx::Rect content_bounds(bounds); |
157 content_bounds.Inset(insets); | 176 content_bounds.Inset(insets); |
158 | 177 |
159 BuildShape(content_bounds, | 178 BuildShape(content_bounds, |
160 arrow_location(), | 179 arrow_location(), |
161 SkIntToScalar(GetArrowOffset()), | 180 SkIntToScalar(GetArrowOffset()), |
162 SkIntToScalar(kBorderSize), | 181 SkIntToScalar(kBorderSize), |
163 mask); | 182 mask, |
183 corner_radius_, | |
184 arrow_height_, | |
185 arrow_width_); | |
164 } | 186 } |
165 | 187 |
166 int AppListBubbleBorder::GetArrowOffset() const { | 188 void BubbleBorderGeometric::SetShadow(gfx::ShadowValue shadow) { |
167 if (ArrowAtTopOrBottom()) { | 189 shadows_.clear(); |
168 // Picks x offset and moves bubble arrow in the opposite direction. | 190 shadows_.push_back(shadow); |
169 // i.e. If bubble bounds is moved to right (positive offset), we need to | 191 } |
170 // move arrow to left so that it points to the same position. | 192 |
171 return -offset_.x(); | 193 int BubbleBorderGeometric::border_thickness() const { |
172 } else if (ArrowOnLeftOrRight()) { | 194 return border_size_; |
173 // Picks y offset and moves bubble arrow in the opposite direction. | 195 } |
174 return -offset_.y(); | 196 |
197 void BubbleBorderGeometric::PaintBackground(gfx::Canvas* canvas, | |
198 const gfx::Rect& bounds) const { | |
199 canvas->FillRect(bounds, background_color_); | |
200 } | |
201 | |
202 int BubbleBorderGeometric::GetArrowOffset() const { | |
203 if (has_arrow(arrow_location())) { | |
204 if (is_arrow_on_horizontal(arrow_location())) { | |
205 // Picks x offset and moves bubble arrow in the opposite direction. | |
206 // i.e. If bubble bounds is moved to right (positive offset), we need to | |
207 // move arrow to left so that it points to the same position. | |
208 return -offset_.x(); | |
209 } else { | |
210 // Picks y offset and moves bubble arrow in the opposite direction. | |
211 return -offset_.y(); | |
212 } | |
175 } | 213 } |
176 | 214 |
177 // Other style does not have an arrow, so return 0. | 215 // Other style does not have an arrow, so return 0. |
178 return 0; | 216 return 0; |
179 } | 217 } |
180 | 218 |
181 void AppListBubbleBorder::PaintBackground(gfx::Canvas* canvas, | 219 void BubbleBorderGeometric::GetInsets(gfx::Insets* insets) const { |
182 const gfx::Rect& bounds) const { | |
183 const gfx::Rect search_box_view_bounds = | |
184 app_list_view_->ConvertRectToWidget(search_box_view_->bounds()); | |
185 gfx::Rect search_box_rect(bounds.x(), | |
186 bounds.y(), | |
187 bounds.width(), | |
188 search_box_view_bounds.bottom() - bounds.y()); | |
189 | |
190 SkPaint paint; | |
191 paint.setStyle(SkPaint::kFill_Style); | |
192 paint.setColor(kSearchBoxBackground); | |
193 canvas->DrawRect(search_box_rect, paint); | |
194 | |
195 gfx::Rect seperator_rect(search_box_rect); | |
196 seperator_rect.set_y(seperator_rect.bottom()); | |
197 seperator_rect.set_height(kTopSeparatorSize); | |
198 canvas->FillRect(seperator_rect, kTopSeparatorColor); | |
199 | |
200 gfx::Rect contents_rect(bounds.x(), | |
201 seperator_rect.bottom(), | |
202 bounds.width(), | |
203 bounds.bottom() - seperator_rect.bottom()); | |
204 | |
205 paint.setColor(kContentsBackground); | |
206 canvas->DrawRect(contents_rect, paint); | |
207 } | |
208 | |
209 void AppListBubbleBorder::GetInsets(gfx::Insets* insets) const { | |
210 // Negate to change from outer margin to inner padding. | 220 // Negate to change from outer margin to inner padding. |
211 gfx::Insets shadow_padding(-gfx::ShadowValue::GetMargin(shadows_)); | 221 gfx::Insets shadow_padding(-gfx::ShadowValue::GetMargin(shadows_)); |
212 | 222 |
213 if (arrow_location() == views::BubbleBorder::TOP_LEFT || | 223 if (arrow_location() == views::BubbleBorder::TOP_LEFT || |
214 arrow_location() == views::BubbleBorder::TOP_RIGHT) { | 224 arrow_location() == views::BubbleBorder::TOP_RIGHT) { |
215 // Arrow at top. | 225 // Arrow at top. |
216 insets->Set(shadow_padding.top() + kArrowHeight, | 226 insets->Set(shadow_padding.top() + arrow_height_, |
217 shadow_padding.left(), | 227 shadow_padding.left(), |
218 shadow_padding.bottom(), | 228 shadow_padding.bottom(), |
219 shadow_padding.right()); | 229 shadow_padding.right()); |
220 } else if (arrow_location() == views::BubbleBorder::BOTTOM_LEFT || | 230 } else if (arrow_location() == views::BubbleBorder::BOTTOM_LEFT || |
221 arrow_location() == views::BubbleBorder::BOTTOM_RIGHT) { | 231 arrow_location() == views::BubbleBorder::BOTTOM_RIGHT) { |
222 // Arrow at bottom. | 232 // Arrow at bottom. |
223 insets->Set(shadow_padding.top(), | 233 insets->Set(shadow_padding.top(), |
224 shadow_padding.left(), | 234 shadow_padding.left(), |
225 shadow_padding.bottom() + kArrowHeight, | 235 shadow_padding.bottom() + arrow_height_, |
226 shadow_padding.right()); | 236 shadow_padding.right()); |
227 } else if (arrow_location() == views::BubbleBorder::LEFT_TOP || | 237 } else if (arrow_location() == views::BubbleBorder::LEFT_TOP || |
228 arrow_location() == views::BubbleBorder::LEFT_BOTTOM) { | 238 arrow_location() == views::BubbleBorder::LEFT_BOTTOM) { |
229 // Arrow on left. | 239 // Arrow on left. |
230 insets->Set(shadow_padding.top(), | 240 insets->Set(shadow_padding.top(), |
231 shadow_padding.left() + kArrowHeight, | 241 shadow_padding.left() + arrow_height_, |
232 shadow_padding.bottom(), | 242 shadow_padding.bottom(), |
233 shadow_padding.right()); | 243 shadow_padding.right()); |
234 } else if (arrow_location() == views::BubbleBorder::RIGHT_TOP || | 244 } else if (arrow_location() == views::BubbleBorder::RIGHT_TOP || |
235 arrow_location() == views::BubbleBorder::RIGHT_BOTTOM) { | 245 arrow_location() == views::BubbleBorder::RIGHT_BOTTOM) { |
236 // Arrow on right. | 246 // Arrow on right. |
237 insets->Set(shadow_padding.top(), | 247 insets->Set(shadow_padding.top(), |
238 shadow_padding.left(), | 248 shadow_padding.left(), |
239 shadow_padding.bottom(), | 249 shadow_padding.bottom(), |
240 shadow_padding.right() + kArrowHeight); | 250 shadow_padding.right() + arrow_height_); |
241 } | 251 } |
242 } | 252 } |
243 | 253 |
244 gfx::Rect AppListBubbleBorder::GetBounds( | 254 gfx::Rect BubbleBorderGeometric::GetBounds( |
245 const gfx::Rect& position_relative_to, | 255 const gfx::Rect& position_relative_to, |
246 const gfx::Size& contents_size) const { | 256 const gfx::Size& contents_size) const { |
247 gfx::Size border_size(contents_size); | 257 gfx::Size border_size(contents_size); |
248 gfx::Insets insets; | 258 gfx::Insets insets; |
249 GetInsets(&insets); | 259 GetInsets(&insets); |
250 border_size.Enlarge(insets.width(), insets.height()); | 260 border_size.Enlarge(insets.width(), insets.height()); |
251 | 261 |
252 // Negate to change from outer margin to inner padding. | 262 // Negate to change from outer margin to inner padding. |
253 gfx::Insets shadow_padding(-gfx::ShadowValue::GetMargin(shadows_)); | 263 gfx::Insets shadow_padding(-gfx::ShadowValue::GetMargin(shadows_)); |
254 | 264 |
(...skipping 12 matching lines...) Expand all Loading... | |
267 int arrow_tip_x = insets.left() + contents_size.width() / 2 + | 277 int arrow_tip_x = insets.left() + contents_size.width() / 2 + |
268 GetArrowOffset(); | 278 GetArrowOffset(); |
269 int arrow_tip_y = insets.top() + contents_size.height() / 2 + | 279 int arrow_tip_y = insets.top() + contents_size.height() / 2 + |
270 GetArrowOffset() + 1; | 280 GetArrowOffset() + 1; |
271 | 281 |
272 if (arrow_location() == views::BubbleBorder::TOP_LEFT || | 282 if (arrow_location() == views::BubbleBorder::TOP_LEFT || |
273 arrow_location() == views::BubbleBorder::TOP_RIGHT) { | 283 arrow_location() == views::BubbleBorder::TOP_RIGHT) { |
274 // Arrow at top. | 284 // Arrow at top. |
275 return gfx::Rect( | 285 return gfx::Rect( |
276 gfx::Point(anchor_center_x - arrow_tip_x, | 286 gfx::Point(anchor_center_x - arrow_tip_x, |
277 position_relative_to.bottom() - shadow_padding.top() - | 287 position_relative_to.bottom() - shadow_padding.top() + |
278 kArrowHeight), | 288 anchor_edge_offset_), |
279 border_size); | 289 border_size); |
280 } else if (arrow_location() == views::BubbleBorder::BOTTOM_LEFT || | 290 } else if (arrow_location() == views::BubbleBorder::BOTTOM_LEFT || |
281 arrow_location() == views::BubbleBorder::BOTTOM_RIGHT) { | 291 arrow_location() == views::BubbleBorder::BOTTOM_RIGHT) { |
282 // Arrow at bottom. | 292 // Arrow at bottom. |
283 return gfx::Rect( | 293 return gfx::Rect( |
284 gfx::Point(anchor_center_x - arrow_tip_x, | 294 gfx::Point(anchor_center_x - arrow_tip_x, |
285 position_relative_to.y() - border_size.height() + | 295 position_relative_to.y() - border_size.height() + |
286 shadow_padding.bottom() + kArrowHeight), | 296 shadow_padding.bottom() - anchor_edge_offset_), |
287 border_size); | 297 border_size); |
288 } else if (arrow_location() == views::BubbleBorder::LEFT_TOP || | 298 } else if (arrow_location() == views::BubbleBorder::LEFT_TOP || |
289 arrow_location() == views::BubbleBorder::LEFT_BOTTOM) { | 299 arrow_location() == views::BubbleBorder::LEFT_BOTTOM) { |
290 // Arrow on left. | 300 // Arrow on left. |
291 return gfx::Rect( | 301 return gfx::Rect( |
292 gfx::Point(position_relative_to.right() - shadow_padding.left() - | 302 gfx::Point(position_relative_to.right() - shadow_padding.left() + |
293 kArrowHeight, | 303 anchor_edge_offset_, |
294 anchor_center_y - arrow_tip_y), | 304 anchor_center_y - arrow_tip_y), |
295 border_size); | 305 border_size); |
296 } else if (arrow_location() == views::BubbleBorder::RIGHT_TOP || | 306 } else if (arrow_location() == views::BubbleBorder::RIGHT_TOP || |
297 arrow_location() == views::BubbleBorder::RIGHT_BOTTOM) { | 307 arrow_location() == views::BubbleBorder::RIGHT_BOTTOM) { |
298 // Arrow on right. | 308 // Arrow on right. |
299 return gfx::Rect( | 309 return gfx::Rect( |
300 gfx::Point(position_relative_to.x() - border_size.width() + | 310 gfx::Point(position_relative_to.x() - border_size.width() + |
301 shadow_padding.right() + kArrowHeight, | 311 shadow_padding.right() - anchor_edge_offset_, |
302 anchor_center_y - arrow_tip_y), | 312 anchor_center_y - arrow_tip_y), |
303 border_size); | 313 border_size); |
304 } | 314 } |
305 | 315 |
306 // No arrow bubble, center align with anchor. | 316 // No arrow bubble, center align with anchor. |
307 return position_relative_to.Center(border_size); | 317 return position_relative_to.Center(border_size); |
308 } | 318 } |
309 | 319 |
310 void AppListBubbleBorder::Paint(const views::View& view, | 320 void BubbleBorderGeometric::GetInsetsForArrowLocation( |
311 gfx::Canvas* canvas) const { | 321 gfx::Insets* insets, |
322 ArrowLocation arrow_loc) const { | |
323 int top = border_size_; | |
324 int bottom = border_size_; | |
325 int left = border_size_; | |
326 int right = border_size_; | |
327 switch (arrow_loc) { | |
328 case TOP_LEFT: | |
329 case TOP_RIGHT: | |
330 top = std::max(top, arrow_height_); | |
331 break; | |
332 | |
333 case BOTTOM_LEFT: | |
334 case BOTTOM_RIGHT: | |
335 bottom = std::max(bottom, arrow_height_); | |
336 break; | |
337 | |
338 case LEFT_TOP: | |
339 case LEFT_BOTTOM: | |
340 left = std::max(left, arrow_height_); | |
341 break; | |
342 | |
343 case RIGHT_TOP: | |
344 case RIGHT_BOTTOM: | |
345 right = std::max(right, arrow_height_); | |
346 break; | |
347 | |
348 case NONE: | |
349 case FLOAT: | |
350 // Nothing to do. | |
351 break; | |
352 } | |
353 insets->Set(top, left, bottom, right); | |
354 } | |
355 | |
356 void BubbleBorderGeometric::Paint(const views::View& view, | |
357 gfx::Canvas* canvas) const { | |
312 gfx::Insets insets; | 358 gfx::Insets insets; |
313 GetInsets(&insets); | 359 GetInsets(&insets); |
314 | 360 |
315 gfx::Rect content_bounds = view.bounds(); | 361 gfx::Rect content_bounds = view.bounds(); |
316 content_bounds.Inset(insets); | 362 content_bounds.Inset(insets); |
317 | 363 |
318 SkPath path; | 364 SkPath path; |
319 // Pads with 0.5 pixel since anti alias is used. | 365 // Pads with 0.5 pixel since anti alias is used. |
320 BuildShape(content_bounds, | 366 BuildShape(content_bounds, |
321 arrow_location(), | 367 arrow_location(), |
322 SkIntToScalar(GetArrowOffset()), | 368 SkIntToScalar(GetArrowOffset()), |
323 SkDoubleToScalar(0.5), | 369 SkDoubleToScalar(0.5), |
324 &path); | 370 &path, |
371 corner_radius_, | |
372 arrow_height_, | |
373 arrow_width_); | |
325 | 374 |
326 // Draw border and shadow. Note fill is needed to generate enough shadow. | 375 // Draw border and shadow. Note fill is needed to generate enough shadow. |
327 SkPaint paint; | 376 SkPaint paint; |
328 paint.setAntiAlias(true); | 377 paint.setAntiAlias(true); |
329 paint.setStyle(SkPaint::kStrokeAndFill_Style); | 378 paint.setStyle(SkPaint::kStrokeAndFill_Style); |
330 paint.setStrokeWidth(SkIntToScalar(kBorderSize)); | 379 paint.setStrokeWidth(SkIntToScalar(border_size_)); |
331 paint.setColor(kBorderColor); | 380 paint.setColor(border_color_); |
332 SkSafeUnref(paint.setLooper(gfx::CreateShadowDrawLooper(shadows_))); | 381 SkSafeUnref(paint.setLooper(gfx::CreateShadowDrawLooper(shadows_))); |
333 canvas->DrawPath(path, paint); | 382 canvas->DrawPath(path, paint); |
334 | 383 |
335 // Pads with kBoprderSize pixels to leave space for border lines. | 384 // Pads with |border_size_| pixels to leave space for border lines. |
336 BuildShape(content_bounds, | 385 BuildShape(content_bounds, |
337 arrow_location(), | 386 arrow_location(), |
338 SkIntToScalar(GetArrowOffset()), | 387 SkIntToScalar(GetArrowOffset()), |
339 SkIntToScalar(kBorderSize), | 388 SkIntToScalar(border_size_), |
340 &path); | 389 &path, |
390 corner_radius_, | |
391 arrow_height_, | |
392 arrow_width_); | |
341 canvas->Save(); | 393 canvas->Save(); |
342 canvas->ClipPath(path); | 394 canvas->ClipPath(path); |
343 | 395 |
344 // Use full bounds so that arrow is also painted. | 396 // Use full bounds so that arrow is also painted. |
345 const gfx::Rect& bounds = view.bounds(); | 397 const gfx::Rect& bounds = view.bounds(); |
346 PaintBackground(canvas, bounds); | 398 PaintBackground(canvas, bounds); |
347 | 399 |
348 canvas->Restore(); | 400 canvas->Restore(); |
349 } | 401 } |
350 | 402 |
351 } // namespace app_list | 403 } // namespace views |
OLD | NEW |