summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-03 20:36:06 +0000
committersail@chromium.org <sail@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-03 20:36:06 +0000
commit41939cf6e1b288242c2345793235cf1ab0bd98d9 (patch)
tree046ba41d9afc0733c89a9c2e552b4ece7853f687
parent924b5b4fca09230ddde4191dc03beac7d6f8a370 (diff)
downloadchromium_src-41939cf6e1b288242c2345793235cf1ab0bd98d9.zip
chromium_src-41939cf6e1b288242c2345793235cf1ab0bd98d9.tar.gz
chromium_src-41939cf6e1b288242c2345793235cf1ab0bd98d9.tar.bz2
Align avatar bubble with edge of anchor control
Currently when showing the avatar bubble the tip of the bubble points to the middle of the anchor control. This can look weird so I'm changing it to be aligned with the edge of the anchor control. BUG=98884 TEST= Review URL: http://codereview.chromium.org/8439064 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@108537 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chromeos/login/message_bubble.cc2
-rw-r--r--chrome/browser/chromeos/status/caps_lock_menu_button.cc12
-rw-r--r--chrome/browser/external_tab_container_win.cc1
-rw-r--r--chrome/browser/resources/ntp4/new_tab.css2
-rw-r--r--chrome/browser/speech/speech_input_bubble_views.cc5
-rw-r--r--chrome/browser/ui/confirm_bubble_model.cc1
-rw-r--r--chrome/browser/ui/views/avatar_menu_button.cc3
-rw-r--r--chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc3
-rw-r--r--chrome/browser/ui/views/bubble/bubble.cc9
-rw-r--r--chrome/browser/ui/views/bubble/bubble.h3
-rw-r--r--chrome/browser/ui/views/extensions/extension_installed_bubble.cc4
-rw-r--r--chrome/browser/ui/views/first_run_bubble.cc3
-rw-r--r--chrome/browser/ui/views/frame/browser_view.cc9
-rw-r--r--chrome/browser/ui/views/global_error_bubble_view.cc5
-rw-r--r--chrome/browser/ui/views/location_bar/content_setting_image_view.cc1
-rw-r--r--chrome/browser/ui/views/page_info_bubble_view.cc1
-rw-r--r--chrome/browser/ui/views/pinned_contents_info_bubble.cc1
-rw-r--r--chrome/browser/ui/views/toolbar_view.cc1
-rw-r--r--chrome/browser/ui/views/web_intent_picker_view.cc4
-rw-r--r--views/bubble/border_contents_view.cc5
-rw-r--r--views/bubble/border_contents_view.h3
-rw-r--r--views/bubble/bubble_border.cc14
-rw-r--r--views/bubble/bubble_border.h14
23 files changed, 80 insertions, 26 deletions
diff --git a/chrome/browser/chromeos/login/message_bubble.cc b/chrome/browser/chromeos/login/message_bubble.cc
index 074494ff..3304705 100644
--- a/chrome/browser/chromeos/login/message_bubble.cc
+++ b/chrome/browser/chromeos/login/message_bubble.cc
@@ -150,6 +150,7 @@ MessageBubble* MessageBubble::ShowWithLinks(
views::Widget::InitParams::TYPE_POPUP, parent, image, text, links,
true, delegate);
bubble->InitBubble(parent, position_relative_to, arrow_location,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
bubble->text_->parent(), delegate);
return bubble;
}
@@ -171,6 +172,7 @@ MessageBubble* MessageBubble::ShowNoGrab(
views::Widget::InitParams::TYPE_CONTROL, parent, image, text, links,
false, delegate);
bubble->InitBubble(parent, position_relative_to, arrow_location,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
bubble->text_->parent(), delegate);
return bubble;
}
diff --git a/chrome/browser/chromeos/status/caps_lock_menu_button.cc b/chrome/browser/chromeos/status/caps_lock_menu_button.cc
index 7dc5e3e..73f2876 100644
--- a/chrome/browser/chromeos/status/caps_lock_menu_button.cc
+++ b/chrome/browser/chromeos/status/caps_lock_menu_button.cc
@@ -316,12 +316,12 @@ void CapsLockMenuButton::CreateAndShowBubble() {
gfx::Rect button_bounds = GetScreenBounds();
button_bounds.set_y(button_bounds.y() + 1); // See login/message_bubble.cc.
- bubble_ = Bubble::ShowFocusless(GetWidget(),
- button_bounds,
- views::BubbleBorder::TOP_RIGHT,
- new CapsLockMenuButton::StatusView(this),
- NULL /* no delegate */,
- true /* show_while_screen_is_locked */);
+ bubble_ = Bubble::ShowFocusless(GetWidget(), button_bounds,
+ views::BubbleBorder::TOP_RIGHT,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
+ new CapsLockMenuButton::StatusView(this),
+ NULL /* no delegate */,
+ true /* show_while_screen_is_locked */);
}
void CapsLockMenuButton::HideBubble() {
diff --git a/chrome/browser/external_tab_container_win.cc b/chrome/browser/external_tab_container_win.cc
index 5d6bc58..e442a32 100644
--- a/chrome/browser/external_tab_container_win.cc
+++ b/chrome/browser/external_tab_container_win.cc
@@ -603,6 +603,7 @@ void ExternalTabContainer::ShowPageInfo(Profile* profile,
ssl, show_history);
Bubble* bubble = Bubble::Show(GetWidget(), bounds,
views::BubbleBorder::TOP_LEFT,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
page_info_bubble, page_info_bubble);
page_info_bubble->set_bubble(bubble);
}
diff --git a/chrome/browser/resources/ntp4/new_tab.css b/chrome/browser/resources/ntp4/new_tab.css
index f0b037d..ceec95c 100644
--- a/chrome/browser/resources/ntp4/new_tab.css
+++ b/chrome/browser/resources/ntp4/new_tab.css
@@ -177,8 +177,10 @@ html[dir='rtl'] #attribution {
cursor: pointer;
font-size: 13px;
/* Leave room for the scrollbar. */
+ margin-left: 13px;
margin-right: 13px;
margin-top: 5px;
+ padding: 0;
position: fixed;
right: 0;
text-align: right;
diff --git a/chrome/browser/speech/speech_input_bubble_views.cc b/chrome/browser/speech/speech_input_bubble_views.cc
index f8c0646..26f8bc1 100644
--- a/chrome/browser/speech/speech_input_bubble_views.cc
+++ b/chrome/browser/speech/speech_input_bubble_views.cc
@@ -364,8 +364,9 @@ void SpeechInputBubbleImpl::Show() {
}
bubble_ = Bubble::Show(toplevel_widget,
target_rect,
- views::BubbleBorder::TOP_LEFT, bubble_content_,
- this);
+ views::BubbleBorder::TOP_LEFT,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
+ bubble_content_, this);
// We don't want fade outs when closing because it makes speech recognition
// appear slower than it is. Also setting it to false allows |Close| to
// destroy the bubble immediately instead of waiting for the fade animation
diff --git a/chrome/browser/ui/confirm_bubble_model.cc b/chrome/browser/ui/confirm_bubble_model.cc
index 9501b2b..edc379f 100644
--- a/chrome/browser/ui/confirm_bubble_model.cc
+++ b/chrome/browser/ui/confirm_bubble_model.cc
@@ -52,6 +52,7 @@ void ConfirmBubbleModel::Show(gfx::NativeView view,
ConfirmBubbleView* bubble_view = new ConfirmBubbleView(model);
Bubble* bubble = Bubble::Show(parent, gfx::Rect(origin, gfx::Size()),
views::BubbleBorder::NONE,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
bubble_view, bubble_view);
bubble->SizeToContents();
#else
diff --git a/chrome/browser/ui/views/avatar_menu_button.cc b/chrome/browser/ui/views/avatar_menu_button.cc
index 36a899d..6640ca6 100644
--- a/chrome/browser/ui/views/avatar_menu_button.cc
+++ b/chrome/browser/ui/views/avatar_menu_button.cc
@@ -158,7 +158,8 @@ void AvatarMenuButton::ShowAvatarBubble() {
AvatarMenuBubbleView* bubble_view = new AvatarMenuBubbleView(browser_);
// Bubble::Show() takes ownership of the view.
bubble_ = Bubble::Show(browser_view->GetWidget(), bounds,
- views::BubbleBorder::TOP_LEFT, bubble_view, bubble_view);
+ views::BubbleBorder::TOP_LEFT,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR, bubble_view, bubble_view);
bubble_->AddObserver(this);
}
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
index 462b84a..b9a76af 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_bubble_view.cc
@@ -91,7 +91,8 @@ void BookmarkBubbleView::Show(views::Widget* parent,
bookmark_bubble_ = new BookmarkBubbleView(delegate, profile, url,
newly_bookmarked);
Bubble* bubble = Bubble::Show(
- parent, bounds, views::BubbleBorder::TOP_RIGHT, bookmark_bubble_,
+ parent, bounds, views::BubbleBorder::TOP_RIGHT,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR, bookmark_bubble_,
bookmark_bubble_);
// |bubble_| can be set to NULL in BubbleClosing when we close the bubble
// asynchronously. However, that can happen during the Show call above if the
diff --git a/chrome/browser/ui/views/bubble/bubble.cc b/chrome/browser/ui/views/bubble/bubble.cc
index f972eb0..f16c03f 100644
--- a/chrome/browser/ui/views/bubble/bubble.cc
+++ b/chrome/browser/ui/views/bubble/bubble.cc
@@ -50,10 +50,11 @@ string16 BubbleDelegate::GetAccessibleName() {
Bubble* Bubble::Show(views::Widget* parent,
const gfx::Rect& position_relative_to,
views::BubbleBorder::ArrowLocation arrow_location,
+ views::BubbleBorder::BubbleAlignment alignment,
views::View* contents,
BubbleDelegate* delegate) {
Bubble* bubble = new Bubble;
- bubble->InitBubble(parent, position_relative_to, arrow_location,
+ bubble->InitBubble(parent, position_relative_to, arrow_location, alignment,
contents, delegate);
// Register the Escape accelerator for closing.
@@ -71,12 +72,13 @@ Bubble* Bubble::ShowFocusless(
views::Widget* parent,
const gfx::Rect& position_relative_to,
views::BubbleBorder::ArrowLocation arrow_location,
+ views::BubbleBorder::BubbleAlignment alignment,
views::View* contents,
BubbleDelegate* delegate,
bool show_while_screen_is_locked) {
Bubble* bubble = new Bubble(views::Widget::InitParams::TYPE_POPUP,
show_while_screen_is_locked);
- bubble->InitBubble(parent, position_relative_to, arrow_location,
+ bubble->InitBubble(parent, position_relative_to, arrow_location, alignment,
contents, delegate);
return bubble;
}
@@ -186,6 +188,7 @@ Bubble::~Bubble() {
void Bubble::InitBubble(views::Widget* parent,
const gfx::Rect& position_relative_to,
views::BubbleBorder::ArrowLocation arrow_location,
+ views::BubbleBorder::BubbleAlignment alignment,
views::View* contents,
BubbleDelegate* delegate) {
delegate_ = delegate;
@@ -223,6 +226,7 @@ void Bubble::InitBubble(views::Widget* parent,
border_->InitBorderWidgetWin(CreateBorderContents(), parent->GetNativeView());
border_->border_contents()->SetBackgroundColor(kBackgroundColor);
+ border_->border_contents()->SetAlignment(alignment);
// We make the BorderWidgetWin the owner of the Bubble HWND, so that the
// latter is displayed on top of the former.
@@ -288,6 +292,7 @@ void Bubble::InitBubble(views::Widget* parent,
border_contents_ = CreateBorderContents();
border_contents_->Init();
border_contents_->SetBackgroundColor(kBackgroundColor);
+ border_contents_->SetAlignment(alignment);
gfx::Rect contents_bounds;
border_contents_->SizeAndGetBounds(position_relative_to,
arrow_location, false, contents->GetPreferredSize(),
diff --git a/chrome/browser/ui/views/bubble/bubble.h b/chrome/browser/ui/views/bubble/bubble.h
index 22402c5..b6093d1 100644
--- a/chrome/browser/ui/views/bubble/bubble.h
+++ b/chrome/browser/ui/views/bubble/bubble.h
@@ -112,6 +112,7 @@ class Bubble
static Bubble* Show(views::Widget* parent,
const gfx::Rect& position_relative_to,
views::BubbleBorder::ArrowLocation arrow_location,
+ views::BubbleBorder::BubbleAlignment alignment,
views::View* contents,
BubbleDelegate* delegate);
@@ -126,6 +127,7 @@ class Bubble
views::Widget* parent,
const gfx::Rect& position_relative_to,
views::BubbleBorder::ArrowLocation arrow_location,
+ views::BubbleBorder::BubbleAlignment alignment,
views::View* contents,
BubbleDelegate* delegate,
bool show_while_screen_is_locked);
@@ -181,6 +183,7 @@ class Bubble
virtual void InitBubble(views::Widget* parent,
const gfx::Rect& position_relative_to,
views::BubbleBorder::ArrowLocation arrow_location,
+ views::BubbleBorder::BubbleAlignment alignment,
views::View* contents,
BubbleDelegate* delegate);
diff --git a/chrome/browser/ui/views/extensions/extension_installed_bubble.cc b/chrome/browser/ui/views/extensions/extension_installed_bubble.cc
index c8962f8..adb2520 100644
--- a/chrome/browser/ui/views/extensions/extension_installed_bubble.cc
+++ b/chrome/browser/ui/views/extensions/extension_installed_bubble.cc
@@ -410,7 +410,9 @@ void ExtensionInstalledBubble::ShowInternal() {
bubble_content_ = new InstalledBubbleContent(
browser_, extension_, type_, &icon_);
Bubble* bubble = Bubble::Show(browser_view->GetWidget(), bounds,
- arrow_location, bubble_content_, this);
+ arrow_location,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
+ bubble_content_, this);
bubble_content_->set_bubble(bubble);
}
diff --git a/chrome/browser/ui/views/first_run_bubble.cc b/chrome/browser/ui/views/first_run_bubble.cc
index 349257a..ea925db 100644
--- a/chrome/browser/ui/views/first_run_bubble.cc
+++ b/chrome/browser/ui/views/first_run_bubble.cc
@@ -510,7 +510,8 @@ FirstRunBubble* FirstRunBubble::Show(
}
bubble->set_view(view);
bubble->InitBubble(
- parent, position_relative_to, arrow_location, view, bubble);
+ parent, position_relative_to, arrow_location,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR, view, bubble);
bubble->GetWidget()->GetFocusManager()->AddFocusChangeListener(view);
view->BubbleShown();
return bubble;
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 3c4efd5..d359085 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -2601,15 +2601,14 @@ BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) {
void BrowserView::ShowAvatarBubble(TabContents* tab_contents,
const gfx::Rect& rect) {
- gfx::Point origin(rect.right(), rect.bottom());
+ gfx::Point origin(rect.origin());
views::View::ConvertPointToScreen(GetTabContentsContainerView(), &origin);
- gfx::Rect bounds;
- bounds.set_origin(origin);
+ gfx::Rect bounds(origin, rect.size());
AvatarMenuBubbleView* bubble_view = new AvatarMenuBubbleView(browser_.get());
// Bubble::Show() takes ownership of the view.
- Bubble::Show(this->GetWidget(), bounds,
- views::BubbleBorder::TOP_RIGHT,
+ Bubble::Show(this->GetWidget(), bounds, views::BubbleBorder::TOP_RIGHT,
+ views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE,
bubble_view, bubble_view);
}
diff --git a/chrome/browser/ui/views/global_error_bubble_view.cc b/chrome/browser/ui/views/global_error_bubble_view.cc
index 4db3ffe..a0cf75e 100644
--- a/chrome/browser/ui/views/global_error_bubble_view.cc
+++ b/chrome/browser/ui/views/global_error_bubble_view.cc
@@ -171,7 +171,8 @@ void GlobalError::ShowBubbleView(Browser* browser, GlobalError* error) {
new GlobalErrorBubbleView(browser, error);
// Bubble::Show() takes ownership of the view.
Bubble* bubble = Bubble::Show(
- browser_view->GetWidget(), bounds,
- views::BubbleBorder::TOP_RIGHT, bubble_view, bubble_view);
+ browser_view->GetWidget(), bounds, views::BubbleBorder::TOP_RIGHT,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR, bubble_view,
+ bubble_view);
bubble_view->set_bubble(bubble);
}
diff --git a/chrome/browser/ui/views/location_bar/content_setting_image_view.cc b/chrome/browser/ui/views/location_bar/content_setting_image_view.cc
index 11c1835..d6cebb2 100644
--- a/chrome/browser/ui/views/location_bar/content_setting_image_view.cc
+++ b/chrome/browser/ui/views/location_bar/content_setting_image_view.cc
@@ -144,6 +144,7 @@ void ContentSettingImageView::OnMouseReleased(const views::MouseEvent& event) {
profile, tab_contents->tab_contents());
bubble_ = Bubble::Show(GetWidget(), screen_bounds,
views::BubbleBorder::TOP_RIGHT,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
bubble_contents, this);
bubble_contents->set_bubble(bubble_);
}
diff --git a/chrome/browser/ui/views/page_info_bubble_view.cc b/chrome/browser/ui/views/page_info_bubble_view.cc
index 16033d9..9a6dbed 100644
--- a/chrome/browser/ui/views/page_info_bubble_view.cc
+++ b/chrome/browser/ui/views/page_info_bubble_view.cc
@@ -502,6 +502,7 @@ void ShowPageInfoBubble(BrowserView* browser_view,
Bubble* bubble =
Bubble::Show(browser_view->GetWidget(), bounds,
views::BubbleBorder::TOP_LEFT,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
page_info_bubble, page_info_bubble);
page_info_bubble->set_bubble(bubble);
}
diff --git a/chrome/browser/ui/views/pinned_contents_info_bubble.cc b/chrome/browser/ui/views/pinned_contents_info_bubble.cc
index 6d85672..a87d1eb 100644
--- a/chrome/browser/ui/views/pinned_contents_info_bubble.cc
+++ b/chrome/browser/ui/views/pinned_contents_info_bubble.cc
@@ -44,6 +44,7 @@ PinnedContentsInfoBubble* PinnedContentsInfoBubble::Show(
PinnedContentsInfoBubble* bubble =
new PinnedContentsInfoBubble(bubble_anchor);
bubble->InitBubble(parent, position_relative_to, arrow_location,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
contents, delegate);
return bubble;
}
diff --git a/chrome/browser/ui/views/toolbar_view.cc b/chrome/browser/ui/views/toolbar_view.cc
index c792bb1f..4616302 100644
--- a/chrome/browser/ui/views/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar_view.cc
@@ -731,6 +731,7 @@ void ToolbarView::ShowCriticalNotification() {
Bubble* bubble = Bubble::Show(GetWidget(),
gfx::Rect(screen_loc, app_menu_->size()),
views::BubbleBorder::TOP_RIGHT,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
critical_notification_bubble,
critical_notification_bubble);
bubble->set_close_on_deactivate(false);
diff --git a/chrome/browser/ui/views/web_intent_picker_view.cc b/chrome/browser/ui/views/web_intent_picker_view.cc
index 9f01250..14fce13 100644
--- a/chrome/browser/ui/views/web_intent_picker_view.cc
+++ b/chrome/browser/ui/views/web_intent_picker_view.cc
@@ -168,7 +168,9 @@ WebIntentPickerView::WebIntentPickerView(Browser* browser,
bounds.set_width(kIconHorizontalOffset);
bubble_ = Bubble::Show(browser_view->GetWidget(), bounds,
- views::BubbleBorder::TOP_LEFT, this, this);
+ views::BubbleBorder::TOP_LEFT,
+ views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR,
+ this, this);
}
WebIntentPickerView::~WebIntentPickerView() {
diff --git a/views/bubble/border_contents_view.cc b/views/bubble/border_contents_view.cc
index 1582751..f846b3a 100644
--- a/views/bubble/border_contents_view.cc
+++ b/views/bubble/border_contents_view.cc
@@ -87,6 +87,11 @@ void BorderContentsView::SetBackgroundColor(SkColor color) {
bubble_border_->set_background_color(color);
}
+void BorderContentsView::SetAlignment(
+ views::BubbleBorder::BubbleAlignment alignment) {
+ bubble_border_->set_alignment(alignment);
+}
+
void BorderContentsView::SizeAndGetBounds(
const gfx::Rect& position_relative_to,
BubbleBorder::ArrowLocation arrow_location,
diff --git a/views/bubble/border_contents_view.h b/views/bubble/border_contents_view.h
index 3c5a162..49ddb6a 100644
--- a/views/bubble/border_contents_view.h
+++ b/views/bubble/border_contents_view.h
@@ -27,6 +27,9 @@ class VIEWS_EXPORT BorderContentsView : public View {
// Sets the background color.
void SetBackgroundColor(SkColor color);
+ // Sets the bubble alignment.
+ void SetAlignment(views::BubbleBorder::BubbleAlignment alignment);
+
// Given the size of the contents and the rect to point at, returns the bounds
// of both the border and the contents inside the bubble.
// |arrow_location| specifies the preferred location for the arrow
diff --git a/views/bubble/bubble_border.cc b/views/bubble/bubble_border.cc
index 377e94f..70f08dd 100644
--- a/views/bubble/bubble_border.cc
+++ b/views/bubble/bubble_border.cc
@@ -60,12 +60,15 @@ gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to,
switch (arrow_location_) {
case TOP_LEFT:
case BOTTOM_LEFT:
- x += w / 2 - arrow_offset;
+ x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? w / 2 - arrow_offset :
+ -kArrowOverlap;
break;
case TOP_RIGHT:
case BOTTOM_RIGHT:
- x += w / 2 + arrow_offset - border_size.width() + 1;
+ x += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ?
+ w / 2 + arrow_offset - border_size.width() + 1 :
+ w - border_size.width() + kArrowOverlap;
break;
case LEFT_TOP:
@@ -98,12 +101,15 @@ gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& position_relative_to,
case LEFT_TOP:
case RIGHT_TOP:
- y += h / 2 - arrow_offset;
+ y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ? h / 2 - arrow_offset :
+ -kArrowOverlap;
break;
case LEFT_BOTTOM:
case RIGHT_BOTTOM:
- y += h / 2 + arrow_offset - border_size.height() + 1;
+ y += alignment_ == ALIGN_ARROW_TO_MID_ANCHOR ?
+ h / 2 + arrow_offset - border_size.height() + 1 :
+ h - border_size.height() + kArrowOverlap;
break;
case NONE:
diff --git a/views/bubble/bubble_border.h b/views/bubble/bubble_border.h
index ce0c448..edca71e 100644
--- a/views/bubble/bubble_border.h
+++ b/views/bubble/bubble_border.h
@@ -34,9 +34,18 @@ class VIEWS_EXPORT BubbleBorder : public views::Border {
FLOAT = 9 // No arrow. Centered over the supplied rect.
};
+ // The position of the bubble in relation to the anchor.
+ enum BubbleAlignment {
+ // The tip of the arrow points to the middle of the anchor.
+ ALIGN_ARROW_TO_MID_ANCHOR,
+ // The edge nearest to the arrow is lined up with the edge of the anchor.
+ ALIGN_EDGE_TO_ANCHOR_EDGE
+ };
+
explicit BubbleBorder(ArrowLocation arrow_location)
: override_arrow_offset_(0),
arrow_location_(arrow_location),
+ alignment_(ALIGN_ARROW_TO_MID_ANCHOR),
background_color_(SK_ColorWHITE) {
InitClass();
}
@@ -56,6 +65,10 @@ class VIEWS_EXPORT BubbleBorder : public views::Border {
}
ArrowLocation arrow_location() const { return arrow_location_; }
+ // Sets the alignment.
+ void set_alignment(BubbleAlignment alignment) { alignment_ = alignment; }
+ BubbleAlignment alignment() const { return alignment_; }
+
static ArrowLocation horizontal_mirror(ArrowLocation loc) {
return loc >= NONE ? loc : static_cast<ArrowLocation>(loc ^ 1);
}
@@ -150,6 +163,7 @@ class VIEWS_EXPORT BubbleBorder : public views::Border {
int override_arrow_offset_;
ArrowLocation arrow_location_;
+ BubbleAlignment alignment_;
SkColor background_color_;
DISALLOW_COPY_AND_ASSIGN(BubbleBorder);