summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-23 20:29:07 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-23 20:29:07 +0000
commit6c940e699a1bf82046416bed61040a8568b42197 (patch)
tree552d1245076b8b0286a7e97343c28b6a11306d61
parentadfb98c43223a2f40da7d6ee76a9dae3f8c57070 (diff)
downloadchromium_src-6c940e699a1bf82046416bed61040a8568b42197.zip
chromium_src-6c940e699a1bf82046416bed61040a8568b42197.tar.gz
chromium_src-6c940e699a1bf82046416bed61040a8568b42197.tar.bz2
Handle RTL layout in the gtk tabstrip.
BUG=none TEST=Open the browser with --lang=he and make sure the tabs are ordered starting from the right. Also, the UI elements in the tabs should be reversed as well. Review URL: http://codereview.chromium.org/147020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19051 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gtk/custom_button.cc18
-rw-r--r--chrome/browser/gtk/custom_button.h1
-rwxr-xr-xchrome/browser/gtk/tabs/tab_renderer_gtk.cc25
-rwxr-xr-xchrome/browser/gtk/tabs/tab_strip_gtk.cc25
-rw-r--r--chrome/common/gtk_util.cc8
-rw-r--r--chrome/common/gtk_util.h4
6 files changed, 54 insertions, 27 deletions
diff --git a/chrome/browser/gtk/custom_button.cc b/chrome/browser/gtk/custom_button.cc
index 8f9a211..bed3128 100644
--- a/chrome/browser/gtk/custom_button.cc
+++ b/chrome/browser/gtk/custom_button.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/gtk/custom_button.h"
+#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/basictypes.h"
@@ -40,12 +41,17 @@ gboolean CustomDrawButtonBase::OnExpose(GtkWidget* widget, GdkEventExpose* e) {
if (!pixbuf)
return FALSE;
- gdk_draw_pixbuf(widget->window,
- widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
- pixbuf,
- 0, 0,
- widget->allocation.x, widget->allocation.y, -1, -1,
- GDK_RGB_DITHER_NONE, 0, 0);
+ cairo_t* cairo_context = gdk_cairo_create(GDK_DRAWABLE(widget->window));
+ cairo_translate(cairo_context, widget->allocation.x, widget->allocation.y);
+
+ if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) {
+ cairo_translate(cairo_context, widget->allocation.width, 0.0f);
+ cairo_scale(cairo_context, -1.0f, 1.0f);
+ }
+
+ gdk_cairo_set_source_pixbuf(cairo_context, pixbuf, 0, 0);
+ cairo_paint(cairo_context);
+ cairo_destroy(cairo_context);
return TRUE;
}
diff --git a/chrome/browser/gtk/custom_button.h b/chrome/browser/gtk/custom_button.h
index fa6897b..10cd1e6 100644
--- a/chrome/browser/gtk/custom_button.h
+++ b/chrome/browser/gtk/custom_button.h
@@ -69,6 +69,7 @@ class CustomDrawButton {
}
int width() const { return widget_->allocation.width; }
+ int height() const { return widget_->allocation.height; }
// Set the state to draw. We will paint the widget as if it were in this
// state.
diff --git a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
index b4456de..5f83620 100755
--- a/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_renderer_gtk.cc
@@ -12,6 +12,7 @@
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/gtk_util.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -473,8 +474,6 @@ void TabRendererGtk::Layout() {
close_button_bounds_.SetRect(0, 0, 0, 0);
}
- MoveCloseButtonWidget();
-
// 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;
@@ -496,7 +495,14 @@ void TabRendererGtk::Layout() {
}
title_bounds_.SetRect(title_left, title_top, title_width, title_font_height_);
- // TODO(jhawkins): Handle RTL layout.
+ favicon_bounds_.set_x(
+ gtk_util::MirroredLeftPointForRect(tab_.get(), favicon_bounds_));
+ close_button_bounds_.set_x(
+ gtk_util::MirroredLeftPointForRect(tab_.get(), close_button_bounds_));
+ title_bounds_.set_x(
+ gtk_util::MirroredLeftPointForRect(tab_.get(), title_bounds_));
+
+ MoveCloseButtonWidget();
}
void TabRendererGtk::MoveCloseButtonWidget() {
@@ -534,10 +540,6 @@ void TabRendererGtk::PaintTabBackground(gfx::Canvas* canvas) {
PaintInactiveTabBackground(canvas);
if (animation->GetCurrentValue() > 0) {
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,
@@ -643,9 +645,12 @@ void TabRendererGtk::PaintLoadingAnimation(gfx::Canvas* canvas) {
// Just like with the Tab's title and favicon, the position for the page
// loading animation also needs to be mirrored if the UI layout is RTL.
- // TODO(willchan): Handle RTL.
- // dst_x = width() - kLeftPadding - image_size;
- int dst_x = kLeftPadding;
+ int dst_x;
+ if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) {
+ dst_x = width() - 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,
diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
index 4dc2b4d..daeaa5c 100755
--- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc
+++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc
@@ -959,23 +959,24 @@ void TabStripGtk::GenerateIdealBounds() {
void TabStripGtk::LayoutNewTabButton(double last_tab_right,
double unselected_width) {
-#if defined(LINUX2)
- gtk_fixed_move(GTK_FIXED(tabstrip_.get()), newtab_button_->widget(), 0,
- kNewTabButtonVOffset);
-#else
+ gfx::Rect bounds(0, kNewTabButtonVOffset,
+ newtab_button_->width(), newtab_button_->height());
+#if !defined(LINUX2)
int delta = abs(Round(unselected_width) - TabGtk::GetStandardSize().width());
if (delta > 1 && !resize_layout_scheduled_) {
// We're shrinking tabs, so we need to anchor the New Tab button to the
// right edge of the TabStrip's bounds, rather than the right edge of the
// right-most Tab, otherwise it'll bounce when animating.
- gtk_fixed_move(GTK_FIXED(tabstrip_.get()), newtab_button_->widget(),
- bounds_.width() - newtab_button_->width(), kNewTabButtonVOffset);
+ bounds.set_x(bounds_.width() - newtab_button_->width());
} else {
- gtk_fixed_move(GTK_FIXED(tabstrip_.get()), newtab_button_->widget(),
- Round(last_tab_right - kTabHOffset) + kNewTabButtonHOffset,
- kNewTabButtonVOffset);
+ bounds.set_x(Round(last_tab_right - kTabHOffset) + kNewTabButtonHOffset);
}
+
+ bounds.set_x(gtk_util::MirroredLeftPointForRect(tabstrip_.get(), bounds));
#endif
+
+ gtk_fixed_move(GTK_FIXED(tabstrip_.get()), newtab_button_->widget(),
+ bounds.x(), bounds.y());
}
void TabStripGtk::GetDesiredTabWidths(int tab_count,
@@ -1545,9 +1546,11 @@ void TabStripGtk::OnNewTabClicked(GtkWidget* widget, TabStripGtk* tabstrip) {
}
void TabStripGtk::SetTabBounds(TabGtk* tab, const gfx::Rect& bounds) {
- tab->SetBounds(bounds);
+ gfx::Rect bds = bounds;
+ bds.set_x(gtk_util::MirroredLeftPointForRect(tabstrip_.get(), bounds));
+ tab->SetBounds(bds);
gtk_fixed_move(GTK_FIXED(tabstrip_.get()), tab->widget(),
- bounds.x(), bounds.y());
+ bds.x(), bds.y());
}
CustomDrawButton* TabStripGtk::MakeNewTabButton() {
diff --git a/chrome/common/gtk_util.cc b/chrome/common/gtk_util.cc
index f89d5a8..f02b3b8 100644
--- a/chrome/common/gtk_util.cc
+++ b/chrome/common/gtk_util.cc
@@ -8,6 +8,7 @@
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
+#include "app/l10n_util.h"
#include "base/linux_util.h"
#include "base/logging.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -246,4 +247,11 @@ void SetButtonTriggersNavigation(GtkWidget* button) {
G_CALLBACK(OnMouseButtonReleased), NULL);
}
+int MirroredLeftPointForRect(GtkWidget* widget, const gfx::Rect& bounds) {
+ if (l10n_util::GetTextDirection() != l10n_util::RIGHT_TO_LEFT) {
+ return bounds.x();
+ }
+ return widget->allocation.width - bounds.x() - bounds.width();
+}
+
} // namespace gtk_util
diff --git a/chrome/common/gtk_util.h b/chrome/common/gtk_util.h
index 2f38092..a8aa205 100644
--- a/chrome/common/gtk_util.h
+++ b/chrome/common/gtk_util.h
@@ -97,6 +97,10 @@ void EnumerateTopLevelWindows(x11_util::EnumerateWindowsDelegate* delegate);
// those events.
void SetButtonTriggersNavigation(GtkWidget* button);
+// Returns the mirrored x value for |bounds| if the layout is RTL; otherwise,
+// the original value is returned unchanged.
+int MirroredLeftPointForRect(GtkWidget* widget, const gfx::Rect& bounds);
+
} // namespace gtk_util
#endif // CHROME_COMMON_GTK_UTIL_H_