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

Unified Diff: chrome/browser/views/bubble_border.cc

Issue 195099: Convert InfoBubble to using BubbleBorder. This also replaces the border grap... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/views/bubble_border.h ('k') | chrome/browser/views/info_bubble.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/views/bubble_border.cc
===================================================================
--- chrome/browser/views/bubble_border.cc (revision 26373)
+++ chrome/browser/views/bubble_border.cc (working copy)
@@ -20,7 +20,15 @@
SkBitmap* BubbleBorder::bottom_right_ = NULL;
SkBitmap* BubbleBorder::bottom_ = NULL;
SkBitmap* BubbleBorder::bottom_left_ = NULL;
+SkBitmap* BubbleBorder::top_arrow_ = NULL;
+SkBitmap* BubbleBorder::bottom_arrow_ = NULL;
+//static
+int BubbleBorder::arrow_x_offset_;
+
+// The height inside the arrow image, in pixels.
+static const int kArrowInteriorHeight = 7;
+
gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to,
const gfx::Size& contents_size) const {
// The spacing (in pixels) between |position_relative_to| and the bubble
@@ -34,16 +42,35 @@
border_size.Enlarge(insets.left() + insets.right(),
insets.top() + insets.bottom());
- int x = position_relative_to.x() + (position_relative_to.width() / 2) -
- (contents_size.width() / 2) - insets.left();
- int y = position_relative_to.bottom() - (top_->height() - kBubbleSpacing);
+ // Screen position depends on the arrow location.
+ int x = position_relative_to.x() + (position_relative_to.width() / 2);
+ if (arrow_is_left())
+ x -= arrow_x_offset_;
+ else if (arrow_location_ == NONE)
+ x -= ((contents_size.width() / 2) + insets.left());
+ else
+ x += (arrow_x_offset_ - border_size.width() + 1);
+ int y = position_relative_to.y();
+ if (arrow_is_top()) {
+ y += (position_relative_to.height() -
+ (top_arrow_->height() - kBubbleSpacing));
+ } else if (arrow_location_ == NONE) {
+ y += (position_relative_to.height() - (top_->height() - kBubbleSpacing));
+ } else {
+ y += ((bottom_arrow_->height() - kBubbleSpacing) - border_size.height());
+ }
return gfx::Rect(x, y, border_size.width(), border_size.height());
}
void BubbleBorder::GetInsets(gfx::Insets* insets) const {
- insets->Set(top_->height(), left_->width(), bottom_->height(),
- right_->width());
+ int top = top_->height();
+ int bottom = bottom_->height();
+ if (arrow_is_top())
+ top = std::max(top, top_arrow_->height());
+ else if (arrow_location_ != NONE)
+ bottom = std::max(bottom, bottom_arrow_->height());
+ insets->Set(top, left_->width(), bottom, right_->width());
}
// static
@@ -60,7 +87,16 @@
bottom_right_ = rb.GetBitmapNamed(IDR_BUBBLE_BR);
bottom_ = rb.GetBitmapNamed(IDR_BUBBLE_B);
bottom_left_ = rb.GetBitmapNamed(IDR_BUBBLE_BL);
+ top_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_T_ARROW);
+ bottom_arrow_ = rb.GetBitmapNamed(IDR_BUBBLE_B_ARROW);
+ // Calculate horizontal inset for arrow by ensuring that the widest arrow
+ // and corner images will have enough room to avoid overlap.
+ arrow_x_offset_ =
+ (std::max(top_arrow_->width(), bottom_arrow_->width()) / 2) +
+ std::max(std::max(top_left_->width(), top_right_->width()),
+ std::max(bottom_left_->width(), bottom_right_->width()));
+
initialized = true;
}
}
@@ -82,17 +118,21 @@
/* The variables below can be confusing; here's what they mean:
*
- * border_top∙∙∙∙∙∙∙┌────┬────────┬────┐
- * │ / │--------│ \ │
- * top∙∙∙∙∙∙∙∙∙∙∙∙∙∙│ / ├────────┤ \ │
- * tl_bottom∙∙∙∙∙∙├───┬┘ └┬───┤∙∙∙∙∙∙tr_bottom
- * │ | │ │ | │
- * │ | │ │ | │
- * │ | │ │ | │
- * bl_y∙∙∙∙∙∙∙∙∙∙∙├───┴┐ ┌┴───┤∙∙∙∙∙∙br_y
- * bottom∙∙∙∙∙∙∙∙∙∙∙│ \ ├────────┤ / │
- * │ \ │--------│ / │
- * border_bottom∙∙∙∙└────┴────────┴────┘
+ * 0∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙┌───┐ ┌───┐
+ * border_top∙∙∙∙∙∙∙┌────┬─┤ ▲ ├──────┤ ▲ ├─┬────┐
+ * │ / │-│∙ ∙│------│∙ ∙│-│ \ │
+ * top∙∙∙∙∙∙∙∙∙∙∙∙∙∙│ / ├─┴───┴──────┴───┴─┤ \ │
+ * tl_bottom∙∙∙∙∙∙├───┬┘ └┬───┤∙∙∙∙∙∙tr_bottom
+ * │ | │ │ | │
+ * │ | │ │ | │
+ * │ | │ │ | │
+ * bl_y∙∙∙∙∙∙∙∙∙∙∙├───┴┐ ┌┴───┤∙∙∙∙∙∙br_y
+ * bottom∙∙∙∙∙∙∙∙∙∙∙│ \ ├─┬───┬──────┬───┬─┤ / │
+ * │ \ │-│. .│------│. .│-│ / │
+ * border_bottom∙∙∙∙└────┴─┤ ▼ ├──────┤ ▼ ├─┴────┘
+ * view.height()∙∙∙∙∙∙∙∙∙∙∙└───┘ └───┘
+ *
+ * (At most one of the arrows will be drawn)
*/
gfx::Insets insets;
@@ -109,10 +149,6 @@
// Top left corner
canvas->DrawBitmapInt(*top_left_, 0, border_top);
- // Top edge
- canvas->TileImageInt(*top_, tl_width, border_top, width - tl_width - tr_width,
- t_height);
-
// Top right corner
canvas->DrawBitmapInt(*top_right_, width - tr_width, border_top);
@@ -123,13 +159,109 @@
// Bottom right corner
canvas->DrawBitmapInt(*bottom_right_, width - br_width, br_y);
- // Bottom edge
- canvas->TileImageInt(*bottom_, bl_width, bottom, width - bl_width - br_width,
- b_height);
// Bottom left corner
canvas->DrawBitmapInt(*bottom_left_, 0, bl_y);
// Left edge
canvas->TileImageInt(*left_, 0, tl_bottom, left_->width(), bl_y - tl_bottom);
+
+ // Arrow edge, if necessary
+ bool should_draw_top_edge = true;
+ bool should_draw_bottom_edge = true;
+ if (arrow_location_ != NONE) {
+ /* Here's what the variables below mean (without loss of generality):
+ *
+ * arrow_center
+ * arrow_x │ arrow_r
+ * │ │ │
+ * left_of_edge─┬────┐ │ │ │ ┌────┬─right_of_edge
+ * arrow_y∙∙∙∙∙∙∙∙∙∙∙∙∙∙∙┌───┐
+ * edge_y∙∙∙∙∙∙∙┌────┬───┤ ▲ ├───────┬────┐ ┐
+ * │ / │---│∙ ∙│-------│ \ │ ├─e_height
+ * │ / ├───┴───┴───────┤ \ │ ┘
+ * ├───┬┘ └┬───┤
+ * | | └─┬─┘ | |
+ * ∙ ∙└─┬─┘ │ └───┬───┘∙ ∙
+ * left_of_arrow─┘ │ └─right_of_arrow
+ * arrow_width
+ *
+ * Not shown: border_y and tip_y contain the base and tip coordinates inside
+ * the arrow for use filling the arrow interior with the background color.
+ */
+
+ SkBitmap* edge;
+ SkBitmap* arrow;
+ int left_of_edge, right_of_edge, edge_y, arrow_y;
+ SkScalar border_y, tip_y;
+ if (arrow_is_top()) {
+ should_draw_top_edge = false;
+ edge = top_;
+ arrow = top_arrow_;
+ left_of_edge = tl_width;
+ right_of_edge = tr_width;
+ edge_y = border_top;
+ arrow_y = top - top_arrow_->height();
+ border_y = SkIntToScalar(top);
+ tip_y = SkIntToScalar(top - kArrowInteriorHeight);
+ } else {
+ should_draw_bottom_edge = false;
+ edge = bottom_;
+ arrow = bottom_arrow_;
+ left_of_edge = bl_width;
+ right_of_edge = br_width;
+ edge_y = arrow_y = bottom;
+ border_y = SkIntToScalar(bottom);
+ tip_y = SkIntToScalar(bottom + kArrowInteriorHeight);
+ }
+ int arrow_width = (arrow_is_top() ? top_arrow_ : bottom_arrow_)->width();
+ int arrow_center = arrow_is_left() ?
+ arrow_x_offset_ : width - arrow_x_offset_ - 1;
+ int arrow_x = arrow_center - (arrow_width / 2);
+ SkScalar arrow_interior_x =
+ SkIntToScalar(arrow_center - kArrowInteriorHeight);
+ SkScalar arrow_interior_r =
+ SkIntToScalar(arrow_center + kArrowInteriorHeight);
+ int arrow_r = arrow_x + arrow_width;
+ int e_height = edge->height();
+
+ // Edge to the left of the arrow
+ int left_of_arrow = arrow_x - left_of_edge;
+ if (left_of_arrow) {
+ canvas->TileImageInt(*edge, left_of_edge, edge_y, left_of_arrow,
+ e_height);
+ }
+
+ // Interior of the arrow (filled with background color)
+ SkPaint paint;
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setColor(background_color_);
+ gfx::Path path;
+ path.incReserve(4);
+ path.moveTo(arrow_interior_x, border_y);
+ path.lineTo(SkIntToScalar(arrow_center), tip_y);
+ path.lineTo(arrow_interior_r, border_y);
+ path.close();
+ canvas->drawPath(path, paint);
+
+ // Arrow border
+ canvas->DrawBitmapInt(*arrow, arrow_x, arrow_y);
+
+ // Edge to the right of the arrow
+ int right_of_arrow = width - arrow_r - right_of_edge;
+ if (right_of_arrow)
+ canvas->TileImageInt(*edge, arrow_r, edge_y, right_of_arrow, e_height);
+ }
+
+ // Top edge, if not already drawn
+ if (should_draw_top_edge) {
+ canvas->TileImageInt(*top_, tl_width, border_top,
+ width - tl_width - tr_width, t_height);
+ }
+
+ // Bottom edge, if not already drawn
+ if (should_draw_bottom_edge) {
+ canvas->TileImageInt(*bottom_, bl_width, bottom,
+ width - bl_width - br_width, b_height);
+ }
}
« no previous file with comments | « chrome/browser/views/bubble_border.h ('k') | chrome/browser/views/info_bubble.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698