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_list.h" | 8 #include "chrome/browser/browser_list.h" |
9 #include "chrome/browser/browser_window.h" | 9 #include "chrome/browser/browser_window.h" |
10 #include "chrome/browser/debugger/devtools_manager.h" | 10 #include "chrome/browser/debugger/devtools_manager.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 using views::Widget; | 34 using views::Widget; |
35 | 35 |
36 // The minimum/maximum dimensions of the popup. | 36 // The minimum/maximum dimensions of the popup. |
37 // The minimum is just a little larger than the size of the button itself. | 37 // The minimum is just a little larger than the size of the button itself. |
38 // The maximum is an arbitrary number that should be smaller than most screens. | 38 // The maximum is an arbitrary number that should be smaller than most screens. |
39 const int ExtensionPopup::kMinWidth = 25; | 39 const int ExtensionPopup::kMinWidth = 25; |
40 const int ExtensionPopup::kMinHeight = 25; | 40 const int ExtensionPopup::kMinHeight = 25; |
41 const int ExtensionPopup::kMaxWidth = 800; | 41 const int ExtensionPopup::kMaxWidth = 800; |
42 const int ExtensionPopup::kMaxHeight = 600; | 42 const int ExtensionPopup::kMaxHeight = 600; |
43 | 43 |
| 44 namespace { |
| 45 |
44 // The width, in pixels, of the black-border on a popup. | 46 // The width, in pixels, of the black-border on a popup. |
45 const int kPopupBorderWidth = 1; | 47 const int kPopupBorderWidth = 1; |
46 | 48 |
47 const int kPopupBubbleCornerRadius = BubbleBorder::GetCornerRadius() / 2; | 49 const int kPopupBubbleCornerRadius = BubbleBorder::GetCornerRadius() / 2; |
48 | 50 |
| 51 } // namespace |
| 52 |
49 ExtensionPopup::ExtensionPopup(ExtensionHost* host, | 53 ExtensionPopup::ExtensionPopup(ExtensionHost* host, |
50 views::Widget* frame, | 54 views::Widget* frame, |
51 const gfx::Rect& relative_to, | 55 const gfx::Rect& relative_to, |
52 BubbleBorder::ArrowLocation arrow_location, | 56 BubbleBorder::ArrowLocation arrow_location, |
53 bool activate_on_show, | 57 bool activate_on_show, |
54 bool inspect_with_devtools, | 58 bool inspect_with_devtools, |
55 PopupChrome chrome, | 59 PopupChrome chrome, |
56 Observer* observer) | 60 Observer* observer) |
57 : BrowserBubble(host->view(), | 61 : BrowserBubble(host->view(), |
58 frame, | 62 frame, |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 view()->set_border(border); | 135 view()->set_border(border); |
132 } | 136 } |
133 } | 137 } |
134 | 138 |
135 ExtensionPopup::~ExtensionPopup() { | 139 ExtensionPopup::~ExtensionPopup() { |
136 // The widget is set to delete on destroy, so no leak here. | 140 // The widget is set to delete on destroy, so no leak here. |
137 if (border_widget_) | 141 if (border_widget_) |
138 border_widget_->Close(); | 142 border_widget_->Close(); |
139 } | 143 } |
140 | 144 |
| 145 void ExtensionPopup::SetArrowPosition( |
| 146 BubbleBorder::ArrowLocation arrow_location) { |
| 147 DCHECK_NE(BubbleBorder::NONE, arrow_location) << |
| 148 "Extension popups must be positioned relative to an arrow."; |
| 149 |
| 150 anchor_position_ = arrow_location; |
| 151 if (border_) |
| 152 border_->set_arrow_location(anchor_position_); |
| 153 } |
| 154 |
141 void ExtensionPopup::Hide() { | 155 void ExtensionPopup::Hide() { |
142 BrowserBubble::Hide(); | 156 BrowserBubble::Hide(); |
143 if (border_widget_) | 157 if (border_widget_) |
144 border_widget_->Hide(); | 158 border_widget_->Hide(); |
145 } | 159 } |
146 | 160 |
147 void ExtensionPopup::Show(bool activate) { | 161 void ExtensionPopup::Show(bool activate) { |
148 if (visible()) | 162 if (visible()) |
149 return; | 163 return; |
150 | 164 |
151 #if defined(OS_WIN) | 165 #if defined(OS_WIN) |
152 if (frame_->GetWindow()) | 166 if (frame_->GetWindow()) |
153 frame_->GetWindow()->DisableInactiveRendering(); | 167 frame_->GetWindow()->DisableInactiveRendering(); |
154 #endif | 168 #endif |
155 | 169 |
156 ResizeToView(); | 170 ResizeToView(); |
157 | 171 |
158 // Show the border first, then the popup overlaid on top. | 172 // Show the border first, then the popup overlaid on top. |
159 if (border_widget_) | 173 if (border_widget_) |
160 border_widget_->Show(); | 174 border_widget_->Show(); |
161 BrowserBubble::Show(activate); | 175 BrowserBubble::Show(activate); |
162 } | 176 } |
163 | 177 |
164 void ExtensionPopup::ResizeToView() { | 178 void ExtensionPopup::ResizeToView() { |
165 // We'll be sizing ourselves to this size shortly, but wait until we | 179 if (observer_) |
166 // know our position to do it. | 180 observer_->ExtensionPopupResized(this); |
167 gfx::Size new_size = view()->size(); | |
168 | 181 |
169 // Convert rect to screen coordinates. | 182 gfx::Rect rect = GetOuterBounds(); |
170 gfx::Rect rect = relative_to_; | 183 |
171 gfx::Point origin = rect.origin(); | 184 gfx::Point origin = rect.origin(); |
172 views::View::ConvertPointToScreen(frame_->GetRootView(), &origin); | 185 views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin); |
173 rect.set_origin(origin); | |
174 | 186 |
175 rect = GetOuterBounds(rect, new_size); | |
176 origin = rect.origin(); | |
177 views::View::ConvertPointToView(NULL, frame_->GetRootView(), &origin); | |
178 if (border_widget_) { | 187 if (border_widget_) { |
179 // Set the bubble-chrome widget according to the outer bounds of the entire | 188 // Set the bubble-chrome widget according to the outer bounds of the entire |
180 // popup. | 189 // popup. |
181 border_widget_->SetBounds(rect); | 190 border_widget_->SetBounds(rect); |
182 | 191 |
183 // Now calculate the inner bounds. This is a bit more convoluted than | 192 // Now calculate the inner bounds. This is a bit more convoluted than |
184 // it should be because BrowserBubble coordinates are in Browser coordinates | 193 // it should be because BrowserBubble coordinates are in Browser coordinates |
185 // while |rect| is in screen coordinates. | 194 // while |rect| is in screen coordinates. |
186 gfx::Insets border_insets; | 195 gfx::Insets border_insets; |
187 border_->GetInsets(&border_insets); | 196 border_->GetInsets(&border_insets); |
188 | 197 |
189 origin.set_x(origin.x() + border_insets.left() + kPopupBubbleCornerRadius); | 198 origin.set_x(origin.x() + border_insets.left() + kPopupBubbleCornerRadius); |
190 origin.set_y(origin.y() + border_insets.top() + kPopupBubbleCornerRadius); | 199 origin.set_y(origin.y() + border_insets.top() + kPopupBubbleCornerRadius); |
191 | 200 |
| 201 gfx::Size new_size = view()->size(); |
192 SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height()); | 202 SetBounds(origin.x(), origin.y(), new_size.width(), new_size.height()); |
193 } else { | 203 } else { |
194 SetBounds(origin.x(), origin.y(), rect.width(), rect.height()); | 204 SetBounds(origin.x(), origin.y(), rect.width(), rect.height()); |
195 } | 205 } |
196 } | 206 } |
197 | 207 |
198 void ExtensionPopup::BubbleBrowserWindowMoved(BrowserBubble* bubble) { | 208 void ExtensionPopup::BubbleBrowserWindowMoved(BrowserBubble* bubble) { |
199 ResizeToView(); | 209 ResizeToView(); |
200 } | 210 } |
201 | 211 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 | 299 |
290 gfx::Rect bounds(view->bounds()); | 300 gfx::Rect bounds(view->bounds()); |
291 gfx::Size size(bounds.size()); | 301 gfx::Size size(bounds.size()); |
292 size.Enlarge(border_insets.width(), border_insets.height()); | 302 size.Enlarge(border_insets.width(), border_insets.height()); |
293 view->SetBounds(bounds.x(), bounds.y(), size.width(), size.height()); | 303 view->SetBounds(bounds.x(), bounds.y(), size.width(), size.height()); |
294 } | 304 } |
295 | 305 |
296 ResizeToView(); | 306 ResizeToView(); |
297 } | 307 } |
298 | 308 |
299 gfx::Rect ExtensionPopup::GetOuterBounds(const gfx::Rect& position_relative_to, | 309 gfx::Rect ExtensionPopup::GetOuterBounds() const { |
300 const gfx::Size& contents_size) const { | 310 gfx::Rect relative_rect = relative_to_; |
| 311 gfx::Point origin = relative_rect.origin(); |
| 312 views::View::ConvertPointToScreen(frame_->GetRootView(), &origin); |
| 313 relative_rect.set_origin(origin); |
| 314 |
| 315 gfx::Size contents_size = view()->size(); |
| 316 |
301 // If the popup has a bubble-chrome, then let the BubbleBorder compute | 317 // If the popup has a bubble-chrome, then let the BubbleBorder compute |
302 // the bounds. | 318 // the bounds. |
303 if (BUBBLE_CHROME == popup_chrome_) { | 319 if (BUBBLE_CHROME == popup_chrome_) { |
304 // The rounded corners cut off more of the view than the border insets | 320 // The rounded corners cut off more of the view than the border insets |
305 // claim. Since we can't clip the ExtensionView's corners, we need to | 321 // claim. Since we can't clip the ExtensionView's corners, we need to |
306 // increase the inset by half the corner radius as well as lying about the | 322 // increase the inset by half the corner radius as well as lying about the |
307 // size of the contents size to compensate. | 323 // size of the contents size to compensate. |
308 gfx::Size adjusted_size = contents_size; | 324 contents_size.Enlarge(2 * kPopupBubbleCornerRadius, |
309 adjusted_size.Enlarge(2 * kPopupBubbleCornerRadius, | |
310 2 * kPopupBubbleCornerRadius); | 325 2 * kPopupBubbleCornerRadius); |
311 return border_->GetBounds(position_relative_to, adjusted_size); | 326 return border_->GetBounds(relative_rect, contents_size); |
312 } | 327 } |
313 | 328 |
314 // Position the bounds according to the location of the |anchor_position_|. | 329 // Position the bounds according to the location of the |anchor_position_|. |
315 int y; | 330 int y; |
316 if ((anchor_position_ == BubbleBorder::TOP_LEFT) || | 331 if (BubbleBorder::is_arrow_on_top(anchor_position_)) |
317 (anchor_position_ == BubbleBorder::TOP_RIGHT)) { | 332 y = relative_rect.bottom(); |
318 y = position_relative_to.bottom(); | 333 else |
319 } else { | 334 y = relative_rect.y() - contents_size.height(); |
320 y = position_relative_to.y() - contents_size.height(); | |
321 } | |
322 | 335 |
323 return gfx::Rect(position_relative_to.x(), y, contents_size.width(), | 336 int x; |
324 contents_size.height()); | 337 if (BubbleBorder::is_arrow_on_left(anchor_position_)) |
| 338 x = relative_rect.x(); |
| 339 else |
| 340 x = relative_rect.x() - contents_size.width(); |
| 341 |
| 342 return gfx::Rect(x, y, contents_size.width(), contents_size.height()); |
325 } | 343 } |
326 | 344 |
327 // static | 345 // static |
328 ExtensionPopup* ExtensionPopup::Show( | 346 ExtensionPopup* ExtensionPopup::Show( |
329 const GURL& url, | 347 const GURL& url, |
330 Browser* browser, | 348 Browser* browser, |
331 Profile* profile, | 349 Profile* profile, |
332 gfx::NativeWindow frame_window, | 350 gfx::NativeWindow frame_window, |
333 const gfx::Rect& relative_to, | 351 const gfx::Rect& relative_to, |
334 BubbleBorder::ArrowLocation arrow_location, | 352 BubbleBorder::ArrowLocation arrow_location, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 | 390 |
373 void ExtensionPopup::Close() { | 391 void ExtensionPopup::Close() { |
374 if (closing_) | 392 if (closing_) |
375 return; | 393 return; |
376 closing_ = true; | 394 closing_ = true; |
377 DetachFromBrowser(); | 395 DetachFromBrowser(); |
378 if (observer_) | 396 if (observer_) |
379 observer_->ExtensionPopupClosed(this); | 397 observer_->ExtensionPopupClosed(this); |
380 Release(); // Balanced in ctor. | 398 Release(); // Balanced in ctor. |
381 } | 399 } |
OLD | NEW |