| 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/ui/views/tabs/tab.h" | 5 #include "chrome/browser/ui/views/tabs/tab.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "app/multi_animation.h" | 9 #include "app/multi_animation.h" |
| 10 #include "app/resource_bundle.h" | 10 #include "app/resource_bundle.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 // When a non-mini-tab becomes a mini-tab the width of the tab animates. If | 46 // When a non-mini-tab becomes a mini-tab the width of the tab animates. If |
| 47 // the width of a mini-tab is >= kMiniTabRendererAsNormalTabWidth then the tab | 47 // the width of a mini-tab is >= kMiniTabRendererAsNormalTabWidth then the tab |
| 48 // is rendered as a normal tab. This is done to avoid having the title | 48 // is rendered as a normal tab. This is done to avoid having the title |
| 49 // immediately disappear when transitioning a tab from normal to mini-tab. | 49 // immediately disappear when transitioning a tab from normal to mini-tab. |
| 50 static const int kMiniTabRendererAsNormalTabWidth = | 50 static const int kMiniTabRendererAsNormalTabWidth = |
| 51 browser_defaults::kMiniTabWidth + 30; | 51 browser_defaults::kMiniTabWidth + 30; |
| 52 | 52 |
| 53 // How opaque to make the hover state (out of 1). | 53 // How opaque to make the hover state (out of 1). |
| 54 static const double kHoverOpacity = 0.33; | 54 static const double kHoverOpacity = 0.33; |
| 55 | 55 |
| 56 Tab::TabImage Tab::tab_alpha = {0}; | 56 Tab::TabImage Tab::tab_alpha_ = {0}; |
| 57 Tab::TabImage Tab::tab_active = {0}; | 57 Tab::TabImage Tab::tab_active_ = {0}; |
| 58 Tab::TabImage Tab::tab_inactive = {0}; | 58 Tab::TabImage Tab::tab_inactive_ = {0}; |
| 59 | 59 |
| 60 // Durations for the various parts of the mini tab title animation. | 60 // Durations for the various parts of the mini tab title animation. |
| 61 static const int kMiniTitleChangeAnimationDuration1MS = 1600; | 61 static const int kMiniTitleChangeAnimationDuration1MS = 1600; |
| 62 static const int kMiniTitleChangeAnimationStart1MS = 0; | 62 static const int kMiniTitleChangeAnimationStart1MS = 0; |
| 63 static const int kMiniTitleChangeAnimationEnd1MS = 1900; | 63 static const int kMiniTitleChangeAnimationEnd1MS = 1900; |
| 64 static const int kMiniTitleChangeAnimationDuration2MS = 0; | 64 static const int kMiniTitleChangeAnimationDuration2MS = 0; |
| 65 static const int kMiniTitleChangeAnimationDuration3MS = 550; | 65 static const int kMiniTitleChangeAnimationDuration3MS = 550; |
| 66 static const int kMiniTitleChangeAnimationStart3MS = 150; | 66 static const int kMiniTitleChangeAnimationStart3MS = 150; |
| 67 static const int kMiniTitleChangeAnimationEnd3MS = 800; | 67 static const int kMiniTitleChangeAnimationEnd3MS = 800; |
| 68 | 68 |
| 69 // Offset from the right edge for the start of the mini title change animation. | 69 // Offset from the right edge for the start of the mini title change animation. |
| 70 static const int kMiniTitleChangeInitialXOffset = 6; | 70 static const int kMiniTitleChangeInitialXOffset = 6; |
| 71 | 71 |
| 72 // Radius of the radial gradient used for mini title change animation. | 72 // Radius of the radial gradient used for mini title change animation. |
| 73 static const int kMiniTitleChangeGradientRadius = 20; | 73 static const int kMiniTitleChangeGradientRadius = 20; |
| 74 | 74 |
| 75 // Colors of the gradient used during the mini title change animation. | 75 // Colors of the gradient used during the mini title change animation. |
| 76 static const SkColor kMiniTitleChangeGradientColor1 = SK_ColorWHITE; | 76 static const SkColor kMiniTitleChangeGradientColor1 = SK_ColorWHITE; |
| 77 static const SkColor kMiniTitleChangeGradientColor2 = | 77 static const SkColor kMiniTitleChangeGradientColor2 = |
| 78 SkColorSetARGB(0, 255, 255, 255); | 78 SkColorSetARGB(0, 255, 255, 255); |
| 79 | 79 |
| 80 // Hit mask constants. | 80 // Hit mask constants. |
| 81 static const SkScalar kTabCapWidth = 15; | 81 static const SkScalar kTabCapWidth = 15; |
| 82 static const SkScalar kTabTopCurveWidth = 4; | 82 static const SkScalar kTabTopCurveWidth = 4; |
| 83 static const SkScalar kTabBottomCurveWidth = 3; | 83 static const SkScalar kTabBottomCurveWidth = 3; |
| 84 | 84 |
| 85 namespace { | |
| 86 | |
| 87 void InitTabResources() { | |
| 88 static bool initialized = false; | |
| 89 if (initialized) | |
| 90 return; | |
| 91 | |
| 92 initialized = true; | |
| 93 Tab::LoadTabImages(); | |
| 94 } | |
| 95 | |
| 96 } // namespace | |
| 97 | |
| 98 // static | 85 // static |
| 99 const char Tab::kViewClassName[] = "browser/tabs/Tab"; | 86 const char Tab::kViewClassName[] = "browser/tabs/Tab"; |
| 100 | 87 |
| 101 //////////////////////////////////////////////////////////////////////////////// | 88 //////////////////////////////////////////////////////////////////////////////// |
| 102 // Tab, public: | 89 // Tab, public: |
| 103 | 90 |
| 104 Tab::Tab(TabController* controller) | 91 Tab::Tab(TabController* controller) |
| 105 : BaseTab(controller), | 92 : BaseTab(controller), |
| 106 showing_icon_(false), | 93 showing_icon_(false), |
| 107 showing_close_button_(false), | 94 showing_close_button_(false), |
| (...skipping 22 matching lines...) Expand all Loading... |
| 130 mini_title_animation_->set_delegate(this); | 117 mini_title_animation_->set_delegate(this); |
| 131 } | 118 } |
| 132 mini_title_animation_->Start(); | 119 mini_title_animation_->Start(); |
| 133 } | 120 } |
| 134 | 121 |
| 135 void Tab::StopMiniTabTitleAnimation() { | 122 void Tab::StopMiniTabTitleAnimation() { |
| 136 if (mini_title_animation_.get()) | 123 if (mini_title_animation_.get()) |
| 137 mini_title_animation_->Stop(); | 124 mini_title_animation_->Stop(); |
| 138 } | 125 } |
| 139 | 126 |
| 140 void Tab::PaintIcon(gfx::Canvas* canvas) { | |
| 141 BaseTab::PaintIcon(canvas, favicon_bounds_.x(), favicon_bounds_.y()); | |
| 142 } | |
| 143 | |
| 144 // static | 127 // static |
| 145 gfx::Size Tab::GetMinimumUnselectedSize() { | 128 gfx::Size Tab::GetMinimumUnselectedSize() { |
| 146 InitTabResources(); | 129 InitTabResources(); |
| 147 | 130 |
| 148 gfx::Size minimum_size; | 131 gfx::Size minimum_size; |
| 149 minimum_size.set_width(kLeftPadding + kRightPadding); | 132 minimum_size.set_width(kLeftPadding + kRightPadding); |
| 150 // Since we use bitmap images, the real minimum height of the image is | 133 // Since we use bitmap images, the real minimum height of the image is |
| 151 // defined most accurately by the height of the end cap images. | 134 // defined most accurately by the height of the end cap images. |
| 152 minimum_size.set_height(tab_active.image_l->height()); | 135 minimum_size.set_height(tab_active_.image_l->height()); |
| 153 return minimum_size; | 136 return minimum_size; |
| 154 } | 137 } |
| 155 | 138 |
| 156 // static | 139 // static |
| 157 gfx::Size Tab::GetMinimumSelectedSize() { | 140 gfx::Size Tab::GetMinimumSelectedSize() { |
| 158 gfx::Size minimum_size = GetMinimumUnselectedSize(); | 141 gfx::Size minimum_size = GetMinimumUnselectedSize(); |
| 159 minimum_size.set_width(kLeftPadding + kFavIconSize + kRightPadding); | 142 minimum_size.set_width(kLeftPadding + kFavIconSize + kRightPadding); |
| 160 return minimum_size; | 143 return minimum_size; |
| 161 } | 144 } |
| 162 | 145 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 // as child Views (which is the preferred method). Instead, these UI elements | 294 // as child Views (which is the preferred method). Instead, these UI elements |
| 312 // are drawn directly on the canvas from within Tab::Paint(). The Tab's child | 295 // are drawn directly on the canvas from within Tab::Paint(). The Tab's child |
| 313 // Views (for example, the Tab's close button which is a views::Button | 296 // Views (for example, the Tab's close button which is a views::Button |
| 314 // instance) are automatically mirrored by the mirroring infrastructure in | 297 // instance) are automatically mirrored by the mirroring infrastructure in |
| 315 // views. The elements Tab draws directly on the canvas need to be manually | 298 // views. The elements Tab draws directly on the canvas need to be manually |
| 316 // mirrored if the View's layout is right-to-left. | 299 // mirrored if the View's layout is right-to-left. |
| 317 title_bounds_.set_x(MirroredLeftPointForRect(title_bounds_)); | 300 title_bounds_.set_x(MirroredLeftPointForRect(title_bounds_)); |
| 318 } | 301 } |
| 319 | 302 |
| 320 void Tab::OnThemeChanged() { | 303 void Tab::OnThemeChanged() { |
| 321 Tab::LoadTabImages(); | 304 LoadTabImages(); |
| 322 } | 305 } |
| 323 | 306 |
| 324 bool Tab::HasHitTestMask() const { | 307 bool Tab::HasHitTestMask() const { |
| 325 return true; | 308 return true; |
| 326 } | 309 } |
| 327 | 310 |
| 328 void Tab::GetHitTestMask(gfx::Path* path) const { | 311 void Tab::GetHitTestMask(gfx::Path* path) const { |
| 329 DCHECK(path); | 312 DCHECK(path); |
| 330 | 313 |
| 331 SkScalar h = SkIntToScalar(height()); | 314 SkScalar h = SkIntToScalar(height()); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 360 void Tab::OnMouseMoved(const views::MouseEvent& e) { | 343 void Tab::OnMouseMoved(const views::MouseEvent& e) { |
| 361 hover_point_ = e.location(); | 344 hover_point_ = e.location(); |
| 362 // We need to redraw here because otherwise the hover glow does not update | 345 // We need to redraw here because otherwise the hover glow does not update |
| 363 // and follow the new mouse position. | 346 // and follow the new mouse position. |
| 364 SchedulePaint(); | 347 SchedulePaint(); |
| 365 } | 348 } |
| 366 | 349 |
| 367 //////////////////////////////////////////////////////////////////////////////// | 350 //////////////////////////////////////////////////////////////////////////////// |
| 368 // Tab, private | 351 // Tab, private |
| 369 | 352 |
| 353 void Tab::PaintIcon(gfx::Canvas* canvas) { |
| 354 BaseTab::PaintIcon(canvas, favicon_bounds_.x(), favicon_bounds_.y()); |
| 355 } |
| 356 |
| 370 void Tab::PaintTabBackground(gfx::Canvas* canvas) { | 357 void Tab::PaintTabBackground(gfx::Canvas* canvas) { |
| 371 if (IsSelected()) { | 358 if (IsSelected()) { |
| 372 PaintActiveTabBackground(canvas); | 359 PaintActiveTabBackground(canvas); |
| 373 } else { | 360 } else { |
| 374 if (mini_title_animation_.get() && mini_title_animation_->is_animating()) | 361 if (mini_title_animation_.get() && mini_title_animation_->is_animating()) |
| 375 PaintInactiveTabBackgroundWithTitleChange(canvas); | 362 PaintInactiveTabBackgroundWithTitleChange(canvas); |
| 376 else | 363 else |
| 377 PaintInactiveTabBackground(canvas); | 364 PaintInactiveTabBackground(canvas); |
| 378 | 365 |
| 379 double throb_value = GetThrobValue(); | 366 double throb_value = GetThrobValue(); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 if (GetWidget() && | 442 if (GetWidget() && |
| 456 GetWidget()->GetWindow()->GetNonClientView()->UseNativeFrame()) { | 443 GetWidget()->GetWindow()->GetNonClientView()->UseNativeFrame()) { |
| 457 tab_id = IDR_THEME_TAB_BACKGROUND_V; | 444 tab_id = IDR_THEME_TAB_BACKGROUND_V; |
| 458 } else { | 445 } else { |
| 459 tab_id = is_otr ? IDR_THEME_TAB_BACKGROUND_INCOGNITO : | 446 tab_id = is_otr ? IDR_THEME_TAB_BACKGROUND_INCOGNITO : |
| 460 IDR_THEME_TAB_BACKGROUND; | 447 IDR_THEME_TAB_BACKGROUND; |
| 461 } | 448 } |
| 462 | 449 |
| 463 SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(tab_id); | 450 SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(tab_id); |
| 464 | 451 |
| 465 TabImage* tab_image = &tab_active; | 452 TabImage* tab_image = &tab_active_; |
| 466 TabImage* tab_inactive_image = &tab_inactive; | 453 TabImage* tab_inactive_image = &tab_inactive_; |
| 467 TabImage* alpha = &tab_alpha; | 454 TabImage* alpha = &tab_alpha_; |
| 468 | 455 |
| 469 // If the theme is providing a custom background image, then its top edge | 456 // If the theme is providing a custom background image, then its top edge |
| 470 // should be at the top of the tab. Otherwise, we assume that the background | 457 // should be at the top of the tab. Otherwise, we assume that the background |
| 471 // image is a composited foreground + frame image. | 458 // image is a composited foreground + frame image. |
| 472 int bg_offset_y = GetThemeProvider()->HasCustomImage(tab_id) ? | 459 int bg_offset_y = GetThemeProvider()->HasCustomImage(tab_id) ? |
| 473 0 : background_offset_.y(); | 460 0 : background_offset_.y(); |
| 474 | 461 |
| 475 // We need a CanvasSkia object to be able to extract the bitmap from. | 462 // We need a CanvasSkia object to be able to extract the bitmap from. |
| 476 // We draw everything to this canvas and then output it to the canvas | 463 // We draw everything to this canvas and then output it to the canvas |
| 477 // parameter in addition to using it to mask the hover glow if needed. | 464 // parameter in addition to using it to mask the hover glow if needed. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 tab_inactive_image->r_width, | 516 tab_inactive_image->r_width, |
| 530 height()); | 517 height()); |
| 531 canvas->DrawBitmapInt(*tab_inactive_image->image_r, | 518 canvas->DrawBitmapInt(*tab_inactive_image->image_r, |
| 532 width() - tab_inactive_image->r_width, 0); | 519 width() - tab_inactive_image->r_width, 0); |
| 533 } | 520 } |
| 534 | 521 |
| 535 void Tab::PaintActiveTabBackground(gfx::Canvas* canvas) { | 522 void Tab::PaintActiveTabBackground(gfx::Canvas* canvas) { |
| 536 int offset = GetX(views::View::APPLY_MIRRORING_TRANSFORMATION) + | 523 int offset = GetX(views::View::APPLY_MIRRORING_TRANSFORMATION) + |
| 537 background_offset_.x(); | 524 background_offset_.x(); |
| 538 ThemeProvider* tp = GetThemeProvider(); | 525 ThemeProvider* tp = GetThemeProvider(); |
| 539 if (!tp) | 526 DCHECK(tp) << "Unable to get theme provider"; |
| 540 NOTREACHED() << "Unable to get theme provider"; | |
| 541 | 527 |
| 542 SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(IDR_THEME_TOOLBAR); | 528 SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(IDR_THEME_TOOLBAR); |
| 543 | 529 |
| 544 TabImage* tab_image = &tab_active; | 530 TabImage* tab_image = &tab_active_; |
| 545 TabImage* alpha = &tab_alpha; | 531 TabImage* alpha = &tab_alpha_; |
| 546 | 532 |
| 547 // Draw left edge. | 533 // Draw left edge. |
| 548 SkBitmap tab_l = SkBitmapOperations::CreateTiledBitmap( | 534 SkBitmap tab_l = SkBitmapOperations::CreateTiledBitmap( |
| 549 *tab_bg, offset, 0, tab_image->l_width, height()); | 535 *tab_bg, offset, 0, tab_image->l_width, height()); |
| 550 SkBitmap theme_l = | 536 SkBitmap theme_l = |
| 551 SkBitmapOperations::CreateMaskedBitmap(tab_l, *alpha->image_l); | 537 SkBitmapOperations::CreateMaskedBitmap(tab_l, *alpha->image_l); |
| 552 canvas->DrawBitmapInt(theme_l, 0, 0); | 538 canvas->DrawBitmapInt(theme_l, 0, 0); |
| 553 | 539 |
| 554 // Draw right edge. | 540 // Draw right edge. |
| 555 SkBitmap tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_bg, | 541 SkBitmap tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_bg, |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 return pulse_animation()->GetCurrentValue() * kHoverOpacity; | 628 return pulse_animation()->GetCurrentValue() * kHoverOpacity; |
| 643 | 629 |
| 644 return hover_animation() ? | 630 return hover_animation() ? |
| 645 kHoverOpacity * hover_animation()->GetCurrentValue() : 0; | 631 kHoverOpacity * hover_animation()->GetCurrentValue() : 0; |
| 646 } | 632 } |
| 647 | 633 |
| 648 //////////////////////////////////////////////////////////////////////////////// | 634 //////////////////////////////////////////////////////////////////////////////// |
| 649 // Tab, private: | 635 // Tab, private: |
| 650 | 636 |
| 651 // static | 637 // static |
| 638 void Tab::InitTabResources() { |
| 639 static bool initialized = false; |
| 640 if (initialized) |
| 641 return; |
| 642 |
| 643 initialized = true; |
| 644 |
| 645 // Load the tab images once now, and maybe again later if the theme changes. |
| 646 LoadTabImages(); |
| 647 } |
| 648 |
| 649 // static |
| 652 void Tab::LoadTabImages() { | 650 void Tab::LoadTabImages() { |
| 653 // We're not letting people override tab images just yet. | 651 // We're not letting people override tab images just yet. |
| 654 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | 652 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
| 655 | 653 |
| 656 tab_alpha.image_l = rb.GetBitmapNamed(IDR_TAB_ALPHA_LEFT); | 654 tab_alpha_.image_l = rb.GetBitmapNamed(IDR_TAB_ALPHA_LEFT); |
| 657 tab_alpha.image_r = rb.GetBitmapNamed(IDR_TAB_ALPHA_RIGHT); | 655 tab_alpha_.image_r = rb.GetBitmapNamed(IDR_TAB_ALPHA_RIGHT); |
| 658 | 656 |
| 659 tab_active.image_l = rb.GetBitmapNamed(IDR_TAB_ACTIVE_LEFT); | 657 tab_active_.image_l = rb.GetBitmapNamed(IDR_TAB_ACTIVE_LEFT); |
| 660 tab_active.image_c = rb.GetBitmapNamed(IDR_TAB_ACTIVE_CENTER); | 658 tab_active_.image_c = rb.GetBitmapNamed(IDR_TAB_ACTIVE_CENTER); |
| 661 tab_active.image_r = rb.GetBitmapNamed(IDR_TAB_ACTIVE_RIGHT); | 659 tab_active_.image_r = rb.GetBitmapNamed(IDR_TAB_ACTIVE_RIGHT); |
| 662 tab_active.l_width = tab_active.image_l->width(); | 660 tab_active_.l_width = tab_active_.image_l->width(); |
| 663 tab_active.r_width = tab_active.image_r->width(); | 661 tab_active_.r_width = tab_active_.image_r->width(); |
| 664 | 662 |
| 665 tab_inactive.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT); | 663 tab_inactive_.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT); |
| 666 tab_inactive.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER); | 664 tab_inactive_.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER); |
| 667 tab_inactive.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT); | 665 tab_inactive_.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT); |
| 668 tab_inactive.l_width = tab_inactive.image_l->width(); | 666 tab_inactive_.l_width = tab_inactive_.image_l->width(); |
| 669 tab_inactive.r_width = tab_inactive.image_r->width(); | 667 tab_inactive_.r_width = tab_inactive_.image_r->width(); |
| 670 } | 668 } |
| OLD | NEW |