diff options
author | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-17 19:47:15 +0000 |
---|---|---|
committer | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-17 19:47:15 +0000 |
commit | ea9a760bf723eda730f6de3662e71d3af3b9cdd1 (patch) | |
tree | bf26aa989ade18c4eb6a158595566041f3f9ddaa /chrome/browser/gtk/nine_box.cc | |
parent | d55ad15d8c3e118d6f03dbf236d6b98c62d66fe9 (diff) | |
download | chromium_src-ea9a760bf723eda730f6de3662e71d3af3b9cdd1.zip chromium_src-ea9a760bf723eda730f6de3662e71d3af3b9cdd1.tar.gz chromium_src-ea9a760bf723eda730f6de3662e71d3af3b9cdd1.tar.bz2 |
Make the toolbar background themed on Linux.
Add a class for managing images for scalable themed widgets, and then
implement the toolbar on top of this.
Review URL: http://codereview.chromium.org/21390
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9898 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk/nine_box.cc')
-rw-r--r-- | chrome/browser/gtk/nine_box.cc | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/chrome/browser/gtk/nine_box.cc b/chrome/browser/gtk/nine_box.cc new file mode 100644 index 0000000..98164d9 --- /dev/null +++ b/chrome/browser/gtk/nine_box.cc @@ -0,0 +1,90 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/gtk/nine_box.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); +} + +} // anonymous namespace + +NineBox::NineBox(GdkPixbuf* images[9]) { + memcpy(images_, images, 9*sizeof(GdkPixbuf*)); +} + +NineBox::~NineBox() { + for (int i = 0; i < 9; ++i) { + if (images_[i]) + gdk_pixbuf_unref(images_[i]); + } +} + +void NineBox::RenderToPixbuf(GdkPixbuf* dst) { + // This function paints one row at a time. + // To make indexing sane, |images| points at the current row of images, + // so images[0] always refers to the left-most image of the current row. + GdkPixbuf** images = &images_[0]; + + // x, y coordinate of bottom right corner drawing offset. + int x = gdk_pixbuf_get_width(dst) - gdk_pixbuf_get_width(images[2]); + int y = gdk_pixbuf_get_height(dst) - gdk_pixbuf_get_height(images[2]); + + DrawPixbuf(images[0], dst, 0, 0); + RenderTopCenterStrip(dst, gdk_pixbuf_get_width(images[0]), x); + DrawPixbuf(images[2], dst, x, 0); + + // Center row. Needs vertical tiling. + images = &images_[1 * 3]; + TileImage(images[0], dst, + 0, gdk_pixbuf_get_height(images[0]), + 0, y); + // TODO(port): tile center image if it exists. + DCHECK(images[1] == NULL); + TileImage(images[2], dst, + x, gdk_pixbuf_get_height(images[0]), + x, y); + + // Bottom row. + images = &images_[2 * 3]; + DrawPixbuf(images[0], dst, 0, y); + TileImage(images[1], dst, + gdk_pixbuf_get_width(images[0]), y, + x, y); + DrawPixbuf(images[2], dst, x, y); +} + +void NineBox::RenderTopCenterStrip(GdkPixbuf* dst, int x1, int x2) { + TileImage(images_[1], dst, + x1, 0, + x2, 0); +} + +void NineBox::TileImage(GdkPixbuf* src, GdkPixbuf* dst, + int x1, int y1, int x2, int y2) { + const int width = gdk_pixbuf_get_width(src); + const int height = gdk_pixbuf_get_height(src); + + // Compute delta x or y. + int dx = 0, dy = 0; + if (x2 > x1) + dx = width; + if (y2 > y1) + dy = height; + + for (int x = x1, y = y1; + x + width <= x2 || y + height <= y2; + x += dx, y += dy) { + DrawPixbuf(src, dst, x, y); + } +} |