summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-19 20:35:32 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-19 20:35:32 +0000
commitb086dac54cdcf764cbfea528dff68d4ae7da5854 (patch)
treefcb4117b038ff2199d39ef58b42b5e39c62a7dc9 /chrome
parent970210cdcd03803acfe9f08bfa20edb5e84f07ce (diff)
downloadchromium_src-b086dac54cdcf764cbfea528dff68d4ae7da5854.zip
chromium_src-b086dac54cdcf764cbfea528dff68d4ae7da5854.tar.gz
chromium_src-b086dac54cdcf764cbfea528dff68d4ae7da5854.tar.bz2
Changes the rendering of mini-tabs slightly:
. the icons of mini-tabs scales up to 24x24 on mouse over. . phantom tabs are rendered in their own layer behind other tabs at 40% opacity. The icon for phantom tabs are rendered at 60% opactiy. BUG=32845 TEST=none Review URL: http://codereview.chromium.org/646067 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@39489 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/gtk/tabs/tab_renderer_gtk.cc3
-rw-r--r--chrome/browser/views/tabs/tab_renderer.cc97
-rw-r--r--chrome/browser/views/tabs/tab_renderer.h6
-rw-r--r--chrome/browser/views/tabs/tab_strip.cc60
-rw-r--r--chrome/browser/views/tabs/tab_strip.h3
5 files changed, 107 insertions, 62 deletions
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
index c37b4f1..861ff04 100644
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
@@ -844,9 +844,6 @@ void TabRendererGtk::PaintIcon(gfx::Canvas* canvas) {
void TabRendererGtk::PaintTabBackground(gfx::Canvas* 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 {
PaintInactiveTabBackground(canvas);
diff --git a/chrome/browser/views/tabs/tab_renderer.cc b/chrome/browser/views/tabs/tab_renderer.cc
index 8a8d61a..7918408 100644
--- a/chrome/browser/views/tabs/tab_renderer.cc
+++ b/chrome/browser/views/tabs/tab_renderer.cc
@@ -86,6 +86,9 @@ const double kMiniTitleChangeThrobOpacity = 0.75;
// Duration for when the title of an inactive mini-tab changes.
const int kMiniTitleChangeThrobDuration = 1000;
+// Size to render the favicon at when the mouse is over a mini-tab.
+static const int kMiniTabHoverFavIconSize = 24;
+
namespace {
void InitResources() {
@@ -391,6 +394,46 @@ void TabRenderer::StopMiniTabTitleAnimation() {
mini_title_animation_->Stop();
}
+void TabRenderer::PaintIcon(gfx::Canvas* canvas) {
+ if (animation_state_ != ANIMATION_NONE) {
+ PaintLoadingAnimation(canvas);
+ } else {
+ canvas->save();
+ canvas->ClipRectInt(0, 0, width(), height());
+ 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()) {
+ // TODO(pkasting): Use code in tab_icon_view.cc:PaintIcon() (or switch
+ // to using that class to render the favicon).
+ int x = favicon_bounds_.x();
+ int y = favicon_bounds_.y() + fav_icon_hiding_offset_;
+ int size = kFavIconSize;
+ if (mini() && (hover_animation_->IsAnimating() ||
+ hover_animation_->IsShowing())) {
+ int hover_size = hover_animation_->CurrentValueBetween(
+ size, kMiniTabHoverFavIconSize);
+ x -= (hover_size - size) / 2;
+ y -= (hover_size - size) / 2;
+ size = hover_size;
+ }
+ canvas->DrawBitmapInt(data_.favicon, 0, 0,
+ data_.favicon.width(),
+ data_.favicon.height(),
+ x, y, size, size,
+ true);
+ }
+ }
+ canvas->restore();
+ }
+}
+
// static
gfx::Size TabRenderer::GetMinimumUnselectedSize() {
InitResources();
@@ -450,14 +493,13 @@ void TabRenderer::Paint(gfx::Canvas* canvas) {
return;
// See if the model changes whether the icons should be painted.
- const bool show_icon = ShouldShowIcon();
+ const bool show_icon = ShouldShowIcon() && !phantom();
const bool show_close_button = ShouldShowCloseBox();
if (show_icon != showing_icon_ ||
show_close_button != showing_close_button_)
Layout();
- if (!data_.phantom)
- PaintTabBackground(canvas);
+ PaintTabBackground(canvas);
SkColor title_color = GetThemeProvider()->
GetColor(IsSelected() ?
@@ -604,42 +646,8 @@ void TabRenderer::PaintTitle(SkColor title_color, gfx::Canvas* canvas) {
title_bounds_.width(), title_bounds_.height());
}
-void TabRenderer::PaintIcon(gfx::Canvas* canvas) {
- if (animation_state_ != ANIMATION_NONE) {
- PaintLoadingAnimation(canvas);
- } else {
- canvas->save();
- canvas->ClipRectInt(0, 0, width(), height() - kFavIconTitleSpacing);
- 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()) {
- // TODO(pkasting): Use code in tab_icon_view.cc:PaintIcon() (or switch
- // to using that class to render the favicon).
- 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();
- }
-}
-
void TabRenderer::PaintTabBackground(gfx::Canvas* 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 {
PaintInactiveTabBackground(canvas);
@@ -762,21 +770,6 @@ void TabRenderer::PaintActiveTabBackground(gfx::Canvas* canvas) {
canvas->DrawBitmapInt(*tab_active.image_r, width() - tab_active.r_width, 0);
}
-void TabRenderer::PaintHoverTabBackground(gfx::Canvas* canvas,
- double opacity) {
- SkBitmap left = SkBitmapOperations::CreateBlendedBitmap(
- *tab_inactive.image_l, *tab_active.image_l, opacity);
- SkBitmap center = SkBitmapOperations::CreateBlendedBitmap(
- *tab_inactive.image_c, *tab_active.image_c, opacity);
- SkBitmap right = SkBitmapOperations::CreateBlendedBitmap(
- *tab_inactive.image_r, *tab_active.image_r, opacity);
-
- canvas->DrawBitmapInt(left, 0, 0);
- canvas->TileImageInt(center, tab_active.l_width, 0,
- width() - tab_active.l_width - tab_active.r_width, height());
- canvas->DrawBitmapInt(right, width() - tab_active.r_width, 0);
-}
-
void TabRenderer::PaintLoadingAnimation(gfx::Canvas* canvas) {
SkBitmap* frames = (animation_state_ == ANIMATION_WAITING) ?
waiting_animation_frames : loading_animation_frames;
diff --git a/chrome/browser/views/tabs/tab_renderer.h b/chrome/browser/views/tabs/tab_renderer.h
index ec3e319..78208ae 100644
--- a/chrome/browser/views/tabs/tab_renderer.h
+++ b/chrome/browser/views/tabs/tab_renderer.h
@@ -93,6 +93,10 @@ class TabRenderer : public views::View,
theme_provider_ = provider;
}
+ // Paints the icon. Most of the time you'll want to invoke Paint directly, but
+ // in certain situations this invoked outside of Paint.
+ void PaintIcon(gfx::Canvas* canvas);
+
// Returns the minimum possible size of a single unselected Tab.
static gfx::Size GetMinimumUnselectedSize();
// Returns the minimum possible size of a selected Tab. Selected tabs must
@@ -150,11 +154,9 @@ class TabRenderer : public views::View,
// Paint various portions of the Tab
void PaintTitle(SkColor title_color, gfx::Canvas* canvas);
- void PaintIcon(gfx::Canvas* canvas);
void PaintTabBackground(gfx::Canvas* canvas);
void PaintInactiveTabBackground(gfx::Canvas* canvas);
void PaintActiveTabBackground(gfx::Canvas* canvas);
- void PaintHoverTabBackground(gfx::Canvas* canvas, double opacity);
void PaintLoadingAnimation(gfx::Canvas* canvas);
// Returns the number of favicon-size elements that can fit in the tab's
diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc
index cac1e62..a71caf5 100644
--- a/chrome/browser/views/tabs/tab_strip.cc
+++ b/chrome/browser/views/tabs/tab_strip.cc
@@ -62,6 +62,12 @@ static const int kSuspendAnimationsTimeMs = 200;
static const int kTabHOffset = -16;
static const int kTabStripAnimationVSlop = 40;
+// Alpha value phantom tabs are rendered at.
+static const int kPhantomTabAlpha = 105;
+
+// Alpha value phantom tab icons are rendered at.
+static const int kPhantomTabIconAlpha = 160;
+
// Size of the drop indicator.
static int drop_indicator_width;
static int drop_indicator_height;
@@ -886,17 +892,53 @@ TabStrip* TabStrip::AsTabStrip() {
// TabStrip, views::View overrides:
void TabStrip::PaintChildren(gfx::Canvas* canvas) {
- // Paint the tabs in reverse order, so they stack to the left.
+ // Tabs are painted in reverse order, so they stack to the left.
+
+ // Phantom tabs appear behind all other tabs and are rendered first. To make
+ // them slightly transparent we render them to a different layer.
+ if (HasPhantomTabs()) {
+ SkRect bounds;
+ bounds.set(0, 0, SkIntToScalar(width()), SkIntToScalar(height()));
+ canvas->saveLayerAlpha(&bounds, kPhantomTabAlpha,
+ SkCanvas::kARGB_ClipLayer_SaveFlag);
+ canvas->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode);
+ for (int i = GetTabCount() - 1; i >= 0; --i) {
+ Tab* tab = GetTabAt(i);
+ if (tab->phantom())
+ tab->ProcessPaint(canvas);
+ }
+ canvas->restore();
+
+ canvas->saveLayerAlpha(&bounds, kPhantomTabIconAlpha,
+ SkCanvas::kARGB_ClipLayer_SaveFlag);
+ canvas->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode);
+ for (int i = GetTabCount() - 1; i >= 0; --i) {
+ Tab* tab = GetTabAt(i);
+ if (tab->phantom()) {
+ canvas->save();
+ canvas->ClipRectInt(tab->MirroredX(), tab->y(), tab->width(),
+ tab->height());
+ canvas->TranslateInt(tab->MirroredX(), tab->y());
+ tab->PaintIcon(canvas);
+ canvas->restore();
+ }
+ }
+ canvas->restore();
+ }
+
Tab* selected_tab = NULL;
+
for (int i = GetTabCount() - 1; i >= 0; --i) {
Tab* tab = GetTabAt(i);
// We must ask the _Tab's_ model, not ourselves, because in some situations
// the model will be different to this object, e.g. when a Tab is being
// removed after its TabContents has been destroyed.
- if (!tab->IsSelected()) {
- tab->ProcessPaint(canvas);
- } else {
- selected_tab = tab;
+ if (!tab->phantom()) {
+ if (!tab->IsSelected()) {
+ tab->ProcessPaint(canvas);
+ } else {
+ selected_tab = tab;
+ }
}
}
@@ -2007,3 +2049,11 @@ void TabStrip::HandleGlobalMouseMoveEvent() {
resize_layout_factory_.RevokeAll();
}
}
+
+bool TabStrip::HasPhantomTabs() const {
+ for (int i = 0; i < GetTabCount(); ++i) {
+ if (GetTabAt(i)->phantom())
+ return true;
+ }
+ return false;
+}
diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h
index 8c5dbe5..a0c0aeb 100644
--- a/chrome/browser/views/tabs/tab_strip.h
+++ b/chrome/browser/views/tabs/tab_strip.h
@@ -309,6 +309,9 @@ class TabStrip : public BaseTabStrip,
// anywhere over our containing window.
void HandleGlobalMouseMoveEvent();
+ // Returns true if any of the tabs are phantom.
+ bool HasPhantomTabs() const;
+
// -- Member Variables ------------------------------------------------------
// Our model.