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 |