diff options
author | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-02 00:12:37 +0000 |
---|---|---|
committer | cpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-09-02 00:12:37 +0000 |
commit | 3c6aa3a788da02a2cf6f616c5ae20fdce5353dda (patch) | |
tree | 03a39e493e19a88b891ffabfabc9d7cb9704bfa0 /chrome | |
parent | 7f891c729c1993920d287efbb698af371205db56 (diff) | |
download | chromium_src-3c6aa3a788da02a2cf6f616c5ae20fdce5353dda.zip chromium_src-3c6aa3a788da02a2cf6f616c5ae20fdce5353dda.tar.gz chromium_src-3c6aa3a788da02a2cf6f616c5ae20fdce5353dda.tar.bz2 |
Add avatar decoration to the windows7 taskbar
-So you can find your window without playing wack-a-mole.
The change is windows 7 specific, because it is easy, we don't have to
to create .ico files, manage them, jump to the file thread to read
them etc.
BUG=94808
TEST=see bug
Review URL: http://codereview.chromium.org/7778025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@99272 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/ui/views/avatar_menu_button.cc | 65 | ||||
-rw-r--r-- | chrome/browser/ui/views/avatar_menu_button.h | 4 |
2 files changed, 67 insertions, 2 deletions
diff --git a/chrome/browser/ui/views/avatar_menu_button.cc b/chrome/browser/ui/views/avatar_menu_button.cc index f754f7d..6e05d60 100644 --- a/chrome/browser/ui/views/avatar_menu_button.cc +++ b/chrome/browser/ui/views/avatar_menu_button.cc @@ -11,19 +11,67 @@ #include "ui/gfx/canvas_skia.h" #include "views/widget/widget.h" + +#if defined(OS_WIN) +#include <shobjidl.h> +#include "base/win/scoped_comptr.h" +#include "base/win/windows_version.h" +#include "skia/ext/image_operations.h" +#include "ui/gfx/icon_util.h" +#endif + static inline int Round(double x) { return static_cast<int>(x + 0.5); } +// The Windows 7 taskbar supports dynamic overlays and effects, we use this +// to ovelay the avatar icon there. The overlay only applies if the taskbar +// is in "default large icon mode". This function is a best effort deal so +// we bail out silently at any error condition. +// See http://msdn.microsoft.com/en-us/library/dd391696(VS.85).aspx for +// more information. +void DrawTaskBarDecoration(const Browser* browser, const SkBitmap* bitmap) { +#if defined(OS_WIN) + if (base::win::GetVersion() < base::win::VERSION_WIN7) + return; + + base::win::ScopedComPtr<ITaskbarList3> taskbar; + HRESULT result = taskbar.CreateInstance(CLSID_TaskbarList, NULL, + CLSCTX_INPROC_SERVER); + if (FAILED(result) || FAILED(taskbar->HrInit())) + return; + gfx::NativeWindow window = browser->window()->GetNativeHandle(); + if (!window) + return; + HICON icon = NULL; + if (bitmap) { + // Since the target size is so small, we use our best resizer. + SkBitmap sk_icon = skia::ImageOperations::Resize( + *bitmap, + skia::ImageOperations::RESIZE_LANCZOS3, + 16, 16); + icon = IconUtil::CreateHICONFromSkBitmap(sk_icon); + if (!icon) + return; + } + taskbar->SetOverlayIcon(window, icon, L""); + if (icon) + DestroyIcon(icon); +#endif +} + AvatarMenuButton::AvatarMenuButton(Browser* browser, bool has_menu) : MenuButton(NULL, std::wstring(), this, false), browser_(browser), - has_menu_(has_menu) { + has_menu_(has_menu), + set_taskbar_decoration_(false) { // In RTL mode, the avatar icon should be looking the opposite direction. EnableCanvasFlippingForRTLUI(true); } -AvatarMenuButton::~AvatarMenuButton() {} +AvatarMenuButton::~AvatarMenuButton() { + DrawTaskBarDecoration(browser_, NULL); +} void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) { const SkBitmap& icon = GetImageToPaint(); @@ -50,6 +98,13 @@ void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) { canvas->DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(), dst_x, dst_y, dst_width, dst_height, false); + + if (set_taskbar_decoration_) { + // Drawing the taskbar decoration uses lanczos resizing so we really + // want to do it only once. + DrawTaskBarDecoration(browser_, &icon); + set_taskbar_decoration_ = false; + } } bool AvatarMenuButton::HitTest(const gfx::Point& point) const { @@ -58,6 +113,12 @@ bool AvatarMenuButton::HitTest(const gfx::Point& point) const { return views::MenuButton::HitTest(point); } +// If the icon changes, we need to set the taskbar decoration again. +void AvatarMenuButton::SetIcon(const SkBitmap& icon) { + views::MenuButton::SetIcon(icon); + set_taskbar_decoration_ = true; +} + // views::ViewMenuDelegate implementation void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { if (!has_menu_) diff --git a/chrome/browser/ui/views/avatar_menu_button.h b/chrome/browser/ui/views/avatar_menu_button.h index fd2b16e..de595c2 100644 --- a/chrome/browser/ui/views/avatar_menu_button.h +++ b/chrome/browser/ui/views/avatar_menu_button.h @@ -36,12 +36,16 @@ class AvatarMenuButton : public views::MenuButton, virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; virtual bool HitTest(const gfx::Point& point) const OVERRIDE; + // views::TextButton + virtual void SetIcon(const SkBitmap& icon) OVERRIDE; + private: // views::ViewMenuDelegate virtual void RunMenu(views::View* source, const gfx::Point& pt) OVERRIDE; Browser* browser_; bool has_menu_; + bool set_taskbar_decoration_; scoped_ptr<ui::MenuModel> menu_model_; DISALLOW_COPY_AND_ASSIGN(AvatarMenuButton); |