| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/views/bubble/bubble_delegate.h" | 5 #include "ui/views/bubble/bubble_delegate.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 #include "ui/accessibility/ax_view_state.h" | 8 #include "ui/accessibility/ax_view_state.h" |
| 9 #include "ui/base/resource/resource_bundle.h" | 9 #include "ui/base/resource/resource_bundle.h" |
| 10 #include "ui/gfx/color_utils.h" | 10 #include "ui/gfx/color_utils.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 bubble_widget->StackAbove(bubble_params.parent); | 45 bubble_widget->StackAbove(bubble_params.parent); |
| 46 return bubble_widget; | 46 return bubble_widget; |
| 47 } | 47 } |
| 48 | 48 |
| 49 } // namespace | 49 } // namespace |
| 50 | 50 |
| 51 // static | 51 // static |
| 52 const char BubbleDelegateView::kViewClassName[] = "BubbleDelegateView"; | 52 const char BubbleDelegateView::kViewClassName[] = "BubbleDelegateView"; |
| 53 | 53 |
| 54 BubbleDelegateView::BubbleDelegateView() | 54 BubbleDelegateView::BubbleDelegateView() |
| 55 : BubbleDelegateView(nullptr, BubbleBorder::TOP_LEFT) {} | 55 : BubbleDelegateView(static_cast<View*>(nullptr), BubbleBorder::TOP_LEFT) {} |
| 56 |
| 57 BubbleDelegateView::BubbleDelegateView(WidgetObserverView* anchor_view, |
| 58 BubbleBorder::Arrow arrow) |
| 59 : BubbleDelegateView(static_cast<View*>(anchor_view), arrow) { |
| 60 anchor_view_has_widget_observer_ = true; |
| 61 } |
| 56 | 62 |
| 57 BubbleDelegateView::BubbleDelegateView(View* anchor_view, | 63 BubbleDelegateView::BubbleDelegateView(View* anchor_view, |
| 58 BubbleBorder::Arrow arrow) | 64 BubbleBorder::Arrow arrow) |
| 59 : close_on_esc_(true), | 65 : close_on_esc_(true), |
| 60 close_on_deactivate_(true), | 66 close_on_deactivate_(true), |
| 61 anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()), | 67 anchor_view_storage_id_(ViewStorage::GetInstance()->CreateStorageID()), |
| 62 anchor_widget_(NULL), | 68 anchor_widget_(NULL), |
| 69 anchor_view_has_widget_observer_(false), |
| 63 arrow_(arrow), | 70 arrow_(arrow), |
| 64 shadow_(BubbleBorder::SMALL_SHADOW), | 71 shadow_(BubbleBorder::SMALL_SHADOW), |
| 65 color_explicitly_set_(false), | 72 color_explicitly_set_(false), |
| 66 margins_(kDefaultMargin, kDefaultMargin, kDefaultMargin, kDefaultMargin), | 73 margins_(kDefaultMargin, kDefaultMargin, kDefaultMargin, kDefaultMargin), |
| 67 accept_events_(true), | 74 accept_events_(true), |
| 68 border_accepts_events_(true), | 75 border_accepts_events_(true), |
| 69 adjust_if_offscreen_(true), | 76 adjust_if_offscreen_(true), |
| 70 parent_window_(NULL), | 77 parent_window_(NULL), |
| 71 close_reason_(CloseReason::UNKNOWN) { | 78 close_reason_(CloseReason::UNKNOWN) { |
| 72 if (anchor_view) | 79 if (anchor_view) |
| 73 SetAnchorView(anchor_view); | 80 SetAnchorView(anchor_view); |
| 74 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); | 81 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); |
| 75 UpdateColorsFromTheme(GetNativeTheme()); | 82 UpdateColorsFromTheme(GetNativeTheme()); |
| 76 } | 83 } |
| 77 | 84 |
| 78 BubbleDelegateView::~BubbleDelegateView() { | 85 BubbleDelegateView::~BubbleDelegateView() { |
| 79 if (GetWidget()) | 86 if (GetWidget()) { |
| 80 GetWidget()->RemoveObserver(this); | 87 GetWidget()->RemoveObserver(this); |
| 88 if (anchor_view_has_widget_observer_) { |
| 89 View* anchor_view = GetAnchorView(); |
| 90 if (anchor_view) { |
| 91 GetWidget()->RemoveObserver( |
| 92 static_cast<WidgetObserverView*>(anchor_view)); |
| 93 } |
| 94 } |
| 95 } |
| 81 SetLayoutManager(NULL); | 96 SetLayoutManager(NULL); |
| 82 SetAnchorView(NULL); | 97 SetAnchorView(NULL); |
| 83 } | 98 } |
| 84 | 99 |
| 85 // static | 100 // static |
| 86 Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) { | 101 Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) { |
| 87 bubble_delegate->Init(); | 102 bubble_delegate->Init(); |
| 88 // Get the latest anchor widget from the anchor view at bubble creation time. | 103 // Get the latest anchor widget from the anchor view at bubble creation time. |
| 89 bubble_delegate->SetAnchorView(bubble_delegate->GetAnchorView()); | 104 View* anchor_view = bubble_delegate->GetAnchorView(); |
| 105 bubble_delegate->SetAnchorView(anchor_view); |
| 90 Widget* bubble_widget = CreateBubbleWidget(bubble_delegate); | 106 Widget* bubble_widget = CreateBubbleWidget(bubble_delegate); |
| 91 | 107 |
| 92 #if defined(OS_WIN) | 108 #if defined(OS_WIN) |
| 93 // If glass is enabled, the bubble is allowed to extend outside the bounds of | 109 // If glass is enabled, the bubble is allowed to extend outside the bounds of |
| 94 // the parent frame and let DWM handle compositing. If not, then we don't | 110 // the parent frame and let DWM handle compositing. If not, then we don't |
| 95 // want to allow the bubble to extend the frame because it will be clipped. | 111 // want to allow the bubble to extend the frame because it will be clipped. |
| 96 bubble_delegate->set_adjust_if_offscreen(ui::win::IsAeroGlassEnabled()); | 112 bubble_delegate->set_adjust_if_offscreen(ui::win::IsAeroGlassEnabled()); |
| 97 #elif (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || defined(OS_MACOSX) | 113 #elif (defined(OS_LINUX) && !defined(OS_CHROMEOS)) || defined(OS_MACOSX) |
| 98 // Linux clips bubble windows that extend outside their parent window bounds. | 114 // Linux clips bubble windows that extend outside their parent window bounds. |
| 99 // Mac never adjusts. | 115 // Mac never adjusts. |
| 100 bubble_delegate->set_adjust_if_offscreen(false); | 116 bubble_delegate->set_adjust_if_offscreen(false); |
| 101 #endif | 117 #endif |
| 102 | 118 |
| 103 bubble_delegate->SizeToContents(); | 119 bubble_delegate->SizeToContents(); |
| 104 bubble_widget->AddObserver(bubble_delegate); | 120 bubble_widget->AddObserver(bubble_delegate); |
| 121 if (bubble_delegate->anchor_view_has_widget_observer_) |
| 122 bubble_widget->AddObserver(static_cast<WidgetObserverView*>(anchor_view)); |
| 105 return bubble_widget; | 123 return bubble_widget; |
| 106 } | 124 } |
| 107 | 125 |
| 108 BubbleDelegateView* BubbleDelegateView::AsBubbleDelegate() { | 126 BubbleDelegateView* BubbleDelegateView::AsBubbleDelegate() { |
| 109 return this; | 127 return this; |
| 110 } | 128 } |
| 111 | 129 |
| 112 bool BubbleDelegateView::ShouldShowCloseButton() const { | 130 bool BubbleDelegateView::ShouldShowCloseButton() const { |
| 113 return false; | 131 return false; |
| 114 } | 132 } |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 return true; | 243 return true; |
| 226 } | 244 } |
| 227 | 245 |
| 228 void BubbleDelegateView::OnNativeThemeChanged(const ui::NativeTheme* theme) { | 246 void BubbleDelegateView::OnNativeThemeChanged(const ui::NativeTheme* theme) { |
| 229 UpdateColorsFromTheme(theme); | 247 UpdateColorsFromTheme(theme); |
| 230 } | 248 } |
| 231 | 249 |
| 232 void BubbleDelegateView::Init() {} | 250 void BubbleDelegateView::Init() {} |
| 233 | 251 |
| 234 void BubbleDelegateView::SetAnchorView(View* anchor_view) { | 252 void BubbleDelegateView::SetAnchorView(View* anchor_view) { |
| 253 View* previous_anchor_view = GetAnchorView(); |
| 254 if (anchor_view == previous_anchor_view) |
| 255 return; |
| 235 // When the anchor view gets set the associated anchor widget might | 256 // When the anchor view gets set the associated anchor widget might |
| 236 // change as well. | 257 // change as well. |
| 237 if (!anchor_view || anchor_widget() != anchor_view->GetWidget()) { | 258 if (!anchor_view || anchor_widget() != anchor_view->GetWidget()) { |
| 238 if (anchor_widget()) { | 259 if (anchor_widget()) { |
| 239 anchor_widget_->RemoveObserver(this); | 260 anchor_widget_->RemoveObserver(this); |
| 240 anchor_widget_ = NULL; | 261 anchor_widget_ = NULL; |
| 241 } | 262 } |
| 242 if (anchor_view) { | 263 if (anchor_view) { |
| 243 anchor_widget_ = anchor_view->GetWidget(); | 264 anchor_widget_ = anchor_view->GetWidget(); |
| 244 if (anchor_widget_) | 265 if (anchor_widget_) |
| 245 anchor_widget_->AddObserver(this); | 266 anchor_widget_->AddObserver(this); |
| 246 } | 267 } |
| 247 } | 268 } |
| 248 | 269 |
| 249 // Remove the old storage item and set the new (if there is one). | 270 // Remove the old storage item and set the new (if there is one). |
| 250 ViewStorage* view_storage = ViewStorage::GetInstance(); | 271 ViewStorage* view_storage = ViewStorage::GetInstance(); |
| 251 if (view_storage->RetrieveView(anchor_view_storage_id_)) | 272 if (previous_anchor_view) { |
| 273 if (anchor_view_has_widget_observer_ && GetWidget()) { |
| 274 GetWidget()->RemoveObserver( |
| 275 static_cast<WidgetObserverView*>(previous_anchor_view)); |
| 276 } |
| 277 anchor_view_has_widget_observer_ = false; |
| 252 view_storage->RemoveView(anchor_view_storage_id_); | 278 view_storage->RemoveView(anchor_view_storage_id_); |
| 279 } |
| 253 if (anchor_view) | 280 if (anchor_view) |
| 254 view_storage->StoreView(anchor_view_storage_id_, anchor_view); | 281 view_storage->StoreView(anchor_view_storage_id_, anchor_view); |
| 255 | 282 |
| 256 // Do not update anchoring for NULL views; this could indicate that our | 283 // Do not update anchoring for NULL views; this could indicate that our |
| 257 // NativeWindow is being destroyed, so it would be dangerous for us to update | 284 // NativeWindow is being destroyed, so it would be dangerous for us to update |
| 258 // our anchor bounds at that point. (It's safe to skip this, since if we were | 285 // our anchor bounds at that point. (It's safe to skip this, since if we were |
| 259 // to update the bounds when |anchor_view| is NULL, the bubble won't move.) | 286 // to update the bounds when |anchor_view| is NULL, the bubble won't move.) |
| 260 if (anchor_view && GetWidget()) | 287 if (anchor_view && GetWidget()) |
| 261 OnAnchorBoundsChanged(); | 288 OnAnchorBoundsChanged(); |
| 262 } | 289 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 // http://crbug.com/474622 for details. | 342 // http://crbug.com/474622 for details. |
| 316 if (widget == GetWidget() && visible) { | 343 if (widget == GetWidget() && visible) { |
| 317 ui::AXViewState state; | 344 ui::AXViewState state; |
| 318 GetAccessibleState(&state); | 345 GetAccessibleState(&state); |
| 319 if (state.role == ui::AX_ROLE_ALERT_DIALOG) | 346 if (state.role == ui::AX_ROLE_ALERT_DIALOG) |
| 320 NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true); | 347 NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true); |
| 321 } | 348 } |
| 322 } | 349 } |
| 323 | 350 |
| 324 } // namespace views | 351 } // namespace views |
| OLD | NEW |