summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.cc67
-rw-r--r--chrome/browser/gtk/download_shelf_gtk.h4
-rw-r--r--chrome/browser/gtk/link_button_gtk.cc65
-rw-r--r--chrome/browser/gtk/link_button_gtk.h37
-rw-r--r--chrome/chrome.gyp2
5 files changed, 115 insertions, 60 deletions
diff --git a/chrome/browser/gtk/download_shelf_gtk.cc b/chrome/browser/gtk/download_shelf_gtk.cc
index 9ba9f4a..3e46436 100644
--- a/chrome/browser/gtk/download_shelf_gtk.cc
+++ b/chrome/browser/gtk/download_shelf_gtk.cc
@@ -8,6 +8,7 @@
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/download_item_gtk.h"
+#include "chrome/browser/gtk/link_button_gtk.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/resource_bundle.h"
@@ -39,55 +40,6 @@ static GdkColor kBackgroundColor = GDK_COLOR_RGB(230, 237, 244);
// Border color (the top pixel of the shelf).
static GdkColor kBorderColor = GDK_COLOR_RGB(214, 214, 214);
-const char* kLinkMarkup =
- "<u><span color=\"blue\">%s</span></u>";
-
-gboolean OnLinkExpose(GtkWidget* widget, GdkEventExpose* e, void*) {
- // Draw the link inside the button.
- gtk_container_propagate_expose(GTK_CONTAINER(widget),
- gtk_bin_get_child(GTK_BIN(widget)),
- e);
- // Don't let the button draw itself, ever.
- return TRUE;
-}
-
-// |button| and |box| are out parameters. The caller of this function will want
-// to connect to the click event on |button|. |box| will be set to the highest
-// level widget.
-// TODO(estade): either figure out a way to use GtkLinkButton, or move this
-// to base/gfx/gtk_util.cc
-void MakeLinkButton(const char* text, GdkColor* background_color,
- GtkWidget** button, GtkWidget** box) {
- // We put a label in a button so we can connect to the click event. We put the
- // button in an event box so we can attach a cursor to it. We don't let the
- // button draw itself; catch all expose events to the button and pass them
- // through to the label. We stick the event box in an hbox, and to the left of
- // that pack the download icon.
- // TODO(estade): the link should turn red during the user's click.
-
- GtkWidget* label = gtk_label_new(NULL);
- char* markup = g_markup_printf_escaped(kLinkMarkup, text);
- gtk_label_set_markup(GTK_LABEL(label), markup);
- g_free(markup);
-
- *button = gtk_button_new();
- gtk_widget_set_app_paintable(GTK_WIDGET(*button), TRUE);
- g_signal_connect(G_OBJECT(*button), "expose-event",
- G_CALLBACK(OnLinkExpose), NULL);
- gtk_container_add(GTK_CONTAINER(*button), label);
-
- *box = gtk_event_box_new();
- gtk_widget_modify_bg(*box, GTK_STATE_NORMAL, background_color);
- gtk_container_add(GTK_CONTAINER(*box), *button);
-}
-
-// This should be called only after |link_box| has been realized.
-void AttachCursorToLinkButton(GtkWidget* link_box) {
- GdkCursor* cursor = gdk_cursor_new(GDK_HAND2);
- gdk_window_set_cursor(link_box->window, cursor);
- gdk_cursor_unref(cursor);
-}
-
} // namespace
// static
@@ -131,18 +83,14 @@ DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents)
// Create and pack the close button.
close_button_.reset(CustomDrawButton::AddBarCloseButton(hbox_));
- g_signal_connect(G_OBJECT(close_button_->widget()), "clicked",
+ g_signal_connect(close_button_->widget(), "clicked",
G_CALLBACK(OnButtonClick), this);
- // Create and pack the "Show all downloads..." link.
- // TODO(estade): there are some pixels above and below the link that
- // can be clicked. I tried to fix this with a vbox, but no dice.
- GtkWidget* link_box;
- GtkWidget* link_button;
+ // Create the "Show all downloads..." link and connect to the click event.
std::string link_text =
WideToUTF8(l10n_util::GetString(IDS_SHOW_ALL_DOWNLOADS));
- MakeLinkButton(link_text.c_str(), &kBackgroundColor, &link_button, &link_box);
- g_signal_connect(G_OBJECT(link_button), "clicked",
+ link_button_.reset(new LinkButtonGtk(link_text.c_str()));
+ g_signal_connect(link_button_->widget(), "clicked",
G_CALLBACK(OnButtonClick), this);
// Make the download arrow icon.
@@ -154,15 +102,14 @@ DownloadShelfGtk::DownloadShelfGtk(TabContents* tab_contents)
// Pack the link and the icon in an hbox.
link_hbox_ = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(link_hbox_), download_image, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(link_hbox_), link_box, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(link_hbox_), link_button_->widget(),
+ FALSE, FALSE, 0);
gtk_box_pack_end(GTK_BOX(hbox_), link_hbox_, FALSE, FALSE, 0);
// Stick ourselves at the bottom of the parent tab contents.
GtkWidget* parent_contents = tab_contents->GetNativeView();
gtk_box_pack_end(GTK_BOX(parent_contents), shelf_, FALSE, FALSE, 0);
Show();
-
- AttachCursorToLinkButton(link_box);
}
DownloadShelfGtk::~DownloadShelfGtk() {
diff --git a/chrome/browser/gtk/download_shelf_gtk.h b/chrome/browser/gtk/download_shelf_gtk.h
index 89f2fc9..78297d1 100644
--- a/chrome/browser/gtk/download_shelf_gtk.h
+++ b/chrome/browser/gtk/download_shelf_gtk.h
@@ -15,6 +15,7 @@
class BaseDownloadItemModel;
class CustomDrawButton;
class DownloadItemGtk;
+class LinkButtonGtk;
class DownloadShelfGtk : public DownloadShelf {
public:
@@ -46,6 +47,9 @@ class DownloadShelfGtk : public DownloadShelf {
// distinction of being the leftmost non-download item widget on the shelf.
GtkWidget* link_hbox_;
+ // The clickable "Show all downloads..." link text.
+ scoped_ptr<LinkButtonGtk> link_button_;
+
// The 'x' that the user can press to hide the download shelf.
scoped_ptr<CustomDrawButton> close_button_;
diff --git a/chrome/browser/gtk/link_button_gtk.cc b/chrome/browser/gtk/link_button_gtk.cc
new file mode 100644
index 0000000..4b1d010
--- /dev/null
+++ b/chrome/browser/gtk/link_button_gtk.cc
@@ -0,0 +1,65 @@
+// 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/link_button_gtk.h"
+
+static const char* kLinkMarkup = "<u><span color=\"blue\">%s</span></u>";
+
+LinkButtonGtk::LinkButtonGtk(const char* text)
+ : hand_cursor_(gdk_cursor_new(GDK_HAND2)) {
+ // We put a label in a button so we can connect to the click event. We don't
+ // let the button draw itself; catch all expose events to the button and pass
+ // them through to the label.
+ // TODO(estade): the link should turn red during the user's click.
+ GtkWidget* label = gtk_label_new(NULL);
+ char* markup = g_markup_printf_escaped(kLinkMarkup, text);
+ gtk_label_set_markup(GTK_LABEL(label), markup);
+ g_free(markup);
+
+ widget_.Own(gtk_button_new());
+ gtk_widget_set_app_paintable(widget_.get(), TRUE);
+ g_signal_connect(widget_.get(), "expose-event",
+ G_CALLBACK(OnExpose), NULL);
+ // We connect to these signals so we can set the cursor appropriately. We
+ // could give the link button its own GdkWindow (e.g. by placing it in a
+ // GtkEventBox), but that would wreak havok with painting of the parent
+ // widget. We can't use the enter- and leave- notify events as they operate
+ // on the widget's GdkWindow, and |label| nor |button| has its own GdkWindow.
+ g_signal_connect(widget_.get(), "enter",
+ G_CALLBACK(OnEnter), this);
+ g_signal_connect(widget_.get(), "leave",
+ G_CALLBACK(OnLeave), this);
+ gtk_container_add(GTK_CONTAINER(widget_.get()), label);
+}
+
+LinkButtonGtk::~LinkButtonGtk() {
+ gdk_cursor_unref(hand_cursor_);
+ widget_.Destroy();
+}
+
+// static
+gboolean LinkButtonGtk::OnEnter(GtkWidget* widget,
+ LinkButtonGtk* link_button) {
+ gdk_window_set_cursor(widget->window, link_button->hand_cursor_);
+ return FALSE;
+}
+
+// static
+gboolean LinkButtonGtk::OnLeave(GtkWidget* widget,
+ LinkButtonGtk* link_button) {
+ gdk_window_set_cursor(widget->window, NULL);
+ return FALSE;
+}
+
+// static
+gboolean LinkButtonGtk::OnExpose(GtkWidget* widget,
+ GdkEventExpose* event,
+ gpointer user_data) {
+ // Draw the link inside the button.
+ gtk_container_propagate_expose(GTK_CONTAINER(widget),
+ gtk_bin_get_child(GTK_BIN(widget)),
+ event);
+ // Don't let the button draw itself, ever.
+ return TRUE;
+}
diff --git a/chrome/browser/gtk/link_button_gtk.h b/chrome/browser/gtk/link_button_gtk.h
new file mode 100644
index 0000000..2dfce7d
--- /dev/null
+++ b/chrome/browser/gtk/link_button_gtk.h
@@ -0,0 +1,37 @@
+// 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 <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#include "chrome/common/owned_widget_gtk.h"
+
+// Creates a link button that shows |text| in blue and underlined. The cursor
+// changes to a hand when over the link.
+// TODO(estade): the link should turn red during the user's click.
+class LinkButtonGtk {
+ public:
+ explicit LinkButtonGtk(const char* text);
+ virtual ~LinkButtonGtk();
+
+ GtkWidget* widget() { return widget_.get(); }
+
+ private:
+ // Called when the pointer enters or leaves the button.
+ static gboolean OnEnter(GtkWidget* widget, LinkButtonGtk* link_button);
+ static gboolean OnLeave(GtkWidget* widget, LinkButtonGtk* link_button);
+
+ // Called when the pointer moves over the link button's gdk window.
+ static gboolean OnMotionNotify(GtkWidget* widget,
+ GdkEventMotion* event,
+ LinkButtonGtk* link_button);
+
+ // Called when the widget is exposed.
+ static gboolean OnExpose(GtkWidget* widget,
+ GdkEventExpose* event,
+ gpointer user_data);
+
+ OwnedWidgetGtk widget_;
+ GdkCursor* hand_cursor_;
+};
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index b38c506..cc402c5 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -725,6 +725,8 @@
'browser/gtk/infobar_container_gtk.h',
'browser/gtk/find_bar_gtk.cc',
'browser/gtk/find_bar_gtk.h',
+ 'browser/gtk/link_button_gtk.cc',
+ 'browser/gtk/link_button_gtk.cc',
'browser/gtk/location_bar_view_gtk.cc',
'browser/gtk/location_bar_view_gtk.h',
'browser/gtk/menu_gtk.cc',