Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: chrome/browser/views/tabs/base_tab.cc

Issue 3064006: Make the throbber and tab close button correctly respond to theme changes. T... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/views/tabs/base_tab.h ('k') | chrome/browser/views/tabs/tab.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/views/tabs/base_tab.h" 5 #include "chrome/browser/views/tabs/base_tab.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "app/animation_container.h" 9 #include "app/animation_container.h"
10 #include "app/l10n_util.h" 10 #include "app/l10n_util.h"
11 #include "app/resource_bundle.h" 11 #include "app/resource_bundle.h"
12 #include "app/slide_animation.h" 12 #include "app/slide_animation.h"
13 #include "app/theme_provider.h"
13 #include "app/throb_animation.h" 14 #include "app/throb_animation.h"
14 #include "base/command_line.h" 15 #include "base/command_line.h"
15 #include "base/utf_string_conversions.h" 16 #include "base/utf_string_conversions.h"
16 #include "chrome/browser/browser.h" 17 #include "chrome/browser/browser.h"
17 #include "chrome/browser/tab_contents/tab_contents.h" 18 #include "chrome/browser/tab_contents/tab_contents.h"
18 #include "chrome/browser/views/tabs/tab_controller.h" 19 #include "chrome/browser/views/tabs/tab_controller.h"
19 #include "chrome/browser/view_ids.h" 20 #include "chrome/browser/view_ids.h"
20 #include "chrome/common/chrome_switches.h" 21 #include "chrome/common/chrome_switches.h"
21 #include "gfx/canvas_skia.h" 22 #include "gfx/canvas_skia.h"
22 #include "gfx/favicon_size.h" 23 #include "gfx/favicon_size.h"
23 #include "gfx/font.h" 24 #include "gfx/font.h"
24 #include "grit/app_resources.h" 25 #include "grit/app_resources.h"
25 #include "grit/generated_resources.h" 26 #include "grit/generated_resources.h"
26 #include "grit/theme_resources.h" 27 #include "grit/theme_resources.h"
27 #include "views/controls/button/image_button.h" 28 #include "views/controls/button/image_button.h"
28 29
29 #ifdef WIN32 30 #ifdef WIN32
30 #include "app/win_util.h" 31 #include "app/win_util.h"
31 #endif 32 #endif
32 33
33 // How long the pulse throb takes. 34 // How long the pulse throb takes.
34 static const int kPulseDurationMs = 200; 35 static const int kPulseDurationMs = 200;
35 36
36 // How long the hover state takes. 37 // How long the hover state takes.
37 static const int kHoverDurationMs = 90; 38 static const int kHoverDurationMs = 90;
38 39
39 static SkBitmap* waiting_animation_frames = NULL;
40 static SkBitmap* loading_animation_frames = NULL;
41 static int loading_animation_frame_count = 0;
42 static int waiting_animation_frame_count = 0;
43 static int waiting_to_loading_frame_count_ratio = 0;
44
45 // Close button images.
46 static SkBitmap* close_button_n = NULL;
47 static SkBitmap* close_button_h = NULL;
48 static SkBitmap* close_button_p = NULL;
49
50 static SkBitmap* crashed_fav_icon = NULL;
51
52 namespace { 40 namespace {
53 41
54 //////////////////////////////////////////////////////////////////////////////// 42 ////////////////////////////////////////////////////////////////////////////////
55 // TabCloseButton 43 // TabCloseButton
56 // 44 //
57 // This is a Button subclass that causes middle clicks to be forwarded to the 45 // This is a Button subclass that causes middle clicks to be forwarded to the
58 // parent View by explicitly not handling them in OnMousePressed. 46 // parent View by explicitly not handling them in OnMousePressed.
59 class TabCloseButton : public views::ImageButton { 47 class TabCloseButton : public views::ImageButton {
60 public: 48 public:
61 explicit TabCloseButton(views::ButtonListener* listener) 49 explicit TabCloseButton(views::ButtonListener* listener)
(...skipping 21 matching lines...) Expand all
83 GetParent()->OnMouseExited(event); 71 GetParent()->OnMouseExited(event);
84 } 72 }
85 73
86 private: 74 private:
87 DISALLOW_COPY_AND_ASSIGN(TabCloseButton); 75 DISALLOW_COPY_AND_ASSIGN(TabCloseButton);
88 }; 76 };
89 77
90 } // namespace 78 } // namespace
91 79
92 // static 80 // static
93 int BaseTab::close_button_width_ = 0;
94 // static
95 int BaseTab::close_button_height_ = 0;
96 // static
97 int BaseTab::loading_animation_size_ = 0;
98
99 // static
100 gfx::Font* BaseTab::font_ = NULL; 81 gfx::Font* BaseTab::font_ = NULL;
101 // static 82 // static
102 int BaseTab::font_height_ = 0; 83 int BaseTab::font_height_ = 0;
103 84
104 //////////////////////////////////////////////////////////////////////////////// 85 ////////////////////////////////////////////////////////////////////////////////
105 // FaviconCrashAnimation 86 // FaviconCrashAnimation
106 // 87 //
107 // A custom animation subclass to manage the favicon crash animation. 88 // A custom animation subclass to manage the favicon crash animation.
108 class BaseTab::FavIconCrashAnimation : public LinearAnimation, 89 class BaseTab::FavIconCrashAnimation : public LinearAnimation,
109 public AnimationDelegate { 90 public AnimationDelegate {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 loading_animation_frame_(0), 128 loading_animation_frame_(0),
148 throbber_disabled_(false), 129 throbber_disabled_(false),
149 theme_provider_(NULL), 130 theme_provider_(NULL),
150 fav_icon_hiding_offset_(0), 131 fav_icon_hiding_offset_(0),
151 should_display_crashed_favicon_(false) { 132 should_display_crashed_favicon_(false) {
152 BaseTab::InitResources(); 133 BaseTab::InitResources();
153 134
154 SetID(VIEW_ID_TAB); 135 SetID(VIEW_ID_TAB);
155 136
156 // Add the Close Button. 137 // Add the Close Button.
157 TabCloseButton* close_button = new TabCloseButton(this); 138 close_button_ = new TabCloseButton(this);
158 close_button_ = close_button; 139 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
159 close_button->SetImage(views::CustomButton::BS_NORMAL, close_button_n); 140 close_button_->SetImage(views::CustomButton::BS_NORMAL,
160 close_button->SetImage(views::CustomButton::BS_HOT, close_button_h); 141 rb.GetBitmapNamed(IDR_TAB_CLOSE));
161 close_button->SetImage(views::CustomButton::BS_PUSHED, close_button_p); 142 close_button_->SetImage(views::CustomButton::BS_HOT,
162 close_button->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_CLOSE_TAB)); 143 rb.GetBitmapNamed(IDR_TAB_CLOSE_H));
163 close_button->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE)); 144 close_button_->SetImage(views::CustomButton::BS_PUSHED,
145 rb.GetBitmapNamed(IDR_TAB_CLOSE_P));
146 close_button_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_CLOSE_TAB));
147 close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE));
164 // Disable animation so that the red danger sign shows up immediately 148 // Disable animation so that the red danger sign shows up immediately
165 // to help avoid mis-clicks. 149 // to help avoid mis-clicks.
166 close_button->SetAnimationDuration(0); 150 close_button_->SetAnimationDuration(0);
167 AddChildView(close_button); 151 AddChildView(close_button_);
168 152
169 SetContextMenuController(this); 153 SetContextMenuController(this);
170 } 154 }
171 155
172 BaseTab::~BaseTab() { 156 BaseTab::~BaseTab() {
173 } 157 }
174 158
175 void BaseTab::SetData(const TabRendererData& data) { 159 void BaseTab::SetData(const TabRendererData& data) {
176 TabRendererData old(data_); 160 TabRendererData old(data_);
177 data_ = data; 161 data_ = data;
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 return true; 312 return true;
329 } 313 }
330 314
331 ThemeProvider* BaseTab::GetThemeProvider() { 315 ThemeProvider* BaseTab::GetThemeProvider() {
332 ThemeProvider* tp = View::GetThemeProvider(); 316 ThemeProvider* tp = View::GetThemeProvider();
333 return tp ? tp : theme_provider_; 317 return tp ? tp : theme_provider_;
334 } 318 }
335 319
336 void BaseTab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state, 320 void BaseTab::AdvanceLoadingAnimation(TabRendererData::NetworkState old_state,
337 TabRendererData::NetworkState state) { 321 TabRendererData::NetworkState state) {
322 static bool initialized = false;
323 static int loading_animation_frame_count = 0,
324 waiting_animation_frame_count = 0,
325 waiting_to_loading_frame_count_ratio = 0;
326 if (!initialized) {
327 initialized = true;
328 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
329 SkBitmap loading_animation(*rb.GetBitmapNamed(IDR_THROBBER));
330 loading_animation_frame_count =
331 loading_animation.width() / loading_animation.height();
332 SkBitmap waiting_animation(*rb.GetBitmapNamed(IDR_THROBBER_WAITING));
333 waiting_animation_frame_count =
334 waiting_animation.width() / waiting_animation.height();
335 waiting_to_loading_frame_count_ratio =
336 waiting_animation_frame_count / loading_animation_frame_count;
337 }
338
338 // The waiting animation is the reverse of the loading animation, but at a 339 // The waiting animation is the reverse of the loading animation, but at a
339 // different rate - the following reverses and scales the animation_frame_ 340 // different rate - the following reverses and scales the animation_frame_
340 // so that the frame is at an equivalent position when going from one 341 // so that the frame is at an equivalent position when going from one
341 // animation to the other. 342 // animation to the other.
342 if (state != old_state) { 343 if (state != old_state) {
343 loading_animation_frame_ = loading_animation_frame_count - 344 loading_animation_frame_ = loading_animation_frame_count -
344 (loading_animation_frame_ / waiting_to_loading_frame_count_ratio); 345 (loading_animation_frame_ / waiting_to_loading_frame_count_ratio);
345 } 346 }
346 347
347 if (state != TabRendererData::NETWORK_STATE_NONE) { 348 if (state != TabRendererData::NETWORK_STATE_NONE) {
(...skipping 12 matching lines...) Expand all
360 x = width() - x - data().favicon.width(); 361 x = width() - x - data().favicon.width();
361 else 362 else
362 x = width() - x - kFavIconSize; 363 x = width() - x - kFavIconSize;
363 } 364 }
364 365
365 int favicon_x = x; 366 int favicon_x = x;
366 if (!data().favicon.isNull() && data().favicon.width() != kFavIconSize) 367 if (!data().favicon.isNull() && data().favicon.width() != kFavIconSize)
367 favicon_x += (data().favicon.width() - kFavIconSize) / 2; 368 favicon_x += (data().favicon.width() - kFavIconSize) / 2;
368 369
369 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) { 370 if (data().network_state != TabRendererData::NETWORK_STATE_NONE) {
370 SkBitmap* frames = 371 ThemeProvider* tp = GetThemeProvider();
372 SkBitmap frames(*tp->GetBitmapNamed(
371 (data().network_state == TabRendererData::NETWORK_STATE_WAITING) ? 373 (data().network_state == TabRendererData::NETWORK_STATE_WAITING) ?
372 waiting_animation_frames : loading_animation_frames; 374 IDR_THROBBER_WAITING : IDR_THROBBER));
373 int image_size = frames->height(); 375 int image_size = frames.height();
374 int image_offset = loading_animation_frame_ * image_size; 376 int image_offset = loading_animation_frame_ * image_size;
375 int dst_y = (height() - image_size) / 2; 377 int dst_y = (height() - image_size) / 2;
376 canvas->DrawBitmapInt(*frames, image_offset, 0, image_size, 378 canvas->DrawBitmapInt(frames, image_offset, 0, image_size,
377 image_size, favicon_x, dst_y, image_size, image_size, 379 image_size, favicon_x, dst_y, image_size, image_size,
378 false); 380 false);
379 } else { 381 } else {
380 canvas->Save(); 382 canvas->Save();
381 canvas->ClipRectInt(0, 0, width(), height()); 383 canvas->ClipRectInt(0, 0, width(), height());
382 if (should_display_crashed_favicon_) { 384 if (should_display_crashed_favicon_) {
383 canvas->DrawBitmapInt(*crashed_fav_icon, 0, 0, 385 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
384 crashed_fav_icon->width(), 386 SkBitmap crashed_fav_icon(*rb.GetBitmapNamed(IDR_SAD_FAVICON));
385 crashed_fav_icon->height(), 387 canvas->DrawBitmapInt(crashed_fav_icon, 0, 0, crashed_fav_icon.width(),
386 favicon_x, 388 crashed_fav_icon.height(), favicon_x,
387 (height() - crashed_fav_icon->height()) / 2 + 389 (height() - crashed_fav_icon.height()) / 2 + fav_icon_hiding_offset_,
388 fav_icon_hiding_offset_, 390 kFavIconSize, kFavIconSize, true);
389 kFavIconSize, kFavIconSize,
390 true);
391 } else { 391 } else {
392 if (!data().favicon.isNull()) { 392 if (!data().favicon.isNull()) {
393 // TODO(pkasting): Use code in tab_icon_view.cc:PaintIcon() (or switch 393 // TODO(pkasting): Use code in tab_icon_view.cc:PaintIcon() (or switch
394 // to using that class to render the favicon). 394 // to using that class to render the favicon).
395 int size = data().favicon.width(); 395 int size = data().favicon.width();
396 canvas->DrawBitmapInt(data().favicon, 0, 0, 396 canvas->DrawBitmapInt(data().favicon, 0, 0,
397 data().favicon.width(), 397 data().favicon.width(),
398 data().favicon.height(), 398 data().favicon.height(),
399 x, y + fav_icon_hiding_offset_, size, size, 399 x, y + fav_icon_hiding_offset_, size, size,
400 true); 400 true);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 controller()->CloseTab(this); 437 controller()->CloseTab(this);
438 } 438 }
439 439
440 void BaseTab::ShowContextMenu(views::View* source, 440 void BaseTab::ShowContextMenu(views::View* source,
441 const gfx::Point& p, 441 const gfx::Point& p,
442 bool is_mouse_gesture) { 442 bool is_mouse_gesture) {
443 if (controller()) 443 if (controller())
444 controller()->ShowContextMenu(this, p); 444 controller()->ShowContextMenu(this, p);
445 } 445 }
446 446
447 void BaseTab::ThemeChanged() {
448 views::View::ThemeChanged();
449 LoadThemeImages();
450 }
451
452 void BaseTab::SetFavIconHidingOffset(int offset) { 447 void BaseTab::SetFavIconHidingOffset(int offset) {
453 fav_icon_hiding_offset_ = offset; 448 fav_icon_hiding_offset_ = offset;
454 SchedulePaint(); 449 SchedulePaint();
455 } 450 }
456 451
457 void BaseTab::DisplayCrashedFavIcon() { 452 void BaseTab::DisplayCrashedFavIcon() {
458 should_display_crashed_favicon_ = true; 453 should_display_crashed_favicon_ = true;
459 } 454 }
460 455
461 void BaseTab::ResetCrashedFavIcon() { 456 void BaseTab::ResetCrashedFavIcon() {
(...skipping 13 matching lines...) Expand all
475 crash_animation_->Stop(); 470 crash_animation_->Stop();
476 } 471 }
477 472
478 bool BaseTab::IsPerformingCrashAnimation() const { 473 bool BaseTab::IsPerformingCrashAnimation() const {
479 return crash_animation_.get() && crash_animation_->is_animating(); 474 return crash_animation_.get() && crash_animation_->is_animating();
480 } 475 }
481 476
482 // static 477 // static
483 void BaseTab::InitResources() { 478 void BaseTab::InitResources() {
484 static bool initialized = false; 479 static bool initialized = false;
485 if (initialized) 480 if (!initialized) {
486 return; 481 initialized = true;
487 482 font_ = new gfx::Font(
488 initialized = true; 483 ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::BaseFont));
489 484 font_height_ = font_->height();
490 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 485 }
491
492 crashed_fav_icon = rb.GetBitmapNamed(IDR_SAD_FAVICON);
493
494 close_button_n = rb.GetBitmapNamed(IDR_TAB_CLOSE);
495 close_button_h = rb.GetBitmapNamed(IDR_TAB_CLOSE_H);
496 close_button_p = rb.GetBitmapNamed(IDR_TAB_CLOSE_P);
497
498 close_button_width_ = close_button_n->width();
499 close_button_height_ = close_button_n->height();
500
501 // The loading animation image is a strip of states. Each state must be
502 // square, so the height must divide the width evenly.
503 loading_animation_frames = rb.GetBitmapNamed(IDR_THROBBER);
504 loading_animation_size_ = loading_animation_frames->height();
505 DCHECK(loading_animation_frames);
506 DCHECK(loading_animation_frames->width() %
507 loading_animation_frames->height() == 0);
508 loading_animation_frame_count =
509 loading_animation_frames->width() / loading_animation_frames->height();
510
511 waiting_animation_frames = rb.GetBitmapNamed(IDR_THROBBER_WAITING);
512 DCHECK(waiting_animation_frames);
513 DCHECK(waiting_animation_frames->width() %
514 waiting_animation_frames->height() == 0);
515 waiting_animation_frame_count =
516 waiting_animation_frames->width() / waiting_animation_frames->height();
517
518 waiting_to_loading_frame_count_ratio =
519 waiting_animation_frame_count / loading_animation_frame_count;
520
521 font_ = new gfx::Font(rb.GetFont(ResourceBundle::BaseFont));
522 font_height_ = font_->height();
523 } 486 }
524
525 // static
526 void BaseTab::LoadThemeImages() {
527 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
528 loading_animation_frames = rb.GetBitmapNamed(IDR_THROBBER);
529 waiting_animation_frames = rb.GetBitmapNamed(IDR_THROBBER_WAITING);
530 loading_animation_size_ = loading_animation_frames->height();
531 }
OLDNEW
« no previous file with comments | « chrome/browser/views/tabs/base_tab.h ('k') | chrome/browser/views/tabs/tab.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698