Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(372)

Side by Side Diff: chrome/browser/ui/views/avatar_menu_button.cc

Issue 7778025: Add avatar decoration to the windows7 taskbar (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/views/avatar_menu_button.h ('k') | views/controls/button/text_button.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/avatar_menu_button.h" 5 #include "chrome/browser/ui/views/avatar_menu_button.h"
6 6
7 #include "chrome/browser/ui/browser.h" 7 #include "chrome/browser/ui/browser.h"
8 #include "chrome/browser/ui/profile_menu_model.h" 8 #include "chrome/browser/ui/profile_menu_model.h"
9 #include "chrome/browser/ui/views/avatar_menu_bubble_view.h" 9 #include "chrome/browser/ui/views/avatar_menu_bubble_view.h"
10 #include "chrome/browser/ui/views/frame/browser_view.h" 10 #include "chrome/browser/ui/views/frame/browser_view.h"
11 #include "ui/gfx/canvas_skia.h" 11 #include "ui/gfx/canvas_skia.h"
12 #include "views/widget/widget.h" 12 #include "views/widget/widget.h"
13 13
14
15 #if defined(OS_WIN)
16 #include <shobjidl.h>
17 #include "base/win/scoped_comptr.h"
18 #include "base/win/windows_version.h"
19 #include "skia/ext/image_operations.h"
20 #include "ui/gfx/icon_util.h"
21 #endif
22
14 static inline int Round(double x) { 23 static inline int Round(double x) {
15 return static_cast<int>(x + 0.5); 24 return static_cast<int>(x + 0.5);
16 } 25 }
17 26
27 // The Windows 7 taskbar supports dynamic overlays and effects, we use this
28 // to ovelay the avatar icon there. The overlay only applies if the taskbar
29 // is in "default large icon mode". This function is a best effort deal so
30 // we bail out silently at any error condition.
31 // See http://msdn.microsoft.com/en-us/library/dd391696(VS.85).aspx for
32 // more information.
33 void DrawTaskBarDecoration(const Browser* browser, const SkBitmap* bitmap) {
34 #if defined(OS_WIN)
35 if (base::win::GetVersion() < base::win::VERSION_WIN7)
36 return;
37
38 base::win::ScopedComPtr<ITaskbarList3> taskbar;
39 HRESULT result = taskbar.CreateInstance(CLSID_TaskbarList, NULL,
40 CLSCTX_INPROC_SERVER);
41 if (FAILED(result) || FAILED(taskbar->HrInit()))
42 return;
43 gfx::NativeWindow window = browser->window()->GetNativeHandle();
44 if (!window)
45 return;
46 HICON icon = NULL;
47 if (bitmap) {
48 // Since the target size is so small, we use our best resizer.
49 SkBitmap sk_icon = skia::ImageOperations::Resize(
50 *bitmap,
51 skia::ImageOperations::RESIZE_LANCZOS3,
52 16, 16);
53 icon = IconUtil::CreateHICONFromSkBitmap(sk_icon);
54 if (!icon)
55 return;
56 }
57 taskbar->SetOverlayIcon(window, icon, L"");
58 if (icon)
59 DestroyIcon(icon);
60 #endif
61 }
62
18 AvatarMenuButton::AvatarMenuButton(Browser* browser, bool has_menu) 63 AvatarMenuButton::AvatarMenuButton(Browser* browser, bool has_menu)
19 : MenuButton(NULL, std::wstring(), this, false), 64 : MenuButton(NULL, std::wstring(), this, false),
20 browser_(browser), 65 browser_(browser),
21 has_menu_(has_menu) { 66 has_menu_(has_menu),
67 set_taskbar_decoration_(false) {
22 // In RTL mode, the avatar icon should be looking the opposite direction. 68 // In RTL mode, the avatar icon should be looking the opposite direction.
23 EnableCanvasFlippingForRTLUI(true); 69 EnableCanvasFlippingForRTLUI(true);
24 } 70 }
25 71
26 AvatarMenuButton::~AvatarMenuButton() {} 72 AvatarMenuButton::~AvatarMenuButton() {
73 DrawTaskBarDecoration(browser_, NULL);
74 }
27 75
28 void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) { 76 void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) {
29 const SkBitmap& icon = GetImageToPaint(); 77 const SkBitmap& icon = GetImageToPaint();
30 if (icon.isNull()) 78 if (icon.isNull())
31 return; 79 return;
32 80
33 // Scale the image to fit the width of the button. 81 // Scale the image to fit the width of the button.
34 int dst_width = std::min(icon.width(), width()); 82 int dst_width = std::min(icon.width(), width());
35 // Truncate rather than rounding, so that for odd widths we put the extra 83 // Truncate rather than rounding, so that for odd widths we put the extra
36 // pixel on the left. 84 // pixel on the left.
37 int dst_x = (width() - dst_width) / 2; 85 int dst_x = (width() - dst_width) / 2;
38 86
39 // Scale the height and maintain aspect ratio. This means that the 87 // Scale the height and maintain aspect ratio. This means that the
40 // icon may not fit in the view. That's ok, we just vertically center it. 88 // icon may not fit in the view. That's ok, we just vertically center it.
41 float scale = 89 float scale =
42 static_cast<float>(dst_width) / static_cast<float>(icon.width()); 90 static_cast<float>(dst_width) / static_cast<float>(icon.width());
43 // Round here so that we minimize the aspect ratio drift. 91 // Round here so that we minimize the aspect ratio drift.
44 int dst_height = Round(icon.height() * scale); 92 int dst_height = Round(icon.height() * scale);
45 // Round rather than truncating, so that for odd heights we select an extra 93 // Round rather than truncating, so that for odd heights we select an extra
46 // pixel below the image center rather than above. This is because the 94 // pixel below the image center rather than above. This is because the
47 // incognito image has shadows at the top that make the apparent center below 95 // incognito image has shadows at the top that make the apparent center below
48 // the real center. 96 // the real center.
49 int dst_y = Round((height() - dst_height) / 2.0); 97 int dst_y = Round((height() - dst_height) / 2.0);
50 98
51 canvas->DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(), 99 canvas->DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(),
52 dst_x, dst_y, dst_width, dst_height, false); 100 dst_x, dst_y, dst_width, dst_height, false);
101
102 if (set_taskbar_decoration_) {
103 // Drawing the taskbar decoration uses lanczos resizing so we really
104 // want to do it only once.
105 DrawTaskBarDecoration(browser_, &icon);
106 set_taskbar_decoration_ = false;
107 }
53 } 108 }
54 109
55 bool AvatarMenuButton::HitTest(const gfx::Point& point) const { 110 bool AvatarMenuButton::HitTest(const gfx::Point& point) const {
56 if (!has_menu_) 111 if (!has_menu_)
57 return false; 112 return false;
58 return views::MenuButton::HitTest(point); 113 return views::MenuButton::HitTest(point);
59 } 114 }
60 115
116 // If the icon changes, we need to set the taskbar decoration again.
117 void AvatarMenuButton::SetIcon(const SkBitmap& icon) {
118 views::MenuButton::SetIcon(icon);
119 set_taskbar_decoration_ = true;
120 }
121
61 // views::ViewMenuDelegate implementation 122 // views::ViewMenuDelegate implementation
62 void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { 123 void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) {
63 if (!has_menu_) 124 if (!has_menu_)
64 return; 125 return;
65 126
66 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow( 127 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow(
67 browser_->window()->GetNativeHandle()); 128 browser_->window()->GetNativeHandle());
68 129
69 gfx::Point origin; 130 gfx::Point origin;
70 views::View::ConvertPointToScreen(this, &origin); 131 views::View::ConvertPointToScreen(this, &origin);
71 gfx::Rect bounds(0, 0, width(), height()); 132 gfx::Rect bounds(0, 0, width(), height());
72 bounds.set_origin(origin); 133 bounds.set_origin(origin);
73 134
74 AvatarMenuBubbleView* bubble_view = new AvatarMenuBubbleView(browser_); 135 AvatarMenuBubbleView* bubble_view = new AvatarMenuBubbleView(browser_);
75 // Bubble::Show() takes ownership of the view. 136 // Bubble::Show() takes ownership of the view.
76 Bubble::Show(browser_view->GetWidget(), bounds, 137 Bubble::Show(browser_view->GetWidget(), bounds,
77 views::BubbleBorder::TOP_LEFT, 138 views::BubbleBorder::TOP_LEFT,
78 bubble_view, bubble_view); 139 bubble_view, bubble_view);
79 } 140 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/avatar_menu_button.h ('k') | views/controls/button/text_button.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698