diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-30 23:35:44 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-30 23:35:44 +0000 |
commit | 36622b18a61d8896fa8417ee17863469e6aea427 (patch) | |
tree | 6547736dc86d92a561213ee4236754b68396084f | |
parent | d38f83f98ff29ec940f0bc978a925fa7828fad67 (diff) | |
download | chromium_src-36622b18a61d8896fa8417ee17863469e6aea427.zip chromium_src-36622b18a61d8896fa8417ee17863469e6aea427.tar.gz chromium_src-36622b18a61d8896fa8417ee17863469e6aea427.tar.bz2 |
GTK: unify the bookmark dragging icon generation code into bookmark utils.
this also has the effect of standardizing the appearance of boomkark drags. On compositing window managers, the drag widget will have no background.
BUG=42147
TEST=manual
Review URL: http://codereview.chromium.org/1780016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46153 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/bookmark_bar_gtk.cc | 26 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_bar_gtk.h | 8 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_menu_controller_gtk.cc | 8 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_menu_controller_gtk.h | 3 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_utils_gtk.cc | 217 | ||||
-rw-r--r-- | chrome/browser/gtk/bookmark_utils_gtk.h | 10 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_util.cc | 9 | ||||
-rw-r--r-- | chrome/browser/gtk/gtk_util.h | 3 | ||||
-rw-r--r-- | chrome/browser/gtk/location_bar_view_gtk.cc | 60 | ||||
-rw-r--r-- | chrome/browser/gtk/location_bar_view_gtk.h | 4 | ||||
-rw-r--r-- | gfx/point.h | 12 | ||||
-rw-r--r-- | gfx/rect.cc | 13 | ||||
-rw-r--r-- | gfx/rect.h | 1 |
13 files changed, 247 insertions, 127 deletions
diff --git a/chrome/browser/gtk/bookmark_bar_gtk.cc b/chrome/browser/gtk/bookmark_bar_gtk.cc index 7181ed6..de3008c 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.cc +++ b/chrome/browser/gtk/bookmark_bar_gtk.cc @@ -132,6 +132,7 @@ BookmarkBarGtk::BookmarkBarGtk(BrowserWindowGtk* window, instructions_(NULL), sync_service_(NULL), dragged_node_(NULL), + drag_icon_(NULL), toolbar_drop_item_(NULL), theme_provider_(GtkThemeProvider::GetFrom(profile)), show_instructions_(true), @@ -960,6 +961,8 @@ void BookmarkBarGtk::PopupMenuForNode(GtkWidget* sender, gboolean BookmarkBarGtk::OnButtonPressed(GtkWidget* sender, GdkEventButton* event) { + last_pressed_coordinates_ = gfx::Point(event->x, event->y); + if (event->button == 3 && GTK_WIDGET_VISIBLE(bookmark_hbox_)) { const BookmarkNode* node = GetNodeForToolButton(sender); DCHECK(node); @@ -1006,11 +1009,20 @@ void BookmarkBarGtk::OnButtonDragBegin(GtkWidget* button, dragged_node_ = node; DCHECK(dragged_node_); - GtkWidget* window = bookmark_utils::GetDragRepresentation( + drag_icon_ = bookmark_utils::GetDragRepresentationForNode( node, model_, theme_provider_); - gint x, y; - gtk_widget_get_pointer(button, &x, &y); - gtk_drag_set_icon_widget(drag_context, window, x, y); + + // We have to jump through some hoops to get the drag icon to line up because + // it is a different size than the button. + GtkRequisition req; + gtk_widget_size_request(drag_icon_, &req); + gfx::Rect button_rect = gtk_util::WidgetBounds(button); + gfx::Point drag_icon_relative = + gfx::Rect(req.width, req.height).CenterPoint().Add( + (last_pressed_coordinates_.Subtract(button_rect.CenterPoint()))); + gtk_drag_set_icon_widget(drag_context, drag_icon_, + drag_icon_relative.x(), + drag_icon_relative.y()); // Hide our node, but reserve space for it on the toolbar. int index = gtk_toolbar_get_item_index(GTK_TOOLBAR(bookmark_toolbar_.get()), @@ -1032,11 +1044,17 @@ void BookmarkBarGtk::OnButtonDragEnd(GtkWidget* button, if (toolbar_drop_item_) { g_object_unref(toolbar_drop_item_); toolbar_drop_item_ = NULL; + gtk_toolbar_set_drop_highlight_item(GTK_TOOLBAR(bookmark_toolbar_.get()), + NULL, 0); } DCHECK(dragged_node_); dragged_node_ = NULL; + DCHECK(drag_icon_); + gtk_widget_destroy(drag_icon_); + drag_icon_ = NULL; + g_object_unref(button->parent); } diff --git a/chrome/browser/gtk/bookmark_bar_gtk.h b/chrome/browser/gtk/bookmark_bar_gtk.h index 405ca15..c6e7ae0 100644 --- a/chrome/browser/gtk/bookmark_bar_gtk.h +++ b/chrome/browser/gtk/bookmark_bar_gtk.h @@ -22,6 +22,7 @@ #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/owned_widget_gtk.h" +#include "gfx/point.h" #include "gfx/size.h" #include "testing/gtest/include/gtest/gtest_prod.h" @@ -319,6 +320,9 @@ class BookmarkBarGtk : public AnimationDelegate, // dragging. const BookmarkNode* dragged_node_; + // The visual representation that follows the cursor during drags. + GtkWidget* drag_icon_; + // We create a GtkToolbarItem from |dragged_node_| ;or display. GtkToolItem* toolbar_drop_item_; @@ -358,6 +362,10 @@ class BookmarkBarGtk : public AnimationDelegate, // of this so we don't force too many paints. gfx::Size last_tab_contents_size_; + // The last coordinates recorded by OnButtonPress; used to line up the + // drag icon during bookmark drags. + gfx::Point last_pressed_coordinates_; + // The currently throbbing widget. This is NULL if no widget is throbbing. // We track it because we only want to allow one widget to throb at a time. GtkWidget* throbbing_widget_; diff --git a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc index 485b440..491c885 100644 --- a/chrome/browser/gtk/bookmark_menu_controller_gtk.cc +++ b/chrome/browser/gtk/bookmark_menu_controller_gtk.cc @@ -76,6 +76,7 @@ BookmarkMenuController::BookmarkMenuController(Browser* browser, parent_window_(window), model_(profile->GetBookmarkModel()), node_(node), + drag_icon_(NULL), ignore_button_release_(false), triggering_widget_(NULL) { menu_ = gtk_menu_new(); @@ -321,11 +322,11 @@ void BookmarkMenuController::OnMenuItemDragBegin(GtkWidget* menu_item, ignore_button_release_ = true; const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(menu_item); - GtkWidget* window = bookmark_utils::GetDragRepresentation( + drag_icon_ = bookmark_utils::GetDragRepresentationForNode( node, model_, GtkThemeProvider::GetFrom(profile_)); gint x, y; gtk_widget_get_pointer(menu_item, &x, &y); - gtk_drag_set_icon_widget(drag_context, window, x, y); + gtk_drag_set_icon_widget(drag_context, drag_icon_, x, y); // Hide our node. gtk_widget_hide(menu_item); @@ -335,6 +336,9 @@ void BookmarkMenuController::OnMenuItemDragEnd(GtkWidget* menu_item, GdkDragContext* drag_context) { gtk_widget_show(menu_item); g_object_unref(menu_item->parent); + + gtk_widget_destroy(drag_icon_); + drag_icon_ = NULL; } void BookmarkMenuController::OnMenuItemDragGet( diff --git a/chrome/browser/gtk/bookmark_menu_controller_gtk.h b/chrome/browser/gtk/bookmark_menu_controller_gtk.h index 843f556..c1c4517 100644 --- a/chrome/browser/gtk/bookmark_menu_controller_gtk.h +++ b/chrome/browser/gtk/bookmark_menu_controller_gtk.h @@ -115,6 +115,9 @@ class BookmarkMenuController : public BaseBookmarkModelObserver, // - The menu items have context menus. GtkWidget* menu_; + // The visual representation that follows the cursor during drags. + GtkWidget* drag_icon_; + // Whether we should ignore the next button release event (because we were // dragging). bool ignore_button_release_; diff --git a/chrome/browser/gtk/bookmark_utils_gtk.cc b/chrome/browser/gtk/bookmark_utils_gtk.cc index 0ea4b82..9c9c235 100644 --- a/chrome/browser/gtk/bookmark_utils_gtk.cc +++ b/chrome/browser/gtk/bookmark_utils_gtk.cc @@ -16,10 +16,15 @@ #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/gtk_util.h" #include "chrome/browser/profile.h" +#include "gfx/canvas_paint.h" +#include "gfx/font.h" #include "gfx/gtk_util.h" namespace { +// Spacing between the favicon and the text. +const int kBarButtonPadding = 4; + // Used in gtk_selection_data_set(). (I assume from this parameter that gtk has // to some really exotic hardware...) const int kBitsInAByte = 8; @@ -47,15 +52,115 @@ void* AsVoid(const BookmarkNode* node) { return const_cast<BookmarkNode*>(node); } +// Creates the widget hierarchy for a bookmark button. +void PackButton(GdkPixbuf* pixbuf, const std::wstring& title, bool ellipsize, + GtkThemeProvider* provider, GtkWidget* button) { + GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(button)); + if (former_child) + gtk_container_remove(GTK_CONTAINER(button), former_child); + + // We pack the button manually (rather than using gtk_button_set_*) so that + // we can have finer control over its label. + GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); + + GtkWidget* box = gtk_hbox_new(FALSE, kBarButtonPadding); + gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0); + + std::string label_string = WideToUTF8(title); + if (!label_string.empty()) { + GtkWidget* label = gtk_label_new(label_string.c_str()); + // Until we switch to vector graphics, force the font size. + gtk_util::ForceFontSizePixels(label, 13.4); // 13.4px == 10pt @ 96dpi + + // Ellipsize long bookmark names. + if (ellipsize) { + gtk_label_set_max_width_chars(GTK_LABEL(label), kMaxCharsOnAButton); + gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); + } + + gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); + bookmark_utils::SetButtonTextColors(label, provider); + } + + GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); + // If we are not showing the label, don't set any padding, so that the icon + // will just be centered. + if (label_string.c_str()) { + gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), + kButtonPaddingTop, kButtonPaddingBottom, + kButtonPaddingLeft, kButtonPaddingRight); + } + gtk_container_add(GTK_CONTAINER(alignment), box); + gtk_container_add(GTK_CONTAINER(button), alignment); + + gtk_widget_show_all(alignment); +} + +const int kDragRepresentationWidth = 140; + +struct DragRepresentationData { + public: + GdkPixbuf* favicon; + std::wstring text; + SkColor text_color; + + DragRepresentationData(GdkPixbuf* favicon, + const std::wstring& text, + SkColor text_color) + : favicon(favicon), + text(text), + text_color(text_color) { + g_object_ref(favicon); + } + + ~DragRepresentationData() { + g_object_unref(favicon); + } + + private: + DISALLOW_COPY_AND_ASSIGN(DragRepresentationData); +}; + +gboolean OnDragIconExpose(GtkWidget* sender, + GdkEventExpose* event, + DragRepresentationData* data) { + // Clear the background. + cairo_t* cr = gdk_cairo_create(event->window); + gdk_cairo_rectangle(cr, &event->area); + cairo_clip(cr); + cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); + cairo_paint(cr); + + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + gdk_cairo_set_source_pixbuf(cr, data->favicon, 0, 0); + cairo_paint(cr); + cairo_destroy(cr); + + // Paint the title text. + gfx::CanvasPaint canvas(event, false); + int text_x = gdk_pixbuf_get_width(data->favicon) + kBarButtonPadding; + int text_width = sender->allocation.width - text_x; + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + const gfx::Font& base_font = rb.GetFont(ResourceBundle::BaseFont); + canvas.DrawStringInt(data->text, + base_font, data->text_color, + text_x, 0, text_width, sender->allocation.height); + + return TRUE; +} + +void OnDragIconDestroy(GtkWidget* drag_icon, + DragRepresentationData* data) { + g_object_unref(drag_icon); + delete data; +} + } // namespace namespace bookmark_utils { const char kBookmarkNode[] = "bookmark-node"; -// Spacing between the buttons on the bar. -const int kBarButtonPadding = 4; - GdkPixbuf* GetPixbufForNode(const BookmarkNode* node, BookmarkModel* model, bool native) { GdkPixbuf* pixbuf; @@ -75,83 +180,69 @@ GdkPixbuf* GetPixbufForNode(const BookmarkNode* node, BookmarkModel* model, return pixbuf; } -GtkWidget* GetDragRepresentation(const BookmarkNode* node, - BookmarkModel* model, +GtkWidget* GetDragRepresentation(GdkPixbuf* pixbuf, + const std::wstring& title, GtkThemeProvider* provider) { - // Build a windowed representation for our button. GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); - if (!provider->UseGtkTheme()) { - // TODO(erg): Theme wise, which color should I be picking here? - // COLOR_BUTTON_BACKGROUND doesn't match the default theme! - 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); + if (gtk_util::IsScreenComposited() && + gtk_util::AddWindowAlphaChannel(window)) { + DragRepresentationData* data = new DragRepresentationData( + pixbuf, title, + provider->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT)); + g_signal_connect(window, "expose-event", G_CALLBACK(OnDragIconExpose), + data); + g_object_ref(window); + g_signal_connect(window, "destroy", G_CALLBACK(OnDragIconDestroy), data); + + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + const gfx::Font& base_font = rb.GetFont(ResourceBundle::BaseFont); + gtk_widget_set_size_request(window, kDragRepresentationWidth, + base_font.height()); + } else { + if (!provider->UseGtkTheme()) { + // TODO(erg): Theme wise, which color should I be picking here? + // COLOR_BUTTON_BACKGROUND doesn't match the default theme! + gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &kBackgroundColor); + } + gtk_widget_realize(window); - GtkWidget* floating_button = provider->BuildChromeButton(); - bookmark_utils::ConfigureButtonForNode(node, model, floating_button, - provider); - gtk_container_add(GTK_CONTAINER(frame), floating_button); - gtk_widget_show(floating_button); + GtkWidget* frame = gtk_frame_new(NULL); + gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT); + gtk_container_add(GTK_CONTAINER(window), frame); + + GtkWidget* floating_button = provider->BuildChromeButton(); + PackButton(pixbuf, title, true, provider, floating_button); + gtk_container_add(GTK_CONTAINER(frame), floating_button); + gtk_widget_show_all(frame); + } return window; } +GtkWidget* GetDragRepresentationForNode(const BookmarkNode* node, + BookmarkModel* model, + GtkThemeProvider* provider) { + GdkPixbuf* pixbuf = GetPixbufForNode(node, model, provider->UseGtkTheme()); + GtkWidget* widget = GetDragRepresentation(pixbuf, node->GetTitle(), provider); + g_object_unref(pixbuf); + return widget; +} + void ConfigureButtonForNode(const BookmarkNode* node, BookmarkModel* model, GtkWidget* button, GtkThemeProvider* provider) { - GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(button)); - if (former_child) - gtk_container_remove(GTK_CONTAINER(button), former_child); - - std::string tooltip = BuildTooltipFor(node); - if (!tooltip.empty()) - gtk_widget_set_tooltip_markup(button, tooltip.c_str()); - - // We pack the button manually (rather than using gtk_button_set_*) so that - // we can have finer control over its label. GdkPixbuf* pixbuf = bookmark_utils::GetPixbufForNode(node, model, provider->UseGtkTheme()); - GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); + PackButton(pixbuf, node->GetTitle(), node != model->other_node(), + provider, button); g_object_unref(pixbuf); - GtkWidget* box = gtk_hbox_new(FALSE, kBarButtonPadding); - gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0); - - std::string label_string = WideToUTF8(node->GetTitle()); - if (!label_string.empty()) { - GtkWidget* label = gtk_label_new(label_string.c_str()); - // Until we switch to vector graphics, force the font size. - gtk_util::ForceFontSizePixels(label, 13.4); // 13.4px == 10pt @ 96dpi - - // Ellipsize long bookmark names. - if (node != model->other_node()) { - gtk_label_set_max_width_chars(GTK_LABEL(label), kMaxCharsOnAButton); - gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); - } - - gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); - SetButtonTextColors(label, provider); - } - - GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); - // If we are not showing the label, don't set any padding, so that the icon - // will just be centered. - if (label_string.c_str()) { - gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), - kButtonPaddingTop, kButtonPaddingBottom, - kButtonPaddingLeft, kButtonPaddingRight); - } - gtk_container_add(GTK_CONTAINER(alignment), box); - gtk_container_add(GTK_CONTAINER(button), alignment); + std::string tooltip = BuildTooltipFor(node); + if (!tooltip.empty()) + gtk_widget_set_tooltip_markup(button, tooltip.c_str()); g_object_set_data(G_OBJECT(button), bookmark_utils::kBookmarkNode, AsVoid(node)); - - gtk_widget_show_all(alignment); } std::string BuildTooltipFor(const BookmarkNode* node) { diff --git a/chrome/browser/gtk/bookmark_utils_gtk.h b/chrome/browser/gtk/bookmark_utils_gtk.h index 012ce96..6c2227c 100644 --- a/chrome/browser/gtk/bookmark_utils_gtk.h +++ b/chrome/browser/gtk/bookmark_utils_gtk.h @@ -18,9 +18,6 @@ namespace bookmark_utils { extern const char kBookmarkNode[]; -// Padding between the image and the label of a bookmark bar button. -extern const int kBarButtonPadding; - // Get the image that is used to represent the node. This function adds a ref // to the returned pixbuf, so it requires a matching call to g_object_unref(). GdkPixbuf* GetPixbufForNode(const BookmarkNode* node, BookmarkModel* model, @@ -28,9 +25,12 @@ 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, +GtkWidget* GetDragRepresentation(GdkPixbuf* pixbuf, + const std::wstring& title, GtkThemeProvider* provider); +GtkWidget* GetDragRepresentationForNode(const BookmarkNode* node, + BookmarkModel* model, + GtkThemeProvider* provider); // Helper function that sets visual properties of GtkButton |button| to the // contents of |node|. diff --git a/chrome/browser/gtk/gtk_util.cc b/chrome/browser/gtk/gtk_util.cc index 4d5796a..2658d60 100644 --- a/chrome/browser/gtk/gtk_util.cc +++ b/chrome/browser/gtk/gtk_util.cc @@ -899,4 +899,13 @@ bool URLFromPrimarySelection(Profile* profile, GURL* url) { return true; } +bool AddWindowAlphaChannel(GtkWidget* window) { + GdkScreen* screen = gtk_widget_get_screen(window); + GdkColormap* rgba = gdk_screen_get_rgba_colormap(screen); + if (rgba) + gtk_widget_set_colormap(window, rgba); + + return rgba; +} + } // namespace gtk_util diff --git a/chrome/browser/gtk/gtk_util.h b/chrome/browser/gtk/gtk_util.h index 1d8b6d3..e469a19 100644 --- a/chrome/browser/gtk/gtk_util.h +++ b/chrome/browser/gtk/gtk_util.h @@ -277,6 +277,9 @@ guint32 XTimeNow(); // otherwise returns false. bool URLFromPrimarySelection(Profile* profile, GURL* url); +// Set the colormap of the given window to rgba to allow transparency. +bool AddWindowAlphaChannel(GtkWidget* window); + } // namespace gtk_util #endif // CHROME_BROWSER_GTK_GTK_UTIL_H_ diff --git a/chrome/browser/gtk/location_bar_view_gtk.cc b/chrome/browser/gtk/location_bar_view_gtk.cc index 6b73f34..e31262c 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.cc +++ b/chrome/browser/gtk/location_bar_view_gtk.cc @@ -28,6 +28,7 @@ #include "chrome/browser/extensions/extension_tabs_module.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/gtk/bookmark_bubble_gtk.h" +#include "chrome/browser/gtk/bookmark_utils_gtk.h" #include "chrome/browser/gtk/cairo_cached_surface.h" #include "chrome/browser/gtk/content_setting_bubble_gtk.h" #include "chrome/browser/gtk/extension_popup_gtk.h" @@ -92,9 +93,6 @@ const GdkColor kHintTextColor = GDK_COLOR_RGB(0x75, 0x75, 0x75); // Size of the rounding of the "Search site for:" box. const int kCornerSize = 3; -// Space between the favicon and the title when dragging the location icon. -const int kFavIconTitleSpacing = 4; - // Returns the short name for a keyword. std::wstring GetKeywordName(Profile* profile, const std::wstring& keyword) { @@ -182,8 +180,6 @@ LocationBarViewGtk::~LocationBarViewGtk() { // All of our widgets should have be children of / owned by the alignment. star_.Destroy(); hbox_.Destroy(); - if (drag_icon_) - g_object_unref(drag_icon_); content_setting_hbox_.Destroy(); page_action_hbox_.Destroy(); } @@ -416,19 +412,8 @@ void LocationBarViewGtk::SetSiteTypeDragSource() { G_CALLBACK(&OnIconDragDataThunk), this); g_signal_connect(site_type_event_box_, "drag-begin", G_CALLBACK(&OnIconDragBeginThunk), this); - - drag_icon_ = gtk_window_new(GTK_WINDOW_POPUP); - g_object_ref(drag_icon_); - g_signal_connect(drag_icon_, "expose-event", - G_CALLBACK(OnDragIconExposeThunk), this); - GdkScreen* screen = gtk_widget_get_screen(drag_icon_); - GdkColormap* rgba = gdk_screen_get_rgba_colormap(screen); - if (rgba) - gtk_widget_set_colormap(drag_icon_, rgba); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - const gfx::Font& base_font = rb.GetFont(ResourceBundle::BaseFont); - gtk_widget_set_size_request(drag_icon_, 200, base_font.height()); + g_signal_connect(site_type_event_box_, "drag-end", + G_CALLBACK(&OnIconDragEndThunk), this); } void LocationBarViewGtk::SetProfile(Profile* profile) { @@ -989,35 +974,20 @@ void LocationBarViewGtk::OnIconDragData(GtkWidget* sender, void LocationBarViewGtk::OnIconDragBegin(GtkWidget* sender, GdkDragContext* context) { - if (gtk_util::IsScreenComposited()) - gtk_drag_set_icon_widget(context, drag_icon_, 0, 0); + SkBitmap favicon = GetFavIcon(); + GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&favicon); + if (!pixbuf) + return; + drag_icon_ = bookmark_utils::GetDragRepresentation(pixbuf, GetTitle(), + theme_provider_); + g_object_unref(pixbuf); + gtk_drag_set_icon_widget(context, drag_icon_, 0, 0); } -gboolean LocationBarViewGtk::OnDragIconExpose(GtkWidget* sender, - GdkEventExpose* event) { - // Clear the background. - cairo_t* cr = gdk_cairo_create(event->window); - gdk_cairo_rectangle(cr, &event->area); - cairo_clip(cr); - cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); - cairo_paint(cr); - cairo_destroy(cr); - - // Paint the favicon. - gfx::CanvasPaint canvas(event, false); - SkBitmap icon = GetFavIcon(); - canvas.DrawBitmapInt(icon, 0, 0); - - // Paint the title text. - int text_x = icon.width() + kFavIconTitleSpacing; - int text_width = sender->allocation.width - text_x; - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - const gfx::Font& base_font = rb.GetFont(ResourceBundle::BaseFont); - canvas.DrawStringInt(GetTitle(), - base_font, SK_ColorBLACK, - text_x, 0, text_width, sender->allocation.height); - - return TRUE; +void LocationBarViewGtk::OnIconDragEnd(GtkWidget* sender, + GdkDragContext* context) { + gtk_widget_destroy(drag_icon_); + drag_icon_ = NULL; } void LocationBarViewGtk::OnEntryBoxSizeAllocate(GtkWidget* sender, diff --git a/chrome/browser/gtk/location_bar_view_gtk.h b/chrome/browser/gtk/location_bar_view_gtk.h index 6f21c74..486e5d7 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.h +++ b/chrome/browser/gtk/location_bar_view_gtk.h @@ -280,8 +280,8 @@ class LocationBarViewGtk : public AutocompleteEditController, GdkDragContext*, GtkSelectionData*, guint, guint); CHROMEGTK_CALLBACK_1(LocationBarViewGtk, void, OnIconDragBegin, GdkDragContext*); - CHROMEGTK_CALLBACK_1(LocationBarViewGtk, gboolean, OnDragIconExpose, - GdkEventExpose*); + CHROMEGTK_CALLBACK_1(LocationBarViewGtk, void, OnIconDragEnd, + GdkDragContext*); CHROMEGTK_CALLBACK_1(LocationBarViewGtk, void, OnEntryBoxSizeAllocate, GtkAllocation*); CHROMEGTK_CALLBACK_1(LocationBarViewGtk, gboolean, OnStarButtonPress, diff --git a/gfx/point.h b/gfx/point.h index 6e2cfe7..b3bb37b 100644 --- a/gfx/point.h +++ b/gfx/point.h @@ -52,6 +52,18 @@ class Point { y_ += delta_y; } + Point Add(const Point& other) { + Point copy = *this; + copy.Offset(other.x_, other.y_); + return copy; + } + + Point Subtract(const Point& other) { + Point copy = *this; + copy.Offset(-other.x_, -other.y_); + return copy; + } + bool operator==(const Point& rhs) const { return x_ == rhs.x_ && y_ == rhs.y_; } diff --git a/gfx/rect.cc b/gfx/rect.cc index 30338f4..dd8f392 100644 --- a/gfx/rect.cc +++ b/gfx/rect.cc @@ -35,15 +35,16 @@ namespace gfx { Rect::Rect() { } -Rect::Rect(int width, int height) { - set_width(width); - set_height(height); +Rect::Rect(int width, int height) + : size_(width, height) { } Rect::Rect(int x, int y, int width, int height) - : origin_(x, y) { - set_width(width); - set_height(height); + : origin_(x, y), size_(width, height) { +} + +Rect::Rect(const gfx::Size& size) + : size_(size) { } Rect::Rect(const gfx::Point& origin, const gfx::Size& size) @@ -37,6 +37,7 @@ class Rect { #elif defined(USE_X11) explicit Rect(const GdkRectangle& r); #endif + Rect(const gfx::Size& size); Rect(const gfx::Point& origin, const gfx::Size& size); ~Rect() {} |