Chromium Code Reviews| 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/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& avatar) { | |
| 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, | |
|
Peter Kasting
2011/08/31 16:59:46
Nit: Shorter:
if (FAILED(taskbar.CreateInstance
| |
| 40 CLSCTX_INPROC_SERVER); | |
| 41 if (FAILED(result)) | |
| 42 return; | |
| 43 result = taskbar->HrInit(); | |
| 44 if (FAILED(result)) | |
| 45 return; | |
| 46 BrowserWindow* bw = browser->window(); | |
|
Peter Kasting
2011/08/31 16:59:46
Nit: Do we really need to check window() and GetNa
| |
| 47 if (!bw) | |
| 48 return; | |
| 49 gfx::NativeWindow window = bw->GetNativeHandle(); | |
| 50 if (!window) | |
| 51 return; | |
| 52 // Since the target size is so small, we use our best resizer. | |
| 53 SkBitmap sk_icon = skia::ImageOperations::Resize( | |
| 54 avatar, | |
| 55 skia::ImageOperations::RESIZE_LANCZOS3, | |
| 56 16, 16); | |
| 57 HICON icon = IconUtil::CreateHICONFromSkBitmap(sk_icon); | |
| 58 if (!icon) | |
| 59 return; | |
| 60 taskbar->SetOverlayIcon(window, icon, L""); | |
| 61 ::DestroyIcon(icon); | |
|
Peter Kasting
2011/08/31 16:59:46
Nit: I think you can get away without :: here
| |
| 62 #endif | |
| 63 } | |
| 64 | |
| 18 AvatarMenuButton::AvatarMenuButton(Browser* browser, bool has_menu) | 65 AvatarMenuButton::AvatarMenuButton(Browser* browser, bool has_menu) |
| 19 : MenuButton(NULL, std::wstring(), this, false), | 66 : MenuButton(NULL, std::wstring(), this, false), |
| 20 browser_(browser), | 67 browser_(browser), |
| 21 has_menu_(has_menu) { | 68 has_menu_(has_menu), |
| 69 first_time_(true) { | |
| 22 // In RTL mode, the avatar icon should be looking the opposite direction. | 70 // In RTL mode, the avatar icon should be looking the opposite direction. |
| 23 EnableCanvasFlippingForRTLUI(true); | 71 EnableCanvasFlippingForRTLUI(true); |
| 24 } | 72 } |
| 25 | 73 |
| 26 AvatarMenuButton::~AvatarMenuButton() {} | 74 AvatarMenuButton::~AvatarMenuButton() {} |
| 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; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 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 (first_time_) { | |
|
Peter Kasting
2011/08/31 16:59:46
Nit: Sounds like this variable should be named |sh
| |
| 103 // Drawing the taskbar decoration uses lanczos resizing so we really | |
| 104 // want to do it only once. | |
| 105 DrawTaskBarDecoration(browser_, icon); | |
| 106 first_time_ = 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 |
| 61 // views::ViewMenuDelegate implementation | 116 // views::ViewMenuDelegate implementation |
| 62 void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { | 117 void AvatarMenuButton::RunMenu(views::View* source, const gfx::Point& pt) { |
| 63 if (!has_menu_) | 118 if (!has_menu_) |
| 64 return; | 119 return; |
| 65 | 120 |
| 66 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow( | 121 BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow( |
| 67 browser_->window()->GetNativeHandle()); | 122 browser_->window()->GetNativeHandle()); |
| 68 | 123 |
| 69 gfx::Point origin; | 124 gfx::Point origin; |
| 70 views::View::ConvertPointToScreen(this, &origin); | 125 views::View::ConvertPointToScreen(this, &origin); |
| 71 gfx::Rect bounds(0, 0, width(), height()); | 126 gfx::Rect bounds(0, 0, width(), height()); |
| 72 bounds.set_origin(origin); | 127 bounds.set_origin(origin); |
| 73 | 128 |
| 74 AvatarMenuBubbleView* bubble_view = new AvatarMenuBubbleView(browser_); | 129 AvatarMenuBubbleView* bubble_view = new AvatarMenuBubbleView(browser_); |
| 75 // Bubble::Show() takes ownership of the view. | 130 // Bubble::Show() takes ownership of the view. |
| 76 Bubble::Show(browser_view->GetWidget(), bounds, | 131 Bubble::Show(browser_view->GetWidget(), bounds, |
| 77 views::BubbleBorder::TOP_LEFT, | 132 views::BubbleBorder::TOP_LEFT, |
| 78 bubble_view, bubble_view); | 133 bubble_view, bubble_view); |
| 79 } | 134 } |
| OLD | NEW |