Chromium Code Reviews| Index: chrome/browser/ui/panels/panel_browser_view.cc |
| diff --git a/chrome/browser/ui/panels/panel_browser_view.cc b/chrome/browser/ui/panels/panel_browser_view.cc |
| index d8c04ec8b10ffe1573e0bd7c72448cb725285b7d..437091b3135c84a3aa150bba69016490cde31ff1 100644 |
| --- a/chrome/browser/ui/panels/panel_browser_view.cc |
| +++ b/chrome/browser/ui/panels/panel_browser_view.cc |
| @@ -17,11 +17,17 @@ |
| #include "chrome/common/chrome_notification_types.h" |
| #include "content/public/browser/notification_service.h" |
| #include "grit/chromium_strings.h" |
| +#include "skia/ext/image_operations.h" |
| #include "ui/base/l10n/l10n_util.h" |
| +#include "ui/gfx/canvas.h" |
| #include "ui/views/controls/button/image_button.h" |
| #include "ui/views/controls/label.h" |
| #include "ui/views/widget/widget.h" |
| +#if defined(OS_WIN) |
| +#include "base/win/windows_version.h" |
| +#endif |
| + |
| using content::WebContents; |
| NativePanel* Panel::CreateNativePanel(Browser* browser, Panel* panel, |
| @@ -41,6 +47,7 @@ PanelBrowserView::PanelBrowserView(Browser* browser, Panel* panel, |
| mouse_pressed_(false), |
| mouse_dragging_state_(NO_DRAGGING), |
| is_drawing_attention_(false), |
| + force_to_paint_as_inactive_(false), |
| old_focused_view_(NULL) { |
| } |
| @@ -241,6 +248,33 @@ void PanelBrowserView::OnWindowBeginUserBoundsChange() { |
| panel_->OnPanelStartUserResizing(); |
| } |
| +SkBitmap PanelBrowserView::GetPreviewImage(const gfx::Size& size, bool live) { |
|
Ben Goodger (Google)
2012/05/21 21:45:12
rather than add all this win32-specific code to wi
|
| +#if defined(OS_WIN) && !defined(USE_AURA) |
| + // Returns the live captured image if requested. |
| + if (live) |
| + return CaptureWindowImage(); |
| + |
| + // No need to scale if the requested size matches. |
| + int width = size.width(); |
| + int height = size.height(); |
| + if (capture_bitmap_->width() == width || capture_bitmap_->height() == height) |
| + return *capture_bitmap_; |
| + |
| + SkBitmap scaled_bitmap; |
| + double x_scale = static_cast<double>(width) / capture_bitmap_->width(); |
| + double y_scale = static_cast<double>(height) / capture_bitmap_->height(); |
| + double scale = std::min(x_scale, y_scale); |
| + width = capture_bitmap_->width() * scale; |
| + height = capture_bitmap_->height() * scale; |
| + scaled_bitmap = skia::ImageOperations::Resize( |
| + *capture_bitmap_, skia::ImageOperations::RESIZE_GOOD, width, height); |
| + |
| + return scaled_bitmap; |
| +#else |
| + return SkBitmap(); |
| +#endif |
| +} |
| + |
| void PanelBrowserView::OnWindowEndUserBoundsChange() { |
| bounds_ = GetBounds(); |
| panel_->IncreaseMaxSize(bounds_.size()); |
| @@ -518,7 +552,6 @@ void PanelBrowserView::UpdatePanelMinimizeRestoreButtonVisibility() { |
| GetFrameView()->UpdateTitleBarMinimizeRestoreButtonVisibility(); |
| } |
| - |
| #if defined(OS_WIN) && !defined(USE_AURA) |
| void PanelBrowserView::UpdateWindowAttribute(int attribute_index, |
| int attribute_value, |
| @@ -533,7 +566,66 @@ void PanelBrowserView::UpdateWindowAttribute(int attribute_index, |
| if (value != expected_value) |
| ::SetWindowLong(native_window, attribute_index, expected_value); |
| } |
| + |
| +SkBitmap PanelBrowserView::CaptureWindowImage() { |
| + // Transfer the contents of the panel window to the screen-shot canvas' DIB. |
| + HWND native_window = GetNativeHandle(); |
| + gfx::Canvas canvas(bounds_.size(), false); |
| + HDC target_dc = canvas.BeginPlatformPaint(); |
| + HDC source_dc = ::GetDC(native_window); |
| + ::BitBlt(target_dc, 0, 0, bounds_.width(), bounds_.height(), source_dc, |
| + 0, 0, SRCCOPY); |
| + ::ReleaseDC(native_window, source_dc); |
| + canvas.EndPlatformPaint(); |
| + |
| + return canvas.ExtractBitmap(); |
| +} |
| +#endif |
| + |
| +void PanelBrowserView::PanelExpansionStateChanging( |
| + Panel::ExpansionState old_state, Panel::ExpansionState new_state) { |
| +#if defined(OS_WIN) && !defined(USE_AURA) |
| + // Live preview is only available since Windows 7. |
| + if (base::win::GetVersion() < base::win::VERSION_WIN7) |
| + return; |
| + |
| + bool is_minimized = old_state != Panel::EXPANDED; |
| + bool will_be_minimized = new_state != Panel::EXPANDED; |
| + if (is_minimized == will_be_minimized) |
| + return; |
| + |
| + HWND native_window = GetNativeHandle(); |
| + |
| + // Cache the image at this point. |
| + if (will_be_minimized) { |
| + // If the panel is still active (we will deactivate the minimizd panel at |
| + // later time), we need to paint it immediately as inactive so that we can |
| + // take a snapshot of inactive panel. |
| + if (focused_) { |
| + force_to_paint_as_inactive_ = true; |
| + ::RedrawWindow(native_window, NULL, NULL, |
| + RDW_NOCHILDREN | RDW_INVALIDATE | RDW_UPDATENOW); |
| + } |
| + |
| + capture_bitmap_.reset(new SkBitmap(CaptureWindowImage())); |
| + } else { |
| + capture_bitmap_.reset(); |
| + force_to_paint_as_inactive_ = false; |
| + } |
| + |
| + // We need to provide static bitmap to show the bitmap of the panel |
| + // before it is minimized. |
| + BOOL enable = will_be_minimized; |
| + ::DwmSetWindowAttribute(native_window, |
| + DWMWA_FORCE_ICONIC_REPRESENTATION, |
| + &enable, |
| + sizeof(enable)); |
| + ::DwmSetWindowAttribute(native_window, |
| + DWMWA_HAS_ICONIC_BITMAP, |
| + &enable, |
| + sizeof(enable)); |
| #endif |
| +} |
| // NativePanelTesting implementation. |
| class NativePanelTestingWin : public NativePanelTesting { |