summaryrefslogtreecommitdiffstats
path: root/ui/views/bubble/bubble_delegate.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ui/views/bubble/bubble_delegate.cc')
-rw-r--r--ui/views/bubble/bubble_delegate.cc56
1 files changed, 39 insertions, 17 deletions
diff --git a/ui/views/bubble/bubble_delegate.cc b/ui/views/bubble/bubble_delegate.cc
index 3942c92..f593a1b 100644
--- a/ui/views/bubble/bubble_delegate.cc
+++ b/ui/views/bubble/bubble_delegate.cc
@@ -20,7 +20,7 @@ namespace views {
namespace {
// Create a widget to host the bubble.
-Widget* CreateBubbleWidget(BubbleDelegateView* bubble, Widget* parent) {
+Widget* CreateBubbleWidget(BubbleDelegateView* bubble) {
Widget* bubble_widget = new Widget();
Widget::InitParams bubble_params(Widget::InitParams::TYPE_BUBBLE);
bubble_params.delegate = bubble;
@@ -28,7 +28,7 @@ Widget* CreateBubbleWidget(BubbleDelegateView* bubble, Widget* parent) {
if (bubble->parent_window())
bubble_params.parent = bubble->parent_window();
else
- bubble_params.parent_widget = parent;
+ bubble_params.parent_widget = bubble->anchor_widget();
if (bubble->use_focusless())
bubble_params.can_activate = false;
#if defined(OS_WIN) && !defined(USE_AURA)
@@ -81,12 +81,12 @@ class BubbleBorderDelegate : public WidgetDelegate,
};
// Create a widget to host the bubble's border.
-Widget* CreateBorderWidget(BubbleDelegateView* bubble, Widget* parent) {
+Widget* CreateBorderWidget(BubbleDelegateView* bubble) {
Widget* border_widget = new Widget();
Widget::InitParams border_params(Widget::InitParams::TYPE_BUBBLE);
border_params.delegate = new BubbleBorderDelegate(bubble, border_widget);
border_params.transparent = true;
- border_params.parent_widget = parent;
+ border_params.parent_widget = bubble->anchor_widget();
border_widget->Init(border_params);
return border_widget;
}
@@ -106,6 +106,8 @@ BubbleDelegateView::BubbleDelegateView()
: close_on_esc_(true),
close_on_deactivate_(true),
anchor_view_(NULL),
+ anchor_widget_(NULL),
+ move_with_anchor_(false),
arrow_location_(BubbleBorder::TOP_LEFT),
color_(kBackgroundColor),
margin_(kDefaultMargin),
@@ -123,6 +125,8 @@ BubbleDelegateView::BubbleDelegateView(
: close_on_esc_(true),
close_on_deactivate_(true),
anchor_view_(anchor_view),
+ anchor_widget_(NULL),
+ move_with_anchor_(false),
arrow_location_(arrow_location),
color_(kBackgroundColor),
margin_(kDefaultMargin),
@@ -139,14 +143,15 @@ BubbleDelegateView::~BubbleDelegateView() {}
// static
Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) {
bubble_delegate->Init();
- Widget* parent = bubble_delegate->anchor_view() ?
+ // Determine the anchor widget from the anchor view at bubble creation time.
+ bubble_delegate->anchor_widget_ = bubble_delegate->anchor_view() ?
bubble_delegate->anchor_view()->GetWidget() : NULL;
- Widget* bubble_widget = CreateBubbleWidget(bubble_delegate, parent);
+ Widget* bubble_widget = CreateBubbleWidget(bubble_delegate);
#if defined(OS_WIN) && !defined(USE_AURA)
// First set the contents view to initialize view bounds for widget sizing.
bubble_widget->SetContentsView(bubble_delegate->GetContentsView());
- bubble_delegate->border_widget_ = CreateBorderWidget(bubble_delegate, parent);
+ bubble_delegate->border_widget_ = CreateBorderWidget(bubble_delegate);
#endif
bubble_delegate->SizeToContents();
@@ -171,19 +176,31 @@ NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView(
return new BubbleFrameView(arrow_location(), color(), margin());
}
+void BubbleDelegateView::OnWidgetClosing(Widget* widget) {
+ if (anchor_widget() == widget) {
+ anchor_view_ = NULL;
+ anchor_widget_ = NULL;
+ }
+}
+
void BubbleDelegateView::OnWidgetVisibilityChanged(Widget* widget,
bool visible) {
- if (widget == GetWidget()) {
- if (visible) {
- if (border_widget_)
- border_widget_->Show();
- GetFocusManager()->SetFocusedView(GetInitiallyFocusedView());
- Widget* anchor_widget = anchor_view() ? anchor_view()->GetWidget() : NULL;
- if (anchor_widget && anchor_widget->GetTopLevelWidget())
- anchor_widget->GetTopLevelWidget()->DisableInactiveRendering();
- } else if (border_widget_) {
+ if (widget != GetWidget())
+ return;
+
+ if (visible) {
+ if (border_widget_)
+ border_widget_->Show();
+ if (anchor_widget())
+ anchor_widget()->AddObserver(this);
+ GetFocusManager()->SetFocusedView(GetInitiallyFocusedView());
+ if (anchor_widget() && anchor_widget()->GetTopLevelWidget())
+ anchor_widget()->GetTopLevelWidget()->DisableInactiveRendering();
+ } else {
+ if (border_widget_)
border_widget_->Hide();
- }
+ if (anchor_widget())
+ anchor_widget()->RemoveObserver(this);
}
}
@@ -193,6 +210,11 @@ void BubbleDelegateView::OnWidgetActivationChanged(Widget* widget,
GetWidget()->Close();
}
+void BubbleDelegateView::OnWidgetMoved(Widget* widget) {
+ if (move_with_anchor() && anchor_widget() == widget)
+ SizeToContents();
+}
+
gfx::Rect BubbleDelegateView::GetAnchorRect() {
return anchor_view() ? anchor_view()->GetScreenBounds() : gfx::Rect();
}