Chromium Code Reviews| Index: chrome/browser/ui/gtk/validation_message_bubble_gtk.cc |
| diff --git a/chrome/browser/ui/gtk/validation_message_bubble_gtk.cc b/chrome/browser/ui/gtk/validation_message_bubble_gtk.cc |
| index fa9a65a1d65bb06ba7136dd87a1fdc69279b1b43..1e695c8507f99034cd89d7e081d5b852b6581dd4 100644 |
| --- a/chrome/browser/ui/gtk/validation_message_bubble_gtk.cc |
| +++ b/chrome/browser/ui/gtk/validation_message_bubble_gtk.cc |
| @@ -4,6 +4,123 @@ |
| #include "chrome/browser/ui/validation_message_bubble.h" |
| +#include "base/utf_string_conversions.h" |
| +#include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/ui/gtk/bubble/bubble_gtk.h" |
| +#include "chrome/browser/ui/gtk/gtk_theme_service.h" |
| +#include "chrome/browser/ui/gtk/gtk_util.h" |
| +#include "content/public/browser/render_view_host.h" |
| +#include "content/public/browser/render_widget_host_view.h" |
| +#include "content/public/browser/web_contents.h" |
| +#include "grit/theme_resources.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| +#include "ui/gfx/gtk_util.h" |
| +#include "ui/gfx/image/image_skia.h" |
| +#include "ui/gfx/rect.h" |
| + |
| +namespace { |
| + |
| +const int kPadding = 4; |
| +const int kIconTextMargin = 8; |
| +const int kTextMargin = 4; |
| +const int kTextMaxWidth = 256; |
| + |
| +// A GTK implementation of ValidationMessageBubble. |
| +class ValidationMessageBubbleGtk : public chrome::ValidationMessageBubble, |
| + public BubbleDelegateGtk { |
| + public: |
| + ValidationMessageBubbleGtk(content::RenderWidgetHost* widget_host, |
| + const gfx::Rect& anchor_in_screen, |
| + const string16& main_text, |
| + const string16& sub_text); |
| + virtual ~ValidationMessageBubbleGtk(); |
| + |
| + // BubbleDelegateGtk override: |
| + virtual void BubbleClosing(BubbleGtk*, bool) OVERRIDE; |
| + |
| + private: |
| + static GtkWidget* constructContent(const string16& main_text, |
|
Nico
2013/05/02 16:55:59
nit: chromium style is to capitalize the first let
tkent
2013/05/03 14:53:03
Done.
|
| + const string16& sub_text); |
| + |
| + BubbleGtk* bubble_; |
| +}; |
| + |
| +ValidationMessageBubbleGtk::ValidationMessageBubbleGtk( |
| + content::RenderWidgetHost* widget_host, |
| + const gfx::Rect& anchor_in_screen, |
| + const string16& main_text, |
| + const string16& sub_text) |
| + : bubble_(NULL) { |
| + if (!widget_host->IsRenderView()) |
| + return; |
| + gfx::Rect bounds_in_screen = widget_host->GetView()->GetViewBounds(); |
| + gfx::Rect anchor = anchor_in_screen; |
| + anchor.Offset(-bounds_in_screen.x(), -bounds_in_screen.y()); |
| + |
| + Profile* profile = Profile::FromBrowserContext( |
| + content::WebContents::FromRenderViewHost( |
| + content::RenderViewHost::From(widget_host))->GetBrowserContext()); |
| + bubble_ = BubbleGtk::Show(widget_host->GetView()->GetNativeView(), |
| + &anchor, |
| + constructContent(main_text, sub_text), |
| + BubbleGtk::ANCHOR_TOP_LEFT, |
| + BubbleGtk::POPUP_WINDOW, |
| + GtkThemeService::GetFrom(profile), |
| + this); |
| +} |
| + |
| +ValidationMessageBubbleGtk::~ValidationMessageBubbleGtk() { |
| + if (bubble_) |
| + bubble_->Close(); |
| +} |
| + |
| +void ValidationMessageBubbleGtk::BubbleClosing(BubbleGtk*, bool) { |
| + bubble_ = NULL; |
| +} |
| + |
| +// static |
| +GtkWidget* ValidationMessageBubbleGtk::constructContent( |
| + const string16& main_text, const string16& sub_text) { |
| + GtkWidget* icon = gtk_image_new(); |
| + gtk_misc_set_alignment(GTK_MISC(icon), 0.5, 0); |
| + gtk_misc_set_padding(GTK_MISC(icon), 2, 2); |
|
Evan Stade
2013/05/02 22:42:33
what's this magic 2 for? why not add the padding i
tkent
2013/05/03 14:53:03
I changed 2 to kPadding.
I don't want to center ic
|
| + ResourceBundle& bundle = ResourceBundle::GetSharedInstance(); |
| + GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap( |
| + *bundle.GetImageSkiaNamed(IDR_INPUT_ALERT)->bitmap()); |
| + gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pixbuf); |
| + g_object_unref(pixbuf); |
| + GtkWidget* icon_text_box = gtk_hbox_new(FALSE, kIconTextMargin); |
| + gtk_box_pack_start(GTK_BOX(icon_text_box), icon, FALSE, FALSE, 0); |
|
Evan Stade
2013/05/02 22:42:33
I think this is equivalent to gtk_container_add
tkent
2013/05/03 14:53:03
Done.
|
| + |
| + GtkWidget* text_box = gtk_vbox_new(FALSE, kTextMargin); |
| + GtkWidget* label = gtk_label_new(UTF16ToUTF8(main_text).c_str()); |
| + const gfx::Font& main_font = bundle.GetFont(ResourceBundle::MediumFont); |
| + gtk_util::ForceFontSizePixels(label, main_font.GetHeight()); |
| + gtk_box_pack_start( |
| + GTK_BOX(text_box), gtk_util::LeftAlignMisc(label), TRUE, TRUE, 0); |
| + |
| + if (!sub_text.empty()) { |
| + GtkWidget* sub_label = gtk_label_new(UTF16ToUTF8(sub_text).c_str()); |
| + const gfx::Font& sub_font = bundle.GetFont(ResourceBundle::BaseFont); |
| + gtk_util::ForceFontSizePixels(sub_label, sub_font.GetHeight()); |
| + int max_characters = kTextMaxWidth / sub_font.GetAverageCharacterWidth(); |
| + if (sub_text.length() > static_cast<size_t>(max_characters)) |
| + gtk_util::SetLabelWidth(sub_label, kTextMaxWidth); |
| + gtk_box_pack_start( |
| + GTK_BOX(text_box), gtk_util::LeftAlignMisc(sub_label), TRUE, TRUE, 0); |
| + } |
| + |
| + gtk_box_pack_start(GTK_BOX(icon_text_box), text_box, FALSE, TRUE, 0); |
|
Evan Stade
2013/05/02 22:42:33
I think this is equivalent to gtk_container_add (n
tkent
2013/05/03 14:53:03
Done.
|
| + |
| + GtkWidget* content = gtk_alignment_new(0, 0, 0, 0); |
| + gtk_alignment_set_padding( |
| + GTK_ALIGNMENT(content), kPadding, kPadding, kPadding, kPadding); |
| + gtk_container_add(GTK_CONTAINER(content), icon_text_box); |
| + return content; |
| +} |
| + |
| +} // namespace |
| + |
| namespace chrome { |
| scoped_ptr<ValidationMessageBubble> ValidationMessageBubble::CreateAndShow( |
| @@ -11,8 +128,8 @@ scoped_ptr<ValidationMessageBubble> ValidationMessageBubble::CreateAndShow( |
| const gfx::Rect& anchor_in_screen, |
| const string16& main_text, |
| const string16& sub_text) { |
| - // TODO(tkent): Implement this and enable it. crbug.com/235717. |
| - return scoped_ptr<ValidationMessageBubble>().Pass(); |
| + return scoped_ptr<ValidationMessageBubble>(new ValidationMessageBubbleGtk( |
| + widget_host, anchor_in_screen, main_text, sub_text)).Pass(); |
| } |
| -} |
| +} // namespace chrome |