summaryrefslogtreecommitdiffstats
path: root/chrome/browser/tabs/tab_renderer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/tabs/tab_renderer.cc')
-rw-r--r--chrome/browser/tabs/tab_renderer.cc691
1 files changed, 0 insertions, 691 deletions
diff --git a/chrome/browser/tabs/tab_renderer.cc b/chrome/browser/tabs/tab_renderer.cc
deleted file mode 100644
index 3437900..0000000
--- a/chrome/browser/tabs/tab_renderer.cc
+++ /dev/null
@@ -1,691 +0,0 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <limits>
-
-#include "chrome/browser/tabs/tab_renderer.h"
-
-#include "base/gfx/image_operations.h"
-#include "chrome/app/theme/theme_resources.h"
-#include "chrome/browser/browser.h"
-#include "chrome/browser/tabs/tab_strip_model.h"
-#include "chrome/browser/tab_contents.h"
-#include "chrome/common/gfx/chrome_canvas.h"
-#include "chrome/common/gfx/chrome_font.h"
-#include "chrome/common/resource_bundle.h"
-#include "chrome/common/win_util.h"
-#include "generated_resources.h"
-
-static const int kLeftPadding = 16;
-static const int kTopPadding = 6;
-static const int kRightPadding = 15;
-static const int kBottomPadding = 5;
-static const int kFavIconTitleSpacing = 4;
-static const int kTitleCloseButtonSpacing = 5;
-static const int kStandardTitleWidth = 175;
-static const int kCloseButtonVertFuzz = 0;
-static const int kCloseButtonHorzFuzz = 5;
-static const int kFaviconSize = 16;
-static const int kSelectedTitleColor = SK_ColorBLACK;
-static const int kUnselectedTitleColor = SkColorSetRGB(64, 64, 64);
-
-// How long the hover state takes.
-static const int kHoverDurationMs = 90;
-
-// How long the pulse throb takes.
-static const int kPulseDurationMs = 200;
-
-// How opaque to make the hover state (out of 1).
-static const double kHoverOpacity = 0.33;
-static const double kHoverOpacityVista = 0.7;
-
-// TODO(beng): (Cleanup) This stuff should move onto the class.
-static ChromeFont title_font;
-static int title_font_height = 0;
-static SkBitmap* close_button_n = NULL;
-static SkBitmap* close_button_h = NULL;
-static SkBitmap* close_button_p = NULL;
-static int close_button_height = 0;
-static int close_button_width = 0;
-static SkBitmap* tab_active_l = NULL;
-static SkBitmap* tab_active_c = NULL;
-static SkBitmap* tab_active_r = NULL;
-static int tab_active_l_width = 0;
-static int tab_active_r_width = 0;
-static SkBitmap* tab_inactive_l = NULL;
-static SkBitmap* tab_inactive_c = NULL;
-static SkBitmap* tab_inactive_r = NULL;
-static SkBitmap* tab_inactive_otr_l = NULL;
-static SkBitmap* tab_inactive_otr_c = NULL;
-static SkBitmap* tab_inactive_otr_r = NULL;
-static SkBitmap* tab_hover_l = NULL;
-static SkBitmap* tab_hover_c = NULL;
-static SkBitmap* tab_hover_r = NULL;
-static int tab_inactive_l_width = 0;
-static int tab_inactive_r_width = 0;
-static SkBitmap* waiting_animation_frames = NULL;
-static SkBitmap* loading_animation_frames = NULL;
-static SkBitmap* crashed_fav_icon = NULL;
-static int loading_animation_frame_count = 0;
-static int waiting_animation_frame_count = 0;
-static int waiting_to_loading_frame_count_ratio = 0;
-static SkBitmap* download_icon = NULL;
-static int download_icon_width = 0;
-static int download_icon_height = 0;
-
-namespace {
-
-void InitResources() {
- static bool initialized = false;
- if (!initialized) {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- title_font = rb.GetFont(ResourceBundle::BaseFont);
- title_font_height = title_font.height();
-
- close_button_n = rb.GetBitmapNamed(IDR_TAB_CLOSE);
- close_button_h = rb.GetBitmapNamed(IDR_TAB_CLOSE_H);
- close_button_p = rb.GetBitmapNamed(IDR_TAB_CLOSE_P);
- close_button_width = close_button_n->width();
- close_button_height = close_button_n->height();
-
- tab_active_l = rb.GetBitmapNamed(IDR_TAB_ACTIVE_LEFT);
- tab_active_c = rb.GetBitmapNamed(IDR_TAB_ACTIVE_CENTER);
- tab_active_r = rb.GetBitmapNamed(IDR_TAB_ACTIVE_RIGHT);
- tab_active_l_width = tab_active_l->width();
- tab_active_r_width = tab_active_r->width();
-
- if (win_util::ShouldUseVistaFrame()) {
- tab_inactive_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_V);
- tab_inactive_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_V);
- tab_inactive_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_V);
-
- // Our Vista frame doesn't change background color to show OTR,
- // so we continue to use the existing background tabs.
- tab_inactive_otr_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_V);
- tab_inactive_otr_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_V);
- tab_inactive_otr_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_V);
- } else {
- tab_inactive_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT);
- tab_inactive_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER);
- tab_inactive_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT);
-
- tab_inactive_otr_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_OTR);
- tab_inactive_otr_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_OTR);
- tab_inactive_otr_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_OTR);
- }
-
- tab_hover_l = rb.GetBitmapNamed(IDR_TAB_HOVER_LEFT);
- tab_hover_c = rb.GetBitmapNamed(IDR_TAB_HOVER_CENTER);
- tab_hover_r = rb.GetBitmapNamed(IDR_TAB_HOVER_RIGHT);
-
- tab_inactive_l_width = tab_inactive_l->width();
- tab_inactive_r_width = tab_inactive_r->width();
-
- // The loading animation image is a strip of states. Each state must be
- // square, so the height must divide the width evenly.
- loading_animation_frames = rb.GetBitmapNamed(IDR_THROBBER);
- DCHECK(loading_animation_frames);
- DCHECK(loading_animation_frames->width() %
- loading_animation_frames->height() == 0);
- loading_animation_frame_count =
- loading_animation_frames->width() / loading_animation_frames->height();
-
- waiting_animation_frames = rb.GetBitmapNamed(IDR_THROBBER_WAITING);
- DCHECK(waiting_animation_frames);
- DCHECK(waiting_animation_frames->width() %
- waiting_animation_frames->height() == 0);
- waiting_animation_frame_count =
- waiting_animation_frames->width() / waiting_animation_frames->height();
-
- waiting_to_loading_frame_count_ratio =
- waiting_animation_frame_count / loading_animation_frame_count;
-
- crashed_fav_icon = rb.GetBitmapNamed(IDR_SAD_FAVICON);
-
- download_icon = rb.GetBitmapNamed(IDR_DOWNLOAD_ICON);
- download_icon_width = download_icon->width();
- download_icon_height = download_icon->height();
-
- initialized = true;
- }
-}
-
-int GetContentHeight() {
- // The height of the content of the Tab is the largest of the favicon,
- // the title text and the close button graphic.
- int content_height = std::max(kFaviconSize, title_font_height);
- return std::max(content_height, close_button_height);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TabCloseButton
-//
-// This is a Button subclass that causes middle clicks to be forwarded to the
-// parent View by explicitly not handling them in OnMousePressed.
-class TabCloseButton : public ChromeViews::Button {
- public:
- TabCloseButton() : Button() {}
- virtual ~TabCloseButton() {}
-
- virtual bool OnMousePressed(const ChromeViews::MouseEvent& event) {
- return !event.IsOnlyMiddleMouseButton();
- }
-
- // We need to let the parent know about mouse state so that it
- // can highlight itself appropriately. Note that Exit events
- // fire before Enter events, so this works.
- virtual void OnMouseEntered(const ChromeViews::MouseEvent& event) {
- BaseButton::OnMouseEntered(event);
- GetParent()->OnMouseEntered(event);
- }
-
- virtual void OnMouseExited(const ChromeViews::MouseEvent& event) {
- BaseButton::OnMouseExited(event);
- GetParent()->OnMouseExited(event);
- }
-
- private:
- DISALLOW_EVIL_CONSTRUCTORS(TabCloseButton);
-};
-
-} // namespace
-
-////////////////////////////////////////////////////////////////////////////////
-// FaviconCrashAnimation
-//
-// A custom animation subclass to manage the favicon crash animation.
-class TabRenderer::FavIconCrashAnimation : public Animation,
- public AnimationDelegate {
- public:
- explicit FavIconCrashAnimation(TabRenderer* target)
- : Animation(1000, 25, this),
- target_(target) {
- }
- virtual ~FavIconCrashAnimation() {}
-
- // Animation overrides:
- virtual void AnimateToState(double state) {
- const double kHidingOffset = 27;
-
- if (state < .5) {
- target_->SetFavIconHidingOffset(
- static_cast<int>(floor(kHidingOffset * 2.0 * state)));
- } else {
- target_->DisplayCrashedFavIcon();
- target_->SetFavIconHidingOffset(
- static_cast<int>(
- floor(kHidingOffset - ((state - .5) * 2.0 * kHidingOffset))));
- }
- }
-
- // AnimationDelegate overrides:
- virtual void AnimationCanceled(const Animation* animation) {
- target_->SetFavIconHidingOffset(0);
- }
-
- private:
- TabRenderer* target_;
-
- DISALLOW_EVIL_CONSTRUCTORS(FavIconCrashAnimation);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// TabRenderer, public:
-
-TabRenderer::TabRenderer()
- : animation_state_(ANIMATION_NONE),
- animation_frame_(0),
- showing_icon_(false),
- showing_download_icon_(false),
- showing_close_button_(false),
- crash_animation_(NULL),
- fav_icon_hiding_offset_(0),
- should_display_crashed_favicon_(false) {
- InitResources();
-
- // Add the Close Button.
- close_button_ = new TabCloseButton;
- close_button_->SetImage(ChromeViews::Button::BS_NORMAL, close_button_n);
- close_button_->SetImage(ChromeViews::Button::BS_HOT, close_button_h);
- close_button_->SetImage(ChromeViews::Button::BS_PUSHED, close_button_p);
- AddChildView(close_button_);
-
- hover_animation_.reset(new SlideAnimation(this));
- hover_animation_->SetSlideDuration(kHoverDurationMs);
-
- pulse_animation_.reset(new ThrobAnimation(this));
- pulse_animation_->SetSlideDuration(kPulseDurationMs);
-}
-
-TabRenderer::~TabRenderer() {
- delete crash_animation_;
-}
-
-void TabRenderer::UpdateData(TabContents* contents) {
- DCHECK(contents);
- data_.favicon = contents->GetFavIcon();
- data_.title = contents->GetTitle();
- data_.loading = contents->is_loading();
- data_.off_the_record = contents->profile()->IsOffTheRecord();
- data_.show_icon = contents->ShouldDisplayFavIcon();
- data_.show_download_icon = contents->IsDownloadShelfVisible();
- data_.crashed = contents->IsCrashed();
-}
-
-void TabRenderer::UpdateFromModel() {
- // Force a layout, since the tab may have grown a favicon.
- Layout();
- SchedulePaint();
-
- if (data_.crashed) {
- if (!should_display_crashed_favicon_ && !IsPerformingCrashAnimation())
- StartCrashAnimation();
- } else {
- if (IsPerformingCrashAnimation())
- StopCrashAnimation();
- ResetCrashedFavIcon();
- }
-}
-
-bool TabRenderer::IsSelected() const {
- return true;
-}
-
-void TabRenderer::ValidateLoadingAnimation(AnimationState animation_state) {
- if (animation_state_ != animation_state) {
- // The waiting animation is the reverse of the loading animation, but at a
- // different rate - the following reverses and scales the animation_frame_
- // so that the frame is at an equivalent position when going from one
- // animation to the other.
- if (animation_state_ == ANIMATION_WAITING &&
- animation_state == ANIMATION_LOADING) {
- animation_frame_ = loading_animation_frame_count -
- (animation_frame_ / waiting_to_loading_frame_count_ratio);
- }
- animation_state_ = animation_state;
- }
-
- if (animation_state_ != ANIMATION_NONE) {
- animation_frame_ = ++animation_frame_ %
- ((animation_state_ == ANIMATION_WAITING) ?
- waiting_animation_frame_count :
- loading_animation_frame_count);
- } else {
- animation_frame_ = 0;
- }
-
- SchedulePaint();
-}
-
-void TabRenderer::StartPulse() {
- pulse_animation_->Reset();
- pulse_animation_->StartThrobbing(std::numeric_limits<int>::max());
-}
-
-void TabRenderer::StopPulse() {
- if (pulse_animation_->IsAnimating())
- pulse_animation_->Stop();
-}
-
-// static
-gfx::Size TabRenderer::GetMinimumSize() {
- InitResources();
-
- gfx::Size minimum_size;
- minimum_size.set_width(kLeftPadding + kRightPadding);
- // Since we use bitmap images, the real minimum height of the image is
- // defined most accurately by the height of the end cap images.
- minimum_size.set_height(tab_active_l->height());
- return minimum_size;
-}
-
-// static
-gfx::Size TabRenderer::GetMinimumSelectedSize() {
- gfx::Size minimum_size = GetMinimumSize();
- minimum_size.set_width(kLeftPadding + kFaviconSize + kRightPadding);
- return minimum_size;
-}
-
-// static
-gfx::Size TabRenderer::GetStandardSize() {
- gfx::Size standard_size = GetMinimumSize();
- standard_size.set_width(
- standard_size.width() + kFavIconTitleSpacing + kStandardTitleWidth);
- return standard_size;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TabRenderer, protected:
-
-std::wstring TabRenderer::GetTitle() const {
- return data_.title;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TabRenderer, ChromeViews::View overrides:
-
-void TabRenderer::Paint(ChromeCanvas* canvas) {
- // Don't paint if we're narrower than we can render correctly. (This should
- // only happen during animations).
- if (GetWidth() < GetMinimumSize().width())
- return;
-
- // See if the model changes whether the icons should be painted.
- const bool show_icon = ShouldShowIcon();
- const bool show_download_icon = data_.show_download_icon;
- const bool show_close_button = ShouldShowCloseBox();
- if (show_icon != showing_icon_ ||
- show_download_icon != showing_download_icon_ ||
- show_close_button != showing_close_button_)
- Layout();
-
- PaintTabBackground(canvas);
-
- // Paint the loading animation if the page is currently loading, otherwise
- // show the page's favicon.
- if (show_icon) {
- if (animation_state_ != ANIMATION_NONE) {
- PaintLoadingAnimation(canvas);
- } else {
- canvas->save();
- canvas->ClipRectInt(0, 0, GetWidth(), GetHeight() - 4);
- if (should_display_crashed_favicon_) {
- canvas->DrawBitmapInt(*crashed_fav_icon, 0, 0,
- crashed_fav_icon->width(),
- crashed_fav_icon->height(),
- favicon_bounds_.x(),
- favicon_bounds_.y() + fav_icon_hiding_offset_,
- kFaviconSize, kFaviconSize,
- true);
- } else {
- if (!data_.favicon.isNull()) {
- canvas->DrawBitmapInt(data_.favicon, 0, 0,
- data_.favicon.width(),
- data_.favicon.height(),
- favicon_bounds_.x(),
- favicon_bounds_.y() + fav_icon_hiding_offset_,
- kFaviconSize, kFaviconSize,
- true);
- }
- }
- canvas->restore();
- }
- }
-
- if (show_download_icon) {
- canvas->DrawBitmapInt(*download_icon,
- download_icon_bounds_.x(), download_icon_bounds_.y());
- }
-
- // Paint the Title.
- std::wstring title = data_.title;
- if (title.empty()) {
- if (data_.loading) {
- title = l10n_util::GetString(IDS_TAB_LOADING_TITLE);
- } else {
- title = l10n_util::GetString(IDS_TAB_UNTITLED_TITLE);
- }
- } else {
- Browser::FormatTitleForDisplay(&title);
- }
-
- SkColor title_color = IsSelected() ? kSelectedTitleColor
- : kUnselectedTitleColor;
- canvas->DrawStringInt(title, title_font, title_color, title_bounds_.x(),
- title_bounds_.y(), title_bounds_.width(),
- title_bounds_.height());
-}
-
-void TabRenderer::Layout() {
- CRect lb;
- GetLocalBounds(&lb, false);
- if (lb.IsRectEmpty())
- return;
-
- lb.left += kLeftPadding;
- lb.top += kTopPadding;
- lb.bottom -= kBottomPadding;
- lb.right -= kRightPadding;
-
- // First of all, figure out who is tallest.
- int content_height = GetContentHeight();
-
- // Size the Favicon.
- showing_icon_ = ShouldShowIcon();
- if (showing_icon_) {
- int favicon_top = kTopPadding + (content_height - kFaviconSize) / 2;
- favicon_bounds_.SetRect(lb.left, favicon_top, kFaviconSize, kFaviconSize);
- } else {
- favicon_bounds_.SetRect(lb.left, lb.top, 0, 0);
- }
-
- // Size the download icon.
- showing_download_icon_ = data_.show_download_icon;
- if (showing_download_icon_) {
- int icon_top = kTopPadding + (content_height - download_icon_height) / 2;
- download_icon_bounds_.SetRect(lb.Width() - download_icon_width, icon_top,
- download_icon_width, download_icon_height);
- }
-
- // Size the Close button.
- showing_close_button_ = ShouldShowCloseBox();
- if (showing_close_button_) {
- int close_button_top =
- kTopPadding + kCloseButtonVertFuzz +
- (content_height - close_button_height) / 2;
- // If the ratio of the close button size to tab width exceeds the maximum.
- close_button_->SetBounds(lb.Width() + kCloseButtonHorzFuzz,
- close_button_top, close_button_width,
- close_button_height);
- close_button_->SetVisible(true);
- } else {
- close_button_->SetBounds(0, 0, 0, 0);
- close_button_->SetVisible(false);
- }
-
- // Size the Title text to fill the remaining space.
- int title_left = favicon_bounds_.right() + kFavIconTitleSpacing;
- int title_top = kTopPadding + (content_height - title_font_height) / 2;
-
- // If the user has big fonts, the title will appear rendered too far down on
- // the y-axis if we use the regular top padding, so we need to adjust it so
- // that the text appears centered.
- gfx::Size minimum_size = GetMinimumSize();
- int text_height = title_top + title_font_height + kBottomPadding;
- if (text_height > minimum_size.height())
- title_top -= (text_height - minimum_size.height()) / 2;
-
- int title_width;
- if (close_button_->IsVisible()) {
- title_width = std::max(close_button_->GetX() -
- kTitleCloseButtonSpacing - title_left, 0);
- } else {
- title_width = std::max(lb.Width() - title_left, 0);
- }
- if (data_.show_download_icon)
- title_width = std::max(title_width - download_icon_width, 0);
- title_bounds_.SetRect(title_left, title_top, title_width, title_font_height);
-
- // Certain UI elements within the Tab (the favicon, the download icon, etc.)
- // are not represented as child Views (which is the preferred method).
- // Instead, these UI elements are drawn directly on the canvas from within
- // Tab::Paint(). The Tab's child Views (for example, the Tab's close button
- // which is a ChromeViews::Button instance) are automatically mirrored by the
- // mirroring infrastructure in ChromeViews. The elements Tab draws directly
- // on the canvas need to be manually mirrored if the View's layout is
- // right-to-left.
- favicon_bounds_.set_x(MirroredLeftPointForRect(favicon_bounds_));
- title_bounds_.set_x(MirroredLeftPointForRect(title_bounds_));
- download_icon_bounds_.set_x(MirroredLeftPointForRect(download_icon_bounds_));
-}
-
-void TabRenderer::DidChangeBounds(const CRect& previous,
- const CRect& current) {
- Layout();
-}
-
-
-void TabRenderer::OnMouseEntered(const ChromeViews::MouseEvent& e) {
- hover_animation_->SetTweenType(SlideAnimation::EASE_OUT);
- hover_animation_->Show();
-}
-
-void TabRenderer::OnMouseExited(const ChromeViews::MouseEvent& e) {
- hover_animation_->SetTweenType(SlideAnimation::EASE_IN);
- hover_animation_->Hide();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// TabRenderer, AnimationDelegate implementation:
-
-void TabRenderer::AnimationProgressed(const Animation* animation) {
- SchedulePaint();
-}
-
-void TabRenderer::AnimationCanceled(const Animation* animation) {
- AnimationEnded(animation);
-}
-
-void TabRenderer::AnimationEnded(const Animation* animation) {
- SchedulePaint();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TabRenderer, private
-
-void TabRenderer::PaintTabBackground(ChromeCanvas* canvas) {
- if (IsSelected()) {
- // Sometimes detaching a tab quickly can result in the model reporting it
- // as not being selected, so is_drag_clone_ ensures that we always paint
- // the active representation for the dragged tab.
- PaintActiveTabBackground(canvas);
- } else {
- // Draw our hover state.
- Animation* animation = hover_animation_.get();
- if (pulse_animation_->IsAnimating())
- animation = pulse_animation_.get();
- if (animation->GetCurrentValue() > 0) {
- PaintHoverTabBackground(canvas, animation->GetCurrentValue() *
- (win_util::ShouldUseVistaFrame() ?
- kHoverOpacityVista : kHoverOpacity));
- } else {
- PaintInactiveTabBackground(canvas);
- }
- }
-}
-
-void TabRenderer::PaintInactiveTabBackground(ChromeCanvas* canvas) {
- bool is_otr = data_.off_the_record;
- canvas->DrawBitmapInt(is_otr ? *tab_inactive_otr_l : *tab_inactive_l, 0, 0);
- canvas->TileImageInt(is_otr ? *tab_inactive_otr_c : *tab_inactive_c,
- tab_inactive_l_width, 0,
- GetWidth() - tab_inactive_l_width - tab_inactive_r_width,
- GetHeight());
- canvas->DrawBitmapInt(is_otr ? *tab_inactive_otr_r : *tab_inactive_r,
- GetWidth() - tab_inactive_r_width, 0);
-}
-
-void TabRenderer::PaintActiveTabBackground(ChromeCanvas* canvas) {
- canvas->DrawBitmapInt(*tab_active_l, 0, 0);
- canvas->TileImageInt(*tab_active_c, tab_active_l_width, 0,
- GetWidth() - tab_active_l_width - tab_active_r_width, GetHeight());
- canvas->DrawBitmapInt(*tab_active_r, GetWidth() - tab_active_r_width, 0);
-}
-
-void TabRenderer::PaintHoverTabBackground(ChromeCanvas* canvas,
- double opacity) {
- bool is_otr = data_.off_the_record;
- SkBitmap left = gfx::ImageOperations::CreateBlendedBitmap(
- (is_otr ? *tab_inactive_otr_l : *tab_inactive_l),
- *tab_hover_l, opacity);
- SkBitmap center = gfx::ImageOperations::CreateBlendedBitmap(
- (is_otr ? *tab_inactive_otr_c : *tab_inactive_c),
- *tab_hover_c, opacity);
- SkBitmap right = gfx::ImageOperations::CreateBlendedBitmap(
- (is_otr ? *tab_inactive_otr_r : *tab_inactive_r),
- *tab_hover_r, opacity);
-
- canvas->DrawBitmapInt(left, 0, 0);
- canvas->TileImageInt(center, tab_active_l_width, 0,
- GetWidth() - tab_active_l_width - tab_active_r_width, GetHeight());
- canvas->DrawBitmapInt(right, GetWidth() - tab_active_r_width, 0);
-}
-
-void TabRenderer::PaintLoadingAnimation(ChromeCanvas* canvas) {
- SkBitmap* frames = (animation_state_ == ANIMATION_WAITING) ?
- waiting_animation_frames : loading_animation_frames;
- int image_size = frames->height();
- int image_offset = animation_frame_ * image_size;
- int dst_y = (GetHeight() - image_size) / 2;
-
- // Just like with the Tab's title and favicon, the position for the page
- // loading animation also needs to be mirrored if the View's UI layout is
- // right-to-left.
- int dst_x;
- if (UILayoutIsRightToLeft()) {
- dst_x = GetWidth() - kLeftPadding - image_size;
- } else {
- dst_x = kLeftPadding;
- }
- canvas->DrawBitmapInt(*frames, image_offset, 0, image_size,
- image_size, dst_x, dst_y, image_size, image_size,
- false);
-}
-
-int TabRenderer::IconCapacity() const {
- if (GetHeight() < GetMinimumSize().height()) {
- return 0;
- }
- return (GetWidth() - kLeftPadding - kRightPadding) / kFaviconSize;
-}
-
-bool TabRenderer::ShouldShowIcon() const {
- if (!data_.show_icon) {
- return false;
- } else if (IsSelected()) {
- // The selected tab clips favicon before close button.
- return IconCapacity() >= 2;
- }
- // Non-selected tabs clip close button before favicon.
- return IconCapacity() >= 1;
-}
-
-bool TabRenderer::ShouldShowCloseBox() const {
- // The selected tab never clips close button.
- return IsSelected() || IconCapacity() >= 3;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// TabRenderer, private:
-
-void TabRenderer::StartCrashAnimation() {
- if (!crash_animation_)
- crash_animation_ = new FavIconCrashAnimation(this);
- crash_animation_->Reset();
- crash_animation_->Start();
-}
-
-void TabRenderer::StopCrashAnimation() {
- if (!crash_animation_)
- return;
- crash_animation_->Stop();
-}
-
-bool TabRenderer::IsPerformingCrashAnimation() const {
- return crash_animation_ && crash_animation_->IsAnimating();
-}
-
-void TabRenderer::SetFavIconHidingOffset(int offset) {
- fav_icon_hiding_offset_ = offset;
- SchedulePaint();
-}
-
-void TabRenderer::DisplayCrashedFavIcon() {
- should_display_crashed_favicon_ = true;
-}
-
-void TabRenderer::ResetCrashedFavIcon() {
- should_display_crashed_favicon_ = false;
-}
-