summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk/tabs
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-12 21:17:42 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-12 21:17:42 +0000
commit06912d47ab85ab0b8a67ed5af9cef9d5fa382415 (patch)
tree625998e8320a9daec740efda0bd8206c4737477d /chrome/browser/gtk/tabs
parent382f67951c8586c41ce163385042fca10d824046 (diff)
downloadchromium_src-06912d47ab85ab0b8a67ed5af9cef9d5fa382415.zip
chromium_src-06912d47ab85ab0b8a67ed5af9cef9d5fa382415.tar.gz
chromium_src-06912d47ab85ab0b8a67ed5af9cef9d5fa382415.tar.bz2
Update the Linux tabstrip code to handle themes.
Review URL: http://codereview.chromium.org/115260 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15897 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk/tabs')
-rw-r--r--chrome/browser/gtk/tabs/tab_renderer_gtk.cc152
-rw-r--r--chrome/browser/gtk/tabs/tab_renderer_gtk.h8
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.cc7
-rw-r--r--chrome/browser/gtk/tabs/tab_strip_gtk.h3
4 files changed, 106 insertions, 64 deletions
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
index 6350203..e840290 100644
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
@@ -7,6 +7,7 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"
@@ -23,6 +24,7 @@ const int kFavIconTitleSpacing = 4;
const int kTitleCloseButtonSpacing = 5;
const int kStandardTitleWidth = 175;
const int kFavIconSize = 16;
+const int kDropShadowOffset = 2;
const int kSelectedTitleColor = SK_ColorBLACK;
const int kUnselectedTitleColor = SkColorSetRGB(64, 64, 64);
@@ -81,7 +83,7 @@ void InitializeLoadingAnimationData(
bool TabRendererGtk::initialized_ = false;
TabRendererGtk::TabImage TabRendererGtk::tab_active_ = {0};
TabRendererGtk::TabImage TabRendererGtk::tab_inactive_ = {0};
-TabRendererGtk::TabImage TabRendererGtk::tab_inactive_otr_ = {0};
+TabRendererGtk::TabImage TabRendererGtk::tab_alpha = {0};
TabRendererGtk::TabImage TabRendererGtk::tab_hover_ = {0};
ChromeFont* TabRendererGtk::title_font_ = NULL;
int TabRendererGtk::title_font_height_ = 0;
@@ -168,6 +170,8 @@ void TabRendererGtk::UpdateData(TabContents* contents, bool loading_only) {
// we display the throbber.
data_.loading = contents->is_loading();
data_.show_icon = contents->ShouldDisplayFavIcon();
+
+ theme_provider_ = contents->profile()->GetThemeProvider();
}
void TabRendererGtk::UpdateFromModel() {
@@ -225,6 +229,9 @@ int TabRendererGtk::GetContentHeight() {
void TabRendererGtk::LoadTabImages() {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ tab_alpha.image_l = rb.GetBitmapNamed(IDR_TAB_ALPHA_LEFT);
+ tab_alpha.image_r = rb.GetBitmapNamed(IDR_TAB_ALPHA_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);
@@ -237,18 +244,6 @@ void TabRendererGtk::LoadTabImages() {
tab_inactive_.l_width = tab_inactive_.image_l->width();
tab_inactive_.r_width = tab_inactive_.image_r->width();
- // TODO: Generate these images http://crbug.com/11679
- tab_hover_.image_l = rb.GetBitmapNamed(IDR_TAB_ACTIVE_LEFT);
- tab_hover_.image_c = rb.GetBitmapNamed(IDR_TAB_ACTIVE_CENTER);
- tab_hover_.image_r = rb.GetBitmapNamed(IDR_TAB_ACTIVE_RIGHT);
-
- tab_inactive_otr_.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT);
- tab_inactive_otr_.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER);
- tab_inactive_otr_.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT);
-
- // tab_[hover,inactive_otr] width are not used and are initialized to 0
- // during static initialization.
-
close_button_width_ = rb.GetBitmapNamed(IDR_TAB_CLOSE)->width();
close_button_height_ = rb.GetBitmapNamed(IDR_TAB_CLOSE)->height();
@@ -289,7 +284,7 @@ void TabRendererGtk::AnimationEnded(const Animation* animation) {
// TabRendererGtk, private:
void TabRendererGtk::Paint(GdkEventExpose* event) {
- ChromeCanvasPaint canvas(event);
+ ChromeCanvasPaint canvas(event, false);
if (canvas.isEmpty())
return;
@@ -420,58 +415,111 @@ void TabRendererGtk::PaintTabBackground(ChromeCanvasPaint* canvas) {
} else {
// Draw our hover state.
Animation* animation = hover_animation_.get();
+
+ PaintInactiveTabBackground(canvas);
if (animation->GetCurrentValue() > 0) {
- PaintHoverTabBackground(canvas,
- animation->GetCurrentValue() * kHoverOpacity);
- } else {
- PaintInactiveTabBackground(canvas);
+ SkRect bounds;
+ // TODO(jhawkins): This will only work for the first tab, because
+ // saveLayerAlpha only uses bounds as the size and not the location. In
+ // our situation, canvas spans the entire tabstrip, so saving the layer
+ // at (0,0)x(w,h) will always save the first tab.
+ bounds.set(0, 0,
+ SkIntToScalar(width()), SkIntToScalar(height()));
+ canvas->saveLayerAlpha(&bounds,
+ static_cast<int>(animation->GetCurrentValue() * kHoverOpacity * 0xff),
+ SkCanvas::kARGB_ClipLayer_SaveFlag);
+ canvas->drawARGB(0, 255, 255, 255, SkPorterDuff::kClear_Mode);
+ PaintActiveTabBackground(canvas);
+ canvas->restore();
}
}
}
void TabRendererGtk::PaintInactiveTabBackground(ChromeCanvasPaint* canvas) {
bool is_otr = data_.off_the_record;
- const TabImage& image = is_otr ? tab_inactive_otr_ : tab_inactive_;
- canvas->DrawBitmapInt(*image.image_l, bounds_.x(), bounds_.y());
- canvas->TileImageInt(*image.image_c,
- bounds_.x() + tab_inactive_.l_width, bounds_.y(),
- width() - tab_inactive_.l_width - tab_inactive_.r_width,
- height());
- canvas->DrawBitmapInt(*image.image_r,
- bounds_.x() + width() - tab_inactive_.r_width,
- bounds_.y());
-}
-
-void TabRendererGtk::PaintHoverTabBackground(ChromeCanvasPaint* canvas,
- double opacity) {
- bool is_otr = data_.off_the_record;
- const TabImage& image = is_otr ? tab_inactive_otr_ : tab_inactive_;
-
- SkBitmap left = skia::ImageOperations::CreateBlendedBitmap(
- *image.image_l, *tab_hover_.image_l, opacity);
- SkBitmap center = skia::ImageOperations::CreateBlendedBitmap(
- *image.image_c, *tab_hover_.image_c, opacity);
- SkBitmap right = skia::ImageOperations::CreateBlendedBitmap(
- *image.image_r, *tab_hover_.image_r, opacity);
-
- canvas->DrawBitmapInt(left, bounds_.x(), bounds_.y());
- canvas->TileImageInt(center, bounds_.x() + tab_active_.l_width, bounds_.y(),
- bounds_.width() - tab_active_.l_width - tab_active_.r_width,
- bounds_.height());
- canvas->DrawBitmapInt(right,
- bounds_.x() + bounds_.width() - tab_active_.r_width, bounds_.y());
+ // The tab image needs to be lined up with the background image
+ // so that it feels partially transparent.
+ int offset = 1;
+ int offset_y = 20;
+
+ int tab_id = is_otr ?
+ IDR_THEME_TAB_BACKGROUND_INCOGNITO : IDR_THEME_TAB_BACKGROUND;
+
+ SkBitmap* tab_bg = theme_provider_->GetBitmapNamed(tab_id);
+
+ // Draw left edge.
+ SkBitmap tab_l = skia::ImageOperations::CreateTiledBitmap(
+ *tab_bg, offset, offset_y,
+ tab_active_.l_width, height());
+ SkBitmap theme_l = skia::ImageOperations::CreateMaskedBitmap(
+ tab_l, *tab_alpha.image_l);
+ canvas->DrawBitmapInt(theme_l,
+ 0, 0, theme_l.width(), theme_l.height() - 1,
+ bounds_.x(), bounds_.y(), theme_l.width(), theme_l.height() - 1,
+ false);
+
+ // Draw right edge.
+ SkBitmap tab_r = skia::ImageOperations::CreateTiledBitmap(
+ *tab_bg,
+ offset + width() - tab_active_.r_width, offset_y,
+ tab_active_.r_width, height());
+ SkBitmap theme_r = skia::ImageOperations::CreateMaskedBitmap(
+ tab_r, *tab_alpha.image_r);
+ canvas->DrawBitmapInt(theme_r,
+ 0, 0, theme_r.width(), theme_r.height() - 1,
+ bounds_.x() + width() - theme_r.width(), bounds_.y(),
+ theme_r.width(), theme_r.height() - 1,
+ false);
+
+ // Draw center.
+ canvas->TileImageInt(*tab_bg,
+ offset + tab_active_.l_width, kDropShadowOffset + offset_y,
+ bounds_.x() + tab_active_.l_width, bounds_.y() + 2,
+ width() - tab_active_.l_width - tab_active_.r_width, height() - 3);
+
+ canvas->DrawBitmapInt(*tab_inactive_.image_l, bounds_.x(), bounds_.y());
+ canvas->TileImageInt(*tab_inactive_.image_c, tab_inactive_.l_width, 0,
+ bounds_.x() + width() - tab_inactive_.l_width - tab_inactive_.r_width,
+ bounds_.y() + height());
+ canvas->DrawBitmapInt(*tab_inactive_.image_r,
+ bounds_.x() + width() - tab_inactive_.r_width, bounds_.y());
}
void TabRendererGtk::PaintActiveTabBackground(ChromeCanvasPaint* canvas) {
+ int offset = 1;
+
+ SkBitmap* tab_bg = theme_provider_->GetBitmapNamed(IDR_THEME_TOOLBAR);
+
+ // Draw left edge.
+ SkBitmap tab_l = skia::ImageOperations::CreateTiledBitmap(
+ *tab_bg, offset, 0, tab_active_.l_width, height());
+ SkBitmap theme_l = skia::ImageOperations::CreateMaskedBitmap(
+ tab_l, *tab_alpha.image_l);
+ canvas->DrawBitmapInt(theme_l, bounds_.x(), bounds_.y());
+
+ // Draw right edge.
+ SkBitmap tab_r = skia::ImageOperations::CreateTiledBitmap(
+ *tab_bg,
+ offset + width() - tab_active_.r_width, 0,
+ tab_active_.r_width, height());
+ SkBitmap theme_r = skia::ImageOperations::CreateMaskedBitmap(
+ tab_r, *tab_alpha.image_r);
+ canvas->DrawBitmapInt(theme_r,
+ bounds_.x() + width() - tab_active_.r_width, bounds_.y());
+
+ // Draw center.
+ canvas->TileImageInt(*tab_bg,
+ offset + tab_active_.l_width, 2,
+ bounds_.x() + tab_active_.l_width, bounds_.y() + 2,
+ width() - tab_active_.l_width - tab_active_.r_width, height() - 2);
+
canvas->DrawBitmapInt(*tab_active_.image_l, bounds_.x(), bounds_.y());
canvas->TileImageInt(*tab_active_.image_c,
- bounds_.x() + tab_active_.l_width, bounds_.y(),
- width() - tab_active_.l_width - tab_active_.r_width,
- height());
+ bounds_.x() + tab_active_.l_width, bounds_.y(),
+ width() - tab_active_.l_width - tab_active_.r_width, height());
canvas->DrawBitmapInt(*tab_active_.image_r,
- bounds_.x() + width() - tab_active_.r_width,
- bounds_.y());
+ bounds_.x() + width() - tab_active_.r_width, bounds_.y());
}
void TabRendererGtk::PaintLoadingAnimation(ChromeCanvasPaint* canvas) {
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.h b/chrome/browser/gtk/tabs/tab_renderer_gtk.h
index 74f730d..a2f4721 100644
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.h
@@ -21,6 +21,7 @@ class Size;
} // namespace gfx
class TabContents;
+class ThemeProvider;
class TabRendererGtk : public AnimationDelegate {
public:
@@ -173,7 +174,6 @@ class TabRendererGtk : public AnimationDelegate {
void PaintTabBackground(ChromeCanvasPaint* canvas);
void PaintInactiveTabBackground(ChromeCanvasPaint* canvas);
void PaintActiveTabBackground(ChromeCanvasPaint* canvas);
- void PaintHoverTabBackground(ChromeCanvasPaint* canvas, double opacity);
void PaintLoadingAnimation(ChromeCanvasPaint* canvas);
// Returns the number of favicon-size elements that can fit in the tab's
@@ -204,7 +204,7 @@ class TabRendererGtk : public AnimationDelegate {
static TabImage tab_active_;
static TabImage tab_inactive_;
- static TabImage tab_inactive_otr_;
+ static TabImage tab_alpha;
static TabImage tab_hover_;
static ChromeFont* title_font_;
@@ -246,6 +246,10 @@ class TabRendererGtk : public AnimationDelegate {
// Contains the loading animation state.
LoadingAnimation loading_animation_;
+ // TODO(jhawkins): If the theme is changed after the tab is created, we'll
+ // still render the old theme for this tab.
+ ThemeProvider* theme_provider_;
+
DISALLOW_COPY_AND_ASSIGN(TabRendererGtk);
};
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
index 15d1950..2c75bed 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
@@ -993,8 +993,6 @@ gboolean TabStripGtk::OnExpose(GtkWidget* widget, GdkEventExpose* event,
event->area.height = tabstrip->bounds_.height();
gdk_region_union_with_rect(event->region, &event->area);
- tabstrip->PaintBackground(event);
-
// Paint the New Tab button.
gtk_container_propagate_expose(GTK_CONTAINER(tabstrip->tabstrip_.get()),
tabstrip->newtab_button_.get()->widget(), event);
@@ -1058,11 +1056,6 @@ void TabStripGtk::OnNewTabClicked(GtkWidget* widget, TabStripGtk* tabstrip) {
tabstrip->model_->delegate()->AddBlankTab(true);
}
-void TabStripGtk::PaintBackground(GdkEventExpose* event) {
- ChromeCanvasPaint canvas(event);
- canvas.TileImageInt(*background, 0, 0, bounds_.width(), bounds_.height());
-}
-
void TabStripGtk::SetTabBounds(TabGtk* tab, const gfx::Rect& bounds) {
tab->SetBounds(bounds);
gtk_fixed_move(GTK_FIXED(tabstrip_.get()), tab->widget(),
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.h b/chrome/browser/gtk/tabs/tab_strip_gtk.h
index 0e0739c..d79ed11 100644
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.h
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.h
@@ -112,9 +112,6 @@ class TabStripGtk : public TabStripModelObserver,
// Handles the clicked signal from the new tab button.
static void OnNewTabClicked(GtkWidget* widget, TabStripGtk* tabstrip);
- // Renders the tabstrip background.
- void PaintBackground(GdkEventExpose* event);
-
// Sets the bounds of the tab and moves the tab widget to those bounds.
void SetTabBounds(TabGtk* tab, const gfx::Rect& bounds);