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

Unified Diff: ui/views/bubble/bubble_border_geometric.cc

Issue 10834140: aura: Fix launcher tooltips: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: patch Created 8 years, 4 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
Index: ui/views/bubble/bubble_border_geometric.cc
diff --git a/ui/app_list/app_list_bubble_border.cc b/ui/views/bubble/bubble_border_geometric.cc
similarity index 62%
copy from ui/app_list/app_list_bubble_border.cc
copy to ui/views/bubble/bubble_border_geometric.cc
index 3af0263fd7930e4ff4e51acaf80323dc153b5886..fc8fe03927e32eb7a75dab5b97c3e39d3e7197ff 100644
--- a/ui/app_list/app_list_bubble_border.cc
+++ b/ui/views/bubble/bubble_border_geometric.cc
@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/app_list/app_list_bubble_border.h"
+#include "ui/views/bubble/bubble_border_geometric.h"
-#include "third_party/skia/include/core/SkPath.h"
-#include "third_party/skia/include/core/SkPaint.h"
-#include "third_party/skia/include/effects/SkGradientShader.h"
+#include <algorithm> // for std::max
+
+#include "base/logging.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/path.h"
+#include "ui/gfx/rect.h"
+#include "ui/gfx/screen.h"
#include "ui/gfx/skia_util.h"
namespace {
@@ -20,24 +22,24 @@ const int kCornerRadius = 2;
const int kArrowHeight = 10;
const int kArrowWidth = 20;
-// Bubble border color and width.
-const SkColor kBorderColor = SkColorSetARGB(0x26, 0, 0, 0);
const int kBorderSize = 1;
+const SkColor kBorderColor = SkColorSetARGB(0x26, 0, 0, 0);
+const SkColor kBackgroundColor = SK_ColorWHITE;
-const SkColor kSearchBoxBackground = SK_ColorWHITE;
-const SkColor kContentsBackground = SkColorSetRGB(0xFC, 0xFC, 0xFC);
-
-// Colors and sizes of top separator between searchbox and grid view.
-const SkColor kTopSeparatorColor = SkColorSetRGB(0xF0, 0xF0, 0xF0);
-const int kTopSeparatorSize = 1;
+const gfx::Point kShadowOffset(0, 5);
msw 2012/08/03 18:08:26 Don't static init objects, use ints kShadowOffsetX
varunjain 2012/08/03 18:22:42 Done.
+const double kShadowBlur = 30;
+const SkColor kShadowColor = SkColorSetARGB(0x72, 0, 0, 0);
// Builds a bubble shape for given |bounds|.
void BuildShape(const gfx::Rect& bounds,
views::BubbleBorder::ArrowLocation arrow_location,
SkScalar arrow_offset,
SkScalar padding,
- SkPath* path) {
- const SkScalar corner_radius = SkIntToScalar(kCornerRadius);
+ SkPath* path,
+ int corner_radius_int,
+ int arrow_height_int,
+ int arrow_width_int) {
+ const SkScalar corner_radius = SkIntToScalar(corner_radius_int);
const SkScalar left = SkIntToScalar(bounds.x()) + padding;
const SkScalar top = SkIntToScalar(bounds.y()) + padding;
@@ -47,8 +49,9 @@ void BuildShape(const gfx::Rect& bounds,
const SkScalar center_x = SkIntToScalar((bounds.x() + bounds.right()) / 2);
const SkScalar center_y = SkIntToScalar((bounds.y() + bounds.bottom()) / 2);
- const SkScalar half_arrow_width = (SkIntToScalar(kArrowWidth) - padding) / 2;
- const SkScalar arrow_height = SkIntToScalar(kArrowHeight) - padding;
+ const SkScalar half_arrow_width =
+ (SkIntToScalar(arrow_width_int) - padding) / 2;
+ const SkScalar arrow_height = SkIntToScalar(arrow_height_int) - padding;
path->reset();
path->incReserve(12);
@@ -116,40 +119,56 @@ void BuildShape(const gfx::Rect& bounds,
} // namespace
-namespace app_list {
-
-AppListBubbleBorder::AppListBubbleBorder(views::View* app_list_view,
- views::View* search_box_view)
- : views::BubbleBorder(views::BubbleBorder::BOTTOM_RIGHT,
- views::BubbleBorder::NO_SHADOW),
- app_list_view_(app_list_view),
- search_box_view_(search_box_view) {
- const gfx::ShadowValue kShadows[] = {
- // Offset (0, 5), blur=30, color=0.36 black
- gfx::ShadowValue(gfx::Point(0, 5), 30, SkColorSetARGB(0x72, 0, 0, 0)),
- };
- shadows_.assign(kShadows, kShadows + arraysize(kShadows));
+namespace views {
+
+BubbleBorderGeometric::BubbleBorderGeometric(ArrowLocation arrow_location)
+ : BubbleBorder(arrow_location, views::BubbleBorder::NO_SHADOW),
+ corner_radius_(kCornerRadius),
+ border_size_(kBorderSize),
+ arrow_height_(kArrowHeight),
+ arrow_width_(kArrowWidth),
+ background_color_(kBackgroundColor),
+ border_color_(kBorderColor),
+ anchor_edge_offset_(0) {
+ SetShadow(gfx::ShadowValue(kShadowOffset, kShadowBlur, kShadowColor));
}
-AppListBubbleBorder::~AppListBubbleBorder() {
-}
+BubbleBorderGeometric::~BubbleBorderGeometric() {}
+
+gfx::Rect BubbleBorderGeometric::ComputeOffsetAndUpdateBubbleRect(
+ gfx::Rect bubble_rect,
+ const gfx::Rect& anchor_view_rect) {
+ offset_ = gfx::Point();
+
+ gfx::Rect monitor_rect = gfx::Screen::GetDisplayNearestPoint(
+ anchor_view_rect.CenterPoint()).bounds();
+ if (monitor_rect.IsEmpty() || monitor_rect.Contains(bubble_rect))
+ return bubble_rect;
+
+ gfx::Point offset;
+
+ if (has_arrow(arrow_location())) {
+ if (is_arrow_on_horizontal(arrow_location())) {
+ if (bubble_rect.x() < monitor_rect.x())
+ offset.set_x(monitor_rect.x() - bubble_rect.x());
+ else if (bubble_rect.right() > monitor_rect.right())
+ offset.set_x(monitor_rect.right() - bubble_rect.right());
+ } else {
+ if (bubble_rect.y() < monitor_rect.y())
+ offset.set_y(monitor_rect.y() - bubble_rect.y());
+ else if (bubble_rect.bottom() > monitor_rect.bottom())
+ offset.set_y(monitor_rect.bottom() - bubble_rect.bottom());
+ }
+ }
-bool AppListBubbleBorder::ArrowAtTopOrBottom() const {
- return arrow_location() == views::BubbleBorder::TOP_LEFT ||
- arrow_location() == views::BubbleBorder::TOP_RIGHT ||
- arrow_location() == views::BubbleBorder::BOTTOM_LEFT ||
- arrow_location() == views::BubbleBorder::BOTTOM_RIGHT;
-}
+ bubble_rect.Offset(offset);
+ set_offset(offset);
-bool AppListBubbleBorder::ArrowOnLeftOrRight() const {
- return arrow_location() == views::BubbleBorder::LEFT_TOP ||
- arrow_location() == views::BubbleBorder::LEFT_BOTTOM ||
- arrow_location() == views::BubbleBorder::RIGHT_TOP ||
- arrow_location() == views::BubbleBorder::RIGHT_BOTTOM;
+ return bubble_rect;
}
-void AppListBubbleBorder::GetMask(const gfx::Rect& bounds,
- gfx::Path* mask) const {
+void BubbleBorderGeometric::GetMask(const gfx::Rect& bounds,
+ gfx::Path* mask) const {
gfx::Insets insets;
GetInsets(&insets);
@@ -160,60 +179,51 @@ void AppListBubbleBorder::GetMask(const gfx::Rect& bounds,
arrow_location(),
SkIntToScalar(GetArrowOffset()),
SkIntToScalar(kBorderSize),
- mask);
+ mask,
+ corner_radius_,
+ arrow_height_,
+ arrow_width_);
}
-int AppListBubbleBorder::GetArrowOffset() const {
- if (ArrowAtTopOrBottom()) {
- // Picks x offset and moves bubble arrow in the opposite direction.
- // i.e. If bubble bounds is moved to right (positive offset), we need to
- // move arrow to left so that it points to the same position.
- return -offset_.x();
- } else if (ArrowOnLeftOrRight()) {
- // Picks y offset and moves bubble arrow in the opposite direction.
- return -offset_.y();
- }
+void BubbleBorderGeometric::SetShadow(gfx::ShadowValue shadow) {
+ shadows_.clear();
+ shadows_.push_back(shadow);
+}
- // Other style does not have an arrow, so return 0.
- return 0;
+int BubbleBorderGeometric::border_thickness() const {
+ return border_size_;
}
-void AppListBubbleBorder::PaintBackground(gfx::Canvas* canvas,
- const gfx::Rect& bounds) const {
- const gfx::Rect search_box_view_bounds =
- app_list_view_->ConvertRectToWidget(search_box_view_->bounds());
- gfx::Rect search_box_rect(bounds.x(),
- bounds.y(),
- bounds.width(),
- search_box_view_bounds.bottom() - bounds.y());
+void BubbleBorderGeometric::PaintBackground(gfx::Canvas* canvas,
+ const gfx::Rect& bounds) const {
+ canvas->FillRect(bounds, background_color_);
+}
- SkPaint paint;
- paint.setStyle(SkPaint::kFill_Style);
- paint.setColor(kSearchBoxBackground);
- canvas->DrawRect(search_box_rect, paint);
-
- gfx::Rect seperator_rect(search_box_rect);
- seperator_rect.set_y(seperator_rect.bottom());
- seperator_rect.set_height(kTopSeparatorSize);
- canvas->FillRect(seperator_rect, kTopSeparatorColor);
-
- gfx::Rect contents_rect(bounds.x(),
- seperator_rect.bottom(),
- bounds.width(),
- bounds.bottom() - seperator_rect.bottom());
-
- paint.setColor(kContentsBackground);
- canvas->DrawRect(contents_rect, paint);
+int BubbleBorderGeometric::GetArrowOffset() const {
+ if (has_arrow(arrow_location())) {
+ if (is_arrow_on_horizontal(arrow_location())) {
+ // Picks x offset and moves bubble arrow in the opposite direction.
+ // i.e. If bubble bounds is moved to right (positive offset), we need to
+ // move arrow to left so that it points to the same position.
+ return -offset_.x();
+ } else {
+ // Picks y offset and moves bubble arrow in the opposite direction.
+ return -offset_.y();
+ }
+ }
+
+ // Other style does not have an arrow, so return 0.
+ return 0;
}
-void AppListBubbleBorder::GetInsets(gfx::Insets* insets) const {
+void BubbleBorderGeometric::GetInsets(gfx::Insets* insets) const {
// Negate to change from outer margin to inner padding.
gfx::Insets shadow_padding(-gfx::ShadowValue::GetMargin(shadows_));
if (arrow_location() == views::BubbleBorder::TOP_LEFT ||
arrow_location() == views::BubbleBorder::TOP_RIGHT) {
// Arrow at top.
- insets->Set(shadow_padding.top() + kArrowHeight,
+ insets->Set(shadow_padding.top() + arrow_height_,
shadow_padding.left(),
shadow_padding.bottom(),
shadow_padding.right());
@@ -222,13 +232,13 @@ void AppListBubbleBorder::GetInsets(gfx::Insets* insets) const {
// Arrow at bottom.
insets->Set(shadow_padding.top(),
shadow_padding.left(),
- shadow_padding.bottom() + kArrowHeight,
+ shadow_padding.bottom() + arrow_height_,
shadow_padding.right());
} else if (arrow_location() == views::BubbleBorder::LEFT_TOP ||
arrow_location() == views::BubbleBorder::LEFT_BOTTOM) {
// Arrow on left.
insets->Set(shadow_padding.top(),
- shadow_padding.left() + kArrowHeight,
+ shadow_padding.left() + arrow_height_,
shadow_padding.bottom(),
shadow_padding.right());
} else if (arrow_location() == views::BubbleBorder::RIGHT_TOP ||
@@ -237,11 +247,11 @@ void AppListBubbleBorder::GetInsets(gfx::Insets* insets) const {
insets->Set(shadow_padding.top(),
shadow_padding.left(),
shadow_padding.bottom(),
- shadow_padding.right() + kArrowHeight);
+ shadow_padding.right() + arrow_height_);
}
}
-gfx::Rect AppListBubbleBorder::GetBounds(
+gfx::Rect BubbleBorderGeometric::GetBounds(
const gfx::Rect& position_relative_to,
const gfx::Size& contents_size) const {
gfx::Size border_size(contents_size);
@@ -274,8 +284,8 @@ gfx::Rect AppListBubbleBorder::GetBounds(
// Arrow at top.
return gfx::Rect(
gfx::Point(anchor_center_x - arrow_tip_x,
- position_relative_to.bottom() - shadow_padding.top() -
- kArrowHeight),
+ position_relative_to.bottom() - shadow_padding.top() +
+ anchor_edge_offset_),
border_size);
} else if (arrow_location() == views::BubbleBorder::BOTTOM_LEFT ||
arrow_location() == views::BubbleBorder::BOTTOM_RIGHT) {
@@ -283,14 +293,14 @@ gfx::Rect AppListBubbleBorder::GetBounds(
return gfx::Rect(
gfx::Point(anchor_center_x - arrow_tip_x,
position_relative_to.y() - border_size.height() +
- shadow_padding.bottom() + kArrowHeight),
+ shadow_padding.bottom() - anchor_edge_offset_),
border_size);
} else if (arrow_location() == views::BubbleBorder::LEFT_TOP ||
arrow_location() == views::BubbleBorder::LEFT_BOTTOM) {
// Arrow on left.
return gfx::Rect(
- gfx::Point(position_relative_to.right() - shadow_padding.left() -
- kArrowHeight,
+ gfx::Point(position_relative_to.right() - shadow_padding.left() +
+ anchor_edge_offset_,
anchor_center_y - arrow_tip_y),
border_size);
} else if (arrow_location() == views::BubbleBorder::RIGHT_TOP ||
@@ -298,7 +308,7 @@ gfx::Rect AppListBubbleBorder::GetBounds(
// Arrow on right.
return gfx::Rect(
gfx::Point(position_relative_to.x() - border_size.width() +
- shadow_padding.right() + kArrowHeight,
+ shadow_padding.right() - anchor_edge_offset_,
anchor_center_y - arrow_tip_y),
border_size);
}
@@ -307,8 +317,44 @@ gfx::Rect AppListBubbleBorder::GetBounds(
return position_relative_to.Center(border_size);
}
-void AppListBubbleBorder::Paint(const views::View& view,
- gfx::Canvas* canvas) const {
+void BubbleBorderGeometric::GetInsetsForArrowLocation(
+ gfx::Insets* insets,
+ ArrowLocation arrow_loc) const {
+ int top = border_size_;
+ int bottom = border_size_;
+ int left = border_size_;
+ int right = border_size_;
+ switch (arrow_loc) {
+ case TOP_LEFT:
+ case TOP_RIGHT:
+ top = std::max(top, arrow_height_);
+ break;
+
+ case BOTTOM_LEFT:
+ case BOTTOM_RIGHT:
+ bottom = std::max(bottom, arrow_height_);
+ break;
+
+ case LEFT_TOP:
+ case LEFT_BOTTOM:
+ left = std::max(left, arrow_height_);
+ break;
+
+ case RIGHT_TOP:
+ case RIGHT_BOTTOM:
+ right = std::max(right, arrow_height_);
+ break;
+
+ case NONE:
+ case FLOAT:
+ // Nothing to do.
+ break;
+ }
+ insets->Set(top, left, bottom, right);
+}
+
+void BubbleBorderGeometric::Paint(const views::View& view,
+ gfx::Canvas* canvas) const {
gfx::Insets insets;
GetInsets(&insets);
@@ -321,23 +367,29 @@ void AppListBubbleBorder::Paint(const views::View& view,
arrow_location(),
SkIntToScalar(GetArrowOffset()),
SkDoubleToScalar(0.5),
- &path);
+ &path,
+ corner_radius_,
+ arrow_height_,
+ arrow_width_);
// Draw border and shadow. Note fill is needed to generate enough shadow.
SkPaint paint;
paint.setAntiAlias(true);
paint.setStyle(SkPaint::kStrokeAndFill_Style);
- paint.setStrokeWidth(SkIntToScalar(kBorderSize));
- paint.setColor(kBorderColor);
+ paint.setStrokeWidth(SkIntToScalar(border_size_));
+ paint.setColor(border_color_);
SkSafeUnref(paint.setLooper(gfx::CreateShadowDrawLooper(shadows_)));
canvas->DrawPath(path, paint);
- // Pads with kBoprderSize pixels to leave space for border lines.
+ // Pads with |border_size_| pixels to leave space for border lines.
BuildShape(content_bounds,
arrow_location(),
SkIntToScalar(GetArrowOffset()),
- SkIntToScalar(kBorderSize),
- &path);
+ SkIntToScalar(border_size_),
+ &path,
+ corner_radius_,
+ arrow_height_,
+ arrow_width_);
canvas->Save();
canvas->ClipPath(path);
@@ -348,4 +400,4 @@ void AppListBubbleBorder::Paint(const views::View& view,
canvas->Restore();
}
-} // namespace app_list
+} // namespace views

Powered by Google App Engine
This is Rietveld 408576698