summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorcpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-02 00:12:37 +0000
committercpu@chromium.org <cpu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-02 00:12:37 +0000
commit3c6aa3a788da02a2cf6f616c5ae20fdce5353dda (patch)
tree03a39e493e19a88b891ffabfabc9d7cb9704bfa0 /chrome
parent7f891c729c1993920d287efbb698af371205db56 (diff)
downloadchromium_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.cc65
-rw-r--r--chrome/browser/ui/views/avatar_menu_button.h4
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);