summaryrefslogtreecommitdiffstats
path: root/ui/views/bubble/bubble_border.cc
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-29 17:27:38 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-29 17:27:38 +0000
commitea4f850de4781201481cb38a5b7551e0537fb85f (patch)
treec00508e69b0260b6da0ac12100e14c385abc3ca1 /ui/views/bubble/bubble_border.cc
parent5933d148b99166968bbd2c1de9be676d143ebf39 (diff)
downloadchromium_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.cc87
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);
}