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