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

Unified Diff: chrome/browser/views/info_bubble.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/info_bubble.h ('k') | chrome/browser/views/location_bar_view.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/views/info_bubble.cc
===================================================================
--- chrome/browser/views/info_bubble.cc (revision 26373)
+++ chrome/browser/views/info_bubble.cc (working copy)
@@ -7,68 +7,189 @@
#include "app/gfx/canvas.h"
#include "app/gfx/color_utils.h"
#include "app/gfx/path.h"
-#include "app/resource_bundle.h"
#include "chrome/browser/window_sizer.h"
#include "chrome/common/notification_service.h"
-#include "grit/theme_resources.h"
+#include "third_party/Skia/include/core/SkPaint.h"
+#include "views/fill_layout.h"
#include "views/widget/root_view.h"
#include "views/window/window.h"
+namespace {
+
+// Background color of the bubble.
#if defined(OS_WIN)
-#include "base/win_util.h"
+const SkColor kBackgroundColor = color_utils::GetSysSkColor(COLOR_WINDOW);
+#else
+// TODO(beng): source from theme provider.
+const SkColor kBackgroundColor = SK_ColorWHITE;
#endif
-using views::View;
+}
-namespace {
+#if defined(OS_WIN)
+// BorderContents -------------------------------------------------------------
-// All sizes are in pixels.
+// This is used to paint the border; see comments on BorderWidget below.
+class BorderContents : public views::View {
+ public:
+ BorderContents() { }
-// Size of the border, along each edge.
-const int kBorderSize = 1;
+ // Given the size of the contents and the rect (in screen coordinates) to
+ // point at, initializes the bubble and returns the bounds (in screen
+ // coordinates) of both the border and the contents inside the bubble.
+ // |is_rtl| is true if the UI is RTL and thus the arrow should default to the
+ // right side of the bubble; otherwise it defaults to the left top corner, and
+ // then is moved as necessary to try and fit the whole bubble on the same
+ // monitor as the rect being pointed to.
+ //
+ // TODO(pkasting): Maybe this should use mirroring transformations instead,
+ // which would hopefully simplify this code.
+ void InitAndGetBounds(const gfx::Rect& position_relative_to,
+ const gfx::Size& contents_size,
+ bool is_rtl,
+ gfx::Rect* inner_bounds,
+ gfx::Rect* outer_bounds);
-// Size of the arrow.
-const int kArrowSize = 5;
+ private:
+ virtual ~BorderContents() { }
-// Number of pixels to the start of the arrow from the edge of the window.
-const int kArrowXOffset = 13;
+ // Overridden from View:
+ virtual void Paint(gfx::Canvas* canvas);
-// Number of pixels between the tip of the arrow and the region we're
-// pointing to.
-const int kArrowToContentPadding = -4;
+ DISALLOW_COPY_AND_ASSIGN(BorderContents);
+};
-// Background color of the bubble.
-#if defined(OS_WIN)
-const SkColor kBackgroundColor = color_utils::GetSysSkColor(COLOR_WINDOW);
-#else
-// TODO(beng): source from theme provider.
-const SkColor kBackgroundColor = SK_ColorWHITE;
-#endif
+void BorderContents::InitAndGetBounds(
+ const gfx::Rect& position_relative_to,
+ const gfx::Size& contents_size,
+ bool is_rtl,
+ gfx::Rect* inner_bounds,
+ gfx::Rect* outer_bounds) {
+ // Set the border.
+ BubbleBorder* bubble_border = new BubbleBorder;
+ set_border(bubble_border);
+ bubble_border->set_background_color(kBackgroundColor);
-// Color of the border and arrow.
-const SkColor kBorderColor1 = SkColorSetRGB(99, 99, 99);
-// Border shadow color.
-const SkColor kBorderColor2 = SkColorSetRGB(160, 160, 160);
+ // Try putting the arrow in its default location, and calculating the bounds.
+ BubbleBorder::ArrowLocation arrow_location(is_rtl ?
+ BubbleBorder::TOP_RIGHT : BubbleBorder::TOP_LEFT);
+ bubble_border->set_arrow_location(arrow_location);
+ *outer_bounds = bubble_border->GetBounds(position_relative_to, contents_size);
-// Intended dimensions of the bubble's corner images. If you update these,
-// make sure that the OnSize code works.
-const int kInfoBubbleCornerWidth = 3;
-const int kInfoBubbleCornerHeight = 3;
+ // See if those bounds will fit on the monitor.
+ scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_provider(
+ WindowSizer::CreateDefaultMonitorInfoProvider());
+ gfx::Rect monitor_bounds(
+ monitor_provider->GetMonitorWorkAreaMatching(position_relative_to));
+ if (!monitor_bounds.IsEmpty() && !monitor_bounds.Contains(*outer_bounds)) {
+ // The bounds don't fit. Move the arrow to try and improve things.
+ bool arrow_on_left =
+ (is_rtl ? (outer_bounds->x() < monitor_bounds.x()) :
+ (outer_bounds->right() <= monitor_bounds.right()));
+ if (outer_bounds->bottom() > monitor_bounds.bottom()) {
+ arrow_location = arrow_on_left ?
+ BubbleBorder::BOTTOM_LEFT : BubbleBorder::BOTTOM_RIGHT;
+ } else {
+ arrow_location = arrow_on_left ?
+ BubbleBorder::TOP_LEFT : BubbleBorder::TOP_RIGHT;
+ }
+ bubble_border->set_arrow_location(arrow_location);
-// Bubble corner images.
-const SkBitmap* kInfoBubbleCornerTopLeft = NULL;
-const SkBitmap* kInfoBubbleCornerTopRight = NULL;
-const SkBitmap* kInfoBubbleCornerBottomLeft = NULL;
-const SkBitmap* kInfoBubbleCornerBottomRight = NULL;
+ // Now get the recalculated bounds.
+ *outer_bounds = bubble_border->GetBounds(position_relative_to,
+ contents_size);
+ }
-// Margins around the content.
-const int kInfoBubbleViewTopMargin = 6;
-const int kInfoBubbleViewBottomMargin = 9;
-const int kInfoBubbleViewLeftMargin = 6;
-const int kInfoBubbleViewRightMargin = 6;
+ // Calculate the bounds of the contained contents by subtracting the border
+ // dimensions.
+ *inner_bounds = *outer_bounds;
+ gfx::Insets insets;
+ bubble_border->GetInsets(&insets);
+ inner_bounds->Inset(insets.left(), insets.top(), insets.right(),
+ insets.bottom());
+}
-} // namespace
+void BorderContents::Paint(gfx::Canvas* canvas) {
+ // The border of this view creates an anti-aliased round-rect region for the
+ // contents, which we need to fill with the background color.
+ SkPaint paint;
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kFill_Style);
+ paint.setColor(kBackgroundColor);
+ gfx::Path path;
+ gfx::Rect bounds(GetLocalBounds(false));
+ 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->drawPath(path, paint);
+ // Now we paint the border, so it will be alpha-blended atop the contents.
+ // This looks slightly better in the corners than drawing the contents atop
+ // the border.
+ PaintBorder(canvas);
+}
+
+// BorderWidget ---------------------------------------------------------------
+
+BorderWidget::BorderWidget() {
+ set_delete_on_destroy(false); // Our owner will free us manually.
+ set_window_style(WS_POPUP);
+ set_window_ex_style(WS_EX_TOOLWINDOW | WS_EX_LAYERED);
+}
+
+gfx::Rect BorderWidget::InitAndGetBounds(
+ HWND owner,
+ const gfx::Rect& position_relative_to,
+ const gfx::Size& contents_size,
+ bool is_rtl) {
+ // Margins around the contents.
+ const int kLeftMargin = 6;
+ const int kTopMargin = 6;
+ const int kRightMargin = 6;
+ const int kBottomMargin = 9;
+
+ // Set up the border view and ask it to calculate our bounds (and our
+ // contents').
+ gfx::Size local_contents_size(contents_size);
+ local_contents_size.Enlarge(kLeftMargin + kRightMargin,
+ kTopMargin + kBottomMargin);
+ BorderContents* border_contents = new BorderContents;
+ gfx::Rect inner_bounds, outer_bounds;
+ border_contents->InitAndGetBounds(position_relative_to, local_contents_size,
+ is_rtl, &inner_bounds, &outer_bounds);
+
+ // Initialize ourselves.
+ WidgetWin::Init(GetAncestor(owner, GA_ROOT), outer_bounds);
+ SetContentsView(border_contents);
+ SetWindowPos(owner, 0, 0, 0, 0,
+ SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOREDRAW);
+
+ // Chop a hole out of our region to show the contents through.
+ // CreateRectRgn() expects (left, top, right, bottom) in window coordinates.
+ inner_bounds.Inset(kLeftMargin, kTopMargin, kRightMargin, kBottomMargin);
+ gfx::Rect region_bounds(inner_bounds);
+ region_bounds.Offset(-outer_bounds.x(), -outer_bounds.y());
+ HRGN inner_region = CreateRectRgn(region_bounds.x(), region_bounds.y(),
+ region_bounds.right(), region_bounds.bottom());
+ HRGN outer_region = CreateRectRgn(0, 0,
+ outer_bounds.right(), outer_bounds.bottom());
+ CombineRgn(outer_region, outer_region, inner_region, RGN_XOR);
+ DeleteObject(inner_region);
+ SetWindowRgn(outer_region, true);
+
+ return inner_bounds;
+}
+
+LRESULT BorderWidget::OnMouseActivate(HWND window,
+ UINT hit_test,
+ UINT mouse_message) {
+ // Never activate.
+ return MA_NOACTIVATE;
+}
+#endif
+
// InfoBubble -----------------------------------------------------------------
// static
@@ -76,7 +197,7 @@
const gfx::Rect& position_relative_to,
views::View* contents,
InfoBubbleDelegate* delegate) {
- InfoBubble* window = new InfoBubble();
+ InfoBubble* window = new InfoBubble;
window->Init(parent, position_relative_to, contents, delegate);
return window;
}
@@ -92,7 +213,6 @@
#endif
delegate_(NULL),
parent_(NULL),
- content_view_(NULL),
closed_(false) {
}
@@ -105,24 +225,11 @@
delegate_ = delegate;
- if (kInfoBubbleCornerTopLeft == NULL) {
- kInfoBubbleCornerTopLeft = ResourceBundle::GetSharedInstance()
- .GetBitmapNamed(IDR_INFO_BUBBLE_CORNER_TOP_LEFT);
- kInfoBubbleCornerTopRight = ResourceBundle::GetSharedInstance()
- .GetBitmapNamed(IDR_INFO_BUBBLE_CORNER_TOP_RIGHT);
- kInfoBubbleCornerBottomLeft = ResourceBundle::GetSharedInstance()
- .GetBitmapNamed(IDR_INFO_BUBBLE_CORNER_BOTTOM_LEFT);
- kInfoBubbleCornerBottomRight = ResourceBundle::GetSharedInstance()
- .GetBitmapNamed(IDR_INFO_BUBBLE_CORNER_BOTTOM_RIGHT);
- }
#if defined(OS_WIN)
set_window_style(WS_POPUP | WS_CLIPCHILDREN);
set_window_ex_style(WS_EX_TOOLWINDOW);
- set_initial_class_style(
- (win_util::GetWinVersion() < win_util::WINVERSION_XP) ?
- 0 : CS_DROPSHADOW);
+ border_.reset(new BorderWidget);
#endif
- content_view_ = CreateContentView(contents);
#if defined(OS_WIN)
WidgetWin::Init(parent->GetNativeWindow(), gfx::Rect());
@@ -130,18 +237,28 @@
WidgetGtk::Init(GTK_WIDGET(parent->GetNativeWindow()), gfx::Rect());
#endif
- SetContentsView(content_view_);
- // The preferred size may differ when parented. Ask for the bounds again
- // and if they differ reset the bounds.
- gfx::Rect parented_bounds =
- content_view_->CalculateWindowBoundsAndAjust(position_relative_to);
- SetBounds(parented_bounds);
+ views::View* contents_view = new views::View;
+ contents_view->set_background(
+ views::Background::CreateSolidBackground(kBackgroundColor));
+ contents_view->SetLayoutManager(new views::FillLayout);
+ // Adding |contents| as a child has to be done before we call
+ // contents->GetPreferredSize() below, since some supplied views don't
+ // actually set themselves up until they're added to a hierarchy.
+ contents_view->AddChildView(contents);
+ SetContentsView(contents_view);
+ gfx::Rect bounds;
#if defined(OS_WIN)
+ bounds = border_->InitAndGetBounds(GetNativeView(),
+ position_relative_to,
+ contents_view->GetPreferredSize(),
+ contents->UILayoutIsRightToLeft());
+
// Register the Escape accelerator for closing.
GetFocusManager()->RegisterAccelerator(
views::Accelerator(VK_ESCAPE, false, false, false), this);
#endif
+ SetBounds(bounds);
NotificationService::current()->Notify(NotificationType::INFO_BUBBLE_CREATED,
Source<InfoBubble>(this),
@@ -149,16 +266,13 @@
// Show the window.
#if defined(OS_WIN)
+ border_->ShowWindow(SW_SHOW);
ShowWindow(SW_SHOW);
#else
views::WidgetGtk::Show();
#endif
}
-InfoBubble::ContentView* InfoBubble::CreateContentView(View* content) {
- return new ContentView(content, this);
-}
-
#if defined(OS_WIN)
void InfoBubble::OnActivate(UINT action, BOOL minimized, HWND window) {
// The popup should close when it is deactivated.
@@ -169,22 +283,6 @@
GetRootView()->GetChildViewAt(0)->RequestFocus();
}
}
-
-void InfoBubble::OnSize(UINT param, const CSize& size) {
- // See OnSizeAllocate for the Linux version.
- gfx::Path path;
- content_view_->GetMask(gfx::Size(size.cx, size.cy), &path);
- SetWindowRgn(path.CreateHRGN(), TRUE);
- WidgetWin::OnSize(param, size);
-}
-#elif defined(OS_LINUX)
-void InfoBubble::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) {
- gfx::Path path;
- content_view_->GetMask(gfx::Size(allocation->width, allocation->height),
- &path);
- SetShape(path);
- WidgetGtk::OnSizeAllocate(widget, allocation);
-}
#endif
void InfoBubble::Close(bool closed_by_escape) {
@@ -195,6 +293,7 @@
delegate_->InfoBubbleClosing(this, closed_by_escape);
closed_ = true;
#if defined(OS_WIN)
+ border_->Close();
WidgetWin::Close();
#else
WidgetGtk::Close();
@@ -208,227 +307,3 @@
}
return false;
}
-
-// ContentView ----------------------------------------------------------------
-
-InfoBubble::ContentView::ContentView(views::View* content, InfoBubble* host)
- : content_(content),
- host_(host) {
- if (UILayoutIsRightToLeft()) {
- arrow_edge_ = TOP_RIGHT;
- } else {
- arrow_edge_ = TOP_LEFT;
- }
-}
-
-gfx::Rect InfoBubble::ContentView::CalculateWindowBoundsAndAjust(
- const gfx::Rect& position_relative_to) {
- scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_provider(
- WindowSizer::CreateDefaultMonitorInfoProvider());
- gfx::Rect monitor_bounds(
- monitor_provider->GetMonitorWorkAreaMatching(position_relative_to));
- // Calculate the bounds using TOP_LEFT (the default).
- gfx::Rect window_bounds = CalculateWindowBounds(position_relative_to);
- if (monitor_bounds.IsEmpty() || monitor_bounds.Contains(window_bounds))
- return window_bounds;
- // Didn't fit, adjust the edge to fit as much as we can.
- if (window_bounds.bottom() > monitor_bounds.bottom())
- SetArrowEdge(BOTTOM_LEFT);
- if (window_bounds.right() > monitor_bounds.right()) {
- if (IsTop())
- SetArrowEdge(TOP_RIGHT);
- else
- SetArrowEdge(BOTTOM_RIGHT);
- }
- // And return new bounds.
- return CalculateWindowBounds(position_relative_to);
-}
-
-gfx::Size InfoBubble::ContentView::GetPreferredSize() {
- DCHECK(GetChildViewCount() == 1);
- View* content = GetChildViewAt(0);
- gfx::Size pref = content->GetPreferredSize();
- pref.Enlarge(kBorderSize + kBorderSize + kInfoBubbleViewLeftMargin +
- kInfoBubbleViewRightMargin,
- kBorderSize + kBorderSize + kArrowSize +
- kInfoBubbleViewTopMargin + kInfoBubbleViewBottomMargin);
- return pref;
-}
-
-void InfoBubble::ContentView::Layout() {
- DCHECK(GetChildViewCount() == 1);
- View* content = GetChildViewAt(0);
- int x = kBorderSize;
- int y = kBorderSize;
- int content_width = width() - kBorderSize - kBorderSize -
- kInfoBubbleViewLeftMargin - kInfoBubbleViewRightMargin;
- int content_height = height() - kBorderSize - kBorderSize - kArrowSize -
- kInfoBubbleViewTopMargin - kInfoBubbleViewBottomMargin;
- if (IsTop())
- y += kArrowSize;
- x += kInfoBubbleViewLeftMargin;
- y += kInfoBubbleViewTopMargin;
- content->SetBounds(x, y, content_width, content_height);
-}
-
-void InfoBubble::ContentView::GetMask(const gfx::Size& size, gfx::Path* mask) {
- // Redefine the window visible region so that our dropshadows look right.
- SkScalar width = SkIntToScalar(size.width());
- SkScalar height = SkIntToScalar(size.height());
- SkScalar arrow_size = SkIntToScalar(kArrowSize);
- SkScalar arrow_x = SkIntToScalar(
- (IsLeft() ? kArrowXOffset : width - kArrowXOffset) - 1);
- SkScalar corner_size = SkIntToScalar(kInfoBubbleCornerHeight);
-
- if (IsTop()) {
- // Top left corner.
- mask->moveTo(0, arrow_size + corner_size - 1);
- mask->lineTo(corner_size - 1, arrow_size);
-
- // Draw the arrow and the notch of the arrow.
- mask->lineTo(arrow_x - arrow_size, arrow_size);
- mask->lineTo(arrow_x, 0);
- mask->lineTo(arrow_x + 3, 0);
- mask->lineTo(arrow_x + arrow_size + 3, arrow_size);
-
- // Top right corner.
- mask->lineTo(width - corner_size + 1, arrow_size);
- mask->lineTo(width, arrow_size + corner_size - 1);
-
- // Bottom right corner.
- mask->lineTo(width, height - corner_size);
- mask->lineTo(width - corner_size, height);
-
- // Bottom left corner.
- mask->lineTo(corner_size, height);
- mask->lineTo(0, height - corner_size);
- } else {
- // Top left corner.
- mask->moveTo(0, corner_size - 1);
- mask->lineTo(corner_size - 1, 0);
-
- // Top right corner.
- mask->lineTo(width - corner_size + 1, 0);
- mask->lineTo(width, corner_size - 1);
-
- // Bottom right corner.
- mask->lineTo(width, height - corner_size - arrow_size);
- mask->lineTo(width - corner_size, height - arrow_size);
-
- // Draw the arrow and the notch of the arrow.
- mask->lineTo(arrow_x + arrow_size + 2, height - arrow_size);
- mask->lineTo(arrow_x + 2, height);
- mask->lineTo(arrow_x + 1, height);
- mask->lineTo(arrow_x - arrow_size + 1, height - arrow_size);
-
- // Bottom left corner.
- mask->lineTo(corner_size, height - arrow_size);
- mask->lineTo(0, height - corner_size - arrow_size);
- }
-
- mask->close();
-}
-
-void InfoBubble::ContentView::Paint(gfx::Canvas* canvas) {
- int bubble_x = 0;
- int bubble_y = 0;
- int bubble_w = width();
- int bubble_h = height() - kArrowSize;
-
- int border_w = bubble_w - 2 * kInfoBubbleCornerWidth;
- int border_h = bubble_h - 2 * kInfoBubbleCornerHeight;
-
- if (IsTop())
- bubble_y += kArrowSize;
-
- // Fill in the background.
- // Left side.
- canvas->FillRectInt(kBackgroundColor,
- bubble_x, bubble_y + kInfoBubbleCornerHeight,
- kInfoBubbleCornerWidth, border_h);
- // Center Column.
- canvas->FillRectInt(kBackgroundColor,
- kInfoBubbleCornerWidth, bubble_y,
- border_w, bubble_h);
- // Right Column.
- canvas->FillRectInt(kBackgroundColor,
- bubble_w - kInfoBubbleCornerWidth,
- bubble_y + kInfoBubbleCornerHeight,
- kInfoBubbleCornerWidth, border_h);
-
- // Draw the border.
- // Top border.
- canvas->DrawLineInt(kBorderColor1,
- kInfoBubbleCornerWidth, bubble_y,
- kInfoBubbleCornerWidth + border_w, bubble_y);
- // Bottom border.
- canvas->DrawLineInt(kBorderColor1,
- kInfoBubbleCornerWidth, bubble_y + bubble_h - 1,
- kInfoBubbleCornerWidth + border_w,
- bubble_y + bubble_h - 1);
- // Left border.
- canvas->DrawLineInt(kBorderColor1,
- bubble_x, bubble_y + kInfoBubbleCornerHeight,
- bubble_x, bubble_y + kInfoBubbleCornerHeight + border_h);
-
- // Right border.
- canvas->DrawLineInt(kBorderColor1,
- width() - 1, bubble_y + kInfoBubbleCornerHeight,
- width() - 1,
- bubble_y + kInfoBubbleCornerHeight + border_h);
-
- // Draw the corners.
- canvas->DrawBitmapInt(*kInfoBubbleCornerTopLeft, 0, bubble_y);
- canvas->DrawBitmapInt(*kInfoBubbleCornerTopRight,
- bubble_w - kInfoBubbleCornerWidth, bubble_y);
- canvas->DrawBitmapInt(*kInfoBubbleCornerBottomLeft, 0,
- bubble_y + bubble_h - kInfoBubbleCornerHeight);
- canvas->DrawBitmapInt(*kInfoBubbleCornerBottomRight,
- bubble_w - kInfoBubbleCornerWidth,
- bubble_y + bubble_h - kInfoBubbleCornerHeight);
-
- // Draw the arrow and the notch of the arrow.
- int arrow_x = IsLeft() ? kArrowXOffset : width() - kArrowXOffset;
- int arrow_y = IsTop() ? bubble_y : bubble_y + bubble_h - 1;
- const int arrow_delta = IsTop() ? -1 : 1;
- for (int i = 0, y = arrow_y; i <= kArrowSize; ++i, y += arrow_delta) {
- if (kArrowSize != i) {
- // Draw the notch formed by the arrow.
- canvas->FillRectInt(kBackgroundColor, arrow_x - (kArrowSize - i) + 1,
- y, (kArrowSize - i) * 2 - 1, 1);
- }
- // Draw the sides of the arrow.
- canvas->FillRectInt(kBorderColor1, arrow_x - (kArrowSize - i), y, 1, 1);
- canvas->FillRectInt(kBorderColor1, arrow_x + (kArrowSize - i), y, 1, 1);
- if (i != 0) {
- canvas->FillRectInt(kBorderColor2, arrow_x - (kArrowSize - i) - 1, y, 1,
- 1);
- canvas->FillRectInt(kBorderColor2, arrow_x + (kArrowSize - i) + 1, y, 1,
- 1);
- }
- }
-}
-
-void InfoBubble::ContentView::ViewHierarchyChanged(bool is_add,
- View* parent,
- View* child) {
- if (is_add && child == this)
- AddChildView(content_);
-}
-
-gfx::Rect InfoBubble::ContentView::CalculateWindowBounds(
- const gfx::Rect& position_relative_to) {
- gfx::Size pref = GetPreferredSize();
- int x = position_relative_to.x() + position_relative_to.width() / 2;
- int y;
- if (IsLeft())
- x -= kArrowXOffset;
- else
- x = x + kArrowXOffset - pref.width();
- if (IsTop()) {
- y = position_relative_to.bottom() + kArrowToContentPadding;
- } else {
- y = position_relative_to.y() - kArrowToContentPadding - pref.height();
- }
- return gfx::Rect(x, y, pref.width(), pref.height());
-}
« no previous file with comments | « chrome/browser/views/info_bubble.h ('k') | chrome/browser/views/location_bar_view.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698