summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-26 23:33:05 +0000
committerjhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-26 23:33:05 +0000
commitdc64a63b39f2a047dd597068182c01a2943c396b (patch)
tree400f92c0e44ef36d358d00d28b7ae5937902a747 /chrome/browser/gtk
parente9754eb9c5971d176ab436a1ee6d9f6fc504c17f (diff)
downloadchromium_src-dc64a63b39f2a047dd597068182c01a2943c396b.zip
chromium_src-dc64a63b39f2a047dd597068182c01a2943c396b.tar.gz
chromium_src-dc64a63b39f2a047dd597068182c01a2943c396b.tar.bz2
Change NineBox to render into a GtkWidget. This offers a minor speedup and simplification of code because we get rid of the pixbuf middleman.
Review URL: http://codereview.chromium.org/42620 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12620 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.cc31
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.h11
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc69
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h3
-rw-r--r--chrome/browser/gtk/custom_button.cc20
-rw-r--r--chrome/browser/gtk/download_item_gtk.cc17
-rw-r--r--chrome/browser/gtk/nine_box.cc79
-rw-r--r--chrome/browser/gtk/nine_box.h16
8 files changed, 104 insertions, 142 deletions
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc
index 7240a59..1e476b2 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_toolbar_gtk.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/gtk/back_forward_menu_model_gtk.h"
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/location_bar_view_gtk.h"
+#include "chrome/browser/gtk/nine_box.h"
#include "chrome/browser/gtk/standard_menus.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/common/l10n_util.h"
@@ -45,6 +46,8 @@ BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser)
browser, BackForwardMenuModel::BACKWARD_MENU_DELEGATE));
forward_menu_model_.reset(new BackForwardMenuModelGtk(
browser, BackForwardMenuModel::FORWARD_MENU_DELEGATE));
+
+ InitNineBox();
}
BrowserToolbarGtk::~BrowserToolbarGtk() {
@@ -68,6 +71,8 @@ void BrowserToolbarGtk::Init(Profile* profile,
// Demand we're always at least kToolbarHeight tall.
// -1 for width means "let GTK do its normal sizing".
gtk_widget_set_size_request(toolbar_, -1, kToolbarHeight);
+ g_signal_connect(G_OBJECT(toolbar_), "expose-event",
+ G_CALLBACK(&OnContentAreaExpose), this);
// A GtkAccelGroup is not InitiallyUnowned, meaning we get a real reference
// count starting at one. We don't want the lifetime to be managed by the
@@ -242,6 +247,15 @@ CustomContainerButton* BrowserToolbarGtk::BuildToolbarMenuButton(
}
// static
+gboolean BrowserToolbarGtk::OnContentAreaExpose(GtkWidget* widget,
+ GdkEventExpose* e,
+ BrowserToolbarGtk* toolbar) {
+ toolbar->background_ninebox_.get()->RenderTopCenterStrip(widget,
+ 0, widget->allocation.width);
+ return FALSE; // Allow subwidgets to paint.
+}
+
+// static
void BrowserToolbarGtk::OnButtonClick(GtkWidget* button,
BrowserToolbarGtk* toolbar) {
int tag = -1;
@@ -361,3 +375,20 @@ CustomDrawButton* BrowserToolbarGtk::MakeHomeButton() {
return BuildToolbarButton(IDR_HOME, IDR_HOME_P, IDR_HOME_H, 0,
l10n_util::GetString(IDS_TOOLTIP_HOME));
}
+
+void BrowserToolbarGtk::InitNineBox() {
+ ResourceBundle &rb = ResourceBundle::GetSharedInstance();
+
+ GdkPixbuf* images[9] = {
+ rb.LoadPixbuf(IDR_CONTENT_TOP_LEFT_CORNER),
+ rb.LoadPixbuf(IDR_CONTENT_TOP_CENTER),
+ rb.LoadPixbuf(IDR_CONTENT_TOP_RIGHT_CORNER),
+ rb.LoadPixbuf(IDR_CONTENT_LEFT_SIDE),
+ NULL,
+ rb.LoadPixbuf(IDR_CONTENT_RIGHT_SIDE),
+ rb.LoadPixbuf(IDR_CONTENT_BOTTOM_LEFT_CORNER),
+ rb.LoadPixbuf(IDR_CONTENT_BOTTOM_CENTER),
+ rb.LoadPixbuf(IDR_CONTENT_BOTTOM_RIGHT_CORNER)
+ };
+ background_ninebox_.reset(new NineBox(images));
+}
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h
index 6663bcd..d4134ba9 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.h
+++ b/chrome/browser/gtk/browser_toolbar_gtk.h
@@ -20,6 +20,7 @@ class CustomContainerButton;
class CustomDrawButton;
class LocationBar;
class LocationBarViewGtk;
+class NineBox;
class Profile;
class TabContents;
class ToolbarModel;
@@ -82,6 +83,10 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
unsigned int accelerator,
unsigned int accelerator_mod);
+ // Gtk callback for the "expose-event" signal.
+ static gboolean OnContentAreaExpose(GtkWidget* widget, GdkEventExpose* e,
+ BrowserToolbarGtk* toolbar);
+
// Gtk callback for the "clicked" signal.
static void OnButtonClick(GtkWidget* button, BrowserToolbarGtk* toolbar);
@@ -99,6 +104,12 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
// Construct the Home button.
CustomDrawButton* MakeHomeButton();
+ // Initialize the background NineBox.
+ void InitNineBox();
+
+ // Ninebox for the toolbar background
+ scoped_ptr<NineBox> background_ninebox_;
+
// Gtk widgets. The toolbar is an hbox with each of the other pieces of the
// toolbar placed side by side.
GtkWidget* toolbar_;
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index fcc8fa6..aca7897 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -17,7 +17,6 @@
#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/gtk/browser_toolbar_gtk.h"
#include "chrome/browser/gtk/find_bar_gtk.h"
-#include "chrome/browser/gtk/nine_box.h"
#include "chrome/browser/gtk/status_bubble_gtk.h"
#include "chrome/browser/gtk/tab_contents_container_gtk.h"
#include "chrome/browser/gtk/tab_strip_gtk.h"
@@ -39,34 +38,6 @@ class DummyButtonListener : public views::ButtonListener {
}
};
-static GdkPixbuf* LoadThemeImage(int resource_id) {
- // TODO(mmoss) refactor -- stolen from custom_button.cc
- if (0 == resource_id)
- return NULL;
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- std::vector<unsigned char> data;
- rb.LoadImageResourceBytes(resource_id, &data);
-
- GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
- bool ok = gdk_pixbuf_loader_write(loader, static_cast<guint8*>(data.data()),
- data.size(), NULL);
- DCHECK(ok) << "failed to write " << resource_id;
- // Calling gdk_pixbuf_loader_close forces the data to be parsed by the
- // loader. We must do this before calling gdk_pixbuf_loader_get_pixbuf.
- ok = gdk_pixbuf_loader_close(loader, NULL);
- DCHECK(ok) << "close failed " << resource_id;
- GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
- DCHECK(pixbuf) << "failed to load " << resource_id << " " << data.size();
-
- // The pixbuf is owned by the loader, so add a ref so when we delete the
- // loader, the pixbuf still exists.
- g_object_ref(pixbuf);
- g_object_unref(loader);
-
- return pixbuf;
-}
-
gboolean MainWindowConfigured(GtkWindow* window, GdkEventConfigure* event,
BrowserWindowGtk* browser_win) {
gfx::Rect bounds = gfx::Rect(event->x, event->y, event->width, event->height);
@@ -179,19 +150,6 @@ BrowserWindowGtk::BrowserWindowGtk(Browser* browser)
ConnectAccelerators();
bounds_ = GetInitialWindowBounds(window_);
- GdkPixbuf* images[9] = {
- LoadThemeImage(IDR_CONTENT_TOP_LEFT_CORNER),
- LoadThemeImage(IDR_CONTENT_TOP_CENTER),
- LoadThemeImage(IDR_CONTENT_TOP_RIGHT_CORNER),
- LoadThemeImage(IDR_CONTENT_LEFT_SIDE),
- NULL,
- LoadThemeImage(IDR_CONTENT_RIGHT_SIDE),
- LoadThemeImage(IDR_CONTENT_BOTTOM_LEFT_CORNER),
- LoadThemeImage(IDR_CONTENT_BOTTOM_CENTER),
- LoadThemeImage(IDR_CONTENT_BOTTOM_RIGHT_CORNER)
- };
- content_area_ninebox_.reset(new NineBox(images));
-
// This vbox encompasses all of the widgets within the browser, including
// the tabstrip and the content vbox.
window_vbox_ = gtk_vbox_new(FALSE, 0);
@@ -273,7 +231,7 @@ void BrowserWindowGtk::HandleAccelerator(guint keyval,
default:
// Pass the accelerator on to GTK.
- gtk_accel_groups_activate(G_OBJECT(window_), keyval, modifier);
+ gtk_accel_groups_activate(G_OBJECT(window_), keyval, modifier);
}
}
@@ -285,31 +243,6 @@ gboolean BrowserWindowGtk::OnContentAreaExpose(GtkWidget* widget,
return FALSE;
}
- // The theme graphics include the 2px frame, but we don't draw the frame
- // in the non-custom-frame mode. So we subtract it off.
- const int kFramePixels = 2;
-
- GdkPixbuf* pixbuf =
- gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, // alpha
- 8, // bit depth
- widget->allocation.width,
- BrowserToolbarGtk::kToolbarHeight + kFramePixels);
-
-#ifndef NDEBUG
- // Fill with a bright color so we can see any pixels we're missing.
- gdk_pixbuf_fill(pixbuf, 0x00FFFFFF);
-#endif
-
- window->content_area_ninebox_->RenderTopCenterStrip(pixbuf, 0,
- widget->allocation.width);
- gdk_draw_pixbuf(widget->window, NULL, pixbuf,
- 0, 0,
- widget->allocation.x,
- widget->allocation.y - kFramePixels,
- -1, -1,
- GDK_RGB_DITHER_NORMAL, 0, 0);
- gdk_pixbuf_unref(pixbuf);
-
return FALSE; // Allow subwidgets to paint.
}
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index 073ff45..b161b6e 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -127,9 +127,6 @@ class BrowserWindowGtk : public BrowserWindow,
gfx::Rect bounds_;
GdkWindowState state_;
- // Theme graphics for the content area.
- scoped_ptr<NineBox> content_area_ninebox_;
-
// Whether we're drawing the custom Chrome frame (including title bar).
bool custom_frame_;
diff --git a/chrome/browser/gtk/custom_button.cc b/chrome/browser/gtk/custom_button.cc
index 7fdd4cf..5609937 100644
--- a/chrome/browser/gtk/custom_button.cc
+++ b/chrome/browser/gtk/custom_button.cc
@@ -111,24 +111,8 @@ gboolean CustomContainerButton::OnExpose(GtkWidget* widget, GdkEventExpose* e,
nine_box = button->nine_box_active_.get();
// Only draw theme graphics if we have some.
- if (nine_box) {
- GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
- true, // alpha
- 8, // bits per channel
- widget->allocation.width,
- widget->allocation.height);
-
- nine_box->RenderToPixbuf(pixbuf);
-
- 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);
-
- gdk_pixbuf_unref(pixbuf);
- }
+ if (nine_box)
+ nine_box->RenderToWidget(widget);
// If we return FALSE from the function, the button paints itself.
// If we return TRUE, no children are painted.
diff --git a/chrome/browser/gtk/download_item_gtk.cc b/chrome/browser/gtk/download_item_gtk.cc
index 941afd0..88c73cc 100644
--- a/chrome/browser/gtk/download_item_gtk.cc
+++ b/chrome/browser/gtk/download_item_gtk.cc
@@ -269,22 +269,7 @@ gboolean DownloadItemGtk::OnExpose(GtkWidget* widget, GdkEventExpose* e,
else
nine_box = is_body ? body_nine_box_normal_ : menu_nine_box_normal_;
- GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
- true, // alpha
- 8, // bits per channel
- widget->allocation.width,
- widget->allocation.height);
-
- nine_box->RenderToPixbuf(pixbuf);
-
- 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);
-
- gdk_pixbuf_unref(pixbuf);
+ nine_box->RenderToWidget(widget);
GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget));
if (child)
diff --git a/chrome/browser/gtk/nine_box.cc b/chrome/browser/gtk/nine_box.cc
index 3852314..2c6c88d 100644
--- a/chrome/browser/gtk/nine_box.cc
+++ b/chrome/browser/gtk/nine_box.cc
@@ -4,17 +4,29 @@
#include "chrome/browser/gtk/nine_box.h"
+#include "base/gfx/gtk_util.h"
#include "base/logging.h"
namespace {
// Draw pixbuf |src| into |dst| at position (x, y).
-// Shorthand for gdk_pixbuf_copy_area.
-void DrawPixbuf(GdkPixbuf* src, GdkPixbuf* dst, int x, int y) {
- gdk_pixbuf_copy_area(src, 0, 0,
- gdk_pixbuf_get_width(src),
- gdk_pixbuf_get_height(src),
- dst, x, y);
+void DrawPixbuf(GtkWidget* dst, GdkPixbuf* src, int x, int y) {
+ GdkGC* gc = dst->style->fg_gc[GTK_WIDGET_STATE(dst)];
+ gdk_draw_pixbuf(dst->window, // The destination drawable.
+ gc, // Graphics context.
+ src, 0, 0, // Source image and x,y offset.
+ x, y, -1, -1, // x, y, width, height.
+ GDK_RGB_DITHER_NONE, 0, 0); // Dithering mode, x,y offsets.
+}
+
+// Fills the widget with |color|.
+void FillWidget(GtkWidget* dst, const GdkColor& color) {
+ GdkGC* copy = gdk_gc_new(dst->window);
+ gdk_gc_set_foreground(copy, &color);
+ gdk_draw_rectangle(dst->window, copy, TRUE, 0, 0,
+ dst->allocation.width,
+ dst->allocation.height);
+ g_object_unref(copy);
}
} // anonymous namespace
@@ -30,14 +42,18 @@ NineBox::~NineBox() {
}
}
-void NineBox::RenderToPixbuf(GdkPixbuf* dst) {
+void NineBox::RenderToWidget(GtkWidget* dst) {
// TODO(evanm): this is stupid; it should just be implemented with SkBitmaps
// and convert to a GdkPixbuf at the last second.
+ int dst_width = dst->allocation.width;
+ int dst_height = dst->allocation.height;
+
#ifndef NDEBUG
// Start by filling with a bright color so we can see any pixels
// we're missing.
- gdk_pixbuf_fill(dst, 0x00FFFFFF);
+ GdkColor bright = GDK_COLOR_RGB(0x00, 0xFF, 0xFF);
+ FillWidget(dst, bright);
#endif
// This function paints one row at a time.
@@ -49,37 +65,35 @@ void NineBox::RenderToPixbuf(GdkPixbuf* dst) {
// rendering of the ninebox.
const int x1 = gdk_pixbuf_get_width(images[0]);
const int y1 = gdk_pixbuf_get_height(images[0]);
- const int x2 = images[2] ?
- gdk_pixbuf_get_width(dst) - gdk_pixbuf_get_width(images[2]) : x1;
- const int y2 = images[6] ?
- gdk_pixbuf_get_height(dst) - gdk_pixbuf_get_height(images[6]) : y1;
+ const int x2 = images[2] ? dst_width - gdk_pixbuf_get_width(images[2]) : x1;
+ const int y2 = images[6] ? dst_height - gdk_pixbuf_get_height(images[6]) : y1;
DCHECK(x2 >= x1);
DCHECK(y2 >= y1);
if (images[0])
- DrawPixbuf(images[0], dst, 0, 0);
+ DrawPixbuf(dst, images[0], 0, 0);
if (images[1])
RenderTopCenterStrip(dst, x1, x2);
if (images[2])
- DrawPixbuf(images[2], dst, x2, 0);
+ DrawPixbuf(dst, images[2], x2, 0);
// Center row. Needs vertical tiling.
images = &images_[1 * 3];
if (images[0]) {
- TileImage(images[0], dst,
+ TileImage(dst, images[0],
0, y1,
0, y2);
}
if (images[1]) {
const int delta_y = gdk_pixbuf_get_height(images[1]);
for (int y = y1; y < y2; y += delta_y) {
- TileImage(images[1], dst,
+ TileImage(dst, images[1],
x1, y,
x2, y);
}
}
if (images[2]) {
- TileImage(images[2], dst,
+ TileImage(dst, images[2],
x2, y1,
x2, y2);
}
@@ -87,28 +101,34 @@ void NineBox::RenderToPixbuf(GdkPixbuf* dst) {
// Bottom row.
images = &images_[2 * 3];
if (images[0])
- DrawPixbuf(images[0], dst, 0, y2);
+ DrawPixbuf(dst, images[0], 0, y2);
if (images[1]) {
- TileImage(images[1], dst,
+ TileImage(dst, images[1],
x1, y2,
x2, y2);
}
if (images[2])
- DrawPixbuf(images[2], dst, x2, y2);
+ DrawPixbuf(dst, images[2], x2, y2);
}
-void NineBox::RenderTopCenterStrip(GdkPixbuf* dst, int x1, int x2) {
- TileImage(images_[1], dst,
+void NineBox::RenderTopCenterStrip(GtkWidget* dst, int x1, int x2) {
+ TileImage(dst, images_[1],
x1, 0,
x2, 0);
}
-void NineBox::TileImage(GdkPixbuf* src, GdkPixbuf* dst,
+void NineBox::TileImage(GtkWidget* dst, GdkPixbuf* src,
int x1, int y1, int x2, int y2) {
+ GdkGC* gc = dst->style->fg_gc[GTK_WIDGET_STATE(dst)];
const int src_width = gdk_pixbuf_get_width(src);
const int src_height = gdk_pixbuf_get_height(src);
- const int dst_width = gdk_pixbuf_get_width(dst);
- const int dst_height = gdk_pixbuf_get_height(dst);
+ const int dst_width = dst->allocation.width;
+ const int dst_height = dst->allocation.height;
+
+ x1 += dst->allocation.x;
+ y1 += dst->allocation.y;
+ x2 += dst->allocation.x;
+ y2 += dst->allocation.y;
// We only tile along one axis (see above TODO about nuking all this code),
// dx or dy will be nonzero along that axis.
@@ -120,9 +140,10 @@ void NineBox::TileImage(GdkPixbuf* src, GdkPixbuf* dst,
DCHECK(dx == 0 || dy == 0);
for (int x = x1, y = y1; x < x2 || y < y2; x += dx, y += dy) {
- gdk_pixbuf_copy_area(src, 0, 0,
- dx ? std::min(src_width, dst_width - x) : src_width,
- dy ? std::min(src_height, dst_height - y) : src_height,
- dst, x, y);
+ gdk_draw_pixbuf(dst->window, gc, src, 0, 0,
+ x, y,
+ dx ? std::min(src_width, dst_width - x) : src_width,
+ dy ? std::min(src_height, dst_height - y) : src_height,
+ GDK_RGB_DITHER_NONE, 0, 0);
}
}
diff --git a/chrome/browser/gtk/nine_box.h b/chrome/browser/gtk/nine_box.h
index 8a54406..47c5f78 100644
--- a/chrome/browser/gtk/nine_box.h
+++ b/chrome/browser/gtk/nine_box.h
@@ -5,7 +5,7 @@
#ifndef CHROME_BROWSER_GTK_NINE_BOX_H_
#define CHROME_BROWSER_GTK_NINE_BOX_H_
-#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gtk/gtk.h>
// A NineBox manages a set of source images representing a 3x3 grid, where
// non-corner images can be tiled to make a larger image. It's used to
@@ -25,17 +25,17 @@ class NineBox {
NineBox(GdkPixbuf* images[9]);
~NineBox();
- // Render the NineBox to dst.
- // Expects dst to already be the proper size.
- void RenderToPixbuf(GdkPixbuf* dst);
+ // Render the NineBox to |dst|.
+ // The images will be tiled to fit into the widget.
+ void RenderToWidget(GtkWidget* dst);
- // Render the top row of images to dst between x1 and x2.
- // This is split from RenderToPixbuf so the toolbar can use it.
- void RenderTopCenterStrip(GdkPixbuf* dst, int x1, int x2);
+ // Render the top row of images to |dst| between |x1| and |x2|.
+ // This is split from RenderToWidget so the toolbar can use it.
+ void RenderTopCenterStrip(GtkWidget* dst, int x1, int x2);
private:
// Repeatedly stamp src across dst.
- void TileImage(GdkPixbuf* src, GdkPixbuf* dst,
+ void TileImage(GtkWidget* dst, GdkPixbuf* src,
int x1, int y1, int x2, int y2);
GdkPixbuf* images_[9];