summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/info_bubble.cc
diff options
context:
space:
mode:
authordpolukhin@chromium.org <dpolukhin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-06 12:36:01 +0000
committerdpolukhin@chromium.org <dpolukhin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-06 12:36:01 +0000
commit6c70e1efa665b0cbd13f79597de27ecca7fa4854 (patch)
tree76ac328f8111134d7698ae0fc92efc99039b3f49 /chrome/browser/views/info_bubble.cc
parent41fa44caf6cf4e7c789af0db508ef64efb20a53d (diff)
downloadchromium_src-6c70e1efa665b0cbd13f79597de27ecca7fa4854.zip
chromium_src-6c70e1efa665b0cbd13f79597de27ecca7fa4854.tar.gz
chromium_src-6c70e1efa665b0cbd13f79597de27ecca7fa4854.tar.bz2
Add ability to place bubble arrow on left and right side of the bubble or make it float with top edge.
BUG=crosbug.com/2800 TEST=Should be no visible changes with info bubble, everything should work as before. Bubble is used for example in bookmarking. Review URL: http://codereview.chromium.org/1820002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46564 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/info_bubble.cc')
-rw-r--r--chrome/browser/views/info_bubble.cc82
1 files changed, 42 insertions, 40 deletions
diff --git a/chrome/browser/views/info_bubble.cc b/chrome/browser/views/info_bubble.cc
index 3a69a1b..8d30c83 100644
--- a/chrome/browser/views/info_bubble.cc
+++ b/chrome/browser/views/info_bubble.cc
@@ -5,7 +5,6 @@
#include "chrome/browser/views/info_bubble.h"
#include "base/keyboard_codes.h"
-#include "chrome/browser/views/bubble_border.h"
#include "chrome/browser/window_sizer.h"
#include "chrome/common/notification_service.h"
#include "gfx/canvas.h"
@@ -14,6 +13,8 @@
#include "third_party/skia/include/core/SkPaint.h"
#include "views/fill_layout.h"
#include "views/widget/root_view.h"
+#include "views/widget/widget.h"
+#include "views/window/client_view.h"
#include "views/window/window.h"
#if defined(OS_CHROMEOS)
@@ -32,26 +33,30 @@ const SkColor InfoBubble::kBackgroundColor = SK_ColorWHITE;
void BorderContents::Init() {
DCHECK(!bubble_border_);
- bubble_border_ = new BubbleBorder();
+ bubble_border_ = new BubbleBorder(BubbleBorder::LEFT_TOP);
set_border(bubble_border_);
bubble_border_->set_background_color(InfoBubble::kBackgroundColor);
}
void BorderContents::SizeAndGetBounds(
const gfx::Rect& position_relative_to,
+ BubbleBorder::ArrowLocation arrow_location,
const gfx::Size& contents_size,
- bool prefer_arrow_on_right,
gfx::Rect* contents_bounds,
gfx::Rect* window_bounds) {
+ if (UILayoutIsRightToLeft())
+ arrow_location = BubbleBorder::rtl_mirror(arrow_location);
+ bubble_border_->set_arrow_location(arrow_location);
+ // Set the border.
+ set_border(bubble_border_);
+ bubble_border_->set_background_color(InfoBubble::kBackgroundColor);
+
// Give the contents a margin.
gfx::Size local_contents_size(contents_size);
local_contents_size.Enlarge(kLeftMargin + kRightMargin,
kTopMargin + kBottomMargin);
// Try putting the arrow in its initial location, and calculating the bounds.
- BubbleBorder::ArrowLocation arrow_location(prefer_arrow_on_right ?
- BubbleBorder::TOP_RIGHT : BubbleBorder::TOP_LEFT);
- bubble_border_->set_arrow_location(arrow_location);
*window_bounds =
bubble_border_->GetBounds(position_relative_to, local_contents_size);
@@ -62,16 +67,14 @@ void BorderContents::SizeAndGetBounds(
monitor_provider->GetMonitorWorkAreaMatching(position_relative_to));
if (!monitor_bounds.IsEmpty() && !monitor_bounds.Contains(*window_bounds)) {
// The bounds don't fit. Move the arrow to try and improve things.
- bool arrow_on_left = prefer_arrow_on_right ?
- (window_bounds->x() < monitor_bounds.x()) :
- (window_bounds->right() <= monitor_bounds.right());
- if (window_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;
+ if (window_bounds->bottom() > monitor_bounds.bottom())
+ arrow_location = BubbleBorder::horizontal_mirror(arrow_location);
+ else if (BubbleBorder::is_arrow_on_left(arrow_location) ?
+ (window_bounds->right() > monitor_bounds.right()) :
+ (window_bounds->x() < monitor_bounds.x())) {
+ arrow_location = BubbleBorder::rtl_mirror(arrow_location);
}
+
bubble_border_->set_arrow_location(arrow_location);
// Now get the recalculated bounds.
@@ -134,13 +137,13 @@ void BorderWidget::Init(HWND owner) {
gfx::Rect BorderWidget::SizeAndGetBounds(
const gfx::Rect& position_relative_to,
- const gfx::Size& contents_size,
- bool prefer_arrow_on_right) {
+ BubbleBorder::ArrowLocation arrow_location,
+ const gfx::Size& contents_size) {
// Ask the border view to calculate our bounds (and our contents').
gfx::Rect contents_bounds;
gfx::Rect window_bounds;
- border_contents_->SizeAndGetBounds(position_relative_to, contents_size,
- prefer_arrow_on_right, &contents_bounds,
+ border_contents_->SizeAndGetBounds(position_relative_to, arrow_location,
+ contents_size, &contents_bounds,
&window_bounds);
SetBounds(window_bounds);
@@ -174,12 +177,14 @@ LRESULT BorderWidget::OnMouseActivate(HWND window,
// InfoBubble -----------------------------------------------------------------
// static
-InfoBubble* InfoBubble::Show(views::Window* parent,
+InfoBubble* InfoBubble::Show(views::Widget* parent,
const gfx::Rect& position_relative_to,
+ BubbleBorder::ArrowLocation arrow_location,
views::View* contents,
InfoBubbleDelegate* delegate) {
InfoBubble* window = new InfoBubble;
- window->Init(parent, position_relative_to, contents, delegate);
+ window->Init(parent, position_relative_to, arrow_location,
+ contents, delegate);
return window;
}
@@ -194,29 +199,33 @@ InfoBubble::InfoBubble()
border_contents_(NULL),
#endif
delegate_(NULL),
- parent_(NULL),
closed_(false) {
}
-void InfoBubble::Init(views::Window* parent,
+void InfoBubble::Init(views::Widget* parent,
const gfx::Rect& position_relative_to,
+ BubbleBorder::ArrowLocation arrow_location,
views::View* contents,
InfoBubbleDelegate* delegate) {
- parent_ = parent;
delegate_ = delegate;
position_relative_to_ = position_relative_to;
+ arrow_location_ = arrow_location;
contents_ = contents;
// Create the main window.
#if defined(OS_WIN)
- parent_->DisableInactiveRendering();
+ views::Window* parent_window = parent->GetWindow();
+ if (parent_window)
+ parent_window->DisableInactiveRendering();
set_window_style(WS_POPUP | WS_CLIPCHILDREN);
set_window_ex_style(WS_EX_TOOLWINDOW);
- WidgetWin::Init(parent->GetNativeWindow(), gfx::Rect());
+ WidgetWin::Init(parent->GetNativeView(), gfx::Rect());
#elif defined(OS_LINUX)
MakeTransparent();
make_transient_to_parent();
- WidgetGtk::Init(GTK_WIDGET(parent->GetNativeWindow()), gfx::Rect());
+ WidgetGtk::Init(
+ GTK_WIDGET(static_cast<WidgetGtk*>(parent)->GetNativeView()),
+ gfx::Rect());
#if defined(OS_CHROMEOS)
chromeos::WmIpc::instance()->SetWindowType(
GetNativeView(),
@@ -240,9 +249,6 @@ void InfoBubble::Init(views::Window* parent,
// Calculate and set the bounds for all windows and views.
gfx::Rect window_bounds;
- bool prefer_arrow_on_right = delegate &&
- (contents->UILayoutIsRightToLeft() == delegate->PreferOriginSideAnchor());
-
#if defined(OS_WIN)
DCHECK(!border_.get());
border_.reset(CreateBorderWidget());
@@ -250,8 +256,8 @@ void InfoBubble::Init(views::Window* parent,
// Initialize and position the border window.
window_bounds = border_->SizeAndGetBounds(position_relative_to,
- contents->GetPreferredSize(),
- prefer_arrow_on_right);
+ arrow_location,
+ contents->GetPreferredSize());
// Make |contents| take up the entire contents view.
contents_view->SetLayoutManager(new views::FillLayout);
@@ -265,7 +271,7 @@ void InfoBubble::Init(views::Window* parent,
border_contents_->Init();
gfx::Rect contents_bounds;
border_contents_->SizeAndGetBounds(position_relative_to,
- contents->GetPreferredSize(), prefer_arrow_on_right,
+ arrow_location, contents->GetPreferredSize(),
&contents_bounds, &window_bounds);
// This new view must be added before |contents| so it will paint under it.
contents_view->AddChildView(0, border_contents_);
@@ -304,19 +310,15 @@ BorderWidget* InfoBubble::CreateBorderWidget() {
void InfoBubble::SizeToContents() {
gfx::Rect window_bounds;
- bool prefer_arrow_on_right = delegate_ &&
- (contents_->UILayoutIsRightToLeft() ==
- delegate_->PreferOriginSideAnchor());
-
#if defined(OS_WIN)
// Initialize and position the border window.
window_bounds = border_->SizeAndGetBounds(position_relative_to_,
- contents_->GetPreferredSize(),
- prefer_arrow_on_right);
+ arrow_location_,
+ contents_->GetPreferredSize());
#else
gfx::Rect contents_bounds;
border_contents_->SizeAndGetBounds(position_relative_to_,
- contents_->GetPreferredSize(), prefer_arrow_on_right,
+ arrow_location_, contents_->GetPreferredSize(),
&contents_bounds, &window_bounds);
// |contents_view| has no layout manager, so we have to explicitly position
// its children.