• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/ui/views/tab_icon_view.h"
6 
7 #if defined(OS_WIN)
8 #include <windows.h>
9 #include <shellapi.h>
10 #endif
11 
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"
22 
23 #if defined(OS_WIN)
24 #include "chrome/browser/app_icon_win.h"
25 #include "ui/gfx/icon_util.h"
26 #endif
27 
28 static bool g_initialized = false;
29 static gfx::ImageSkia* g_default_favicon = NULL;
30 
31 // static
InitializeIfNeeded()32 void TabIconView::InitializeIfNeeded() {
33   if (!g_initialized) {
34     g_initialized = true;
35 
36 #if defined(OS_WIN)
37     // The default window icon is the application icon, not the default
38     // favicon.
39     HICON app_icon = GetAppIcon();
40     scoped_ptr<SkBitmap> bitmap(
41         IconUtil::CreateSkBitmapFromHICON(app_icon, gfx::Size(16, 16)));
42     g_default_favicon = new gfx::ImageSkia(gfx::ImageSkiaRep(*bitmap, 1.0f));
43     DestroyIcon(app_icon);
44 #else
45     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
46     g_default_favicon = rb.GetImageSkiaNamed(IDR_PRODUCT_LOGO_16);
47 #endif
48   }
49 }
50 
TabIconView(chrome::TabIconViewModel * model,views::MenuButtonListener * listener)51 TabIconView::TabIconView(chrome::TabIconViewModel* model,
52                          views::MenuButtonListener* listener)
53     : views::MenuButton(NULL, base::string16(), listener, false),
54       model_(model),
55       throbber_running_(false),
56       is_light_(false),
57       throbber_frame_(0) {
58   InitializeIfNeeded();
59 }
60 
~TabIconView()61 TabIconView::~TabIconView() {
62 }
63 
Update()64 void TabIconView::Update() {
65   static bool initialized = false;
66   static int throbber_frame_count = 0;
67   if (!initialized) {
68     initialized = true;
69     gfx::ImageSkia throbber(*ui::ResourceBundle::GetSharedInstance().
70         GetImageSkiaNamed(IDR_THROBBER));
71     throbber_frame_count = throbber.width() / throbber.height();
72   }
73 
74   if (throbber_running_) {
75     // We think the tab is loading.
76     if (!model_->ShouldTabIconViewAnimate()) {
77       // Woops, tab is invalid or not loading, reset our status and schedule
78       // a paint.
79       throbber_running_ = false;
80       SchedulePaint();
81     } else {
82       // The tab is still loading, increment the frame.
83       throbber_frame_ = (throbber_frame_ + 1) % throbber_frame_count;
84       SchedulePaint();
85     }
86   } else if (model_->ShouldTabIconViewAnimate()) {
87     // We didn't think we were loading, but the tab is loading. Reset the
88     // frame and status and schedule a paint.
89     throbber_running_ = true;
90     throbber_frame_ = 0;
91     SchedulePaint();
92   }
93 }
94 
PaintThrobber(gfx::Canvas * canvas)95 void TabIconView::PaintThrobber(gfx::Canvas* canvas) {
96   gfx::ImageSkia throbber(*GetThemeProvider()->GetImageSkiaNamed(
97       is_light_ ? IDR_THROBBER_LIGHT : IDR_THROBBER));
98   int image_size = throbber.height();
99   PaintIcon(canvas, throbber, throbber_frame_ * image_size, 0, image_size,
100             image_size, false);
101 }
102 
PaintFavicon(gfx::Canvas * canvas,const gfx::ImageSkia & image)103 void TabIconView::PaintFavicon(gfx::Canvas* canvas,
104                                const gfx::ImageSkia& image) {
105   PaintIcon(canvas, image, 0, 0, image.width(), image.height(), true);
106 }
107 
PaintIcon(gfx::Canvas * canvas,const gfx::ImageSkia & image,int src_x,int src_y,int src_w,int src_h,bool filter)108 void TabIconView::PaintIcon(gfx::Canvas* canvas,
109                             const gfx::ImageSkia& image,
110                             int src_x,
111                             int src_y,
112                             int src_w,
113                             int src_h,
114                             bool filter) {
115   // For source images smaller than the favicon square, scale them as if they
116   // were padded to fit the favicon square, so we don't blow up tiny favicons
117   // into larger or nonproportional results.
118   float float_src_w = static_cast<float>(src_w);
119   float float_src_h = static_cast<float>(src_h);
120   float scalable_w, scalable_h;
121   if (src_w <= gfx::kFaviconSize && src_h <= gfx::kFaviconSize) {
122     scalable_w = scalable_h = gfx::kFaviconSize;
123   } else {
124     scalable_w = float_src_w;
125     scalable_h = float_src_h;
126   }
127 
128   // Scale proportionately.
129   float scale = std::min(static_cast<float>(width()) / scalable_w,
130                          static_cast<float>(height()) / scalable_h);
131   int dest_w = static_cast<int>(float_src_w * scale);
132   int dest_h = static_cast<int>(float_src_h * scale);
133 
134   // Center the scaled image.
135   canvas->DrawImageInt(image, src_x, src_y, src_w, src_h,
136                        (width() - dest_w) / 2, (height() - dest_h) / 2, dest_w,
137                        dest_h, filter);
138 }
139 
OnPaint(gfx::Canvas * canvas)140 void TabIconView::OnPaint(gfx::Canvas* canvas) {
141   bool rendered = false;
142 
143   if (throbber_running_) {
144     rendered = true;
145     PaintThrobber(canvas);
146   } else {
147     gfx::ImageSkia favicon = model_->GetFaviconForTabIconView();
148     if (!favicon.isNull()) {
149       rendered = true;
150       PaintFavicon(canvas, favicon);
151     }
152   }
153 
154   if (!rendered)
155     PaintFavicon(canvas, *g_default_favicon);
156 }
157 
GetPreferredSize() const158 gfx::Size TabIconView::GetPreferredSize() const {
159   return gfx::Size(gfx::kFaviconSize, gfx::kFaviconSize);
160 }
161