diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-19 23:30:27 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-19 23:30:27 +0000 |
commit | 98f5ea69fed3f2f39646acdffd76baeac4a6a7df (patch) | |
tree | e6f4525d1daf154b650df2c503a5d52445a3eecb /chrome/browser/gtk/status_bubble_gtk.cc | |
parent | fd81a10dc199076671eab98cc5722522004a84d5 (diff) | |
download | chromium_src-98f5ea69fed3f2f39646acdffd76baeac4a6a7df.zip chromium_src-98f5ea69fed3f2f39646acdffd76baeac4a6a7df.tar.gz chromium_src-98f5ea69fed3f2f39646acdffd76baeac4a6a7df.tar.bz2 |
Quick reimplementation of StatusBubbleGtk to not suck as much.
The TabContentsContainerGtk now uses a GtkFixed to store its
children, and the status bubble is now a child of that GtkFixed
so that it can be absolutely positioned on top of the rendered
data. Since it is no longer a GTK_WINDOW_POPUP, all the weird
stuff related to different window managers goes away.
http://crbug.com/11635
Review URL: http://codereview.chromium.org/113590
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16433 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk/status_bubble_gtk.cc')
-rw-r--r-- | chrome/browser/gtk/status_bubble_gtk.cc | 126 |
1 files changed, 88 insertions, 38 deletions
diff --git a/chrome/browser/gtk/status_bubble_gtk.cc b/chrome/browser/gtk/status_bubble_gtk.cc index abb7a0d..1034bf9 100644 --- a/chrome/browser/gtk/status_bubble_gtk.cc +++ b/chrome/browser/gtk/status_bubble_gtk.cc @@ -4,19 +4,35 @@ #include "chrome/browser/gtk/status_bubble_gtk.h" +#include <gtk/gtk.h> + +#include "base/gfx/gtk_util.h" #include "base/string_util.h" +#include "chrome/browser/gtk/slide_animator_gtk.h" +#include "chrome/common/gtk_util.h" #include "googleurl/src/gurl.h" -// NOTE: this code is probably the wrong approach for the status bubble. -// Talk to evanm before you attempt to fix bugs in it -- we're probably -// better off restructuring it. +namespace { + +const GdkColor kBackgroundColor = GDK_COLOR_RGB(0xe6, 0xed, 0xf4); +const GdkColor kFrameBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4); + +// Inner padding between the border and the text label. +const int kInternalTopBottomPadding = 1; +const int kInternalLeftRightPadding = 2; -StatusBubbleGtk::StatusBubbleGtk(GtkWindow* parent) - : parent_(parent), window_(NULL) { +// Border of color kFrameBorderColor around the status bubble. +const int kBorderPadding = 1; + +} // namespace + +StatusBubbleGtk::StatusBubbleGtk() + : parent_(NULL) { + InitWidgets(); } StatusBubbleGtk::~StatusBubbleGtk() { - Hide(); + container_.Destroy(); } void StatusBubbleGtk::SetStatus(const std::string& status) { @@ -25,55 +41,89 @@ void StatusBubbleGtk::SetStatus(const std::string& status) { return; } - if (!window_) - Create(); - gtk_label_set_text(GTK_LABEL(label_), status.c_str()); - Reposition(); - gtk_widget_show(window_); + + Show(); } void StatusBubbleGtk::SetStatus(const std::wstring& status) { SetStatus(WideToUTF8(status)); } +void StatusBubbleGtk::SetParentAllocation( + GtkWidget* parent, GtkAllocation* allocation) { + parent_ = parent; + parent_allocation_ = *allocation; + SetStatusBubbleSize(); +} + void StatusBubbleGtk::SetURL(const GURL& url, const std::wstring& languages) { SetStatus(url.possibly_invalid_spec()); } +void StatusBubbleGtk::Show() { + SetStatusBubbleSize(); + gtk_widget_show_all(container_.get()); + + if (container_.get()->window) + gdk_window_raise(container_.get()->window); +} + void StatusBubbleGtk::Hide() { - if (!window_) - return; - gtk_widget_destroy(window_); - window_ = NULL; + gtk_widget_hide_all(container_.get()); +} + +void StatusBubbleGtk::SetStatusBubbleSize() { + if (parent_) { + GtkRequisition requisition; + gtk_widget_size_request(container_.get(), &requisition); + + // TODO(erg): Previously, I put a call to gtk_fixed_put() here. It appears + // that doing this sets off a size-allocate storm, since gtk_fixed_put() + // calls gtk_widget_queue_resize on the GtkFixed that caused this message. + // The real solution may be creating a subclass of GtkVBox that has extra + // code to deal with floating widgets, but this hack is good enough for + // Friday. evanm says that there's a a GtkFixed subclass in test_shell that + // we'll be stealing for plugin support anyway that should also do the same + // task. + + GtkAllocation widget_allocation; + int child_y = std::max( + parent_allocation_.y + parent_allocation_.height - requisition.height, + 0); + widget_allocation.x = 0; + widget_allocation.y = child_y; + widget_allocation.width = std::min(requisition.width, + parent_allocation_.width); + widget_allocation.height = requisition.height; + gtk_widget_size_allocate(container_.get(), &widget_allocation); + } } void StatusBubbleGtk::MouseMoved() { - if (!window_) - return; - // We ignore for now. - // TODO(port): the fancy sliding behavior. + // We can't do that fancy sliding behaviour where the status bubble slides + // out of the window because the window manager gets in the way. So totally + // ignore this message for now. + // + // TODO(erg): At least get some sliding behaviour so that it slides out of + // the way to hide the status bubble on mouseover. } -void StatusBubbleGtk::Create() { - if (window_) - return; +void StatusBubbleGtk::InitWidgets() { + label_ = gtk_label_new(NULL); - window_ = gtk_window_new(GTK_WINDOW_POPUP); - gtk_window_set_transient_for(GTK_WINDOW(window_), parent_); - gtk_container_set_border_width(GTK_CONTAINER(window_), 2); - label_ = gtk_label_new(""); - gtk_widget_show(label_); - gtk_container_add(GTK_CONTAINER(window_), label_); -} + GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1); + gtk_alignment_set_padding(GTK_ALIGNMENT(padding), + kInternalTopBottomPadding, kInternalTopBottomPadding, + kInternalLeftRightPadding, kInternalLeftRightPadding); + gtk_container_add(GTK_CONTAINER(padding), label_); + + GtkWidget* bg_box = gtk_event_box_new(); + gtk_container_add(GTK_CONTAINER(bg_box), padding); + gtk_widget_modify_bg(bg_box, GTK_STATE_NORMAL, &kBackgroundColor); -void StatusBubbleGtk::Reposition() { - int x, y, width, parent_height; - gdk_window_get_position(GTK_WIDGET(parent_)->window, &x, &y); - gtk_window_get_size(parent_, &width, &parent_height); - GtkRequisition requisition; - gtk_widget_size_request(window_, &requisition); - // TODO(port): RTL positioning. - gtk_window_move(GTK_WINDOW(window_), x, - y + parent_height - requisition.height); + container_.Own(gtk_util::CreateGtkBorderBin(bg_box, &kFrameBorderColor, + kBorderPadding, kBorderPadding, kBorderPadding, kBorderPadding)); + gtk_widget_set_name(container_.get(), "status-bubble"); + gtk_widget_set_app_paintable(container_.get(), TRUE); } |