Index: chrome/browser/gtk/status_bubble_gtk.cc |
diff --git a/chrome/browser/gtk/status_bubble_gtk.cc b/chrome/browser/gtk/status_bubble_gtk.cc |
index abb7a0d1cee0d580b04a680b96c7b9b53fe0607f..1034bf9e3c779ca2ed8c642cd2dd1e9b31558c42 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); |
Evan Stade
2009/05/19 23:41:25
why app paintable?
|
} |