| 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 #include "views/widget/root_view.h" |
| 16 | 17 |
| 17 #include "views/widget/root_view.h" | 18 // The minimum/maximum dimensions of the popup. |
| 19 // The minimum is just a little larger than the size of the button itself. |
| 20 // The maximum is an arbitrary number that should be smaller than most screens. |
| 21 const int ExtensionPopup::kMinWidth = 25; |
| 22 const int ExtensionPopup::kMinHeight = 25; |
| 23 const int ExtensionPopup::kMaxWidth = 800; |
| 24 const int ExtensionPopup::kMaxHeight = 600; |
| 18 | 25 |
| 19 ExtensionPopup::ExtensionPopup(ExtensionHost* host, | 26 ExtensionPopup::ExtensionPopup(ExtensionHost* host, |
| 20 views::Widget* frame, | 27 views::Widget* frame, |
| 21 const gfx::Rect& relative_to) | 28 const gfx::Rect& relative_to) |
| 22 : BrowserBubble(host->view(), frame, gfx::Point()), | 29 : BrowserBubble(host->view(), frame, gfx::Point()), |
| 23 relative_to_(relative_to), | 30 relative_to_(relative_to), |
| 24 extension_host_(host) { | 31 extension_host_(host) { |
| 25 host->view()->SetContainer(this); | 32 host->view()->SetContainer(this); |
| 26 registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING, | 33 registrar_.Add(this, NotificationType::EXTENSION_HOST_DID_STOP_LOADING, |
| 27 Source<Profile>(host->profile())); | 34 Source<Profile>(host->profile())); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 56 return; | 63 return; |
| 57 | 64 |
| 58 ResizeToView(); | 65 ResizeToView(); |
| 59 | 66 |
| 60 // Show the border first, then the popup overlaid on top. | 67 // Show the border first, then the popup overlaid on top. |
| 61 border_widget_->Show(); | 68 border_widget_->Show(); |
| 62 BrowserBubble::Show(true); | 69 BrowserBubble::Show(true); |
| 63 } | 70 } |
| 64 | 71 |
| 65 void ExtensionPopup::ResizeToView() { | 72 void ExtensionPopup::ResizeToView() { |
| 66 BrowserBubble::ResizeToView(); | 73 // We'll be sizing ourselves to this size shortly, but wait until we |
| 74 // know our position to do it. |
| 75 gfx::Size new_size = view()->size(); |
| 67 | 76 |
| 68 // The rounded corners cut off more of the view than the border insets claim. | 77 // The rounded corners cut off more of the view than the border insets claim. |
| 69 // Since we can't clip the ExtensionView's corners, we need to increase the | 78 // Since we can't clip the ExtensionView's corners, we need to increase the |
| 70 // inset by half the corner radius as well as lying about the size of the | 79 // inset by half the corner radius as well as lying about the size of the |
| 71 // contents size to compensate. | 80 // contents size to compensate. |
| 72 int corner_inset = BubbleBorder::GetCornerRadius() / 2; | 81 int corner_inset = BubbleBorder::GetCornerRadius() / 2; |
| 73 gfx::Size adjusted_size = bounds().size(); | 82 gfx::Size adjusted_size = new_size; |
| 74 adjusted_size.Enlarge(2 * corner_inset, 2 * corner_inset); | 83 adjusted_size.Enlarge(2 * corner_inset, 2 * corner_inset); |
| 75 gfx::Rect rect = border_->GetBounds(relative_to_, adjusted_size); | 84 gfx::Rect rect = border_->GetBounds(relative_to_, adjusted_size); |
| 76 border_widget_->SetBounds(rect); | 85 border_widget_->SetBounds(rect); |
| 77 | 86 |
| 78 // Now calculate the inner bounds. This is a bit more convoluted than | 87 // Now calculate the inner bounds. This is a bit more convoluted than |
| 79 // it should be because BrowserBubble coordinates are in Browser coordinates | 88 // it should be because BrowserBubble coordinates are in Browser coordinates |
| 80 // while |rect| is in screen coordinates. | 89 // while |rect| is in screen coordinates. |
| 81 gfx::Insets border_insets; | 90 gfx::Insets border_insets; |
| 82 border_->GetInsets(&border_insets); | 91 border_->GetInsets(&border_insets); |
| 83 gfx::Point origin = rect.origin(); | 92 gfx::Point origin = rect.origin(); |
| 84 views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin); | 93 views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin); |
| 85 origin.set_x(origin.x() + border_insets.left() + corner_inset); | 94 origin.set_x(origin.x() + border_insets.left() + corner_inset); |
| 86 origin.set_y(origin.y() + border_insets.top() + corner_inset); | 95 origin.set_y(origin.y() + border_insets.top() + corner_inset); |
| 87 MoveTo(origin.x(), origin.y()); | 96 |
| 97 SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height()); |
| 88 } | 98 } |
| 89 | 99 |
| 90 void ExtensionPopup::Observe(NotificationType type, | 100 void ExtensionPopup::Observe(NotificationType type, |
| 91 const NotificationSource& source, | 101 const NotificationSource& source, |
| 92 const NotificationDetails& details) { | 102 const NotificationDetails& details) { |
| 93 if (type == NotificationType::EXTENSION_HOST_DID_STOP_LOADING) { | 103 if (type == NotificationType::EXTENSION_HOST_DID_STOP_LOADING) { |
| 94 // Once we receive did stop loading, the content will be complete and | 104 // Once we receive did stop loading, the content will be complete and |
| 95 // the width will have been computed. Now it's safe to show. | 105 // the width will have been computed. Now it's safe to show. |
| 96 if (extension_host_.get() == Details<ExtensionHost>(details).ptr()) | 106 if (extension_host_.get() == Details<ExtensionHost>(details).ptr()) |
| 97 Show(); | 107 Show(); |
| 98 } else { | 108 } else { |
| 99 NOTREACHED() << L"Received unexpected notification"; | 109 NOTREACHED() << L"Received unexpected notification"; |
| 100 } | 110 } |
| 101 } | 111 } |
| 102 | 112 |
| 103 void ExtensionPopup::OnExtensionPreferredSizeChanged(ExtensionView* view) { | 113 void ExtensionPopup::OnExtensionPreferredSizeChanged(ExtensionView* view) { |
| 104 view->SizeToPreferredSize(); | 114 // Constrain the size to popup min/max. |
| 115 gfx::Size sz = view->GetPreferredSize(); |
| 116 view->SetBounds(view->x(), view->y(), |
| 117 std::max(kMinWidth, std::min(kMaxWidth, sz.width())), |
| 118 std::max(kMinHeight, std::min(kMaxHeight, sz.height()))); |
| 119 |
| 105 ResizeToView(); | 120 ResizeToView(); |
| 106 } | 121 } |
| 107 | 122 |
| 108 // static | 123 // static |
| 109 ExtensionPopup* ExtensionPopup::Show(const GURL& url, Browser* browser, | 124 ExtensionPopup* ExtensionPopup::Show(const GURL& url, Browser* browser, |
| 110 const gfx::Rect& relative_to) { | 125 const gfx::Rect& relative_to) { |
| 111 ExtensionProcessManager* manager = | 126 ExtensionProcessManager* manager = |
| 112 browser->profile()->GetExtensionProcessManager(); | 127 browser->profile()->GetExtensionProcessManager(); |
| 113 DCHECK(manager); | 128 DCHECK(manager); |
| 114 if (!manager) | 129 if (!manager) |
| 115 return NULL; | 130 return NULL; |
| 116 | 131 |
| 117 ExtensionHost* host = manager->CreatePopup(url, browser); | 132 ExtensionHost* host = manager->CreatePopup(url, browser); |
| 118 views::Widget* frame = BrowserView::GetBrowserViewForNativeWindow( | 133 views::Widget* frame = BrowserView::GetBrowserViewForNativeWindow( |
| 119 browser->window()->GetNativeHandle())->GetWidget(); | 134 browser->window()->GetNativeHandle())->GetWidget(); |
| 120 ExtensionPopup* popup = new ExtensionPopup(host, frame, relative_to); | 135 ExtensionPopup* popup = new ExtensionPopup(host, frame, relative_to); |
| 121 | 136 |
| 122 // If the host had somehow finished loading, then we'd miss the notification | 137 // If the host had somehow finished loading, then we'd miss the notification |
| 123 // and not show. This seems to happen in single-process mode. | 138 // and not show. This seems to happen in single-process mode. |
| 124 if (host->did_stop_loading()) | 139 if (host->did_stop_loading()) |
| 125 popup->Show(); | 140 popup->Show(); |
| 126 | 141 |
| 127 return popup; | 142 return popup; |
| 128 } | 143 } |
| OLD | NEW |