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