diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-19 20:35:32 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-19 20:35:32 +0000 |
commit | b086dac54cdcf764cbfea528dff68d4ae7da5854 (patch) | |
tree | fcb4117b038ff2199d39ef58b42b5e39c62a7dc9 /chrome | |
parent | 970210cdcd03803acfe9f08bfa20edb5e84f07ce (diff) | |
download | chromium_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.cc | 3 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_renderer.cc | 97 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_renderer.h | 6 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip.cc | 60 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip.h | 3 |
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. |