Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: ui/views/bubble/bubble_border.cc

Issue 1633403002: MacViews: Add native drop shadow to dialogs on OSX < 10.10. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/bubble/bubble_border.h" 5 #include "ui/views/bubble/bubble_border.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "third_party/skia/include/core/SkPaint.h" 10 #include "third_party/skia/include/core/SkPaint.h"
11 #include "third_party/skia/include/core/SkPath.h" 11 #include "third_party/skia/include/core/SkPath.h"
12 #include "ui/base/resource/resource_bundle.h" 12 #include "ui/base/resource/resource_bundle.h"
13 #include "ui/gfx/canvas.h" 13 #include "ui/gfx/canvas.h"
14 #include "ui/gfx/geometry/rect.h" 14 #include "ui/gfx/geometry/rect.h"
15 #include "ui/gfx/path.h"
15 #include "ui/gfx/skia_util.h" 16 #include "ui/gfx/skia_util.h"
16 #include "ui/resources/grit/ui_resources.h" 17 #include "ui/resources/grit/ui_resources.h"
17 #include "ui/views/painter.h" 18 #include "ui/views/painter.h"
18 #include "ui/views/resources/grit/views_resources.h" 19 #include "ui/views/resources/grit/views_resources.h"
19 #include "ui/views/view.h" 20 #include "ui/views/view.h"
20 21
21 namespace views { 22 namespace views {
22 23
23 namespace internal { 24 namespace internal {
24 25
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 135
135 } // namespace 136 } // namespace
136 137
137 const int BubbleBorder::kStroke = 1; 138 const int BubbleBorder::kStroke = 1;
138 139
139 BubbleBorder::BubbleBorder(Arrow arrow, Shadow shadow, SkColor color) 140 BubbleBorder::BubbleBorder(Arrow arrow, Shadow shadow, SkColor color)
140 : arrow_(arrow), 141 : arrow_(arrow),
141 arrow_offset_(0), 142 arrow_offset_(0),
142 arrow_paint_type_(PAINT_NORMAL), 143 arrow_paint_type_(PAINT_NORMAL),
143 alignment_(ALIGN_ARROW_TO_MID_ANCHOR), 144 alignment_(ALIGN_ARROW_TO_MID_ANCHOR),
144 shadow_(shadow),
145 background_color_(color), 145 background_color_(color),
146 use_theme_background_color_(false) { 146 use_theme_background_color_(false) {
147 DCHECK(shadow < SHADOW_COUNT); 147 // On Mac, use the NO_ASSETS bubble border. WindowServer on Mac is able to
tapted 2016/01/28 05:59:22 nit: I think we should have the initializer still,
karandeepb 2016/02/04 03:39:27 Done.
148 images_ = GetBorderImages(shadow); 148 // generate drop shadows for dialogs, hence we don't use raster shadows.
149 #if defined(OS_MACOSX)
150 shadow_ = NO_ASSETS;
151 #else
152 shadow_ = shadow;
153 #endif // OS_MACOSX
154 DCHECK(shadow_ < SHADOW_COUNT);
155 images_ = GetBorderImages(shadow_);
149 } 156 }
150 157
151 BubbleBorder::~BubbleBorder() {} 158 BubbleBorder::~BubbleBorder() {}
152 159
153 gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& anchor_rect, 160 gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& anchor_rect,
154 const gfx::Size& contents_size) const { 161 const gfx::Size& contents_size) const {
155 int x = anchor_rect.x(); 162 int x = anchor_rect.x();
156 int y = anchor_rect.y(); 163 int y = anchor_rect.y();
157 int w = anchor_rect.width(); 164 int w = anchor_rect.width();
158 int h = anchor_rect.height(); 165 int h = anchor_rect.height();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 border_size.width() : border_size.height(); 211 border_size.width() : border_size.height();
205 if (is_arrow_at_center(arrow_) && arrow_offset_ == 0) 212 if (is_arrow_at_center(arrow_) && arrow_offset_ == 0)
206 return edge_length / 2; 213 return edge_length / 2;
207 214
208 // Calculate the minimum offset to not overlap arrow and corner images. 215 // Calculate the minimum offset to not overlap arrow and corner images.
209 const int min = images_->border_thickness + (images_->arrow_width / 2); 216 const int min = images_->border_thickness + (images_->arrow_width / 2);
210 // Ensure the returned value will not cause image overlap, if possible. 217 // Ensure the returned value will not cause image overlap, if possible.
211 return std::max(min, std::min(arrow_offset_, edge_length - min)); 218 return std::max(min, std::min(arrow_offset_, edge_length - min));
212 } 219 }
213 220
221 void BubbleBorder::GetArrowMask(const gfx::Rect& view_bounds,
222 gfx::Path* mask) const {
223 if (!has_arrow(arrow_) || arrow_paint_type_ != PAINT_NORMAL)
224 return;
225
226 return GetArrowMaskFromArrowBounds(GetArrowRect(view_bounds), mask);
227 }
228
214 void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) { 229 void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) {
215 gfx::Rect bounds(view.GetContentsBounds()); 230 gfx::Rect bounds(view.GetContentsBounds());
216 bounds.Inset(-GetBorderThickness(), -GetBorderThickness()); 231 bounds.Inset(-GetBorderThickness(), -GetBorderThickness());
217 const gfx::Rect arrow_bounds = GetArrowRect(view.GetLocalBounds()); 232 const gfx::Rect arrow_bounds = GetArrowRect(view.GetLocalBounds());
218 if (arrow_bounds.IsEmpty()) { 233 if (arrow_bounds.IsEmpty()) {
219 if (images_->border_painter) 234 if (images_->border_painter)
220 Painter::PaintPainterAt(canvas, images_->border_painter.get(), bounds); 235 Painter::PaintPainterAt(canvas, images_->border_painter.get(), bounds);
221 return; 236 return;
222 } 237 }
223 if (!images_->border_painter) { 238 if (!images_->border_painter) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 336
322 // With no assets, return the size enclosing the path filled in DrawArrow(). 337 // With no assets, return the size enclosing the path filled in DrawArrow().
323 DCHECK_EQ(2 * images_->arrow_interior_thickness, images_->arrow_width); 338 DCHECK_EQ(2 * images_->arrow_interior_thickness, images_->arrow_width);
324 int width = images_->arrow_width; 339 int width = images_->arrow_width;
325 int height = images_->arrow_interior_thickness; 340 int height = images_->arrow_interior_thickness;
326 if (!is_arrow_on_horizontal(arrow_)) 341 if (!is_arrow_on_horizontal(arrow_))
327 std::swap(width, height); 342 std::swap(width, height);
328 return gfx::Rect(origin, gfx::Size(width, height)); 343 return gfx::Rect(origin, gfx::Size(width, height));
329 } 344 }
330 345
331 void BubbleBorder::DrawArrow(gfx::Canvas* canvas, 346 void BubbleBorder::GetArrowMaskFromArrowBounds(const gfx::Rect& arrow_bounds,
332 const gfx::Rect& arrow_bounds) const { 347 SkPath* mask) const {
333 canvas->DrawImageInt(*GetArrowImage(), arrow_bounds.x(), arrow_bounds.y());
334 const bool horizontal = is_arrow_on_horizontal(arrow_); 348 const bool horizontal = is_arrow_on_horizontal(arrow_);
335 const int thickness = images_->arrow_interior_thickness; 349 const int thickness = images_->arrow_interior_thickness;
336 float tip_x = horizontal ? arrow_bounds.CenterPoint().x() : 350 float tip_x = horizontal ? arrow_bounds.CenterPoint().x() :
337 is_arrow_on_left(arrow_) ? arrow_bounds.right() - thickness : 351 is_arrow_on_left(arrow_) ? arrow_bounds.right() - thickness :
338 arrow_bounds.x() + thickness; 352 arrow_bounds.x() + thickness;
339 float tip_y = !horizontal ? arrow_bounds.CenterPoint().y() + 0.5f : 353 float tip_y = !horizontal ? arrow_bounds.CenterPoint().y() + 0.5f :
340 is_arrow_on_top(arrow_) ? arrow_bounds.bottom() - thickness : 354 is_arrow_on_top(arrow_) ? arrow_bounds.bottom() - thickness :
341 arrow_bounds.y() + thickness; 355 arrow_bounds.y() + thickness;
342 const bool positive_offset = horizontal ? 356 const bool positive_offset = horizontal ?
343 is_arrow_on_top(arrow_) : is_arrow_on_left(arrow_); 357 is_arrow_on_top(arrow_) : is_arrow_on_left(arrow_);
344 const int offset_to_next_vertex = positive_offset ? 358 const int offset_to_next_vertex = positive_offset ?
345 images_->arrow_interior_thickness : -images_->arrow_interior_thickness; 359 images_->arrow_interior_thickness : -images_->arrow_interior_thickness;
346 360
361 mask->incReserve(4);
362 mask->moveTo(SkDoubleToScalar(tip_x), SkDoubleToScalar(tip_y));
363 mask->lineTo(SkDoubleToScalar(tip_x + offset_to_next_vertex),
364 SkDoubleToScalar(tip_y + offset_to_next_vertex));
365 const int multiplier = horizontal ? 1 : -1;
366 mask->lineTo(SkDoubleToScalar(tip_x - multiplier * offset_to_next_vertex),
367 SkDoubleToScalar(tip_y + multiplier * offset_to_next_vertex));
368 mask->close();
369 }
370
371 void BubbleBorder::DrawArrow(gfx::Canvas* canvas,
372 const gfx::Rect& arrow_bounds) const {
373 canvas->DrawImageInt(*GetArrowImage(), arrow_bounds.x(), arrow_bounds.y());
347 SkPath path; 374 SkPath path;
348 path.incReserve(4); 375 GetArrowMaskFromArrowBounds(arrow_bounds, &path);
349 path.moveTo(SkDoubleToScalar(tip_x), SkDoubleToScalar(tip_y));
350 path.lineTo(SkDoubleToScalar(tip_x + offset_to_next_vertex),
351 SkDoubleToScalar(tip_y + offset_to_next_vertex));
352 const int multiplier = horizontal ? 1 : -1;
353 path.lineTo(SkDoubleToScalar(tip_x - multiplier * offset_to_next_vertex),
354 SkDoubleToScalar(tip_y + multiplier * offset_to_next_vertex));
355 path.close();
356
357 SkPaint paint; 376 SkPaint paint;
358 paint.setStyle(SkPaint::kFill_Style); 377 paint.setStyle(SkPaint::kFill_Style);
359 paint.setColor(background_color_); 378 paint.setColor(background_color_);
360 379
361 canvas->DrawPath(path, paint); 380 canvas->DrawPath(path, paint);
362 } 381 }
363 382
364 internal::BorderImages* BubbleBorder::GetImagesForTest() const { 383 internal::BorderImages* BubbleBorder::GetImagesForTest() const {
365 return images_; 384 return images_;
366 } 385 }
367 386
368 void BubbleBackground::Paint(gfx::Canvas* canvas, views::View* view) const { 387 void BubbleBackground::Paint(gfx::Canvas* canvas, views::View* view) const {
369 if (border_->shadow() == BubbleBorder::NO_SHADOW_OPAQUE_BORDER) 388 if (border_->shadow() == BubbleBorder::NO_SHADOW_OPAQUE_BORDER)
370 canvas->DrawColor(border_->background_color()); 389 canvas->DrawColor(border_->background_color());
371 390
372 // Fill the contents with a round-rect region to match the border images. 391 // Fill the contents with a round-rect region to match the border images.
373 SkPaint paint; 392 SkPaint paint;
374 paint.setAntiAlias(true); 393 paint.setAntiAlias(true);
375 paint.setStyle(SkPaint::kFill_Style); 394 paint.setStyle(SkPaint::kFill_Style);
376 paint.setColor(border_->background_color()); 395 paint.setColor(border_->background_color());
377 SkPath path; 396 SkPath path;
378 gfx::Rect bounds(view->GetLocalBounds()); 397 gfx::Rect bounds(view->GetLocalBounds());
379 bounds.Inset(border_->GetInsets()); 398 bounds.Inset(border_->GetInsets());
380 399
381 canvas->DrawRoundRect(bounds, border_->GetBorderCornerRadius(), paint); 400 canvas->DrawRoundRect(bounds, border_->GetBorderCornerRadius(), paint);
382 } 401 }
383 402
384 } // namespace views 403 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698