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

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

Issue 8744010: Revert 112171 - Views: Custom drawing for GAIA avatar pictures (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 9 years 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
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/profiles/profile_metrics.h" 7 #include "chrome/browser/profiles/profile_metrics.h"
8 #include "chrome/browser/profiles/profile_info_util.h"
9 #include "chrome/browser/ui/browser.h" 8 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/views/avatar_menu_bubble_view.h" 9 #include "chrome/browser/ui/views/avatar_menu_bubble_view.h"
11 #include "chrome/browser/ui/views/frame/browser_view.h" 10 #include "chrome/browser/ui/views/frame/browser_view.h"
12 #include "chrome/browser/ui/views/window.h" 11 #include "chrome/browser/ui/views/window.h"
13 #include "ui/gfx/canvas_skia.h" 12 #include "ui/gfx/canvas_skia.h"
14 #include "ui/views/widget/widget.h" 13 #include "ui/views/widget/widget.h"
15 14
16 15
17 #if defined(OS_WIN) 16 #if defined(OS_WIN)
18 #include <shobjidl.h> 17 #include <shobjidl.h>
19 #include "base/win/scoped_comptr.h" 18 #include "base/win/scoped_comptr.h"
20 #include "base/win/windows_version.h" 19 #include "base/win/windows_version.h"
21 #include "skia/ext/image_operations.h" 20 #include "skia/ext/image_operations.h"
22 #include "ui/gfx/icon_util.h" 21 #include "ui/gfx/icon_util.h"
23 #endif 22 #endif
24 23
25 static inline int Round(double x) { 24 static inline int Round(double x) {
26 return static_cast<int>(x + 0.5); 25 return static_cast<int>(x + 0.5);
27 } 26 }
28 27
29 // The Windows 7 taskbar supports dynamic overlays and effects, we use this 28 // The Windows 7 taskbar supports dynamic overlays and effects, we use this
30 // to ovelay the avatar icon there. The overlay only applies if the taskbar 29 // to ovelay the avatar icon there. The overlay only applies if the taskbar
31 // is in "default large icon mode". This function is a best effort deal so 30 // is in "default large icon mode". This function is a best effort deal so
32 // we bail out silently at any error condition. 31 // we bail out silently at any error condition.
33 // See http://msdn.microsoft.com/en-us/library/dd391696(VS.85).aspx for 32 // See http://msdn.microsoft.com/en-us/library/dd391696(VS.85).aspx for
34 // more information. 33 // more information.
35 void DrawTaskBarDecoration(const Browser* browser, const gfx::Image* image) { 34 void DrawTaskBarDecoration(const Browser* browser, const SkBitmap* bitmap) {
36 #if defined(OS_WIN) && !defined(USE_AURA) 35 #if defined(OS_WIN) && !defined(USE_AURA)
37 if (base::win::GetVersion() < base::win::VERSION_WIN7) 36 if (base::win::GetVersion() < base::win::VERSION_WIN7)
38 return; 37 return;
39 BrowserWindow* bw = browser->window(); 38 BrowserWindow* bw = browser->window();
40 if (!bw) 39 if (!bw)
41 return; 40 return;
42 gfx::NativeWindow window = bw->GetNativeHandle(); 41 gfx::NativeWindow window = bw->GetNativeHandle();
43 if (!window) 42 if (!window)
44 return; 43 return;
45 44
46 base::win::ScopedComPtr<ITaskbarList3> taskbar; 45 base::win::ScopedComPtr<ITaskbarList3> taskbar;
47 HRESULT result = taskbar.CreateInstance(CLSID_TaskbarList, NULL, 46 HRESULT result = taskbar.CreateInstance(CLSID_TaskbarList, NULL,
48 CLSCTX_INPROC_SERVER); 47 CLSCTX_INPROC_SERVER);
49 if (FAILED(result) || FAILED(taskbar->HrInit())) 48 if (FAILED(result) || FAILED(taskbar->HrInit()))
50 return; 49 return;
51 HICON icon = NULL; 50 HICON icon = NULL;
52 if (image) { 51 if (bitmap) {
53 const SkBitmap* bitmap = image->ToSkBitmap();
54 const SkBitmap* source_bitmap = NULL; 52 const SkBitmap* source_bitmap = NULL;
55 SkBitmap squarer_bitmap; 53 SkBitmap squarer_bitmap;
56 if ((bitmap->width() == profiles::kAvatarIconWidth) && 54 if ((bitmap->width() == 38) && (bitmap->height() == 31)) {
57 (bitmap->height() == profiles::kAvatarIconHeight)) {
58 // Shave a couple of columns so the bitmap is more square. So when 55 // Shave a couple of columns so the bitmap is more square. So when
59 // resized to a square aspect ratio it looks pretty. 56 // resized to a square aspect ratio it looks pretty.
60 int x = 2; 57 bitmap->extractSubset(&squarer_bitmap, SkIRect::MakeXYWH(2, 0, 34, 31));
61 bitmap->extractSubset(&squarer_bitmap, SkIRect::MakeXYWH(x, 0,
62 profiles::kAvatarIconWidth - x * 2, profiles::kAvatarIconHeight));
63 source_bitmap = &squarer_bitmap; 58 source_bitmap = &squarer_bitmap;
64 } else { 59 } else {
65 // The bitmaps size has changed. Resize what we have. 60 // The bitmaps size has changed. Resize what we have.
66 source_bitmap = bitmap; 61 source_bitmap = bitmap;
67 } 62 }
68 // Since the target size is so small, we use our best resizer. Never pass 63 // Since the target size is so small, we use our best resizer. Never pass
69 // windows a different size because it will badly hammer it to 16x16. 64 // windows a different size because it will badly hammer it to 16x16.
70 SkBitmap sk_icon = skia::ImageOperations::Resize( 65 SkBitmap sk_icon = skia::ImageOperations::Resize(
71 *source_bitmap, 66 *source_bitmap,
72 skia::ImageOperations::RESIZE_LANCZOS3, 67 skia::ImageOperations::RESIZE_LANCZOS3,
73 16, 16); 68 16, 16);
74 icon = IconUtil::CreateHICONFromSkBitmap(sk_icon); 69 icon = IconUtil::CreateHICONFromSkBitmap(sk_icon);
75 if (!icon) 70 if (!icon)
76 return; 71 return;
77 } 72 }
78 taskbar->SetOverlayIcon(window, icon, L""); 73 taskbar->SetOverlayIcon(window, icon, L"");
79 if (icon) 74 if (icon)
80 DestroyIcon(icon); 75 DestroyIcon(icon);
81 #endif 76 #endif
82 } 77 }
83 78
84 AvatarMenuButton::AvatarMenuButton(Browser* browser, bool has_menu) 79 AvatarMenuButton::AvatarMenuButton(Browser* browser, bool has_menu)
85 : MenuButton(NULL, string16(), this, false), 80 : MenuButton(NULL, string16(), this, false),
86 browser_(browser), 81 browser_(browser),
87 has_menu_(has_menu), 82 has_menu_(has_menu),
88 set_taskbar_decoration_(false), 83 set_taskbar_decoration_(false) {
89 is_gaia_picture_(false),
90 old_height_(0) {
91 // In RTL mode, the avatar icon should be looking the opposite direction. 84 // In RTL mode, the avatar icon should be looking the opposite direction.
92 EnableCanvasFlippingForRTLUI(true); 85 EnableCanvasFlippingForRTLUI(true);
93 } 86 }
94 87
95 AvatarMenuButton::~AvatarMenuButton() { 88 AvatarMenuButton::~AvatarMenuButton() {
96 // During destruction of the browser frame, we might not have a window 89 // During destruction of the browser frame, we might not have a window
97 // so the taskbar button will be removed by windows anyway. 90 // so the taskbar button will be removed by windows anyway.
98 if (browser_->IsAttemptingToCloseBrowser()) 91 if (browser_->IsAttemptingToCloseBrowser())
99 return; 92 return;
100 DrawTaskBarDecoration(browser_, NULL); 93 DrawTaskBarDecoration(browser_, NULL);
101 } 94 }
102 95
103 void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) { 96 void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) {
104 if (!icon_.get()) 97 const SkBitmap& icon = GetImageToPaint();
98 if (icon.isNull())
105 return; 99 return;
106 100
107 if (old_height_ != height() || button_icon_.isNull()) {
108 old_height_ = height();
109 button_icon_ = profiles::GetAvatarIconForTitleBar(
110 *icon_, is_gaia_picture_, width(), height());
111 }
112
113 // Scale the image to fit the width of the button. 101 // Scale the image to fit the width of the button.
114 int dst_width = std::min(button_icon_.width(), width()); 102 int dst_width = std::min(icon.width(), width());
115 // Truncate rather than rounding, so that for odd widths we put the extra 103 // Truncate rather than rounding, so that for odd widths we put the extra
116 // pixel on the left. 104 // pixel on the left.
117 int dst_x = (width() - dst_width) / 2; 105 int dst_x = (width() - dst_width) / 2;
118 106
119 // Scale the height and maintain aspect ratio. This means that the 107 // Scale the height and maintain aspect ratio. This means that the
120 // icon may not fit in the view. That's ok, we just vertically center it. 108 // icon may not fit in the view. That's ok, we just vertically center it.
121 float scale = 109 float scale =
122 static_cast<float>(dst_width) / static_cast<float>(button_icon_.width()); 110 static_cast<float>(dst_width) / static_cast<float>(icon.width());
123 // Round here so that we minimize the aspect ratio drift. 111 // Round here so that we minimize the aspect ratio drift.
124 int dst_height = Round(button_icon_.height() * scale); 112 int dst_height = Round(icon.height() * scale);
125 // Round rather than truncating, so that for odd heights we select an extra 113 // Round rather than truncating, so that for odd heights we select an extra
126 // pixel below the image center rather than above. This is because the 114 // pixel below the image center rather than above. This is because the
127 // incognito image has shadows at the top that make the apparent center below 115 // incognito image has shadows at the top that make the apparent center below
128 // the real center. 116 // the real center.
129 int dst_y = Round((height() - dst_height) / 2.0); 117 int dst_y = Round((height() - dst_height) / 2.0);
130 canvas->DrawBitmapInt(button_icon_, 0, 0, button_icon_.width(), 118
131 button_icon_.height(), dst_x, dst_y, dst_width, dst_height, false); 119 canvas->DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(),
120 dst_x, dst_y, dst_width, dst_height, false);
132 121
133 if (set_taskbar_decoration_) { 122 if (set_taskbar_decoration_) {
134 // Drawing the taskbar decoration uses lanczos resizing so we really 123 // Drawing the taskbar decoration uses lanczos resizing so we really
135 // want to do it only once. 124 // want to do it only once.
136 DrawTaskBarDecoration(browser_, icon_.get()); 125 DrawTaskBarDecoration(browser_, &icon);
137 set_taskbar_decoration_ = false; 126 set_taskbar_decoration_ = false;
138 } 127 }
139 } 128 }
140 129
141 bool AvatarMenuButton::HitTest(const gfx::Point& point) const { 130 bool AvatarMenuButton::HitTest(const gfx::Point& point) const {
142 if (!has_menu_) 131 if (!has_menu_)
143 return false; 132 return false;
144 return views::MenuButton::HitTest(point); 133 return views::MenuButton::HitTest(point);
145 } 134 }
146 135
147 void AvatarMenuButton::SetIcon(const gfx::Image& icon, bool is_gaia_picture) { 136 // If the icon changes, we need to set the taskbar decoration again.
148 icon_.reset(new gfx::Image(icon)); 137 void AvatarMenuButton::SetIcon(const SkBitmap& icon) {
149 button_icon_ = SkBitmap(); 138 views::MenuButton::SetIcon(icon);
150 is_gaia_picture_ = is_gaia_picture;
151 // If the icon changes, we need to set the taskbar decoration again.
152 set_taskbar_decoration_ = true; 139 set_taskbar_decoration_ = true;
153 } 140 }
154 141
155 // views::ViewMenuDelegate implementation 142 // views::ViewMenuDelegate implementation
156 void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { 143 void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) {
157 ShowAvatarBubble(); 144 ShowAvatarBubble();
158 } 145 }
159 146
160 void AvatarMenuButton::ShowAvatarBubble() { 147 void AvatarMenuButton::ShowAvatarBubble() {
161 if (!has_menu_) 148 if (!has_menu_)
162 return; 149 return;
163 150
164 gfx::Point origin; 151 gfx::Point origin;
165 views::View::ConvertPointToScreen(this, &origin); 152 views::View::ConvertPointToScreen(this, &origin);
166 gfx::Rect bounds(origin, size()); 153 gfx::Rect bounds(origin, size());
167 154
168 AvatarMenuBubbleView* bubble = new AvatarMenuBubbleView(this, 155 AvatarMenuBubbleView* bubble = new AvatarMenuBubbleView(this,
169 views::BubbleBorder::TOP_LEFT, bounds, browser_); 156 views::BubbleBorder::TOP_LEFT, bounds, browser_);
170 browser::CreateViewsBubble(bubble); 157 browser::CreateViewsBubble(bubble);
171 bubble->Show(); 158 bubble->Show();
172 159
173 ProfileMetrics::LogProfileOpenMethod(ProfileMetrics::ICON_AVATAR_BUBBLE); 160 ProfileMetrics::LogProfileOpenMethod(ProfileMetrics::ICON_AVATAR_BUBBLE);
174 } 161 }
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/avatar_menu_button.h ('k') | chrome/browser/ui/views/frame/browser_non_client_frame_view.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698