Index: ui/views/bubble/bubble_delegate.cc |
diff --git a/ui/views/bubble/bubble_delegate.cc b/ui/views/bubble/bubble_delegate.cc |
index af08994d487f5905b3471e806cfb899664de10e0..426ea12c0f35b5a8a83b1b3f7517ba1623543643 100644 |
--- a/ui/views/bubble/bubble_delegate.cc |
+++ b/ui/views/bubble/bubble_delegate.cc |
@@ -9,6 +9,7 @@ |
#include "ui/gfx/rect.h" |
#include "ui/native_theme/native_theme.h" |
#include "ui/views/bubble/bubble_frame_view.h" |
+#include "ui/views/focus/view_storage.h" |
#include "ui/views/widget/widget.h" |
#include "ui/views/widget/widget_observer.h" |
@@ -128,7 +129,7 @@ Widget* CreateBorderWidget(BubbleDelegateView* bubble) { |
BubbleDelegateView::BubbleDelegateView() |
: close_on_esc_(true), |
close_on_deactivate_(true), |
- anchor_view_(NULL), |
+ anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()), |
anchor_widget_(NULL), |
move_with_anchor_(false), |
arrow_(BubbleBorder::TOP_LEFT), |
@@ -151,7 +152,7 @@ BubbleDelegateView::BubbleDelegateView( |
BubbleBorder::Arrow arrow) |
: close_on_esc_(true), |
close_on_deactivate_(true), |
- anchor_view_(anchor_view), |
+ anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()), |
anchor_widget_(NULL), |
move_with_anchor_(false), |
arrow_(arrow), |
@@ -165,26 +166,20 @@ BubbleDelegateView::BubbleDelegateView( |
border_accepts_events_(true), |
adjust_if_offscreen_(true), |
parent_window_(NULL) { |
+ SetAnchorView(anchor_view); |
AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); |
UpdateColorsFromTheme(GetNativeTheme()); |
} |
BubbleDelegateView::~BubbleDelegateView() { |
- if (anchor_widget() != NULL) |
- anchor_widget()->RemoveObserver(this); |
- anchor_widget_ = NULL; |
- anchor_view_ = NULL; |
+ SetAnchorView(NULL); |
} |
// static |
Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) { |
bubble_delegate->Init(); |
- // 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; |
- if (bubble_delegate->anchor_widget()) |
- bubble_delegate->anchor_widget()->AddObserver(bubble_delegate); |
- |
+ // Get the latest anchor widget from the anchor view at bubble creation time. |
+ bubble_delegate->SetAnchorView(bubble_delegate->GetAnchorView()); |
Widget* bubble_widget = CreateBubbleWidget(bubble_delegate); |
#if defined(OS_WIN) |
@@ -231,11 +226,8 @@ NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView( |
} |
void BubbleDelegateView::OnWidgetDestroying(Widget* widget) { |
- if (anchor_widget() == widget) { |
- anchor_widget_->RemoveObserver(this); |
- anchor_view_ = NULL; |
- anchor_widget_ = NULL; |
- } |
+ if (anchor_widget() == widget) |
+ SetAnchorView(NULL); |
} |
void BubbleDelegateView::OnWidgetVisibilityChanging(Widget* widget, |
@@ -267,12 +259,17 @@ void BubbleDelegateView::OnWidgetBoundsChanged(Widget* widget, |
SizeToContents(); |
} |
+View* BubbleDelegateView::GetAnchorView() const { |
+ return ViewStorage::GetInstance()->RetrieveView(anchor_view_storage_id_); |
+} |
+ |
gfx::Rect BubbleDelegateView::GetAnchorRect() { |
- if (!anchor_view()) |
+ if (!GetAnchorView()) |
return anchor_rect_; |
- gfx::Rect anchor_bounds = anchor_view()->GetBoundsInScreen(); |
- anchor_bounds.Inset(anchor_view_insets_); |
- return anchor_bounds; |
+ |
+ anchor_rect_ = GetAnchorView()->GetBoundsInScreen(); |
+ anchor_rect_.Inset(anchor_view_insets_); |
+ return anchor_rect_; |
} |
void BubbleDelegateView::StartFade(bool fade_in) { |
@@ -370,6 +367,30 @@ void BubbleDelegateView::AnimationProgressed(const gfx::Animation* animation) { |
void BubbleDelegateView::Init() {} |
+void BubbleDelegateView::SetAnchorView(View* anchor_view) { |
+ // When the anchor view gets set the associated anchor widget might |
+ // change as well. |
+ if (!anchor_view || anchor_widget() != anchor_view->GetWidget()) { |
+ if (anchor_widget()) { |
+ anchor_widget_->RemoveObserver(this); |
+ anchor_widget_ = NULL; |
+ } |
+ if (anchor_view) { |
+ anchor_widget_ = anchor_view->GetWidget(); |
+ if (anchor_widget_) |
+ anchor_widget_->AddObserver(this); |
+ } |
+ } |
+ |
+ // Remove the old storage item and set the new (if there is one). |
+ ViewStorage* view_storage = ViewStorage::GetInstance(); |
+ if (view_storage->RetrieveView(anchor_view_storage_id_)) |
+ view_storage->RemoveView(anchor_view_storage_id_); |
+ |
+ if (anchor_view) |
+ view_storage->StoreView(anchor_view_storage_id_, anchor_view); |
+} |
+ |
void BubbleDelegateView::SizeToContents() { |
#if defined(OS_WIN) && !defined(USE_AURA) |
border_widget_->SetBounds(GetBubbleBounds()); |