summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/tabs/tab_renderer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/views/tabs/tab_renderer.cc')
-rw-r--r--chrome/browser/views/tabs/tab_renderer.cc204
1 files changed, 149 insertions, 55 deletions
diff --git a/chrome/browser/views/tabs/tab_renderer.cc b/chrome/browser/views/tabs/tab_renderer.cc
index b363cb5..f089393 100644
--- a/chrome/browser/views/tabs/tab_renderer.cc
+++ b/chrome/browser/views/tabs/tab_renderer.cc
@@ -6,6 +6,7 @@
#include <limits>
+#include "app/animation_container.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "app/slide_animation.h"
@@ -81,9 +82,15 @@ static int loading_animation_frame_count = 0;
static int waiting_animation_frame_count = 0;
static int waiting_to_loading_frame_count_ratio = 0;
+// Used when |render_as_new_tab| is true.
+static SkBitmap* new_tab_mask = NULL;
+static SkBitmap* new_tab_shadow = NULL;
+
TabRenderer::TabImage TabRenderer::tab_alpha = {0};
TabRenderer::TabImage TabRenderer::tab_active = {0};
+TabRenderer::TabImage TabRenderer::tab_active_nano = {0};
TabRenderer::TabImage TabRenderer::tab_inactive = {0};
+TabRenderer::TabImage TabRenderer::tab_alpha_nano = {0};
// Max opacity for the mini-tab title change animation.
const double kMiniTitleChangeThrobOpacity = 0.75;
@@ -205,7 +212,7 @@ class TabCloseButton : public views::ImageButton {
}
private:
- DISALLOW_EVIL_CONSTRUCTORS(TabCloseButton);
+ DISALLOW_COPY_AND_ASSIGN(TabCloseButton);
};
} // namespace
@@ -246,7 +253,7 @@ class TabRenderer::FavIconCrashAnimation : public Animation,
private:
TabRenderer* target_;
- DISALLOW_EVIL_CONSTRUCTORS(FavIconCrashAnimation);
+ DISALLOW_COPY_AND_ASSIGN(FavIconCrashAnimation);
};
////////////////////////////////////////////////////////////////////////////////
@@ -282,6 +289,10 @@ TabRenderer::~TabRenderer() {
delete crash_animation_;
}
+void TabRenderer::SizeToNewTabButtonImages() {
+ SetBounds(x(), y(), new_tab_shadow->width(), new_tab_shadow->height());
+}
+
void TabRenderer::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
if (parent->GetThemeProvider())
SetThemeProvider(parent->GetThemeProvider());
@@ -407,6 +418,11 @@ void TabRenderer::StopMiniTabTitleAnimation() {
mini_title_animation_->Stop();
}
+void TabRenderer::SetAnimationContainer(AnimationContainer* container) {
+ container_ = container;
+ pulse_animation_->SetContainer(container);
+}
+
void TabRenderer::PaintIcon(gfx::Canvas* canvas) {
if (animation_state_ != ANIMATION_NONE) {
PaintLoadingAnimation(canvas);
@@ -502,6 +518,15 @@ void TabRenderer::OnMouseExited(const views::MouseEvent& e) {
// TabRenderer, views::View overrides:
void TabRenderer::Paint(gfx::Canvas* canvas) {
+ if (data_.render_as_new_tab) {
+ if (UILayoutIsRightToLeft()) {
+ canvas->TranslateInt(width(), 0);
+ canvas->ScaleInt(-1, 1);
+ }
+ PaintAsNewTab(canvas);
+ return;
+ }
+
// Don't paint if we're narrower than we can render correctly. (This should
// only happen during animations).
if (width() < GetMinimumUnselectedSize().width() && !mini())
@@ -715,45 +740,47 @@ void TabRenderer::PaintInactiveTabBackground(gfx::Canvas* canvas) {
int bg_offset_y = GetThemeProvider()->HasCustomImage(tab_id) ?
0 : background_offset_.y();
- // Draw left edge. Don't draw over the toolbar, as we're not the foreground
- // tab.
- SkBitmap tab_l = SkBitmapOperations::CreateTiledBitmap(
- *tab_bg, offset, bg_offset_y, tab_active.l_width, height());
- SkBitmap theme_l =
- SkBitmapOperations::CreateMaskedBitmap(tab_l, *tab_alpha.image_l);
- canvas->DrawBitmapInt(theme_l,
- 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap,
- 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap,
- false);
-
- // Draw right edge. Again, don't draw over the toolbar.
- SkBitmap tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_bg,
- offset + width() - tab_active.r_width, bg_offset_y,
- tab_active.r_width, height());
- SkBitmap theme_r =
- SkBitmapOperations::CreateMaskedBitmap(tab_r, *tab_alpha.image_r);
- canvas->DrawBitmapInt(theme_r,
- 0, 0, theme_r.width(), theme_r.height() - kToolbarOverlap,
- width() - theme_r.width(), 0, theme_r.width(),
- theme_r.height() - kToolbarOverlap, false);
-
- // Draw center. Instead of masking out the top portion we simply skip over it
- // by incrementing by kDropShadowHeight, since it's a simple rectangle. And
- // again, don't draw over the toolbar.
- canvas->TileImageInt(*tab_bg,
- offset + tab_active.l_width, bg_offset_y + kDropShadowHeight,
- tab_active.l_width, kDropShadowHeight,
- width() - tab_active.l_width - tab_active.r_width,
- height() - kDropShadowHeight - kToolbarOverlap);
-
- // Now draw the highlights/shadows around the tab edge.
- canvas->DrawBitmapInt(*tab_inactive.image_l, 0, 0);
- canvas->TileImageInt(*tab_inactive.image_c,
- tab_inactive.l_width, 0,
- width() - tab_inactive.l_width - tab_inactive.r_width,
- height());
- canvas->DrawBitmapInt(*tab_inactive.image_r,
- width() - tab_inactive.r_width, 0);
+ if (!data_.app) {
+ // Draw left edge. Don't draw over the toolbar, as we're not the foreground
+ // tab.
+ SkBitmap tab_l = SkBitmapOperations::CreateTiledBitmap(
+ *tab_bg, offset, bg_offset_y, tab_active.l_width, height());
+ SkBitmap theme_l =
+ SkBitmapOperations::CreateMaskedBitmap(tab_l, *tab_alpha.image_l);
+ canvas->DrawBitmapInt(theme_l,
+ 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap,
+ 0, 0, theme_l.width(), theme_l.height() - kToolbarOverlap,
+ false);
+
+ // Draw right edge. Again, don't draw over the toolbar.
+ SkBitmap tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_bg,
+ offset + width() - tab_active.r_width, bg_offset_y,
+ tab_active.r_width, height());
+ SkBitmap theme_r =
+ SkBitmapOperations::CreateMaskedBitmap(tab_r, *tab_alpha.image_r);
+ canvas->DrawBitmapInt(theme_r,
+ 0, 0, theme_r.width(), theme_r.height() - kToolbarOverlap,
+ width() - theme_r.width(), 0, theme_r.width(),
+ theme_r.height() - kToolbarOverlap, false);
+
+ // Draw center. Instead of masking out the top portion we simply skip over
+ // it by incrementing by kDropShadowHeight, since it's a simple rectangle.
+ // And again, don't draw over the toolbar.
+ canvas->TileImageInt(*tab_bg,
+ offset + tab_active.l_width, bg_offset_y + kDropShadowHeight,
+ tab_active.l_width, kDropShadowHeight,
+ width() - tab_active.l_width - tab_active.r_width,
+ height() - kDropShadowHeight - kToolbarOverlap);
+
+ // Now draw the highlights/shadows around the tab edge.
+ canvas->DrawBitmapInt(*tab_inactive.image_l, 0, 0);
+ canvas->TileImageInt(*tab_inactive.image_c,
+ tab_inactive.l_width, 0,
+ width() - tab_inactive.l_width - tab_inactive.r_width,
+ height());
+ canvas->DrawBitmapInt(*tab_inactive.image_r,
+ width() - tab_inactive.r_width, 0);
+ }
}
void TabRenderer::PaintActiveTabBackground(gfx::Canvas* canvas) {
@@ -765,33 +792,39 @@ void TabRenderer::PaintActiveTabBackground(gfx::Canvas* canvas) {
SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(IDR_THEME_TOOLBAR);
+ // App tabs are drawn slightly differently (as nano tabs).
+ TabImage* tab_image = data_.app ? &tab_active_nano : &tab_active;
+ TabImage* alpha = data_.app ? &tab_alpha_nano : &tab_alpha;
+
// Draw left edge.
SkBitmap tab_l = SkBitmapOperations::CreateTiledBitmap(
- *tab_bg, offset, 0, tab_active.l_width, height());
+ *tab_bg, offset, 0, tab_image->l_width, height());
SkBitmap theme_l =
- SkBitmapOperations::CreateMaskedBitmap(tab_l, *tab_alpha.image_l);
+ SkBitmapOperations::CreateMaskedBitmap(tab_l, *alpha->image_l);
canvas->DrawBitmapInt(theme_l, 0, 0);
// Draw right edge.
SkBitmap tab_r = SkBitmapOperations::CreateTiledBitmap(*tab_bg,
- offset + width() - tab_active.r_width, 0, tab_active.r_width, height());
+ offset + width() - tab_image->r_width, 0, tab_image->r_width, height());
SkBitmap theme_r =
- SkBitmapOperations::CreateMaskedBitmap(tab_r, *tab_alpha.image_r);
- canvas->DrawBitmapInt(theme_r, width() - tab_active.r_width, 0);
+ SkBitmapOperations::CreateMaskedBitmap(tab_r, *alpha->image_r);
+ canvas->DrawBitmapInt(theme_r, width() - tab_image->r_width, 0);
// Draw center. Instead of masking out the top portion we simply skip over it
// by incrementing by kDropShadowHeight, since it's a simple rectangle.
canvas->TileImageInt(*tab_bg,
- offset + tab_active.l_width, kDropShadowHeight,
- tab_active.l_width, kDropShadowHeight,
- width() - tab_active.l_width - tab_active.r_width,
- height() - kDropShadowHeight);
+ offset + tab_image->l_width,
+ kDropShadowHeight + tab_image->y_offset,
+ tab_image->l_width,
+ kDropShadowHeight + tab_image->y_offset,
+ width() - tab_image->l_width - tab_image->r_width,
+ height() - kDropShadowHeight - tab_image->y_offset);
// Now draw the highlights/shadows around the tab edge.
- canvas->DrawBitmapInt(*tab_active.image_l, 0, 0);
- canvas->TileImageInt(*tab_active.image_c, tab_active.l_width, 0,
- width() - tab_active.l_width - tab_active.r_width, height());
- canvas->DrawBitmapInt(*tab_active.image_r, width() - tab_active.r_width, 0);
+ canvas->DrawBitmapInt(*tab_image->image_l, 0, 0);
+ canvas->TileImageInt(*tab_image->image_c, tab_image->l_width, 0,
+ width() - tab_image->l_width - tab_image->r_width, height());
+ canvas->DrawBitmapInt(*tab_image->image_r, width() - tab_image->r_width, 0);
}
void TabRenderer::PaintLoadingAnimation(gfx::Canvas* canvas) {
@@ -819,6 +852,47 @@ void TabRenderer::PaintLoadingAnimation(gfx::Canvas* canvas) {
false);
}
+void TabRenderer::PaintAsNewTab(gfx::Canvas* canvas) {
+ bool is_otr = data_.off_the_record;
+
+ // The tab image needs to be lined up with the background image
+ // so that it feels partially transparent. These offsets represent the tab
+ // position within the frame background image.
+ int offset = GetX(views::View::APPLY_MIRRORING_TRANSFORMATION) +
+ background_offset_.x();
+
+ int tab_id;
+ if (GetWidget() &&
+ GetWidget()->GetWindow()->GetNonClientView()->UseNativeFrame()) {
+ tab_id = IDR_THEME_TAB_BACKGROUND_V;
+ } else {
+ tab_id = is_otr ? IDR_THEME_TAB_BACKGROUND_INCOGNITO :
+ IDR_THEME_TAB_BACKGROUND;
+ }
+
+ SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(tab_id);
+
+ // If the theme is providing a custom background image, then its top edge
+ // should be at the top of the tab. Otherwise, we assume that the background
+ // image is a composited foreground + frame image.
+ int bg_offset_y = GetThemeProvider()->HasCustomImage(tab_id) ?
+ 0 : background_offset_.y();
+
+ SkBitmap image = SkBitmapOperations::CreateTiledBitmap(
+ *tab_bg, offset, bg_offset_y, new_tab_mask->width(),
+ new_tab_mask->height());
+ image = SkBitmapOperations::CreateMaskedBitmap(image, *new_tab_mask);
+ canvas->DrawBitmapInt(image,
+ 0, 0, image.width(), image.height(),
+ 0, 0, image.width(), image.height(),
+ false);
+
+ canvas->DrawBitmapInt(*new_tab_shadow,
+ 0, 0, new_tab_shadow->width(), new_tab_shadow->height(),
+ 0, 0, new_tab_shadow->width(), new_tab_shadow->height(),
+ false);
+}
+
int TabRenderer::IconCapacity() const {
if (height() < GetMinimumUnselectedSize().height())
return 0;
@@ -844,6 +918,9 @@ bool TabRenderer::ShouldShowCloseBox() const {
}
double TabRenderer::GetThrobValue() {
+ if (data_.alpha != 1)
+ return data_.alpha;
+
if (pulse_animation_->IsAnimating())
return pulse_animation_->GetCurrentValue() * kHoverOpacity;
@@ -892,21 +969,38 @@ void TabRenderer::LoadTabImages() {
tab_alpha.image_l = rb.GetBitmapNamed(IDR_TAB_ALPHA_LEFT);
tab_alpha.image_r = rb.GetBitmapNamed(IDR_TAB_ALPHA_RIGHT);
+ tab_alpha_nano.image_l = rb.GetBitmapNamed(IDR_TAB_ALPHA_NANO_LEFT);
+ tab_alpha_nano.image_r = rb.GetBitmapNamed(IDR_TAB_ALPHA_NANO_RIGHT);
+
tab_active.image_l = rb.GetBitmapNamed(IDR_TAB_ACTIVE_LEFT);
tab_active.image_c = rb.GetBitmapNamed(IDR_TAB_ACTIVE_CENTER);
tab_active.image_r = rb.GetBitmapNamed(IDR_TAB_ACTIVE_RIGHT);
tab_active.l_width = tab_active.image_l->width();
tab_active.r_width = tab_active.image_r->width();
+ // This is high much taller *visually* the regular tab is compared to the
+ // nano tabs. The images are the same height, this is really just the
+ // difference in whitespace above the tab image.
+ const int kMiniTabDiffHeight = 14;
+
+ tab_active_nano.image_l = rb.GetBitmapNamed(IDR_TAB_ACTIVE_NANO_LEFT);
+ tab_active_nano.image_c = rb.GetBitmapNamed(IDR_TAB_ACTIVE_NANO_CENTER);
+ tab_active_nano.image_r = rb.GetBitmapNamed(IDR_TAB_ACTIVE_NANO_RIGHT);
+ tab_active_nano.l_width = tab_active_nano.image_l->width();
+ tab_active_nano.r_width = tab_active_nano.image_r->width();
+ tab_active_nano.y_offset = kMiniTabDiffHeight;
+
tab_inactive.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT);
tab_inactive.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER);
tab_inactive.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT);
-
tab_inactive.l_width = tab_inactive.image_l->width();
tab_inactive.r_width = tab_inactive.image_r->width();
loading_animation_frames = rb.GetBitmapNamed(IDR_THROBBER);
waiting_animation_frames = rb.GetBitmapNamed(IDR_THROBBER_WAITING);
+
+ new_tab_mask = rb.GetBitmapNamed(IDR_TAB_ALPHA_NEW_TAB);
+ new_tab_shadow = rb.GetBitmapNamed(IDR_TAB_NEW_TAB_SHADOW);
}
void TabRenderer::SetBlocked(bool blocked) {