summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorerg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-29 18:21:33 +0000
committererg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-29 18:21:33 +0000
commitaa7dc4f275a8c4c0b27a4f581bbb1d51ef7f52ee (patch)
tree8474267434e92789ae7f526b0425a5961a05bede /chrome/browser/gtk
parent0df393b0dabb7f11cd37067113d91ae5b1b23f67 (diff)
downloadchromium_src-aa7dc4f275a8c4c0b27a4f581bbb1d51ef7f52ee.zip
chromium_src-aa7dc4f275a8c4c0b27a4f581bbb1d51ef7f52ee.tar.gz
chromium_src-aa7dc4f275a8c4c0b27a4f581bbb1d51ef7f52ee.tar.bz2
GTK: Drags from bookmark menus to the bookmark bar.
Review URL: http://codereview.chromium.org/147241 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19505 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r--chrome/browser/gtk/bookmark_bar_gtk.cc129
-rw-r--r--chrome/browser/gtk/bookmark_bar_gtk.h7
-rw-r--r--chrome/browser/gtk/bookmark_menu_controller_gtk.cc72
-rw-r--r--chrome/browser/gtk/bookmark_menu_controller_gtk.h17
-rw-r--r--chrome/browser/gtk/bookmark_utils_gtk.cc116
-rw-r--r--chrome/browser/gtk/bookmark_utils_gtk.h33
6 files changed, 244 insertions, 130 deletions
diff --git a/chrome/browser/gtk/bookmark_bar_gtk.cc b/chrome/browser/gtk/bookmark_bar_gtk.cc
index d9b7ae9..959586d 100644
--- a/chrome/browser/gtk/bookmark_bar_gtk.cc
+++ b/chrome/browser/gtk/bookmark_bar_gtk.cc
@@ -39,68 +39,12 @@ namespace {
// The height of the bar.
const int kBookmarkBarHeight = 33;
-// Maximum number of characters on a bookmark button.
-const size_t kMaxCharsOnAButton = 15;
-
-// Dictionary key used to store a BookmarkNode* on a GtkWidget.
-const char kBookmarkNode[] = "bookmark-node";
-
// Left-padding for the instructional text.
const int kInstructionsPadding = 6;
-// Color of the button text, taken from TextButtonView.
-const GdkColor kEnabledColor = GDK_COLOR_RGB(6, 45, 117);
-const GdkColor kDisabledColor = GDK_COLOR_RGB(161, 161, 146);
-// TextButtonView uses 255, 255, 255 with opacity of 200. We don't support
-// transparent text though, so just use a slightly lighter version of
-// kEnabledColor.
-const GdkColor kHighlightColor = GDK_COLOR_RGB(56, 95, 167);
-
// Color of the instructional text.
const GdkColor kInstructionsColor = GDK_COLOR_RGB(128, 128, 142);
-// Only used for the background of the drag widget.
-const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xe6, 0xed, 0xf4);
-
-// Recursively search for label among the children of |widget|.
-void SearchForLabel(GtkWidget* widget, gpointer data) {
- if (GTK_IS_LABEL(widget)) {
- *reinterpret_cast<GtkWidget**>(data) = widget;
- } else if (GTK_IS_CONTAINER(widget)) {
- gtk_container_foreach(GTK_CONTAINER(widget), SearchForLabel, data);
- }
-}
-
-// This function is a temporary hack to fix fonts on dark system themes.
-// NOTE: this makes assumptions about GtkButton internals. Also, it only works
-// if you call it after the last time you edit the button.
-// TODO(estade): remove this function.
-void SetButtonTextColors(GtkWidget* button) {
- GtkWidget* label;
- gtk_container_foreach(GTK_CONTAINER(button), SearchForLabel, &label);
- if (label) {
- gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &kEnabledColor);
- gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, &kEnabledColor);
- gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, &kHighlightColor);
- gtk_widget_modify_fg(label, GTK_STATE_INSENSITIVE, &kDisabledColor);
- }
-}
-
-std::string DoubleUnderscores(const std::string& text) {
- std::string ret;
- ret.reserve(text.length() * 2);
- for (size_t i = 0; i < text.length(); ++i) {
- if ('_' == text[i]) {
- ret.push_back('_');
- ret.push_back('_');
- } else {
- ret.push_back(text[i]);
- }
- }
-
- return ret;
-}
-
} // namespace
BookmarkBarGtk::BookmarkBarGtk(Profile* profile, Browser* browser,
@@ -214,7 +158,7 @@ void BookmarkBarGtk::Init(Profile* profile) {
gtk_button_set_image(GTK_BUTTON(other_bookmarks_button_),
gtk_image_new_from_pixbuf(folder_icon));
// Set the proper text colors.
- SetButtonTextColors(other_bookmarks_button_);
+ bookmark_utils::SetButtonTextColors(other_bookmarks_button_);
gtk_box_pack_start(GTK_BOX(bookmark_hbox_.get()), other_bookmarks_button_,
FALSE, FALSE, 0);
@@ -347,7 +291,7 @@ void BookmarkBarGtk::BookmarkNodeChanged(BookmarkModel* model,
GtkToolItem* item = gtk_toolbar_get_nth_item(
GTK_TOOLBAR(bookmark_toolbar_.get()), index);
GtkWidget* button = gtk_bin_get_child(GTK_BIN(item));
- ConfigureButtonForNode(node, button);
+ bookmark_utils::ConfigureButtonForNode(node, model, button);
}
void BookmarkBarGtk::BookmarkNodeFavIconLoaded(BookmarkModel* model,
@@ -416,33 +360,9 @@ void BookmarkBarGtk::AnimationEnded(const Animation* animation) {
gtk_widget_hide(bookmark_hbox_.get());
}
-void BookmarkBarGtk::ConfigureButtonForNode(const BookmarkNode* node,
- GtkWidget* button) {
- std::string tooltip = BuildTooltip(node);
- if (!tooltip.empty())
- gtk_widget_set_tooltip_text(button, tooltip.c_str());
-
- // TODO(erg): Consider a soft maximum instead of this hard 15.
- std::wstring title = node->GetTitle();
- // Don't treat underscores as mnemonics.
- // O, that we could just use gtk_button_set_use_underline()!
- // See http://bugzilla.gnome.org/show_bug.cgi?id=586330
- std::string text = DoubleUnderscores(WideToUTF8(title));
- text = text.substr(0, std::min(text.size(), kMaxCharsOnAButton));
- gtk_button_set_label(GTK_BUTTON(button), text.c_str());
-
- GdkPixbuf* pixbuf = bookmark_utils::GetPixbufForNode(node, model_);
- gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_pixbuf(pixbuf));
- g_object_unref(pixbuf);
-
- SetButtonTextColors(button);
- g_object_set_data(G_OBJECT(button), kBookmarkNode,
- reinterpret_cast<void*>(const_cast<BookmarkNode*>(node)));
-}
-
GtkWidget* BookmarkBarGtk::CreateBookmarkButton(const BookmarkNode* node) {
GtkWidget* button = gtk_chrome_button_new();
- ConfigureButtonForNode(node, button);
+ bookmark_utils::ConfigureButtonForNode(node, model_, button);
// The tool item is also a source for dragging
gtk_drag_source_set(button, GDK_BUTTON1_MASK,
@@ -496,12 +416,6 @@ void BookmarkBarGtk::ConnectFolderButtonEvents(GtkWidget* widget) {
G_CALLBACK(OnFolderButtonReleased), this);
}
-std::string BookmarkBarGtk::BuildTooltip(const BookmarkNode* node) {
- // TODO(erg): Actually build the tooltip. For now, we punt and just return
- // the URL.
- return node->GetURL().possibly_invalid_spec();
-}
-
const BookmarkNode* BookmarkBarGtk::GetNodeForToolButton(GtkWidget* widget) {
// First check to see if |button| is special cased.
if (widget == other_bookmarks_button_)
@@ -633,21 +547,7 @@ void BookmarkBarGtk::OnButtonDragBegin(GtkWidget* button,
bar->dragged_node_ = node;
DCHECK(bar->dragged_node_);
- // Build a windowed representation for our button.
- GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
- gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &kBackgroundColor);
- gtk_widget_realize(window);
-
- GtkWidget* frame = gtk_frame_new(NULL);
- gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
- gtk_container_add(GTK_CONTAINER(window), frame);
- gtk_widget_show(frame);
-
- GtkWidget* floating_button = gtk_chrome_button_new();
- bar->ConfigureButtonForNode(node, floating_button);
- gtk_container_add(GTK_CONTAINER(frame), floating_button);
- gtk_widget_show(floating_button);
-
+ GtkWidget* window = bookmark_utils::GetDragRepresentation(node, bar->model_);
gint x, y;
gtk_widget_get_pointer(button, &x, &y);
gtk_drag_set_icon_widget(drag_context, window, x, y);
@@ -678,9 +578,7 @@ void BookmarkBarGtk::OnButtonDragGet(GtkWidget* widget, GdkDragContext* context,
GtkSelectionData* selection_data,
guint target_type, guint time,
BookmarkBarGtk* bar) {
- const BookmarkNode* node =
- reinterpret_cast<const BookmarkNode*>(
- g_object_get_data(G_OBJECT(widget), kBookmarkNode));
+ const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(widget);
bookmark_utils::WriteBookmarkToSelection(node, selection_data, target_type,
bar->profile_);
}
@@ -744,11 +642,18 @@ gboolean BookmarkBarGtk::OnToolbarDragMotion(GtkToolbar* toolbar,
return FALSE;
}
- // TODO(estade): Improve support for drags from outside this particular
- // bookmark bar.
- if (!bar->toolbar_drop_item_ && bar->dragged_node_) {
- bar->toolbar_drop_item_ = bar->CreateBookmarkToolItem(bar->dragged_node_);
- g_object_ref_sink(GTK_OBJECT(bar->toolbar_drop_item_));
+ if (!bar->toolbar_drop_item_) {
+ if (bar->dragged_node_) {
+ bar->toolbar_drop_item_ = bar->CreateBookmarkToolItem(bar->dragged_node_);
+ g_object_ref_sink(GTK_OBJECT(bar->toolbar_drop_item_));
+ } else {
+ // Create a fake item the size of other_node().
+ //
+ // TODO(erg): Maybe somehow figure out the real size for the drop target?
+ bar->toolbar_drop_item_ =
+ bar->CreateBookmarkToolItem(bar->model_->other_node());
+ g_object_ref_sink(GTK_OBJECT(bar->toolbar_drop_item_));
+ }
}
if (bar->toolbar_drop_item_) {
diff --git a/chrome/browser/gtk/bookmark_bar_gtk.h b/chrome/browser/gtk/bookmark_bar_gtk.h
index be07088..d7f5eb8 100644
--- a/chrome/browser/gtk/bookmark_bar_gtk.h
+++ b/chrome/browser/gtk/bookmark_bar_gtk.h
@@ -72,11 +72,6 @@ class BookmarkBarGtk : public AnimationDelegate,
virtual void AnimationEnded(const Animation* animation);
private:
- // Helper function that sets visual properties of GtkButton |button| to the
- // contents of |node|.
- void ConfigureButtonForNode(const BookmarkNode* node,
- GtkWidget* button);
-
// Helper function which generates GtkToolItems for |bookmark_toolbar_|.
void CreateAllBookmarkButtons(const BookmarkNode* node);
@@ -127,8 +122,6 @@ class BookmarkBarGtk : public AnimationDelegate,
void ConnectFolderButtonEvents(GtkWidget* widget);
- std::string BuildTooltip(const BookmarkNode* node);
-
// Finds the BookmarkNode from the model associated with |button|.
const BookmarkNode* GetNodeForToolButton(GtkWidget* button);
diff --git a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc
index a0d905b..af9e97f 100644
--- a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc
+++ b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc
@@ -11,6 +11,8 @@
#include "base/gfx/gtk_util.h"
#include "base/string_util.h"
#include "chrome/browser/gtk/bookmark_context_menu.h"
+#include "chrome/browser/gtk/bookmark_utils_gtk.h"
+#include "chrome/browser/gtk/dnd_registry.h"
#include "chrome/browser/gtk/menu_gtk.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/page_navigator.h"
@@ -51,7 +53,8 @@ BookmarkMenuController::BookmarkMenuController(Browser* browser,
profile_(profile),
page_navigator_(navigator),
parent_window_(window),
- node_(node) {
+ node_(node),
+ ignore_button_release_(false) {
menu_.Own(gtk_menu_new());
BuildMenu(node, start_child_index, menu_.get());
gtk_widget_show_all(menu_.get());
@@ -103,6 +106,7 @@ void BookmarkMenuController::BuildMenu(const BookmarkNode* parent,
GtkWidget* menu_item = gtk_image_menu_item_new_with_label(
WideToUTF8(node->GetTitle()).c_str());
+ g_object_set_data(G_OBJECT(menu_item), "bookmark-node", AsVoid(node));
if (node->is_url()) {
SkBitmap icon = profile_->GetBookmarkModel()->GetFavIcon(node);
@@ -111,7 +115,6 @@ void BookmarkMenuController::BuildMenu(const BookmarkNode* parent,
GetBitmapNamed(IDR_DEFAULT_FAVICON);
}
SetImageMenuItem(menu_item, icon);
- g_object_set_data(G_OBJECT(menu_item), "bookmark-node", AsVoid(node));
g_signal_connect(G_OBJECT(menu_item), "activate",
G_CALLBACK(OnMenuItemActivated), this);
g_signal_connect(G_OBJECT(menu_item), "button-press-event",
@@ -130,6 +133,17 @@ void BookmarkMenuController::BuildMenu(const BookmarkNode* parent,
NOTREACHED();
}
+ gtk_drag_source_set(menu_item, GDK_BUTTON1_MASK,
+ NULL, 0, GDK_ACTION_MOVE);
+ dnd::SetSourceTargetListFromCodeMask(menu_item,
+ dnd::X_CHROME_BOOKMARK_ITEM);
+ g_signal_connect(G_OBJECT(menu_item), "drag-begin",
+ G_CALLBACK(&OnMenuItemDragBegin), this);
+ g_signal_connect(G_OBJECT(menu_item), "drag-end",
+ G_CALLBACK(&OnMenuItemDragEnd), this);
+ g_signal_connect(G_OBJECT(menu_item), "drag-data-get",
+ G_CALLBACK(&OnMenuItemDragGet), this);
+
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
node_to_menu_widget_map_[node] = menu_item;
}
@@ -146,6 +160,8 @@ gboolean BookmarkMenuController::OnButtonPressed(
GtkWidget* sender,
GdkEventButton* event,
BookmarkMenuController* controller) {
+ controller->ignore_button_release_ = false;
+
if (event->button == 3) {
// Show the right click menu and stop processing this button event.
const BookmarkNode* node = GetNodeFromMenuItem(sender);
@@ -168,9 +184,11 @@ gboolean BookmarkMenuController::OnButtonReleased(
GtkWidget* sender,
GdkEventButton* event,
BookmarkMenuController* controller) {
- // TODO(erg): The OnButtonPressed and OnButtonReleased handlers should have
- // the same guard code that prevents them from interfering with DnD as
- // BookmarkBarGtk's versions.
+ if (controller->ignore_button_release_) {
+ // Don't handle this message; it was a drag.
+ controller->ignore_button_release_ = false;
+ return FALSE;
+ }
// Releasing either button 1 or 2 should trigger the bookmark menu.
if (event->button == 1 || event->button == 2) {
@@ -191,3 +209,47 @@ void BookmarkMenuController::OnMenuItemActivated(
GtkMenuItem* menu_item, BookmarkMenuController* controller) {
controller->NavigateToMenuItem(GTK_WIDGET(menu_item), CURRENT_TAB);
}
+
+// static
+void BookmarkMenuController::OnMenuItemDragBegin(
+ GtkWidget* menu_item,
+ GdkDragContext* drag_context,
+ BookmarkMenuController* controller) {
+ // The parent menu item might be removed during the drag. Ref it so |button|
+ // won't get destroyed.
+ g_object_ref(menu_item->parent);
+
+ // Signal to any future OnButtonReleased calls that we're dragging instead of
+ // pressing.
+ controller->ignore_button_release_ = true;
+
+ const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(menu_item);
+ GtkWidget* window = bookmark_utils::GetDragRepresentation(node,
+ controller->model_);
+ gint x, y;
+ gtk_widget_get_pointer(menu_item, &x, &y);
+ gtk_drag_set_icon_widget(drag_context, window, x, y);
+
+ // Hide our node.
+ gtk_widget_hide(menu_item);
+}
+
+// static
+void BookmarkMenuController::OnMenuItemDragEnd(
+ GtkWidget* menu_item,
+ GdkDragContext* drag_context,
+ BookmarkMenuController* controller) {
+ gtk_widget_show(menu_item);
+ g_object_unref(menu_item->parent);
+}
+
+// static
+void BookmarkMenuController::OnMenuItemDragGet(
+ GtkWidget* widget, GdkDragContext* context,
+ GtkSelectionData* selection_data,
+ guint target_type, guint time,
+ BookmarkMenuController* controller) {
+ const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(widget);
+ bookmark_utils::WriteBookmarkToSelection(node, selection_data, target_type,
+ controller->profile_);
+}
diff --git a/chrome/browser/gtk/bookmark_menu_controller_gtk.h b/chrome/browser/gtk/bookmark_menu_controller_gtk.h
index 07993c4..d24dcf2 100644
--- a/chrome/browser/gtk/bookmark_menu_controller_gtk.h
+++ b/chrome/browser/gtk/bookmark_menu_controller_gtk.h
@@ -69,6 +69,19 @@ class BookmarkMenuController : public BaseBookmarkModelObserver {
static void OnMenuItemActivated(GtkMenuItem* menuitem,
BookmarkMenuController* controller);
+ // The individual GtkMenuItems in the BookmarkMenu are all drag sources.
+ static void OnMenuItemDragBegin(GtkWidget* menu_item,
+ GdkDragContext* drag_context,
+ BookmarkMenuController* bar);
+ static void OnMenuItemDragEnd(GtkWidget* menu_item,
+ GdkDragContext* drag_context,
+ BookmarkMenuController* controller);
+ static void OnMenuItemDragGet(
+ GtkWidget* widget, GdkDragContext* context,
+ GtkSelectionData* selection_data,
+ guint target_type, guint time,
+ BookmarkMenuController* controller);
+
Browser* browser_;
Profile* profile_;
PageNavigator* page_navigator_;
@@ -88,6 +101,10 @@ class BookmarkMenuController : public BaseBookmarkModelObserver {
// - The menu items have context menus.
OwnedWidgetGtk menu_;
+ // Whether we should ignore the next button release event (because we were
+ // dragging).
+ bool ignore_button_release_;
+
// Mapping from node to GtkMenuItem menu id. This only contains entries for
// nodes of type URL.
std::map<const BookmarkNode*, GtkWidget*> node_to_menu_widget_map_;
diff --git a/chrome/browser/gtk/bookmark_utils_gtk.cc b/chrome/browser/gtk/bookmark_utils_gtk.cc
index 9e49716..7486f1b 100644
--- a/chrome/browser/gtk/bookmark_utils_gtk.cc
+++ b/chrome/browser/gtk/bookmark_utils_gtk.cc
@@ -7,20 +7,70 @@
#include "app/resource_bundle.h"
#include "base/gfx/gtk_util.h"
#include "base/pickle.h"
+#include "base/string_util.h"
#include "chrome/browser/bookmarks/bookmark_drag_data.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/gtk/dnd_registry.h"
+#include "chrome/browser/gtk/gtk_chrome_button.h"
#include "chrome/browser/profile.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
+namespace {
+
// Used in gtk_selection_data_set(). (I assume from this parameter that gtk has
// to some really exotic hardware...)
const int kBitsInAByte = 8;
+// Maximum number of characters on a bookmark button.
+const size_t kMaxCharsOnAButton = 15;
+
+// Only used for the background of the drag widget.
+const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xe6, 0xed, 0xf4);
+
+// Color of the button text, taken from TextButtonView.
+const GdkColor kEnabledColor = GDK_COLOR_RGB(6, 45, 117);
+const GdkColor kDisabledColor = GDK_COLOR_RGB(161, 161, 146);
+// TextButtonView uses 255, 255, 255 with opacity of 200. We don't support
+// transparent text though, so just use a slightly lighter version of
+// kEnabledColor.
+const GdkColor kHighlightColor = GDK_COLOR_RGB(56, 95, 167);
+
+std::string DoubleUnderscores(const std::string& text) {
+ std::string ret;
+ ret.reserve(text.length() * 2);
+ for (size_t i = 0; i < text.length(); ++i) {
+ if ('_' == text[i]) {
+ ret.push_back('_');
+ ret.push_back('_');
+ } else {
+ ret.push_back(text[i]);
+ }
+ }
+
+ return ret;
+}
+
+// Recursively search for label among the children of |widget|.
+void SearchForLabel(GtkWidget* widget, gpointer data) {
+ if (GTK_IS_LABEL(widget)) {
+ *reinterpret_cast<GtkWidget**>(data) = widget;
+ } else if (GTK_IS_CONTAINER(widget)) {
+ gtk_container_foreach(GTK_CONTAINER(widget), SearchForLabel, data);
+ }
+}
+
+void* AsVoid(const BookmarkNode* node) {
+ return const_cast<BookmarkNode*>(node);
+}
+
+} // namespace
+
namespace bookmark_utils {
+const char kBookmarkNode[] = "bookmark-node";
+
GdkPixbuf* GetFolderIcon() {
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
static GdkPixbuf* default_folder_icon = rb.GetPixbufNamed(
@@ -53,6 +103,72 @@ GdkPixbuf* GetPixbufForNode(const BookmarkNode* node, BookmarkModel* model) {
return pixbuf;
}
+GtkWidget* GetDragRepresentation(const BookmarkNode* node,
+ BookmarkModel* model) {
+ // Build a windowed representation for our button.
+ GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP);
+ gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &kBackgroundColor);
+ gtk_widget_realize(window);
+
+ GtkWidget* frame = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
+ gtk_container_add(GTK_CONTAINER(window), frame);
+ gtk_widget_show(frame);
+
+ GtkWidget* floating_button = gtk_chrome_button_new();
+ bookmark_utils::ConfigureButtonForNode(node, model, floating_button);
+ gtk_container_add(GTK_CONTAINER(frame), floating_button);
+ gtk_widget_show(floating_button);
+
+ return window;
+}
+
+void ConfigureButtonForNode(const BookmarkNode* node, BookmarkModel* model,
+ GtkWidget* button) {
+ std::string tooltip = BuildTooltipFor(node);
+ if (!tooltip.empty())
+ gtk_widget_set_tooltip_text(button, tooltip.c_str());
+
+ // TODO(erg): Consider a soft maximum instead of this hard 15.
+ std::wstring title = node->GetTitle();
+ // Don't treat underscores as mnemonics.
+ // O, that we could just use gtk_button_set_use_underline()!
+ // See http://bugzilla.gnome.org/show_bug.cgi?id=586330
+ std::string text = DoubleUnderscores(WideToUTF8(title));
+ text = text.substr(0, std::min(text.size(), kMaxCharsOnAButton));
+ gtk_button_set_label(GTK_BUTTON(button), text.c_str());
+
+ GdkPixbuf* pixbuf = bookmark_utils::GetPixbufForNode(node, model);
+ gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_pixbuf(pixbuf));
+ g_object_unref(pixbuf);
+
+ SetButtonTextColors(button);
+ g_object_set_data(G_OBJECT(button), bookmark_utils::kBookmarkNode,
+ AsVoid(node));
+}
+
+std::string BuildTooltipFor(const BookmarkNode* node) {
+ // TODO(erg): Actually build the tooltip. For now, we punt and just return
+ // the URL.
+ return node->GetURL().possibly_invalid_spec();
+}
+
+const BookmarkNode* BookmarkNodeForWidget(GtkWidget* widget) {
+ return reinterpret_cast<const BookmarkNode*>(
+ g_object_get_data(G_OBJECT(widget), bookmark_utils::kBookmarkNode));
+}
+
+void SetButtonTextColors(GtkWidget* button) {
+ GtkWidget* label;
+ gtk_container_foreach(GTK_CONTAINER(button), SearchForLabel, &label);
+ if (label) {
+ gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &kEnabledColor);
+ gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, &kEnabledColor);
+ gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, &kHighlightColor);
+ gtk_widget_modify_fg(label, GTK_STATE_INSENSITIVE, &kDisabledColor);
+ }
+}
+
// DnD-related -----------------------------------------------------------------
void WriteBookmarkToSelection(const BookmarkNode* node,
diff --git a/chrome/browser/gtk/bookmark_utils_gtk.h b/chrome/browser/gtk/bookmark_utils_gtk.h
index 32fe615..79083f0 100644
--- a/chrome/browser/gtk/bookmark_utils_gtk.h
+++ b/chrome/browser/gtk/bookmark_utils_gtk.h
@@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_GTK_BOOKMARK_UTILS_GTK_
-#define CHROME_BROWSER_GTK_BOOKMARK_UTILS_GTK_
+#ifndef CHROME_BROWSER_GTK_BOOKMARK_UTILS_GTK_H_
+#define CHROME_BROWSER_GTK_BOOKMARK_UTILS_GTK_H_
#include <gtk/gtk.h>
#include <vector>
+#include <string>
class BookmarkModel;
class BookmarkNode;
@@ -14,9 +15,7 @@ class Profile;
namespace bookmark_utils {
-extern const char kInternalURIType[];
-extern const GtkTargetEntry kTargetTable[];
-extern const int kTargetTableSize;
+extern const char kBookmarkNode[];
// These functions do not add a ref to the returned pixbuf, and it should not be
// unreffed.
@@ -27,6 +26,28 @@ GdkPixbuf* GetDefaultFavicon();
// to the returned pixbuf, so it requires a matching call to g_object_unref().
GdkPixbuf* GetPixbufForNode(const BookmarkNode* node, BookmarkModel* model);
+// Returns a GtkWindow with a visual hierarchy for passing to
+// gtk_drag_set_icon_widget().
+GtkWidget* GetDragRepresentation(const BookmarkNode* node,
+ BookmarkModel* model);
+
+// Helper function that sets visual properties of GtkButton |button| to the
+// contents of |node|.
+void ConfigureButtonForNode(const BookmarkNode* node, BookmarkModel* model,
+ GtkWidget* button);
+
+// Returns the tooltip.
+std::string BuildTooltipFor(const BookmarkNode* node);
+
+// Returns the "bookmark-node" property of |widget| casted to the correct type.
+const BookmarkNode* BookmarkNodeForWidget(GtkWidget* widget);
+
+// This function is a temporary hack to fix fonts on dark system themes.
+// NOTE: this makes assumptions about GtkButton internals. Also, it only works
+// if you call it after the last time you edit the button.
+// TODO(estade): remove this function.
+void SetButtonTextColors(GtkWidget* button);
+
// Drag and drop. --------------------------------------------------------------
// Pickle a node into a GtkSelection.
@@ -53,4 +74,4 @@ std::vector<const BookmarkNode*> GetNodesFromSelection(
} // namespace bookmark_utils
-#endif // CHROME_BROWSER_GTK_BOOKMARK_UTILS_GTK_
+#endif // CHROME_BROWSER_GTK_BOOKMARK_UTILS_GTK_H_