OLD | NEW |
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/ui/browser.h" | 8 #include "chrome/browser/ui/browser.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 #include "skia/ext/image_operations.h" |
13 | 14 |
14 | 15 |
15 #if defined(OS_WIN) | 16 #if defined(OS_WIN) |
16 #include <shobjidl.h> | 17 #include <shobjidl.h> |
17 #include "base/win/scoped_comptr.h" | 18 #include "base/win/scoped_comptr.h" |
18 #include "base/win/windows_version.h" | 19 #include "base/win/windows_version.h" |
19 #include "skia/ext/image_operations.h" | |
20 #include "ui/gfx/icon_util.h" | 20 #include "ui/gfx/icon_util.h" |
21 #endif | 21 #endif |
22 | 22 |
23 static inline int Round(double x) { | 23 static inline int Round(double x) { |
24 return static_cast<int>(x + 0.5); | 24 return static_cast<int>(x + 0.5); |
25 } | 25 } |
26 | 26 |
27 // The Windows 7 taskbar supports dynamic overlays and effects, we use this | 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 | 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 | 29 // is in "default large icon mode". This function is a best effort deal so |
30 // we bail out silently at any error condition. | 30 // we bail out silently at any error condition. |
31 // See http://msdn.microsoft.com/en-us/library/dd391696(VS.85).aspx for | 31 // See http://msdn.microsoft.com/en-us/library/dd391696(VS.85).aspx for |
32 // more information. | 32 // more information. |
33 void DrawTaskBarDecoration(const Browser* browser, const SkBitmap* bitmap) { | 33 void DrawTaskBarDecoration(const Browser* browser, const SkBitmap* bitmap) { |
| 34 return; |
34 #if defined(OS_WIN) && !defined(USE_AURA) | 35 #if defined(OS_WIN) && !defined(USE_AURA) |
35 if (base::win::GetVersion() < base::win::VERSION_WIN7) | 36 if (base::win::GetVersion() < base::win::VERSION_WIN7) |
36 return; | 37 return; |
37 BrowserWindow* bw = browser->window(); | 38 BrowserWindow* bw = browser->window(); |
38 if (!bw) | 39 if (!bw) |
39 return; | 40 return; |
40 gfx::NativeWindow window = bw->GetNativeHandle(); | 41 gfx::NativeWindow window = bw->GetNativeHandle(); |
41 if (!window) | 42 if (!window) |
42 return; | 43 return; |
43 | 44 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 if (browser_->IsAttemptingToCloseBrowser()) | 94 if (browser_->IsAttemptingToCloseBrowser()) |
94 return; | 95 return; |
95 DrawTaskBarDecoration(browser_, NULL); | 96 DrawTaskBarDecoration(browser_, NULL); |
96 } | 97 } |
97 | 98 |
98 void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) { | 99 void AvatarMenuButton::OnPaint(gfx::Canvas* canvas) { |
99 const SkBitmap& icon = GetImageToPaint(); | 100 const SkBitmap& icon = GetImageToPaint(); |
100 if (icon.isNull()) | 101 if (icon.isNull()) |
101 return; | 102 return; |
102 | 103 |
103 // Scale the image to fit the width of the button. | 104 if (icon.width() != icon.height()) { |
104 int dst_width = std::min(icon.width(), width()); | 105 // Scale the image to fit the width of the button. |
105 // Truncate rather than rounding, so that for odd widths we put the extra | 106 int dst_width = std::min(icon.width(), width()); |
106 // pixel on the left. | 107 // Truncate rather than rounding, so that for odd widths we put the extra |
107 int dst_x = (width() - dst_width) / 2; | 108 // pixel on the left. |
| 109 int dst_x = (width() - dst_width) / 2; |
108 | 110 |
109 // Scale the height and maintain aspect ratio. This means that the | 111 // Scale the height and maintain aspect ratio. This means that the |
110 // icon may not fit in the view. That's ok, we just vertically center it. | 112 // icon may not fit in the view. That's ok, we just vertically center it. |
111 float scale = | 113 float scale = |
112 static_cast<float>(dst_width) / static_cast<float>(icon.width()); | 114 static_cast<float>(dst_width) / static_cast<float>(icon.width()); |
113 // Round here so that we minimize the aspect ratio drift. | 115 // Round here so that we minimize the aspect ratio drift. |
114 int dst_height = Round(icon.height() * scale); | 116 int dst_height = Round(icon.height() * scale); |
115 // Round rather than truncating, so that for odd heights we select an extra | 117 // Round rather than truncating, so that for odd heights we select an extra |
116 // pixel below the image center rather than above. This is because the | 118 // pixel below the image center rather than above. This is because the |
117 // incognito image has shadows at the top that make the apparent center below | 119 // incognito image has shadows at the top that make the apparent center |
118 // the real center. | 120 // below the real center. |
119 int dst_y = Round((height() - dst_height) / 2.0); | 121 int dst_y = Round((height() - dst_height) / 2.0); |
120 | 122 |
121 canvas->DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(), | 123 canvas->DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(), |
122 dst_x, dst_y, dst_width, dst_height, false); | 124 dst_x, dst_y, dst_width, dst_height, false); |
| 125 } else { |
| 126 int dst_width = 28; |
| 127 int dst_x = (width() - dst_width) / 2 + 2; |
| 128 int dst_height = 28; |
| 129 int dst_y = height() - dst_height; |
| 130 canvas->DrawBitmapInt(icon, 0, 0, icon.width(), icon.height(), |
| 131 dst_x, dst_y, dst_width, dst_height, false); |
| 132 |
| 133 int x1 = dst_x; |
| 134 int x2 = dst_x + dst_width; |
| 135 int y1 = dst_y; |
| 136 int y2 = dst_y + dst_height; |
| 137 |
| 138 // Top highlight |
| 139 canvas->DrawLineInt(SkColorSetARGB(58, 0xff, 0xff, 0xff), |
| 140 x1, y1, x2, y1); |
| 141 |
| 142 // Left Border |
| 143 canvas->DrawLineInt(SkColorSetARGB(28, 0, 0, 0), |
| 144 x1, y1 + 1, x1, y2); |
| 145 |
| 146 // Right Border |
| 147 canvas->DrawLineInt(SkColorSetARGB(28, 0, 0, 0), |
| 148 x2 - 1, y1 + 1, x2 - 1, y2); |
| 149 |
| 150 // Dark Shadow Top |
| 151 canvas->DrawLineInt(SkColorSetARGB(89, 0, 0, 0), |
| 152 x1 - 1, y1 - 1, x2 + 1, y1 - 1); |
| 153 canvas->DrawLineInt(SkColorSetARGB(89, 0, 0, 0), |
| 154 x1 - 1, y1, x1 - 1, y2); |
| 155 canvas->DrawLineInt(SkColorSetARGB(89, 0, 0, 0), |
| 156 x2, y1, x2, y2); |
| 157 |
| 158 // Light Shadow Top |
| 159 canvas->DrawLineInt(SkColorSetARGB(29, 0, 0, 0), |
| 160 x1 - 2, y1 - 2, x2 + 2, y1 - 2); |
| 161 canvas->DrawLineInt(SkColorSetARGB(29, 0, 0, 0), |
| 162 x1 - 2, y1 - 1, x1 - 2, y2); |
| 163 canvas->DrawLineInt(SkColorSetARGB(29, 0, 0, 0), |
| 164 x2 + 1, y1 - 1, x2 + 1, y2); |
| 165 } |
123 | 166 |
124 if (set_taskbar_decoration_) { | 167 if (set_taskbar_decoration_) { |
125 // Drawing the taskbar decoration uses lanczos resizing so we really | 168 // Drawing the taskbar decoration uses lanczos resizing so we really |
126 // want to do it only once. | 169 // want to do it only once. |
127 DrawTaskBarDecoration(browser_, &icon); | 170 DrawTaskBarDecoration(browser_, &icon); |
128 set_taskbar_decoration_ = false; | 171 set_taskbar_decoration_ = false; |
129 } | 172 } |
130 } | 173 } |
131 | 174 |
132 bool AvatarMenuButton::HitTest(const gfx::Point& point) const { | 175 bool AvatarMenuButton::HitTest(const gfx::Point& point) const { |
133 if (!has_menu_) | 176 if (!has_menu_) |
134 return false; | 177 return false; |
135 return views::MenuButton::HitTest(point); | 178 return views::MenuButton::HitTest(point); |
136 } | 179 } |
137 | 180 |
138 // If the icon changes, we need to set the taskbar decoration again. | 181 // If the icon changes, we need to set the taskbar decoration again. |
139 void AvatarMenuButton::SetIcon(const SkBitmap& icon) { | 182 void AvatarMenuButton::SetIcon(const SkBitmap& icon) { |
140 views::MenuButton::SetIcon(icon); | 183 if (icon.width() == icon.height()) { |
| 184 SkBitmap resized_image = skia::ImageOperations::Resize( |
| 185 icon, skia::ImageOperations::RESIZE_BEST, 28, 28); |
| 186 views::MenuButton::SetIcon(resized_image); |
| 187 } else { |
| 188 views::MenuButton::SetIcon(icon); |
| 189 } |
141 set_taskbar_decoration_ = true; | 190 set_taskbar_decoration_ = true; |
142 } | 191 } |
143 | 192 |
144 // views::ViewMenuDelegate implementation | 193 // views::ViewMenuDelegate implementation |
145 void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { | 194 void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { |
146 ShowAvatarBubble(); | 195 ShowAvatarBubble(); |
147 } | 196 } |
148 | 197 |
149 void AvatarMenuButton::ShowAvatarBubble() { | 198 void AvatarMenuButton::ShowAvatarBubble() { |
150 if (!has_menu_ || bubble_) | 199 if (!has_menu_ || bubble_) |
(...skipping 12 matching lines...) Expand all Loading... |
163 views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR, bubble_view, bubble_view); | 212 views::BubbleBorder::ALIGN_ARROW_TO_MID_ANCHOR, bubble_view, bubble_view); |
164 bubble_->AddObserver(this); | 213 bubble_->AddObserver(this); |
165 | 214 |
166 ProfileMetrics::LogProfileOpenMethod(ProfileMetrics::ICON_AVATAR_BUBBLE); | 215 ProfileMetrics::LogProfileOpenMethod(ProfileMetrics::ICON_AVATAR_BUBBLE); |
167 } | 216 } |
168 | 217 |
169 void AvatarMenuButton::OnBubbleClosing() { | 218 void AvatarMenuButton::OnBubbleClosing() { |
170 bubble_->RemoveObserver(this); | 219 bubble_->RemoveObserver(this); |
171 bubble_ = NULL; | 220 bubble_ = NULL; |
172 } | 221 } |
OLD | NEW |