diff options
author | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-26 23:33:05 +0000 |
---|---|---|
committer | jhawkins@chromium.org <jhawkins@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-26 23:33:05 +0000 |
commit | dc64a63b39f2a047dd597068182c01a2943c396b (patch) | |
tree | 400f92c0e44ef36d358d00d28b7ae5937902a747 /chrome/browser/gtk | |
parent | e9754eb9c5971d176ab436a1ee6d9f6fc504c17f (diff) | |
download | chromium_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.cc | 31 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.h | 11 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 69 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.h | 3 | ||||
-rw-r--r-- | chrome/browser/gtk/custom_button.cc | 20 | ||||
-rw-r--r-- | chrome/browser/gtk/download_item_gtk.cc | 17 | ||||
-rw-r--r-- | chrome/browser/gtk/nine_box.cc | 79 | ||||
-rw-r--r-- | chrome/browser/gtk/nine_box.h | 16 |
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]; |