| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/info_bubble.h" | 5 #include "chrome/browser/views/info_bubble.h" |
| 6 | 6 |
| 7 #include "app/gfx/canvas.h" | 7 #include "app/gfx/canvas.h" |
| 8 #include "app/gfx/path.h" | 8 #include "app/gfx/path.h" |
| 9 #include "app/resource_bundle.h" | 9 #include "app/resource_bundle.h" |
| 10 #include "chrome/browser/browser_window.h" | 10 #include "chrome/browser/browser_window.h" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 set_window_style(WS_POPUP | WS_CLIPCHILDREN); | 122 set_window_style(WS_POPUP | WS_CLIPCHILDREN); |
| 123 set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW); | 123 set_window_ex_style(WS_EX_LAYERED | WS_EX_TOOLWINDOW); |
| 124 // Because we're going to change the alpha value of the layered window we | 124 // Because we're going to change the alpha value of the layered window we |
| 125 // don't want to use the offscreen buffer provided by WidgetWin. | 125 // don't want to use the offscreen buffer provided by WidgetWin. |
| 126 SetUseLayeredBuffer(false); | 126 SetUseLayeredBuffer(false); |
| 127 set_initial_class_style( | 127 set_initial_class_style( |
| 128 (win_util::GetWinVersion() < win_util::WINVERSION_XP) ? | 128 (win_util::GetWinVersion() < win_util::WINVERSION_XP) ? |
| 129 0 : CS_DROPSHADOW); | 129 0 : CS_DROPSHADOW); |
| 130 #endif | 130 #endif |
| 131 content_view_ = CreateContentView(content); | 131 content_view_ = CreateContentView(content); |
| 132 gfx::Rect bounds = | |
| 133 content_view_->CalculateWindowBoundsAndAjust(position_relative_to); | |
| 134 | 132 |
| 135 #if defined(OS_WIN) | 133 #if defined(OS_WIN) |
| 136 WidgetWin::Init(parent->GetNativeWindow(), bounds); | 134 WidgetWin::Init(parent->GetNativeWindow(), gfx::Rect()); |
| 137 #else | 135 #else |
| 138 WidgetGtk::Init(GTK_WIDGET(parent->GetNativeWindow()), bounds); | 136 WidgetGtk::Init(GTK_WIDGET(parent->GetNativeWindow()), gfx::Rect()); |
| 139 #endif | 137 #endif |
| 138 |
| 140 SetContentsView(content_view_); | 139 SetContentsView(content_view_); |
| 141 // The preferred size may differ when parented. Ask for the bounds again | 140 // The preferred size may differ when parented. Ask for the bounds again |
| 142 // and if they differ reset the bounds. | 141 // and if they differ reset the bounds. |
| 143 gfx::Rect parented_bounds = | 142 gfx::Rect parented_bounds = |
| 144 content_view_->CalculateWindowBoundsAndAjust(position_relative_to); | 143 content_view_->CalculateWindowBoundsAndAjust(position_relative_to); |
| 145 | 144 |
| 146 if (bounds != parented_bounds) { | 145 // TODO(beng): This should be done in a cleaner and cross-platform way. |
| 147 #if defined(OS_WIN) | 146 #if defined(OS_WIN) |
| 148 SetWindowPos(NULL, parented_bounds.x(), parented_bounds.y(), | 147 SetWindowPos(NULL, parented_bounds.x(), parented_bounds.y(), |
| 149 parented_bounds.width(), parented_bounds.height(), | 148 parented_bounds.width(), parented_bounds.height(), |
| 150 SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOZORDER); | 149 SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOZORDER); |
| 151 // Invoke ChangeSize, otherwise layered window isn't updated correctly. | 150 // Invoke ChangeSize, otherwise layered window isn't updated correctly. |
| 152 ChangeSize(0, CSize(parented_bounds.width(), parented_bounds.height())); | 151 ChangeSize(0, CSize(parented_bounds.width(), parented_bounds.height())); |
| 152 #else |
| 153 SetBounds(parented_bounds); |
| 153 #endif | 154 #endif |
| 154 } | |
| 155 | 155 |
| 156 #if defined(OS_WIN) | 156 #if defined(OS_WIN) |
| 157 // Register the Escape accelerator for closing. | 157 // Register the Escape accelerator for closing. |
| 158 GetFocusManager()->RegisterAccelerator(views::Accelerator(VK_ESCAPE, false, | 158 GetFocusManager()->RegisterAccelerator(views::Accelerator(VK_ESCAPE, false, |
| 159 false, false), | 159 false, false), |
| 160 this); | 160 this); |
| 161 // Set initial alpha value of the layered window. | 161 // Set initial alpha value of the layered window. |
| 162 SetLayeredWindowAttributes(GetNativeView(), | 162 SetLayeredWindowAttributes(GetNativeView(), |
| 163 RGB(0xFF, 0xFF, 0xFF), | 163 RGB(0xFF, 0xFF, 0xFF), |
| 164 kMinimumAlpha, | 164 kMinimumAlpha, |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 // The popup should close when it is deactivated. | 206 // The popup should close when it is deactivated. |
| 207 if (action == WA_INACTIVE && !closed_) { | 207 if (action == WA_INACTIVE && !closed_) { |
| 208 Close(); | 208 Close(); |
| 209 } else if (action == WA_ACTIVE) { | 209 } else if (action == WA_ACTIVE) { |
| 210 DCHECK(GetRootView()->GetChildViewCount() > 0); | 210 DCHECK(GetRootView()->GetChildViewCount() > 0); |
| 211 GetRootView()->GetChildViewAt(0)->RequestFocus(); | 211 GetRootView()->GetChildViewAt(0)->RequestFocus(); |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 | 214 |
| 215 void InfoBubble::OnSize(UINT param, const CSize& size) { | 215 void InfoBubble::OnSize(UINT param, const CSize& size) { |
| 216 // See OnSizeAllocate for the Linux version. |
| 216 gfx::Path path; | 217 gfx::Path path; |
| 217 content_view_->GetMask(gfx::Size(size.cx, size.cy), &path); | 218 content_view_->GetMask(gfx::Size(size.cx, size.cy), &path); |
| 218 SetWindowRgn(path.CreateHRGN(), TRUE); | 219 SetWindowRgn(path.CreateHRGN(), TRUE); |
| 219 WidgetWin::OnSize(param, size); | 220 WidgetWin::OnSize(param, size); |
| 220 } | 221 } |
| 221 #endif | 222 #endif |
| 222 | 223 |
| 223 InfoBubble::ContentView* InfoBubble::CreateContentView(View* content) { | 224 InfoBubble::ContentView* InfoBubble::CreateContentView(View* content) { |
| 224 return new ContentView(content, this); | 225 return new ContentView(content, this); |
| 225 } | 226 } |
| 226 | 227 |
| 227 void InfoBubble::Close(bool closed_by_escape) { | 228 void InfoBubble::Close(bool closed_by_escape) { |
| 228 if (closed_) | 229 if (closed_) |
| 229 return; | 230 return; |
| 230 | 231 |
| 231 // We don't fade out because it looks terrible. | 232 // We don't fade out because it looks terrible. |
| 232 if (delegate_) | 233 if (delegate_) |
| 233 delegate_->InfoBubbleClosing(this, closed_by_escape); | 234 delegate_->InfoBubbleClosing(this, closed_by_escape); |
| 234 closed_ = true; | 235 closed_ = true; |
| 235 #if defined(OS_WIN) | 236 #if defined(OS_WIN) |
| 236 WidgetWin::Close(); | 237 WidgetWin::Close(); |
| 237 #else | 238 #else |
| 238 WidgetGtk::Close(); | 239 WidgetGtk::Close(); |
| 239 #endif | 240 #endif |
| 240 } | 241 } |
| 241 | 242 |
| 243 #if defined(OS_LINUX) |
| 244 void InfoBubble::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) { |
| 245 gfx::Path path; |
| 246 content_view_->GetMask(gfx::Size(allocation->width, allocation->height), |
| 247 &path); |
| 248 SetShape(path); |
| 249 WidgetGtk::OnSizeAllocate(widget, allocation); |
| 250 } |
| 251 #endif |
| 252 |
| 242 // ContentView ---------------------------------------------------------------- | 253 // ContentView ---------------------------------------------------------------- |
| 243 | 254 |
| 244 InfoBubble::ContentView::ContentView(views::View* content, InfoBubble* host) | 255 InfoBubble::ContentView::ContentView(views::View* content, InfoBubble* host) |
| 245 : host_(host) { | 256 : content_(content), |
| 257 host_(host) { |
| 246 if (UILayoutIsRightToLeft()) { | 258 if (UILayoutIsRightToLeft()) { |
| 247 arrow_edge_ = TOP_RIGHT; | 259 arrow_edge_ = TOP_RIGHT; |
| 248 } else { | 260 } else { |
| 249 arrow_edge_ = TOP_LEFT; | 261 arrow_edge_ = TOP_LEFT; |
| 250 } | 262 } |
| 251 AddChildView(content); | |
| 252 } | 263 } |
| 253 | 264 |
| 254 gfx::Rect InfoBubble::ContentView::CalculateWindowBoundsAndAjust( | 265 gfx::Rect InfoBubble::ContentView::CalculateWindowBoundsAndAjust( |
| 255 const gfx::Rect& position_relative_to) { | 266 const gfx::Rect& position_relative_to) { |
| 256 scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_provider( | 267 scoped_ptr<WindowSizer::MonitorInfoProvider> monitor_provider( |
| 257 WindowSizer::CreateDefaultMonitorInfoProvider()); | 268 WindowSizer::CreateDefaultMonitorInfoProvider()); |
| 258 gfx::Rect monitor_bounds( | 269 gfx::Rect monitor_bounds( |
| 259 monitor_provider->GetMonitorWorkAreaMatching(position_relative_to)); | 270 monitor_provider->GetMonitorWorkAreaMatching(position_relative_to)); |
| 260 // Calculate the bounds using TOP_LEFT (the default). | 271 // Calculate the bounds using TOP_LEFT (the default). |
| 261 gfx::Rect window_bounds = CalculateWindowBounds(position_relative_to); | 272 gfx::Rect window_bounds = CalculateWindowBounds(position_relative_to); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 canvas->FillRectInt(kBorderColor1, arrow_x + (kArrowSize - i), y, 1, 1); | 443 canvas->FillRectInt(kBorderColor1, arrow_x + (kArrowSize - i), y, 1, 1); |
| 433 if (i != 0) { | 444 if (i != 0) { |
| 434 canvas->FillRectInt(kBorderColor2, arrow_x - (kArrowSize - i) - 1, y, 1, | 445 canvas->FillRectInt(kBorderColor2, arrow_x - (kArrowSize - i) - 1, y, 1, |
| 435 1); | 446 1); |
| 436 canvas->FillRectInt(kBorderColor2, arrow_x + (kArrowSize - i) + 1, y, 1, | 447 canvas->FillRectInt(kBorderColor2, arrow_x + (kArrowSize - i) + 1, y, 1, |
| 437 1); | 448 1); |
| 438 } | 449 } |
| 439 } | 450 } |
| 440 } | 451 } |
| 441 | 452 |
| 453 void InfoBubble::ContentView::ViewHierarchyChanged(bool is_add, |
| 454 View* parent, |
| 455 View* child) { |
| 456 if (is_add && child == this) |
| 457 AddChildView(content_); |
| 458 } |
| 459 |
| 442 gfx::Rect InfoBubble::ContentView::CalculateWindowBounds( | 460 gfx::Rect InfoBubble::ContentView::CalculateWindowBounds( |
| 443 const gfx::Rect& position_relative_to) { | 461 const gfx::Rect& position_relative_to) { |
| 444 gfx::Size pref = GetPreferredSize(); | 462 gfx::Size pref = GetPreferredSize(); |
| 445 int x = position_relative_to.x() + position_relative_to.width() / 2; | 463 int x = position_relative_to.x() + position_relative_to.width() / 2; |
| 446 int y; | 464 int y; |
| 447 if (IsLeft()) | 465 if (IsLeft()) |
| 448 x -= kArrowXOffset; | 466 x -= kArrowXOffset; |
| 449 else | 467 else |
| 450 x = x + kArrowXOffset - pref.width(); | 468 x = x + kArrowXOffset - pref.width(); |
| 451 if (IsTop()) { | 469 if (IsTop()) { |
| 452 y = position_relative_to.bottom() + kArrowToContentPadding; | 470 y = position_relative_to.bottom() + kArrowToContentPadding; |
| 453 } else { | 471 } else { |
| 454 y = position_relative_to.y() - kArrowToContentPadding - pref.height(); | 472 y = position_relative_to.y() - kArrowToContentPadding - pref.height(); |
| 455 } | 473 } |
| 456 return gfx::Rect(x, y, pref.width(), pref.height()); | 474 return gfx::Rect(x, y, pref.width(), pref.height()); |
| 457 } | 475 } |
| OLD | NEW |