diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-29 17:27:38 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-29 17:27:38 +0000 |
commit | ea4f850de4781201481cb38a5b7551e0537fb85f (patch) | |
tree | c00508e69b0260b6da0ac12100e14c385abc3ca1 /ui/views/bubble/bubble_border.cc | |
parent | 5933d148b99166968bbd2c1de9be676d143ebf39 (diff) | |
download | chromium_src-ea4f850de4781201481cb38a5b7551e0537fb85f.zip chromium_src-ea4f850de4781201481cb38a5b7551e0537fb85f.tar.gz chromium_src-ea4f850de4781201481cb38a5b7551e0537fb85f.tar.bz2 |
Fix a couple issues of bubble border.
- Make sure bubble has a minimum size to draw correctly;
- Fix drawing artifacts for arrow interiors when background color is not white;
BUG=134666
TEST=Verify launcher bubbles looks correct when docked to left/right.
Review URL: https://chromiumcodereview.appspot.com/10656048
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@144919 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/views/bubble/bubble_border.cc')
-rw-r--r-- | ui/views/bubble/bubble_border.cc | 87 |
1 files changed, 37 insertions, 50 deletions
diff --git a/ui/views/bubble/bubble_border.cc b/ui/views/bubble/bubble_border.cc index 3b4f03d..be2e836 100644 --- a/ui/views/bubble/bubble_border.cc +++ b/ui/views/bubble/bubble_border.cc @@ -89,6 +89,12 @@ gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to, GetInsets(&insets); border_size.Enlarge(insets.width(), insets.height()); + // Ensure the bubble has a minimum size that draws arrows correctly. + if (is_arrow_on_horizontal(arrow_location_)) + border_size.set_width(std::max(border_size.width(), 2 * arrow_offset_)); + else if (has_arrow(arrow_location_)) + border_size.set_height(std::max(border_size.height(), 2 * arrow_offset_)); + // Screen position depends on the arrow location. // The arrow should overlap the target by some amount since there is space // for shadow between arrow tip and image bounds. @@ -302,13 +308,10 @@ void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { arrow_offset - start_y - images_->left_arrow->height() / 2; int after_arrow = height - tl_height - bl_height - images_->left_arrow->height() - before_arrow; - int tip_y = start_y + before_arrow + images_->left_arrow->height() / 2; + // Shift tip coordinates half pixel so that skia draws the tip correctly. DrawArrowInterior(canvas, - false, - images_->left_arrow->width() - kArrowInteriorHeight, - tip_y, - kArrowInteriorHeight, - images_->left_arrow->height() / 2 - 1); + images_->left_arrow->width() - kArrowInteriorHeight - 0.5f, + start_y + before_arrow + images_->left_arrow->height() / 2 - 0.5f); DrawEdgeWithArrow(canvas, false, images_->left, @@ -333,11 +336,8 @@ void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { int after_arrow = width - tl_width - tr_width - images_->top_arrow->width() - before_arrow; DrawArrowInterior(canvas, - true, - start_x + before_arrow + images_->top_arrow->width() / 2, - images_->top_arrow->height() - kArrowInteriorHeight, - 1 - images_->top_arrow->width() / 2, - kArrowInteriorHeight); + start_x + before_arrow + images_->top_arrow->width() / 2, + images_->top_arrow->height() - kArrowInteriorHeight); DrawEdgeWithArrow(canvas, true, images_->top, @@ -362,13 +362,10 @@ void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { arrow_offset - start_y - images_->right_arrow->height() / 2; int after_arrow = height - tl_height - bl_height - images_->right_arrow->height() - before_arrow; - int tip_y = start_y + before_arrow + images_->right_arrow->height() / 2; + // Shift tip coordinates half pixel so that skia draws the tip correctly. DrawArrowInterior(canvas, - false, - right - r_width + kArrowInteriorHeight, - tip_y, - -kArrowInteriorHeight, - images_->right_arrow->height() / 2 - 1); + right - r_width + kArrowInteriorHeight - 0.5f, + start_y + before_arrow + images_->right_arrow->height() / 2 - 0.5f); DrawEdgeWithArrow(canvas, false, images_->right, @@ -395,13 +392,9 @@ void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const { arrow_offset - start_x - images_->bottom_arrow->width() / 2; int after_arrow = width - bl_width - br_width - images_->bottom_arrow->width() - before_arrow; - int tip_x = start_x + before_arrow + images_->bottom_arrow->width() / 2; DrawArrowInterior(canvas, - true, - tip_x, - bottom - b_height + kArrowInteriorHeight, - 1 - images_->bottom_arrow->width() / 2, - -kArrowInteriorHeight); + start_x + before_arrow + images_->bottom_arrow->width() / 2, + bottom - b_height + kArrowInteriorHeight); DrawEdgeWithArrow(canvas, true, images_->bottom, @@ -460,36 +453,30 @@ void BubbleBorder::DrawEdgeWithArrow(gfx::Canvas* canvas, } void BubbleBorder::DrawArrowInterior(gfx::Canvas* canvas, - bool is_horizontal, - int tip_x, - int tip_y, - int shift_x, - int shift_y) const { - /* This function fills the interior of the arrow with background color. - * It draws isosceles triangle under semitransparent arrow tip. - * - * Here's what the parameters mean: - * - * ┌──────── |tip_x| - * ┌─────┐ - * │ ▲ │ ──── |tip y| - * │∙∙∙∙∙│ ┐ - * └─────┘ └─── |shift_x| (offset from tip to vertexes of isosceles triangle) - * └────────── |shift_y| - */ - SkPaint paint; - paint.setStyle(SkPaint::kFill_Style); - paint.setColor(background_color_); + float tip_x, + float tip_y) const { + const int offset_to_next_vertex = + (is_arrow_on_left(arrow_location_) || is_arrow_on_top(arrow_location_)) ? + kArrowInteriorHeight : -kArrowInteriorHeight; + SkPath path; path.incReserve(4); - path.moveTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y)); - path.lineTo(SkIntToScalar(tip_x + shift_x), - SkIntToScalar(tip_y + shift_y)); - if (is_horizontal) - path.lineTo(SkIntToScalar(tip_x - shift_x), SkIntToScalar(tip_y + shift_y)); - else - path.lineTo(SkIntToScalar(tip_x + shift_x), SkIntToScalar(tip_y - shift_y)); + path.moveTo(SkDoubleToScalar(tip_x), SkDoubleToScalar(tip_y)); + path.lineTo(SkDoubleToScalar(tip_x + offset_to_next_vertex), + SkDoubleToScalar(tip_y + offset_to_next_vertex)); + if (is_arrow_on_horizontal(arrow_location_)) { + path.lineTo(SkDoubleToScalar(tip_x - offset_to_next_vertex), + SkDoubleToScalar(tip_y + offset_to_next_vertex)); + } else { + path.lineTo(SkDoubleToScalar(tip_x + offset_to_next_vertex), + SkDoubleToScalar(tip_y - offset_to_next_vertex)); + } path.close(); + + SkPaint paint; + paint.setStyle(SkPaint::kFill_Style); + paint.setColor(background_color_); + canvas->DrawPath(path, paint); } |