1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/views/tab_icon_view.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "chrome/app/chrome_command_ids.h"
15 #include "chrome/browser/ui/views/tab_icon_view_model.h"
16 #include "grit/theme_resources.h"
17 #include "ui/base/resource/resource_bundle.h"
18 #include "ui/base/theme_provider.h"
19 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/favicon_size.h"
21 #include "ui/resources/grit/ui_resources.h"
24 #include "chrome/browser/app_icon_win.h"
25 #include "ui/gfx/icon_util.h"
30 bool g_initialized
= false;
31 gfx::ImageSkia
* g_default_favicon
= nullptr;
36 void TabIconView::InitializeIfNeeded() {
41 // The default window icon is the application icon, not the default
43 HICON app_icon
= GetAppIcon();
44 scoped_ptr
<SkBitmap
> bitmap(
45 IconUtil::CreateSkBitmapFromHICON(app_icon
, gfx::Size(16, 16)));
46 g_default_favicon
= new gfx::ImageSkia(gfx::ImageSkiaRep(*bitmap
, 1.0f
));
47 DestroyIcon(app_icon
);
49 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
50 g_default_favicon
= rb
.GetImageSkiaNamed(IDR_PRODUCT_LOGO_16
);
55 TabIconView::TabIconView(chrome::TabIconViewModel
* model
,
56 views::MenuButtonListener
* listener
)
57 : views::MenuButton(NULL
, base::string16(), listener
, false),
59 throbber_running_(false),
65 TabIconView::~TabIconView() {
68 void TabIconView::Update() {
69 static bool initialized
= false;
70 static int throbber_frame_count
= 0;
73 gfx::ImageSkia
throbber(*ui::ResourceBundle::GetSharedInstance().
74 GetImageSkiaNamed(IDR_THROBBER
));
75 throbber_frame_count
= throbber
.width() / throbber
.height();
78 if (throbber_running_
) {
79 // We think the tab is loading.
80 if (!model_
->ShouldTabIconViewAnimate()) {
81 // Woops, tab is invalid or not loading, reset our status and schedule
83 throbber_running_
= false;
86 // The tab is still loading, increment the frame.
87 throbber_frame_
= (throbber_frame_
+ 1) % throbber_frame_count
;
90 } else if (model_
->ShouldTabIconViewAnimate()) {
91 // We didn't think we were loading, but the tab is loading. Reset the
92 // frame and status and schedule a paint.
93 throbber_running_
= true;
99 void TabIconView::PaintThrobber(gfx::Canvas
* canvas
) {
100 gfx::ImageSkia
throbber(*GetThemeProvider()->GetImageSkiaNamed(
101 is_light_
? IDR_THROBBER_LIGHT
: IDR_THROBBER
));
102 int image_size
= throbber
.height();
103 PaintIcon(canvas
, throbber
, throbber_frame_
* image_size
, 0, image_size
,
107 void TabIconView::PaintFavicon(gfx::Canvas
* canvas
,
108 const gfx::ImageSkia
& image
) {
109 PaintIcon(canvas
, image
, 0, 0, image
.width(), image
.height(), true);
112 void TabIconView::PaintIcon(gfx::Canvas
* canvas
,
113 const gfx::ImageSkia
& image
,
119 // For source images smaller than the favicon square, scale them as if they
120 // were padded to fit the favicon square, so we don't blow up tiny favicons
121 // into larger or nonproportional results.
122 float float_src_w
= static_cast<float>(src_w
);
123 float float_src_h
= static_cast<float>(src_h
);
124 float scalable_w
, scalable_h
;
125 if (src_w
<= gfx::kFaviconSize
&& src_h
<= gfx::kFaviconSize
) {
126 scalable_w
= scalable_h
= gfx::kFaviconSize
;
128 scalable_w
= float_src_w
;
129 scalable_h
= float_src_h
;
132 // Scale proportionately.
133 float scale
= std::min(static_cast<float>(width()) / scalable_w
,
134 static_cast<float>(height()) / scalable_h
);
135 int dest_w
= static_cast<int>(float_src_w
* scale
);
136 int dest_h
= static_cast<int>(float_src_h
* scale
);
138 // Center the scaled image.
139 canvas
->DrawImageInt(image
, src_x
, src_y
, src_w
, src_h
,
140 (width() - dest_w
) / 2, (height() - dest_h
) / 2, dest_w
,
144 gfx::Size
TabIconView::GetPreferredSize() const {
145 return gfx::Size(gfx::kFaviconSize
, gfx::kFaviconSize
);
148 const char* TabIconView::GetClassName() const {
149 return "TabIconView";
152 void TabIconView::OnPaint(gfx::Canvas
* canvas
) {
153 bool rendered
= false;
155 if (throbber_running_
) {
157 PaintThrobber(canvas
);
159 gfx::ImageSkia favicon
= model_
->GetFaviconForTabIconView();
160 if (!favicon
.isNull()) {
162 PaintFavicon(canvas
, favicon
);
167 PaintFavicon(canvas
, *g_default_favicon
);