OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/views/frame/glass_browser_frame_view.h" | 5 #include "chrome/browser/ui/views/frame/glass_browser_frame_view.h" |
6 | 6 |
7 #include "base/prefs/pref_service.h" | 7 #include "base/prefs/pref_service.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "base/win/windows_version.h" | 9 #include "base/win/windows_version.h" |
10 #include "chrome/app/chrome_command_ids.h" | 10 #include "chrome/app/chrome_command_ids.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 // buttons, but the space will look cluttered if it actually slides under them, | 58 // buttons, but the space will look cluttered if it actually slides under them, |
59 // so we stop it when the gap between the two is down to 5 px. | 59 // so we stop it when the gap between the two is down to 5 px. |
60 const int kNewTabCaptionRestoredSpacing = 5; | 60 const int kNewTabCaptionRestoredSpacing = 5; |
61 // In maximized mode, where the New Tab button and the caption buttons are at | 61 // In maximized mode, where the New Tab button and the caption buttons are at |
62 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid | 62 // similar vertical coordinates, we need to reserve a larger, 16 px gap to avoid |
63 // looking too cluttered. | 63 // looking too cluttered. |
64 const int kNewTabCaptionMaximizedSpacing = 16; | 64 const int kNewTabCaptionMaximizedSpacing = 16; |
65 | 65 |
66 // Converts the |image| to a Windows icon and returns the corresponding HICON | 66 // Converts the |image| to a Windows icon and returns the corresponding HICON |
67 // handle. |image| is resized to desired |width| and |height| if needed. | 67 // handle. |image| is resized to desired |width| and |height| if needed. |
68 HICON CreateHICONFromSkBitmapSizedTo(const gfx::ImageSkia& image, | 68 base::win::ScopedHICON CreateHICONFromSkBitmapSizedTo( |
69 int width, | 69 const gfx::ImageSkia& image, |
70 int height) { | 70 int width, |
71 if (width == image.width() && height == image.height()) | 71 int height) { |
72 return IconUtil::CreateHICONFromSkBitmap(*image.bitmap()); | 72 return IconUtil::CreateHICONFromSkBitmap( |
73 return IconUtil::CreateHICONFromSkBitmap(skia::ImageOperations::Resize( | 73 width == image.width() && height == image.height() |
74 *image.bitmap(), skia::ImageOperations::RESIZE_BEST, width, height)); | 74 ? *image.bitmap() |
| 75 : skia::ImageOperations::Resize(*image.bitmap(), |
| 76 skia::ImageOperations::RESIZE_BEST, |
| 77 width, height)); |
75 } | 78 } |
76 | 79 |
77 } // namespace | 80 } // namespace |
78 | 81 |
79 /////////////////////////////////////////////////////////////////////////////// | 82 /////////////////////////////////////////////////////////////////////////////// |
80 // GlassBrowserFrameView, public: | 83 // GlassBrowserFrameView, public: |
81 | 84 |
82 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, | 85 GlassBrowserFrameView::GlassBrowserFrameView(BrowserFrame* frame, |
83 BrowserView* browser_view) | 86 BrowserView* browser_view) |
84 : BrowserNonClientFrameView(frame, browser_view), | 87 : BrowserNonClientFrameView(frame, browser_view), |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, | 612 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, |
610 static_cast<WPARAM>(ICON_SMALL), | 613 static_cast<WPARAM>(ICON_SMALL), |
611 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); | 614 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); |
612 } | 615 } |
613 } | 616 } |
614 | 617 |
615 void GlassBrowserFrameView::StopThrobber() { | 618 void GlassBrowserFrameView::StopThrobber() { |
616 if (throbber_running_) { | 619 if (throbber_running_) { |
617 throbber_running_ = false; | 620 throbber_running_ = false; |
618 | 621 |
| 622 base::win::ScopedHICON previous_small_icon; |
| 623 base::win::ScopedHICON previous_big_icon; |
619 HICON small_icon = nullptr; | 624 HICON small_icon = nullptr; |
620 HICON big_icon = nullptr; | 625 HICON big_icon = nullptr; |
621 | 626 |
622 // Check if hosted BrowserView has a window icon to use. | 627 // Check if hosted BrowserView has a window icon to use. |
623 if (browser_view()->ShouldShowWindowIcon()) { | 628 if (browser_view()->ShouldShowWindowIcon()) { |
624 gfx::ImageSkia icon = browser_view()->GetWindowIcon(); | 629 gfx::ImageSkia icon = browser_view()->GetWindowIcon(); |
625 if (!icon.isNull()) { | 630 if (!icon.isNull()) { |
626 small_icon = CreateHICONFromSkBitmapSizedTo( | 631 // Keep previous icons alive as long as they are referenced by the HWND. |
627 icon, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); | 632 previous_small_icon = small_window_icon_.Pass(); |
628 big_icon = CreateHICONFromSkBitmapSizedTo( | 633 previous_big_icon = big_window_icon_.Pass(); |
629 icon, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); | 634 |
| 635 // Take responsibility for eventually destroying the created icons. |
| 636 small_window_icon_ = |
| 637 CreateHICONFromSkBitmapSizedTo(icon, GetSystemMetrics(SM_CXSMICON), |
| 638 GetSystemMetrics(SM_CYSMICON)) |
| 639 .Pass(); |
| 640 big_window_icon_ = |
| 641 CreateHICONFromSkBitmapSizedTo(icon, GetSystemMetrics(SM_CXICON), |
| 642 GetSystemMetrics(SM_CYICON)) |
| 643 .Pass(); |
| 644 |
| 645 small_icon = small_window_icon_.get(); |
| 646 big_icon = big_window_icon_.get(); |
630 } | 647 } |
631 } | 648 } |
632 | 649 |
633 // Fallback to class icon. | 650 // Fallback to class icon. |
634 if (!small_icon) { | 651 if (!small_icon) { |
635 small_icon = reinterpret_cast<HICON>( | 652 small_icon = reinterpret_cast<HICON>( |
636 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICONSM)); | 653 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICONSM)); |
637 } | 654 } |
638 if (!big_icon) { | 655 if (!big_icon) { |
639 big_icon = reinterpret_cast<HICON>( | 656 big_icon = reinterpret_cast<HICON>( |
640 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICON)); | 657 GetClassLongPtr(views::HWNDForWidget(frame()), GCLP_HICON)); |
641 } | 658 } |
642 | 659 |
643 // This will reset the icon which we set in the throbber code. | 660 // This will reset the icon which we set in the throbber code. |
644 // WM_SETICON with null icon restores the icon for title bar but not | 661 // WM_SETICON with null icon restores the icon for title bar but not |
645 // for taskbar. See http://crbug.com/29996 | 662 // for taskbar. See http://crbug.com/29996 |
646 HICON previous_small_icon = reinterpret_cast<HICON>( | 663 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, |
647 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, | 664 static_cast<WPARAM>(ICON_SMALL), |
648 static_cast<WPARAM>(ICON_SMALL), | 665 reinterpret_cast<LPARAM>(small_icon)); |
649 reinterpret_cast<LPARAM>(small_icon))); | |
650 | 666 |
651 HICON previous_big_icon = reinterpret_cast<HICON>( | 667 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, |
652 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, | 668 static_cast<WPARAM>(ICON_BIG), |
653 static_cast<WPARAM>(ICON_BIG), | 669 reinterpret_cast<LPARAM>(big_icon)); |
654 reinterpret_cast<LPARAM>(big_icon))); | |
655 | |
656 if (previous_small_icon) | |
657 ::DestroyIcon(previous_small_icon); | |
658 | |
659 if (previous_big_icon) | |
660 ::DestroyIcon(previous_big_icon); | |
661 } | 670 } |
662 } | 671 } |
663 | 672 |
664 void GlassBrowserFrameView::DisplayNextThrobberFrame() { | 673 void GlassBrowserFrameView::DisplayNextThrobberFrame() { |
665 throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount; | 674 throbber_frame_ = (throbber_frame_ + 1) % kThrobberIconCount; |
666 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, | 675 SendMessage(views::HWNDForWidget(frame()), WM_SETICON, |
667 static_cast<WPARAM>(ICON_SMALL), | 676 static_cast<WPARAM>(ICON_SMALL), |
668 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); | 677 reinterpret_cast<LPARAM>(throbber_icons_[throbber_frame_])); |
669 } | 678 } |
670 | 679 |
671 // static | 680 // static |
672 void GlassBrowserFrameView::InitThrobberIcons() { | 681 void GlassBrowserFrameView::InitThrobberIcons() { |
673 static bool initialized = false; | 682 static bool initialized = false; |
674 if (!initialized) { | 683 if (!initialized) { |
675 for (int i = 0; i < kThrobberIconCount; ++i) { | 684 for (int i = 0; i < kThrobberIconCount; ++i) { |
676 throbber_icons_[i] = | 685 throbber_icons_[i] = |
677 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); | 686 ui::LoadThemeIconFromResourcesDataDLL(IDI_THROBBER_01 + i); |
678 DCHECK(throbber_icons_[i]); | 687 DCHECK(throbber_icons_[i]); |
679 } | 688 } |
680 initialized = true; | 689 initialized = true; |
681 } | 690 } |
682 } | 691 } |
OLD | NEW |