| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/views/extensions/extension_popup.h" | 5 #include "chrome/browser/views/extensions/extension_popup.h" |
| 6 | 6 |
| 7 #include "chrome/browser/browser.h" | 7 #include "chrome/browser/browser.h" |
| 8 #include "chrome/browser/browser_window.h" | 8 #include "chrome/browser/browser_window.h" |
| 9 #include "chrome/browser/profile.h" | 9 #include "chrome/browser/profile.h" |
| 10 #include "chrome/browser/extensions/extension_process_manager.h" | 10 #include "chrome/browser/extensions/extension_process_manager.h" |
| 11 #include "chrome/browser/views/frame/browser_view.h" | 11 #include "chrome/browser/views/frame/browser_view.h" |
| 12 #include "chrome/common/extensions/extension.h" | 12 #include "chrome/common/extensions/extension.h" |
| 13 #include "chrome/common/notification_details.h" | 13 #include "chrome/common/notification_details.h" |
| 14 #include "chrome/common/notification_source.h" | 14 #include "chrome/common/notification_source.h" |
| 15 #include "chrome/common/notification_type.h" | 15 #include "chrome/common/notification_type.h" |
| 16 | 16 |
| 17 #include "views/widget/root_view.h" |
| 18 |
| 17 ExtensionPopup::ExtensionPopup(ExtensionHost* host, | 19 ExtensionPopup::ExtensionPopup(ExtensionHost* host, |
| 18 views::Widget* frame, | 20 views::Widget* frame, |
| 19 const gfx::Rect& relative_to) | 21 const gfx::Rect& relative_to) |
| 20 : BrowserBubble(host->view(), | 22 : BrowserBubble(host->view(), frame, gfx::Point()), |
| 21 frame, | |
| 22 gfx::Point()), | |
| 23 relative_to_(relative_to), | 23 relative_to_(relative_to), |
| 24 extension_host_(host) { | 24 extension_host_(host) { |
| 25 registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING, | 25 registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING, |
| 26 Source<Profile>(host->profile())); | 26 Source<Profile>(host->profile())); |
| 27 |
| 28 // TODO(erikkay) Some of this border code is derived from InfoBubble. |
| 29 // We should see if we can unify these classes. |
| 30 gfx::NativeWindow native_window = frame->GetNativeView(); |
| 31 border_widget_.reset(views::Widget::CreateTransparentPopupWidget(true)); |
| 32 border_widget_->Init(native_window, bounds()); |
| 33 border_ = new BubbleBorder; |
| 34 border_->set_arrow_location(BubbleBorder::TOP_RIGHT); |
| 35 border_view_ = new views::View; |
| 36 border_view_->set_background(new BubbleBackground(border_)); |
| 37 border_view_->set_border(border_); |
| 38 border_widget_->SetContentsView(border_view_); |
| 27 } | 39 } |
| 28 | 40 |
| 29 ExtensionPopup::~ExtensionPopup() { | 41 ExtensionPopup::~ExtensionPopup() { |
| 42 border_widget_->Close(); |
| 43 } |
| 44 |
| 45 void ExtensionPopup::Hide() { |
| 46 BrowserBubble::Hide(); |
| 47 border_widget_->Hide(); |
| 30 } | 48 } |
| 31 | 49 |
| 32 void ExtensionPopup::Show() { | 50 void ExtensionPopup::Show() { |
| 33 ResizeToView(); | 51 ResizeToView(); |
| 34 | 52 |
| 35 // Anchor on the lower right corner and extend to the left. | 53 // The rounded corners cut off more of the view than the border insets claim. |
| 36 SetBounds(relative_to_.right() - width(), relative_to_.bottom(), | 54 // Since we can't clip the ExtensionView's corners, we need to increase the |
| 37 width(), height()); | 55 // inset by half the corner radius as well as lying about the size of the |
| 56 // contents size to compensate. |
| 57 int corner_inset = BubbleBorder::GetCornerRadius() / 2; |
| 58 gfx::Size adjusted_size = bounds().size(); |
| 59 adjusted_size.Enlarge(2 * corner_inset, 2 * corner_inset); |
| 60 gfx::Rect rect = border_->GetBounds(relative_to_, adjusted_size); |
| 61 border_widget_->SetBounds(rect); |
| 62 |
| 63 // Now calculate the inner bounds. This is a bit more convoluted than |
| 64 // it should be because BrowserBubble coordinates are in Browser coordinates |
| 65 // while |rect| is in screen coordinates. |
| 66 gfx::Insets border_insets; |
| 67 border_->GetInsets(&border_insets); |
| 68 gfx::Point origin = rect.origin(); |
| 69 views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin); |
| 70 origin.set_x(origin.x() + border_insets.left() + corner_inset); |
| 71 origin.set_y(origin.y() + border_insets.top() + corner_inset); |
| 72 MoveTo(origin.x(), origin.y()); |
| 73 |
| 74 // Show the border first, then the popup overlaid on top. |
| 75 border_widget_->Show(); |
| 38 BrowserBubble::Show(true); | 76 BrowserBubble::Show(true); |
| 39 } | 77 } |
| 40 | 78 |
| 41 void ExtensionPopup::Observe(NotificationType type, | 79 void ExtensionPopup::Observe(NotificationType type, |
| 42 const NotificationSource& source, | 80 const NotificationSource& source, |
| 43 const NotificationDetails& details) { | 81 const NotificationDetails& details) { |
| 44 if (type == NotificationType::EXTENSION_HOST_DID_STOP_LOADING) { | 82 if (type == NotificationType::EXTENSION_HOST_DID_STOP_LOADING) { |
| 45 // Once we receive did stop loading, the content will be complete and | 83 // Once we receive did stop loading, the content will be complete and |
| 46 // the width will have been computed. Now it's safe to show. | 84 // the width will have been computed. Now it's safe to show. |
| 47 if (extension_host_.get() == Details<ExtensionHost>(details).ptr()) | 85 if (extension_host_.get() == Details<ExtensionHost>(details).ptr()) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 69 sz.set_height(height); | 107 sz.set_height(height); |
| 70 host->view()->SetPreferredSize(sz); | 108 host->view()->SetPreferredSize(sz); |
| 71 | 109 |
| 72 // If the host had somehow finished loading, then we'd miss the notification | 110 // If the host had somehow finished loading, then we'd miss the notification |
| 73 // and not show. This seems to happen in single-process mode. | 111 // and not show. This seems to happen in single-process mode. |
| 74 if (host->did_stop_loading()) | 112 if (host->did_stop_loading()) |
| 75 popup->Show(); | 113 popup->Show(); |
| 76 | 114 |
| 77 return popup; | 115 return popup; |
| 78 } | 116 } |
| OLD | NEW |