summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-05 03:28:22 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-05 03:28:22 +0000
commit3a164a1633cc2c8136aa385223a8ebdbda407150 (patch)
tree67d84aae45d092d6c787426ba53709a225e350c0 /chrome
parent01ac79343211c46314a1fa7fd9d013b6aa683335 (diff)
downloadchromium_src-3a164a1633cc2c8136aa385223a8ebdbda407150.zip
chromium_src-3a164a1633cc2c8136aa385223a8ebdbda407150.tar.gz
chromium_src-3a164a1633cc2c8136aa385223a8ebdbda407150.tar.bz2
Put the dropdown menu button on the linux download shelf.
Also set the background color. Also extend NineBox a little bit. Review URL: http://codereview.chromium.org/40139 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10969 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/gtk/download_item_gtk.cc95
-rw-r--r--chrome/browser/gtk/download_item_gtk.h21
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.cc21
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.h8
-rw-r--r--chrome/browser/gtk/nine_box.cc45
-rw-r--r--chrome/browser/gtk/nine_box.h5
6 files changed, 146 insertions, 49 deletions
diff --git a/chrome/browser/gtk/download_item_gtk.cc b/chrome/browser/gtk/download_item_gtk.cc
index e14f592..c2e72d5 100644
--- a/chrome/browser/gtk/download_item_gtk.cc
+++ b/chrome/browser/gtk/download_item_gtk.cc
@@ -12,9 +12,21 @@
#include "grit/theme_resources.h"
-NineBox* DownloadItemGtk::nine_box_normal_ = NULL;
-NineBox* DownloadItemGtk::nine_box_prelight_ = NULL;
-NineBox* DownloadItemGtk::nine_box_active_ = NULL;
+namespace {
+
+// The width of the |menu_button_| widget. It has to be at least as wide as the
+// bitmap that we use to draw it, i.e. 16, but can be more.
+const int kMenuButtonWidth = 16;
+
+}
+
+NineBox* DownloadItemGtk::body_nine_box_normal_ = NULL;
+NineBox* DownloadItemGtk::body_nine_box_prelight_ = NULL;
+NineBox* DownloadItemGtk::body_nine_box_active_ = NULL;
+
+NineBox* DownloadItemGtk::menu_nine_box_normal_ = NULL;
+NineBox* DownloadItemGtk::menu_nine_box_prelight_ = NULL;
+NineBox* DownloadItemGtk::menu_nine_box_active_ = NULL;
DownloadItemGtk::DownloadItemGtk(BaseDownloadItemModel* download_model,
GtkWidget* parent_shelf)
@@ -25,21 +37,29 @@ DownloadItemGtk::DownloadItemGtk(BaseDownloadItemModel* download_model,
body_ = gtk_button_new();
gtk_widget_set_app_paintable(body_, TRUE);
g_signal_connect(G_OBJECT(body_), "expose-event",
- G_CALLBACK(OnBodyExpose), this);
-
- GtkWidget* label = gtk_label_new(download_model->download()->file_name()
+ G_CALLBACK(OnExpose), this);
+ GTK_WIDGET_UNSET_FLAGS(body_, GTK_CAN_FOCUS);
+ GtkWidget* label = gtk_label_new(download_model->download()->GetFileName()
.value().c_str());
gtk_container_add(GTK_CONTAINER(body_), label);
+ menu_button_ = gtk_button_new();
+ gtk_widget_set_app_paintable(menu_button_, TRUE);
+ GTK_WIDGET_UNSET_FLAGS(menu_button_, GTK_CAN_FOCUS);
+ g_signal_connect(G_OBJECT(menu_button_), "expose-event",
+ G_CALLBACK(OnExpose), this);
+ gtk_widget_set_size_request(menu_button_, kMenuButtonWidth, 0);
+
hbox_ = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox_), body_, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox_), menu_button_, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(parent_shelf), hbox_, FALSE, FALSE, 0);
gtk_widget_show_all(hbox_);
}
// static
void DownloadItemGtk::InitNineBoxes() {
- if (nine_box_normal_)
+ if (body_nine_box_normal_)
return;
GdkPixbuf* images[9];
@@ -55,7 +75,7 @@ void DownloadItemGtk::InitNineBoxes() {
images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM);
images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM);
images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM);
- nine_box_normal_ = new NineBox(images);
+ body_nine_box_normal_ = new NineBox(images);
i = 0;
images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_TOP_H);
@@ -67,7 +87,7 @@ void DownloadItemGtk::InitNineBoxes() {
images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM_H);
images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_H);
images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_H);
- nine_box_prelight_ = new NineBox(images);
+ body_nine_box_prelight_ = new NineBox(images);
i = 0;
images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_TOP_P);
@@ -79,19 +99,57 @@ void DownloadItemGtk::InitNineBoxes() {
images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM_P);
images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_P);
images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_RIGHT_BOTTOM_P);
- nine_box_active_ = new NineBox(images);
+ body_nine_box_active_ = new NineBox(images);
+
+ i = 0;
+ images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_TOP);
+ images[i++] = NULL;
+ images[i++] = NULL;
+ images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE);
+ images[i++] = NULL;
+ images[i++] = NULL;
+ images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM);
+ images[i++] = NULL;
+ images[i++] = NULL;
+ menu_nine_box_normal_ = new NineBox(images);
+
+ i = 0;
+ images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_TOP_H);
+ images[i++] = NULL;
+ images[i++] = NULL;
+ images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_H);
+ images[i++] = NULL;
+ images[i++] = NULL;
+ images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_H);
+ images[i++] = NULL;
+ images[i++] = NULL;
+ menu_nine_box_prelight_ = new NineBox(images);
+
+ i = 0;
+ images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_TOP_P);
+ images[i++] = NULL;
+ images[i++] = NULL;
+ images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_MIDDLE_P);
+ images[i++] = NULL;
+ images[i++] = NULL;
+ images[i++] = rb.LoadPixbuf(IDR_DOWNLOAD_BUTTON_MENU_BOTTOM_P);
+ images[i++] = NULL;
+ images[i++] = NULL;
+ menu_nine_box_active_ = new NineBox(images);
}
// static
-gboolean DownloadItemGtk::OnBodyExpose(GtkWidget* widget, GdkEventExpose* e,
- DownloadItemGtk* download_item) {
+gboolean DownloadItemGtk::OnExpose(GtkWidget* widget, GdkEventExpose* e,
+ DownloadItemGtk* download_item) {
NineBox* nine_box = NULL;
+ // If true, this widget is |body_|, otherwise it is |menu_button_|.
+ bool is_body = widget == download_item->body_;
if (GTK_WIDGET_STATE(widget) == GTK_STATE_PRELIGHT)
- nine_box = nine_box_prelight_;
+ nine_box = is_body ? body_nine_box_prelight_ : menu_nine_box_prelight_;
else if (GTK_WIDGET_STATE(widget) == GTK_STATE_ACTIVE)
- nine_box = nine_box_active_;
+ nine_box = is_body ? body_nine_box_active_ : menu_nine_box_active_;
else
- nine_box = nine_box_normal_;
+ nine_box = is_body ? body_nine_box_normal_ : menu_nine_box_normal_;
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
true, // alpha
@@ -110,11 +168,10 @@ gboolean DownloadItemGtk::OnBodyExpose(GtkWidget* widget, GdkEventExpose* e,
gdk_pixbuf_unref(pixbuf);
- gtk_container_propagate_expose(GTK_CONTAINER(widget),
- gtk_bin_get_child(GTK_BIN(widget)),
- e);
+ GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget));
+ if (child)
+ gtk_container_propagate_expose(GTK_CONTAINER(widget), child, e);
return TRUE;
}
-
diff --git a/chrome/browser/gtk/download_item_gtk.h b/chrome/browser/gtk/download_item_gtk.h
index f9b15e8..397e41c 100644
--- a/chrome/browser/gtk/download_item_gtk.h
+++ b/chrome/browser/gtk/download_item_gtk.h
@@ -14,19 +14,25 @@ class NineBox;
class DownloadItemGtk {
public:
- // DownloadItemGtk takes ownership of |download_item_model|;
+ // DownloadItemGtk takes ownership of |download_item_model|.
DownloadItemGtk(BaseDownloadItemModel* download_item_model,
GtkWidget* parent_shelf);
private:
static void InitNineBoxes();
- static gboolean OnBodyExpose(GtkWidget* widget, GdkEventExpose* e,
- DownloadItemGtk* download_item);
+ static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* e,
+ DownloadItemGtk* download_item);
- static NineBox* nine_box_normal_;
- static NineBox* nine_box_prelight_;
- static NineBox* nine_box_active_;
+ // Nineboxes for the body area.
+ static NineBox* body_nine_box_normal_;
+ static NineBox* body_nine_box_prelight_;
+ static NineBox* body_nine_box_active_;
+
+ // Nineboxes for the menu button.
+ static NineBox* menu_nine_box_normal_;
+ static NineBox* menu_nine_box_prelight_;
+ static NineBox* menu_nine_box_active_;
// The widget that contains the body and menu dropdown.
GtkWidget* hbox_;
@@ -35,6 +41,9 @@ class DownloadItemGtk {
// animation.
GtkWidget* body_;
+ // The widget that creates a dropdown menu when pressed.
+ GtkWidget* menu_button_;
+
// The download item model we represent.
scoped_ptr<BaseDownloadItemModel> download_model_;
diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc
index d583529..0111b21 100644
--- a/chrome/browser/gtk/download_shelf_gtk.cc
+++ b/chrome/browser/gtk/download_shelf_gtk.cc
@@ -17,8 +17,9 @@
namespace {
-// Total height of the shelf.
-const int kShelfHeight = 42;
+// Total height of the shelf. This must be at least 28 + 2 * kTopBottomPadding,
+// or there won't be room to draw the download items.
+const int kShelfHeight = 32;
// Padding between the download widgets.
const int kDownloadItemPadding = 10;
@@ -30,6 +31,9 @@ const int kTopBottomPadding = 2;
// Padding from right edge and close button/show downloads link.
const int kRightPadding = 10;
+// The background color of the shelf.
+static GdkColor kBackgroundColor = { 0, 230 << 8, 237 << 8, 244 << 8 };
+
}
// static
@@ -40,9 +44,12 @@ DownloadShelf* DownloadShelf::Create(TabContents* tab_contents) {
DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents)
: DownloadShelf(tab_contents),
is_showing_(false) {
- shelf_ = gtk_hbox_new(FALSE, 0);
- gtk_widget_set_size_request(shelf_, -1, kShelfHeight);
- gtk_container_set_border_width(GTK_CONTAINER(shelf_), kTopBottomPadding);
+ hbox_ = gtk_hbox_new(FALSE, 0);
+ gtk_widget_set_size_request(hbox_, -1, kShelfHeight);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox_), kTopBottomPadding);
+ shelf_ = gtk_event_box_new();
+ gtk_container_add(GTK_CONTAINER(shelf_), hbox_);
+ gtk_widget_modify_bg(shelf_, GTK_STATE_NORMAL, &kBackgroundColor);
// Create and pack the close button.
close_button_.reset(new CustomDrawButton(IDR_CLOSE_BAR,
@@ -52,7 +59,7 @@ DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents)
GTK_WIDGET_UNSET_FLAGS(close_button_->widget(), GTK_CAN_FOCUS);
GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), close_button_->widget(), TRUE, FALSE, 0);
- gtk_box_pack_end(GTK_BOX(shelf_), vbox, FALSE, FALSE, kRightPadding);
+ gtk_box_pack_end(GTK_BOX(hbox_), vbox, FALSE, FALSE, kRightPadding);
// Stick ourselves at the bottom of the parent tab contents.
GtkWidget* parent_contents = tab_contents->GetNativeView();
@@ -63,7 +70,7 @@ DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents)
void DownloadShelfGtk::AddDownload(BaseDownloadItemModel* download_model_) {
// TODO(estade): we need to delete these at some point. There's no explicit
// mass delete on windows, figure out where they do it.
- download_items_.push_back(new DownloadItemGtk(download_model_, shelf_));
+ download_items_.push_back(new DownloadItemGtk(download_model_, hbox_));
Show();
}
diff --git a/chrome/browser/gtk/download_shelf_gtk.h b/chrome/browser/gtk/download_shelf_gtk.h
index 28b64ad..7a2b82e 100644
--- a/chrome/browser/gtk/download_shelf_gtk.h
+++ b/chrome/browser/gtk/download_shelf_gtk.h
@@ -34,7 +34,13 @@ class DownloadShelfGtk : public DownloadShelf {
static void OnCloseButtonClick(GtkWidget* button,
DownloadShelfGtk* toolbar);
- // |bar_| is the highest level widget of the download shelf. It is an hbox.
+ // |hbox_| holds the download items and buttons of the shelf.
+ GtkWidget* hbox_;
+
+ // |shelf_box_| is the highest level widget of the shelf. It has a single
+ // child, |hbox_|. It exists because we need to be able to set the background
+ // color of the shelf, and GtkBoxes don't have a gdk window, which is a
+ // requisite for changing the background color.
GtkWidget* shelf_;
// The 'x' that the user can press to hide the download shelf.
diff --git a/chrome/browser/gtk/nine_box.cc b/chrome/browser/gtk/nine_box.cc
index eefa8c8..1754536 100644
--- a/chrome/browser/gtk/nine_box.cc
+++ b/chrome/browser/gtk/nine_box.cc
@@ -49,20 +49,27 @@ 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 = gdk_pixbuf_get_width(dst) - gdk_pixbuf_get_width(images[8]);
- const int y2 = gdk_pixbuf_get_height(dst) - gdk_pixbuf_get_height(images[8]);
+ 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;
DCHECK(x2 >= x1);
DCHECK(y2 >= y1);
- DrawPixbuf(images[0], dst, 0, 0);
- RenderTopCenterStrip(dst, x1, x2);
- DrawPixbuf(images[2], dst, x2, 0);
+ if (images[0])
+ DrawPixbuf(images[0], dst, 0, 0);
+ if (images[1])
+ RenderTopCenterStrip(dst, x1, x2);
+ if (images[2])
+ DrawPixbuf(images[2], dst, x2, 0);
// Center row. Needs vertical tiling.
images = &images_[1 * 3];
- TileImage(images[0], dst,
- 0, y1,
- 0, y2);
+ if (images[0]) {
+ TileImage(images[0], dst,
+ 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) {
@@ -71,17 +78,23 @@ void NineBox::RenderToPixbuf(GdkPixbuf* dst) {
x2, y);
}
}
- TileImage(images[2], dst,
- x2, y1,
- x2, y2);
+ if (images[2]) {
+ TileImage(images[2], dst,
+ x2, y1,
+ x2, y2);
+ }
// Bottom row.
images = &images_[2 * 3];
- DrawPixbuf(images[0], dst, 0, y2);
- TileImage(images[1], dst,
- x1, y2,
- x2, y2);
- DrawPixbuf(images[2], dst, x2, y2);
+ if (images[0])
+ DrawPixbuf(images[0], dst, 0, y2);
+ if (images[1]) {
+ TileImage(images[1], dst,
+ x1, y2,
+ x2, y2);
+ }
+ if (images[2])
+ DrawPixbuf(images[2], dst, x2, y2);
}
void NineBox::RenderTopCenterStrip(GdkPixbuf* dst, int x1, int x2) {
diff --git a/chrome/browser/gtk/nine_box.h b/chrome/browser/gtk/nine_box.h
index 3521a82..8a54406 100644
--- a/chrome/browser/gtk/nine_box.h
+++ b/chrome/browser/gtk/nine_box.h
@@ -11,6 +11,11 @@
// non-corner images can be tiled to make a larger image. It's used to
// use bitmaps for constructing image-based resizable widgets like buttons.
//
+// If you want just a vertical image that stretches in height but is fixed
+// in width, only pass in images for the left column (leave others NULL).
+// Similarly, for a horizontal image that stretches in width but is fixed in
+// height, only pass in images for the top row.
+//
// TODO(port): add support for caching server-side pixmaps of prerendered
// nineboxes.
class NineBox {