| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/tab_renderer.h" | 5 #include "chrome/browser/views/tabs/tab_renderer.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "app/gfx/canvas.h" | 9 #include "app/gfx/canvas.h" |
| 10 #include "app/gfx/font.h" | 10 #include "app/gfx/font.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 static SkBitmap* close_button_p = NULL; | 58 static SkBitmap* close_button_p = NULL; |
| 59 static int close_button_height = 0; | 59 static int close_button_height = 0; |
| 60 static int close_button_width = 0; | 60 static int close_button_width = 0; |
| 61 | 61 |
| 62 static SkBitmap* waiting_animation_frames = NULL; | 62 static SkBitmap* waiting_animation_frames = NULL; |
| 63 static SkBitmap* loading_animation_frames = NULL; | 63 static SkBitmap* loading_animation_frames = NULL; |
| 64 static SkBitmap* crashed_fav_icon = NULL; | 64 static SkBitmap* crashed_fav_icon = NULL; |
| 65 static int loading_animation_frame_count = 0; | 65 static int loading_animation_frame_count = 0; |
| 66 static int waiting_animation_frame_count = 0; | 66 static int waiting_animation_frame_count = 0; |
| 67 static int waiting_to_loading_frame_count_ratio = 0; | 67 static int waiting_to_loading_frame_count_ratio = 0; |
| 68 static SkBitmap* download_icon = NULL; | |
| 69 static int download_icon_width = 0; | |
| 70 static int download_icon_height = 0; | |
| 71 | 68 |
| 72 TabRenderer::TabImage TabRenderer::tab_alpha = {0}; | 69 TabRenderer::TabImage TabRenderer::tab_alpha = {0}; |
| 73 TabRenderer::TabImage TabRenderer::tab_active = {0}; | 70 TabRenderer::TabImage TabRenderer::tab_active = {0}; |
| 74 TabRenderer::TabImage TabRenderer::tab_inactive = {0}; | 71 TabRenderer::TabImage TabRenderer::tab_inactive = {0}; |
| 75 | 72 |
| 76 namespace { | 73 namespace { |
| 77 | 74 |
| 78 void InitResources() { | 75 void InitResources() { |
| 79 static bool initialized = false; | 76 static bool initialized = false; |
| 80 if (!initialized) { | 77 if (!initialized) { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 waiting_animation_frame_count / loading_animation_frame_count; | 128 waiting_animation_frame_count / loading_animation_frame_count; |
| 132 // TODO(beng): eventually remove this when we have a proper themeing system. | 129 // TODO(beng): eventually remove this when we have a proper themeing system. |
| 133 // themes not supporting IDR_THROBBER_WAITING are causing this | 130 // themes not supporting IDR_THROBBER_WAITING are causing this |
| 134 // value to be 0 which causes DIV0 crashes. The value of 5 | 131 // value to be 0 which causes DIV0 crashes. The value of 5 |
| 135 // matches the current bitmaps in our source. | 132 // matches the current bitmaps in our source. |
| 136 if (waiting_to_loading_frame_count_ratio == 0) | 133 if (waiting_to_loading_frame_count_ratio == 0) |
| 137 waiting_to_loading_frame_count_ratio = 5; | 134 waiting_to_loading_frame_count_ratio = 5; |
| 138 | 135 |
| 139 crashed_fav_icon = rb.GetBitmapNamed(IDR_SAD_FAVICON); | 136 crashed_fav_icon = rb.GetBitmapNamed(IDR_SAD_FAVICON); |
| 140 | 137 |
| 141 download_icon = rb.GetBitmapNamed(IDR_DOWNLOAD_ICON); | |
| 142 download_icon_width = download_icon->width(); | |
| 143 download_icon_height = download_icon->height(); | |
| 144 | |
| 145 initialized = true; | 138 initialized = true; |
| 146 } | 139 } |
| 147 } | 140 } |
| 148 | 141 |
| 149 int GetContentHeight() { | 142 int GetContentHeight() { |
| 150 // The height of the content of the Tab is the largest of the favicon, | 143 // The height of the content of the Tab is the largest of the favicon, |
| 151 // the title text and the close button graphic. | 144 // the title text and the close button graphic. |
| 152 int content_height = std::max(kFaviconSize, title_font_height); | 145 int content_height = std::max(kFaviconSize, title_font_height); |
| 153 return std::max(content_height, close_button_height); | 146 return std::max(content_height, close_button_height); |
| 154 } | 147 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 DISALLOW_EVIL_CONSTRUCTORS(FavIconCrashAnimation); | 223 DISALLOW_EVIL_CONSTRUCTORS(FavIconCrashAnimation); |
| 231 }; | 224 }; |
| 232 | 225 |
| 233 //////////////////////////////////////////////////////////////////////////////// | 226 //////////////////////////////////////////////////////////////////////////////// |
| 234 // TabRenderer, public: | 227 // TabRenderer, public: |
| 235 | 228 |
| 236 TabRenderer::TabRenderer() | 229 TabRenderer::TabRenderer() |
| 237 : animation_state_(ANIMATION_NONE), | 230 : animation_state_(ANIMATION_NONE), |
| 238 animation_frame_(0), | 231 animation_frame_(0), |
| 239 showing_icon_(false), | 232 showing_icon_(false), |
| 240 showing_download_icon_(false), | |
| 241 showing_close_button_(false), | 233 showing_close_button_(false), |
| 242 fav_icon_hiding_offset_(0), | 234 fav_icon_hiding_offset_(0), |
| 243 crash_animation_(NULL), | 235 crash_animation_(NULL), |
| 244 should_display_crashed_favicon_(false), | 236 should_display_crashed_favicon_(false), |
| 245 theme_provider_(NULL) { | 237 theme_provider_(NULL) { |
| 246 InitResources(); | 238 InitResources(); |
| 247 | 239 |
| 248 // Add the Close Button. | 240 // Add the Close Button. |
| 249 close_button_ = new TabCloseButton(this); | 241 close_button_ = new TabCloseButton(this); |
| 250 close_button_->SetImage(views::CustomButton::BS_NORMAL, close_button_n); | 242 close_button_->SetImage(views::CustomButton::BS_NORMAL, close_button_n); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 279 // return contents->profile()->GetThemeProvider(); | 271 // return contents->profile()->GetThemeProvider(); |
| 280 NOTREACHED() << "Unable to find a theme provider"; | 272 NOTREACHED() << "Unable to find a theme provider"; |
| 281 return NULL; | 273 return NULL; |
| 282 } | 274 } |
| 283 | 275 |
| 284 void TabRenderer::UpdateData(TabContents* contents, bool loading_only) { | 276 void TabRenderer::UpdateData(TabContents* contents, bool loading_only) { |
| 285 DCHECK(contents); | 277 DCHECK(contents); |
| 286 if (!loading_only) { | 278 if (!loading_only) { |
| 287 data_.title = UTF16ToWideHack(contents->GetTitle()); | 279 data_.title = UTF16ToWideHack(contents->GetTitle()); |
| 288 data_.off_the_record = contents->profile()->IsOffTheRecord(); | 280 data_.off_the_record = contents->profile()->IsOffTheRecord(); |
| 289 data_.show_download_icon = contents->IsDownloadShelfVisible(); | |
| 290 data_.crashed = contents->is_crashed(); | 281 data_.crashed = contents->is_crashed(); |
| 291 data_.favicon = contents->GetFavIcon(); | 282 data_.favicon = contents->GetFavIcon(); |
| 292 } | 283 } |
| 293 | 284 |
| 294 // TODO(glen): Temporary hax. | 285 // TODO(glen): Temporary hax. |
| 295 theme_provider_ = contents->profile()->GetThemeProvider(); | 286 theme_provider_ = contents->profile()->GetThemeProvider(); |
| 296 | 287 |
| 297 // Loading state also involves whether we show the favicon, since that's where | 288 // Loading state also involves whether we show the favicon, since that's where |
| 298 // we display the throbber. | 289 // we display the throbber. |
| 299 data_.loading = contents->is_loading(); | 290 data_.loading = contents->is_loading(); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 // TabRenderer, views::View overrides: | 384 // TabRenderer, views::View overrides: |
| 394 | 385 |
| 395 void TabRenderer::Paint(gfx::Canvas* canvas) { | 386 void TabRenderer::Paint(gfx::Canvas* canvas) { |
| 396 // Don't paint if we're narrower than we can render correctly. (This should | 387 // Don't paint if we're narrower than we can render correctly. (This should |
| 397 // only happen during animations). | 388 // only happen during animations). |
| 398 if (width() < GetMinimumUnselectedSize().width()) | 389 if (width() < GetMinimumUnselectedSize().width()) |
| 399 return; | 390 return; |
| 400 | 391 |
| 401 // See if the model changes whether the icons should be painted. | 392 // See if the model changes whether the icons should be painted. |
| 402 const bool show_icon = ShouldShowIcon(); | 393 const bool show_icon = ShouldShowIcon(); |
| 403 const bool show_download_icon = data_.show_download_icon; | |
| 404 const bool show_close_button = ShouldShowCloseBox(); | 394 const bool show_close_button = ShouldShowCloseBox(); |
| 405 if (show_icon != showing_icon_ || | 395 if (show_icon != showing_icon_ || |
| 406 show_download_icon != showing_download_icon_ || | |
| 407 show_close_button != showing_close_button_) | 396 show_close_button != showing_close_button_) |
| 408 Layout(); | 397 Layout(); |
| 409 | 398 |
| 410 PaintTabBackground(canvas); | 399 PaintTabBackground(canvas); |
| 411 | 400 |
| 412 // Paint the loading animation if the page is currently loading, otherwise | 401 // Paint the loading animation if the page is currently loading, otherwise |
| 413 // show the page's favicon. | 402 // show the page's favicon. |
| 414 if (show_icon) { | 403 if (show_icon) { |
| 415 if (animation_state_ != ANIMATION_NONE) { | 404 if (animation_state_ != ANIMATION_NONE) { |
| 416 PaintLoadingAnimation(canvas); | 405 PaintLoadingAnimation(canvas); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 435 favicon_bounds_.x(), | 424 favicon_bounds_.x(), |
| 436 favicon_bounds_.y() + fav_icon_hiding_offset_, | 425 favicon_bounds_.y() + fav_icon_hiding_offset_, |
| 437 kFaviconSize, kFaviconSize, | 426 kFaviconSize, kFaviconSize, |
| 438 true); | 427 true); |
| 439 } | 428 } |
| 440 } | 429 } |
| 441 canvas->restore(); | 430 canvas->restore(); |
| 442 } | 431 } |
| 443 } | 432 } |
| 444 | 433 |
| 445 if (show_download_icon) { | |
| 446 canvas->DrawBitmapInt(*download_icon, | |
| 447 download_icon_bounds_.x(), download_icon_bounds_.y()); | |
| 448 } | |
| 449 | |
| 450 // Paint the Title. | 434 // Paint the Title. |
| 451 std::wstring title = data_.title; | 435 std::wstring title = data_.title; |
| 452 if (title.empty()) { | 436 if (title.empty()) { |
| 453 if (data_.loading) { | 437 if (data_.loading) { |
| 454 title = l10n_util::GetString(IDS_TAB_LOADING_TITLE); | 438 title = l10n_util::GetString(IDS_TAB_LOADING_TITLE); |
| 455 } else { | 439 } else { |
| 456 title = l10n_util::GetString(IDS_TAB_UNTITLED_TITLE); | 440 title = l10n_util::GetString(IDS_TAB_UNTITLED_TITLE); |
| 457 } | 441 } |
| 458 } else { | 442 } else { |
| 459 Browser::FormatTitleForDisplay(&title); | 443 Browser::FormatTitleForDisplay(&title); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 480 | 464 |
| 481 // Size the Favicon. | 465 // Size the Favicon. |
| 482 showing_icon_ = ShouldShowIcon(); | 466 showing_icon_ = ShouldShowIcon(); |
| 483 if (showing_icon_) { | 467 if (showing_icon_) { |
| 484 int favicon_top = kTopPadding + (content_height - kFaviconSize) / 2; | 468 int favicon_top = kTopPadding + (content_height - kFaviconSize) / 2; |
| 485 favicon_bounds_.SetRect(lb.x(), favicon_top, kFaviconSize, kFaviconSize); | 469 favicon_bounds_.SetRect(lb.x(), favicon_top, kFaviconSize, kFaviconSize); |
| 486 } else { | 470 } else { |
| 487 favicon_bounds_.SetRect(lb.x(), lb.y(), 0, 0); | 471 favicon_bounds_.SetRect(lb.x(), lb.y(), 0, 0); |
| 488 } | 472 } |
| 489 | 473 |
| 490 // Size the download icon. | |
| 491 showing_download_icon_ = data_.show_download_icon; | |
| 492 if (showing_download_icon_) { | |
| 493 int icon_top = kTopPadding + (content_height - download_icon_height) / 2; | |
| 494 download_icon_bounds_.SetRect(lb.width() - download_icon_width, icon_top, | |
| 495 download_icon_width, download_icon_height); | |
| 496 } | |
| 497 | |
| 498 // Size the Close button. | 474 // Size the Close button. |
| 499 showing_close_button_ = ShouldShowCloseBox(); | 475 showing_close_button_ = ShouldShowCloseBox(); |
| 500 if (showing_close_button_) { | 476 if (showing_close_button_) { |
| 501 int close_button_top = | 477 int close_button_top = |
| 502 kTopPadding + kCloseButtonVertFuzz + | 478 kTopPadding + kCloseButtonVertFuzz + |
| 503 (content_height - close_button_height) / 2; | 479 (content_height - close_button_height) / 2; |
| 504 // If the ratio of the close button size to tab width exceeds the maximum. | 480 // If the ratio of the close button size to tab width exceeds the maximum. |
| 505 close_button_->SetBounds(lb.width() + kCloseButtonHorzFuzz, | 481 close_button_->SetBounds(lb.width() + kCloseButtonHorzFuzz, |
| 506 close_button_top, close_button_width, | 482 close_button_top, close_button_width, |
| 507 close_button_height); | 483 close_button_height); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 523 if (text_height > minimum_size.height()) | 499 if (text_height > minimum_size.height()) |
| 524 title_top -= (text_height - minimum_size.height()) / 2; | 500 title_top -= (text_height - minimum_size.height()) / 2; |
| 525 | 501 |
| 526 int title_width; | 502 int title_width; |
| 527 if (close_button_->IsVisible()) { | 503 if (close_button_->IsVisible()) { |
| 528 title_width = std::max(close_button_->x() - | 504 title_width = std::max(close_button_->x() - |
| 529 kTitleCloseButtonSpacing - title_left, 0); | 505 kTitleCloseButtonSpacing - title_left, 0); |
| 530 } else { | 506 } else { |
| 531 title_width = std::max(lb.width() - title_left, 0); | 507 title_width = std::max(lb.width() - title_left, 0); |
| 532 } | 508 } |
| 533 if (data_.show_download_icon) | |
| 534 title_width = std::max(title_width - download_icon_width, 0); | |
| 535 title_bounds_.SetRect(title_left, title_top, title_width, title_font_height); | 509 title_bounds_.SetRect(title_left, title_top, title_width, title_font_height); |
| 536 | 510 |
| 537 // Certain UI elements within the Tab (the favicon, the download icon, etc.) | 511 // Certain UI elements within the Tab (the favicon, etc.) are not represented |
| 538 // are not represented as child Views (which is the preferred method). | 512 // as child Views (which is the preferred method). Instead, these UI elements |
| 539 // Instead, these UI elements are drawn directly on the canvas from within | 513 // are drawn directly on the canvas from within Tab::Paint(). The Tab's child |
| 540 // Tab::Paint(). The Tab's child Views (for example, the Tab's close button | 514 // Views (for example, the Tab's close button which is a views::Button |
| 541 // which is a views::Button instance) are automatically mirrored by the | 515 // instance) are automatically mirrored by the mirroring infrastructure in |
| 542 // mirroring infrastructure in views. The elements Tab draws directly | 516 // views. The elements Tab draws directly on the canvas need to be manually |
| 543 // on the canvas need to be manually mirrored if the View's layout is | 517 // mirrored if the View's layout is right-to-left. |
| 544 // right-to-left. | |
| 545 favicon_bounds_.set_x(MirroredLeftPointForRect(favicon_bounds_)); | 518 favicon_bounds_.set_x(MirroredLeftPointForRect(favicon_bounds_)); |
| 546 title_bounds_.set_x(MirroredLeftPointForRect(title_bounds_)); | 519 title_bounds_.set_x(MirroredLeftPointForRect(title_bounds_)); |
| 547 download_icon_bounds_.set_x(MirroredLeftPointForRect(download_icon_bounds_)); | |
| 548 } | 520 } |
| 549 | 521 |
| 550 void TabRenderer::OnMouseEntered(const views::MouseEvent& e) { | 522 void TabRenderer::OnMouseEntered(const views::MouseEvent& e) { |
| 551 hover_animation_->SetTweenType(SlideAnimation::EASE_OUT); | 523 hover_animation_->SetTweenType(SlideAnimation::EASE_OUT); |
| 552 hover_animation_->Show(); | 524 hover_animation_->Show(); |
| 553 } | 525 } |
| 554 | 526 |
| 555 void TabRenderer::OnMouseExited(const views::MouseEvent& e) { | 527 void TabRenderer::OnMouseExited(const views::MouseEvent& e) { |
| 556 hover_animation_->SetTweenType(SlideAnimation::EASE_IN); | 528 hover_animation_->SetTweenType(SlideAnimation::EASE_IN); |
| 557 hover_animation_->Hide(); | 529 hover_animation_->Hide(); |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 tab_inactive.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT); | 790 tab_inactive.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT); |
| 819 tab_inactive.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER); | 791 tab_inactive.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER); |
| 820 tab_inactive.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT); | 792 tab_inactive.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT); |
| 821 | 793 |
| 822 tab_inactive.l_width = tab_inactive.image_l->width(); | 794 tab_inactive.l_width = tab_inactive.image_l->width(); |
| 823 tab_inactive.r_width = tab_inactive.image_r->width(); | 795 tab_inactive.r_width = tab_inactive.image_r->width(); |
| 824 | 796 |
| 825 loading_animation_frames = rb.GetBitmapNamed(IDR_THROBBER); | 797 loading_animation_frames = rb.GetBitmapNamed(IDR_THROBBER); |
| 826 waiting_animation_frames = rb.GetBitmapNamed(IDR_THROBBER_WAITING); | 798 waiting_animation_frames = rb.GetBitmapNamed(IDR_THROBBER_WAITING); |
| 827 } | 799 } |
| OLD | NEW |