| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } | |
| OLD | NEW |