| Index: views/bubble/bubble_border.cc
|
| diff --git a/views/bubble/bubble_border.cc b/views/bubble/bubble_border.cc
|
| deleted file mode 100644
|
| index 368b0be0948b0bbba1b74aaf86aded45a8076559..0000000000000000000000000000000000000000
|
| --- a/views/bubble/bubble_border.cc
|
| +++ /dev/null
|
| @@ -1,511 +0,0 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "views/bubble/bubble_border.h"
|
| -
|
| -#include <algorithm> // for std::max
|
| -
|
| -#include "base/logging.h"
|
| -#include "grit/ui_resources.h"
|
| -#include "grit/ui_resources_standard.h"
|
| -#include "third_party/skia/include/core/SkBitmap.h"
|
| -#include "ui/base/resource/resource_bundle.h"
|
| -#include "ui/gfx/canvas_skia.h"
|
| -#include "ui/gfx/path.h"
|
| -
|
| -namespace views {
|
| -
|
| -struct BubbleBorder::BorderImages {
|
| - BorderImages()
|
| - : left(NULL),
|
| - top_left(NULL),
|
| - top(NULL),
|
| - top_right(NULL),
|
| - right(NULL),
|
| - bottom_right(NULL),
|
| - bottom(NULL),
|
| - bottom_left(NULL),
|
| - left_arrow(NULL),
|
| - top_arrow(NULL),
|
| - right_arrow(NULL),
|
| - bottom_arrow(NULL) {
|
| - }
|
| -
|
| - SkBitmap* left;
|
| - SkBitmap* top_left;
|
| - SkBitmap* top;
|
| - SkBitmap* top_right;
|
| - SkBitmap* right;
|
| - SkBitmap* bottom_right;
|
| - SkBitmap* bottom;
|
| - SkBitmap* bottom_left;
|
| - SkBitmap* left_arrow;
|
| - SkBitmap* top_arrow;
|
| - SkBitmap* right_arrow;
|
| - SkBitmap* bottom_arrow;
|
| -};
|
| -
|
| -// static
|
| -struct BubbleBorder::BorderImages* BubbleBorder::normal_images_ = NULL;
|
| -struct BubbleBorder::BorderImages* BubbleBorder::shadow_images_ = NULL;
|
| -
|
| -
|
| -// The height inside the arrow image, in pixels.
|
| -static const int kArrowInteriorHeight = 7;
|
| -
|
| -BubbleBorder::BubbleBorder(ArrowLocation arrow_location, Shadow shadow)
|
| - : override_arrow_offset_(0),
|
| - arrow_location_(arrow_location),
|
| - alignment_(ALIGN_ARROW_TO_MID_ANCHOR),
|
| - background_color_(SK_ColorWHITE) {
|
| - images_ = GetBorderImages(shadow);
|
| -
|
| - // Calculate horizontal and vertical insets for arrow by ensuring that
|
| - // the widest arrow and corner images will have enough room to avoid overlap
|
| - int offset_x =
|
| - (std::max(images_->top_arrow->width(),
|
| - images_->bottom_arrow->width()) / 2) +
|
| - std::max(std::max(images_->top_left->width(),
|
| - images_->top_right->width()),
|
| - std::max(images_->bottom_left->width(),
|
| - images_->bottom_right->width()));
|
| - int offset_y =
|
| - (std::max(images_->left_arrow->height(),
|
| - images_->right_arrow->height()) / 2) +
|
| - std::max(std::max(images_->top_left->height(),
|
| - images_->top_right->height()),
|
| - std::max(images_->bottom_left->height(),
|
| - images_->bottom_right->height()));
|
| - arrow_offset_ = std::max(offset_x, offset_y);
|
| -}
|
| -
|
| -gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to,
|
| - const gfx::Size& contents_size) const {
|
| - // Desired size is size of contents enlarged by the size of the border images.
|
| - gfx::Size border_size(contents_size);
|
| - gfx::Insets insets;
|
| - GetInsets(&insets);
|
| - border_size.Enlarge(insets.left() + insets.right(),
|
| - insets.top() + insets.bottom());
|
| -
|
| - // 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 bitmap bounds.
|
| - const int kArrowOverlap = 3;
|
| - int x = position_relative_to.x();
|
| - int y = position_relative_to.y();
|
| - int w = position_relative_to.width();
|
| - int h = position_relative_to.height();
|
| - int arrow_offset = override_arrow_offset_ ? override_arrow_offset_ :
|
| - arrow_offset_;
|
| -
|
| - // Calculate bubble x coordinate.
|
| - switch (arrow_location_) {
|
| - case TOP_LEFT:
|
| - case BOTTOM_LEFT:
|
| - x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? w / 2 - arrow_offset :
|
| - -kArrowOverlap;
|
| - break;
|
| -
|
| - case TOP_RIGHT:
|
| - case BOTTOM_RIGHT:
|
| - x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ?
|
| - w / 2 + arrow_offset - border_size.width() + 1 :
|
| - w - border_size.width() + kArrowOverlap;
|
| - break;
|
| -
|
| - case LEFT_TOP:
|
| - case LEFT_BOTTOM:
|
| - x += w - kArrowOverlap;
|
| - break;
|
| -
|
| - case RIGHT_TOP:
|
| - case RIGHT_BOTTOM:
|
| - x += kArrowOverlap - border_size.width();
|
| - break;
|
| -
|
| - case NONE:
|
| - case FLOAT:
|
| - x += w / 2 - border_size.width() / 2;
|
| - break;
|
| - }
|
| -
|
| - // Calculate bubble y coordinate.
|
| - switch (arrow_location_) {
|
| - case TOP_LEFT:
|
| - case TOP_RIGHT:
|
| - y += h - kArrowOverlap;
|
| - break;
|
| -
|
| - case BOTTOM_LEFT:
|
| - case BOTTOM_RIGHT:
|
| - y += kArrowOverlap - border_size.height();
|
| - break;
|
| -
|
| - case LEFT_TOP:
|
| - case RIGHT_TOP:
|
| - y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? h / 2 - arrow_offset :
|
| - -kArrowOverlap;
|
| - break;
|
| -
|
| - case LEFT_BOTTOM:
|
| - case RIGHT_BOTTOM:
|
| - y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ?
|
| - h / 2 + arrow_offset - border_size.height() + 1 :
|
| - h - border_size.height() + kArrowOverlap;
|
| - break;
|
| -
|
| - case NONE:
|
| - y += h;
|
| - break;
|
| -
|
| - case FLOAT:
|
| - y += h / 2 - border_size.height() / 2;
|
| - break;
|
| - }
|
| -
|
| - return gfx::Rect(x, y, border_size.width(), border_size.height());
|
| -}
|
| -
|
| -void BubbleBorder::GetInsets(gfx::Insets* insets) const {
|
| - int top = images_->top->height();
|
| - int bottom = images_->bottom->height();
|
| - int left = images_->left->width();
|
| - int right = images_->right->width();
|
| - switch (arrow_location_) {
|
| - case TOP_LEFT:
|
| - case TOP_RIGHT:
|
| - top = std::max(top, images_->top_arrow->height());
|
| - break;
|
| -
|
| - case BOTTOM_LEFT:
|
| - case BOTTOM_RIGHT:
|
| - bottom = std::max(bottom, images_->bottom_arrow->height());
|
| - break;
|
| -
|
| - case LEFT_TOP:
|
| - case LEFT_BOTTOM:
|
| - left = std::max(left, images_->left_arrow->width());
|
| - break;
|
| -
|
| - case RIGHT_TOP:
|
| - case RIGHT_BOTTOM:
|
| - right = std::max(right, images_->right_arrow->width());
|
| - break;
|
| -
|
| - case NONE:
|
| - case FLOAT:
|
| - // Nothing to do.
|
| - break;
|
| - }
|
| - insets->Set(top, left, bottom, right);
|
| -}
|
| -
|
| -int BubbleBorder::SetArrowOffset(int offset, const gfx::Size& contents_size) {
|
| - gfx::Size border_size(contents_size);
|
| - gfx::Insets insets;
|
| - GetInsets(&insets);
|
| - border_size.Enlarge(insets.left() + insets.right(),
|
| - insets.top() + insets.bottom());
|
| - offset = std::max(arrow_offset_,
|
| - std::min(offset, (is_arrow_on_horizontal(arrow_location_) ?
|
| - border_size.width() : border_size.height()) - arrow_offset_));
|
| - override_arrow_offset_ = offset;
|
| - return override_arrow_offset_;
|
| -}
|
| -
|
| -// static
|
| -BubbleBorder::BorderImages* BubbleBorder::GetBorderImages(Shadow shadow) {
|
| - if (shadow == SHADOW && shadow_images_ == NULL) {
|
| - ResourceBundle& rb = ResourceBundle::GetSharedInstance();
|
| - shadow_images_ = new BorderImages();
|
| - shadow_images_->left = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_L);
|
| - shadow_images_->top_left = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_TL);
|
| - shadow_images_->top = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_T);
|
| - shadow_images_->top_right = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_TR);
|
| - shadow_images_->right = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_R);
|
| - shadow_images_->bottom_right = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_BR);
|
| - shadow_images_->bottom = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_B);
|
| - shadow_images_->bottom_left = rb.GetBitmapNamed(IDR_BUBBLE_SHADOW_BL);
|
| - shadow_images_->left_arrow = new SkBitmap();
|
| - shadow_images_->top_arrow = new SkBitmap();
|
| - shadow_images_->right_arrow = new SkBitmap();
|
| - shadow_images_->bottom_arrow = new SkBitmap();
|
| - } else if (shadow == NO_SHADOW && normal_images_ == NULL) {
|
| - ResourceBundle& rb = ResourceBundle::GetSharedInstance();
|
| - normal_images_ = new BorderImages();
|
| - normal_images_->left = rb.GetBitmapNamed(IDR_BUBBLE_L);
|
| - normal_images_->top_left = rb.GetBitmapNamed(IDR_BUBBLE_TL);
|
| - normal_images_->top = rb.GetBitmapNamed(IDR_BUBBLE_T);
|
| - normal_images_->top_right = rb.GetBitmapNamed(IDR_BUBBLE_TR);
|
| - normal_images_->right = rb.GetBitmapNamed(IDR_BUBBLE_R);
|
| - normal_images_->bottom_right = rb.GetBitmapNamed(IDR_BUBBLE_BR);
|
| - normal_images_->bottom = rb.GetBitmapNamed(IDR_BUBBLE_B);
|
| - normal_images_->bottom_left = rb.GetBitmapNamed(IDR_BUBBLE_BL);
|
| - normal_images_->left_arrow = rb.GetBitmapNamed(IDR_BUBBLE_L_ARROW);
|
| - normal_images_->top_arrow = rb.GetBitmapNamed(IDR_BUBBLE_T_ARROW);
|
| - normal_images_->right_arrow = rb.GetBitmapNamed(IDR_BUBBLE_R_ARROW);
|
| - normal_images_->bottom_arrow = rb.GetBitmapNamed(IDR_BUBBLE_B_ARROW);
|
| - }
|
| - return shadow == SHADOW ? shadow_images_ : normal_images_;
|
| -}
|
| -
|
| -BubbleBorder::~BubbleBorder() {}
|
| -
|
| -void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) const {
|
| - // Convenience shorthand variables.
|
| - const int tl_width = images_->top_left->width();
|
| - const int tl_height = images_->top_left->height();
|
| - const int t_height = images_->top->height();
|
| - const int tr_width = images_->top_right->width();
|
| - const int tr_height = images_->top_right->height();
|
| - const int l_width = images_->left->width();
|
| - const int r_width = images_->right->width();
|
| - const int br_width = images_->bottom_right->width();
|
| - const int br_height = images_->bottom_right->height();
|
| - const int b_height = images_->bottom->height();
|
| - const int bl_width = images_->bottom_left->width();
|
| - const int bl_height = images_->bottom_left->height();
|
| -
|
| - gfx::Insets insets;
|
| - GetInsets(&insets);
|
| - const int top = insets.top() - t_height;
|
| - const int bottom = view.height() - insets.bottom() + b_height;
|
| - const int left = insets.left() - l_width;
|
| - const int right = view.width() - insets.right() + r_width;
|
| - const int height = bottom - top;
|
| - const int width = right - left;
|
| -
|
| - // |arrow_offset| is offset of arrow from the begining of the edge.
|
| - int arrow_offset = arrow_offset_;
|
| - if (override_arrow_offset_)
|
| - arrow_offset = override_arrow_offset_;
|
| - else if (is_arrow_on_horizontal(arrow_location_) &&
|
| - !is_arrow_on_left(arrow_location_)) {
|
| - arrow_offset = view.width() - arrow_offset - 1;
|
| - } else if (!is_arrow_on_horizontal(arrow_location_) &&
|
| - !is_arrow_on_top(arrow_location_)) {
|
| - arrow_offset = view.height() - arrow_offset - 1;
|
| - }
|
| -
|
| - // Left edge.
|
| - if (arrow_location_ == LEFT_TOP || arrow_location_ == LEFT_BOTTOM) {
|
| - int start_y = top + tl_height;
|
| - int before_arrow =
|
| - 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;
|
| - DrawArrowInterior(canvas,
|
| - false,
|
| - images_->left_arrow->width() - kArrowInteriorHeight,
|
| - tip_y,
|
| - kArrowInteriorHeight,
|
| - images_->left_arrow->height() / 2 - 1);
|
| - DrawEdgeWithArrow(canvas,
|
| - false,
|
| - images_->left,
|
| - images_->left_arrow,
|
| - left,
|
| - start_y,
|
| - before_arrow,
|
| - after_arrow,
|
| - images_->left->width() - images_->left_arrow->width());
|
| - } else {
|
| - canvas->TileImageInt(*images_->left, left, top + tl_height, l_width,
|
| - height - tl_height - bl_height);
|
| - }
|
| -
|
| - // Top left corner.
|
| - canvas->DrawBitmapInt(*images_->top_left, left, top);
|
| -
|
| - // Top edge.
|
| - if (arrow_location_ == TOP_LEFT || arrow_location_ == TOP_RIGHT) {
|
| - int start_x = left + tl_width;
|
| - int before_arrow = arrow_offset - start_x - images_->top_arrow->width() / 2;
|
| - 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);
|
| - DrawEdgeWithArrow(canvas,
|
| - true,
|
| - images_->top,
|
| - images_->top_arrow,
|
| - start_x,
|
| - top,
|
| - before_arrow,
|
| - after_arrow,
|
| - images_->top->height() - images_->top_arrow->height());
|
| - } else {
|
| - canvas->TileImageInt(*images_->top, left + tl_width, top,
|
| - width - tl_width - tr_width, t_height);
|
| - }
|
| -
|
| - // Top right corner.
|
| - canvas->DrawBitmapInt(*images_->top_right, right - tr_width, top);
|
| -
|
| - // Right edge.
|
| - if (arrow_location_ == RIGHT_TOP || arrow_location_ == RIGHT_BOTTOM) {
|
| - int start_y = top + tr_height;
|
| - int before_arrow =
|
| - 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;
|
| - DrawArrowInterior(canvas,
|
| - false,
|
| - right - r_width + kArrowInteriorHeight,
|
| - tip_y,
|
| - -kArrowInteriorHeight,
|
| - images_->right_arrow->height() / 2 - 1);
|
| - DrawEdgeWithArrow(canvas,
|
| - false,
|
| - images_->right,
|
| - images_->right_arrow,
|
| - right - r_width,
|
| - start_y,
|
| - before_arrow,
|
| - after_arrow,
|
| - 0);
|
| - } else {
|
| - canvas->TileImageInt(*images_->right, right - r_width, top + tr_height,
|
| - r_width, height - tr_height - br_height);
|
| - }
|
| -
|
| - // Bottom right corner.
|
| - canvas->DrawBitmapInt(*images_->bottom_right,
|
| - right - br_width,
|
| - bottom - br_height);
|
| -
|
| - // Bottom edge.
|
| - if (arrow_location_ == BOTTOM_LEFT || arrow_location_ == BOTTOM_RIGHT) {
|
| - int start_x = left + bl_width;
|
| - int before_arrow =
|
| - 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);
|
| - DrawEdgeWithArrow(canvas,
|
| - true,
|
| - images_->bottom,
|
| - images_->bottom_arrow,
|
| - start_x,
|
| - bottom - b_height,
|
| - before_arrow,
|
| - after_arrow,
|
| - 0);
|
| - } else {
|
| - canvas->TileImageInt(*images_->bottom, left + bl_width, bottom - b_height,
|
| - width - bl_width - br_width, b_height);
|
| - }
|
| -
|
| - // Bottom left corner.
|
| - canvas->DrawBitmapInt(*images_->bottom_left, left, bottom - bl_height);
|
| -}
|
| -
|
| -void BubbleBorder::DrawEdgeWithArrow(gfx::Canvas* canvas,
|
| - bool is_horizontal,
|
| - SkBitmap* edge,
|
| - SkBitmap* arrow,
|
| - int start_x,
|
| - int start_y,
|
| - int before_arrow,
|
| - int after_arrow,
|
| - int offset) const {
|
| - /* Here's what the parameters mean:
|
| - * start_x
|
| - * .
|
| - * . ┌───┐ ┬ offset
|
| - * start_y..........┌────┬────────┤ ▲ ├────────┬────┐
|
| - * │ / │--------│∙ ∙│--------│ \ │
|
| - * │ / ├────────┴───┴────────┤ \ │
|
| - * ├───┬┘ └┬───┤
|
| - * └───┬────┘ └───┬────┘
|
| - * before_arrow ─┘ └─ after_arrow
|
| - */
|
| - if (before_arrow) {
|
| - canvas->TileImageInt(*edge, start_x, start_y,
|
| - is_horizontal ? before_arrow : edge->width(),
|
| - is_horizontal ? edge->height() : before_arrow);
|
| - }
|
| -
|
| - canvas->DrawBitmapInt(*arrow,
|
| - start_x + (is_horizontal ? before_arrow : offset),
|
| - start_y + (is_horizontal ? offset : before_arrow));
|
| -
|
| - if (after_arrow) {
|
| - start_x += (is_horizontal ? before_arrow + arrow->width() : 0);
|
| - start_y += (is_horizontal ? 0 : before_arrow + arrow->height());
|
| - canvas->TileImageInt(*edge, start_x, start_y,
|
| - is_horizontal ? after_arrow : edge->width(),
|
| - is_horizontal ? edge->height() : after_arrow);
|
| - }
|
| -}
|
| -
|
| -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_);
|
| - gfx::Path 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.close();
|
| - canvas->GetSkCanvas()->drawPath(path, paint);
|
| -}
|
| -
|
| -/////////////////////////
|
| -
|
| -void BubbleBackground::Paint(gfx::Canvas* canvas, views::View* view) const {
|
| - // The border of this view creates an anti-aliased round-rect region for the
|
| - // contents, which we need to fill with the background color.
|
| - // NOTE: This doesn't handle an arrow location of "NONE", which has square top
|
| - // corners.
|
| - SkPaint paint;
|
| - paint.setAntiAlias(true);
|
| - paint.setStyle(SkPaint::kFill_Style);
|
| - paint.setColor(border_->background_color());
|
| - gfx::Path path;
|
| - gfx::Rect bounds(view->GetContentsBounds());
|
| - SkRect rect;
|
| - rect.set(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()),
|
| - SkIntToScalar(bounds.right()), SkIntToScalar(bounds.bottom()));
|
| - SkScalar radius = SkIntToScalar(BubbleBorder::GetCornerRadius());
|
| - path.addRoundRect(rect, radius, radius);
|
| - canvas->GetSkCanvas()->drawPath(path, paint);
|
| -}
|
| -
|
| -} // namespace views
|
|
|