Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/validation_message_bubble.h" | 5 #include "chrome/browser/ui/validation_message_bubble.h" |
| 6 | 6 |
| 7 #include "base/utf_string_conversions.h" | |
| 8 #include "chrome/browser/profiles/profile.h" | |
| 9 #include "chrome/browser/ui/gtk/bubble/bubble_gtk.h" | |
| 10 #include "chrome/browser/ui/gtk/gtk_theme_service.h" | |
| 11 #include "chrome/browser/ui/gtk/gtk_util.h" | |
| 12 #include "content/public/browser/render_view_host.h" | |
| 13 #include "content/public/browser/render_widget_host_view.h" | |
| 14 #include "content/public/browser/web_contents.h" | |
| 15 #include "grit/theme_resources.h" | |
| 16 #include "ui/base/resource/resource_bundle.h" | |
| 17 #include "ui/gfx/gtk_util.h" | |
| 18 #include "ui/gfx/image/image_skia.h" | |
| 19 #include "ui/gfx/rect.h" | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 const int kPadding = 4; | |
| 24 const int kIconTextMargin = 8; | |
| 25 const int kTextMargin = 4; | |
| 26 const int kTextMaxWidth = 256; | |
| 27 | |
| 28 // A GTK implementation of ValidationMessageBubble. | |
| 29 class ValidationMessageBubbleGtk : public chrome::ValidationMessageBubble, | |
| 30 public BubbleDelegateGtk { | |
| 31 public: | |
| 32 ValidationMessageBubbleGtk(content::RenderWidgetHost* widget_host, | |
| 33 const gfx::Rect& anchor_in_screen, | |
| 34 const string16& main_text, | |
| 35 const string16& sub_text); | |
| 36 virtual ~ValidationMessageBubbleGtk(); | |
| 37 | |
| 38 // BubbleDelegateGtk override: | |
| 39 virtual void BubbleClosing(BubbleGtk*, bool) OVERRIDE; | |
| 40 | |
| 41 private: | |
| 42 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.
| |
| 43 const string16& sub_text); | |
| 44 | |
| 45 BubbleGtk* bubble_; | |
| 46 }; | |
| 47 | |
| 48 ValidationMessageBubbleGtk::ValidationMessageBubbleGtk( | |
| 49 content::RenderWidgetHost* widget_host, | |
| 50 const gfx::Rect& anchor_in_screen, | |
| 51 const string16& main_text, | |
| 52 const string16& sub_text) | |
| 53 : bubble_(NULL) { | |
| 54 if (!widget_host->IsRenderView()) | |
| 55 return; | |
| 56 gfx::Rect bounds_in_screen = widget_host->GetView()->GetViewBounds(); | |
| 57 gfx::Rect anchor = anchor_in_screen; | |
| 58 anchor.Offset(-bounds_in_screen.x(), -bounds_in_screen.y()); | |
| 59 | |
| 60 Profile* profile = Profile::FromBrowserContext( | |
| 61 content::WebContents::FromRenderViewHost( | |
| 62 content::RenderViewHost::From(widget_host))->GetBrowserContext()); | |
| 63 bubble_ = BubbleGtk::Show(widget_host->GetView()->GetNativeView(), | |
| 64 &anchor, | |
| 65 constructContent(main_text, sub_text), | |
| 66 BubbleGtk::ANCHOR_TOP_LEFT, | |
| 67 BubbleGtk::POPUP_WINDOW, | |
| 68 GtkThemeService::GetFrom(profile), | |
| 69 this); | |
| 70 } | |
| 71 | |
| 72 ValidationMessageBubbleGtk::~ValidationMessageBubbleGtk() { | |
| 73 if (bubble_) | |
| 74 bubble_->Close(); | |
| 75 } | |
| 76 | |
| 77 void ValidationMessageBubbleGtk::BubbleClosing(BubbleGtk*, bool) { | |
| 78 bubble_ = NULL; | |
| 79 } | |
| 80 | |
| 81 // static | |
| 82 GtkWidget* ValidationMessageBubbleGtk::constructContent( | |
| 83 const string16& main_text, const string16& sub_text) { | |
| 84 GtkWidget* icon = gtk_image_new(); | |
| 85 gtk_misc_set_alignment(GTK_MISC(icon), 0.5, 0); | |
| 86 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
| |
| 87 ResourceBundle& bundle = ResourceBundle::GetSharedInstance(); | |
| 88 GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap( | |
| 89 *bundle.GetImageSkiaNamed(IDR_INPUT_ALERT)->bitmap()); | |
| 90 gtk_image_set_from_pixbuf(GTK_IMAGE(icon), pixbuf); | |
| 91 g_object_unref(pixbuf); | |
| 92 GtkWidget* icon_text_box = gtk_hbox_new(FALSE, kIconTextMargin); | |
| 93 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.
| |
| 94 | |
| 95 GtkWidget* text_box = gtk_vbox_new(FALSE, kTextMargin); | |
| 96 GtkWidget* label = gtk_label_new(UTF16ToUTF8(main_text).c_str()); | |
| 97 const gfx::Font& main_font = bundle.GetFont(ResourceBundle::MediumFont); | |
| 98 gtk_util::ForceFontSizePixels(label, main_font.GetHeight()); | |
| 99 gtk_box_pack_start( | |
| 100 GTK_BOX(text_box), gtk_util::LeftAlignMisc(label), TRUE, TRUE, 0); | |
| 101 | |
| 102 if (!sub_text.empty()) { | |
| 103 GtkWidget* sub_label = gtk_label_new(UTF16ToUTF8(sub_text).c_str()); | |
| 104 const gfx::Font& sub_font = bundle.GetFont(ResourceBundle::BaseFont); | |
| 105 gtk_util::ForceFontSizePixels(sub_label, sub_font.GetHeight()); | |
| 106 int max_characters = kTextMaxWidth / sub_font.GetAverageCharacterWidth(); | |
| 107 if (sub_text.length() > static_cast<size_t>(max_characters)) | |
| 108 gtk_util::SetLabelWidth(sub_label, kTextMaxWidth); | |
| 109 gtk_box_pack_start( | |
| 110 GTK_BOX(text_box), gtk_util::LeftAlignMisc(sub_label), TRUE, TRUE, 0); | |
| 111 } | |
| 112 | |
| 113 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.
| |
| 114 | |
| 115 GtkWidget* content = gtk_alignment_new(0, 0, 0, 0); | |
| 116 gtk_alignment_set_padding( | |
| 117 GTK_ALIGNMENT(content), kPadding, kPadding, kPadding, kPadding); | |
| 118 gtk_container_add(GTK_CONTAINER(content), icon_text_box); | |
| 119 return content; | |
| 120 } | |
| 121 | |
| 122 } // namespace | |
| 123 | |
| 7 namespace chrome { | 124 namespace chrome { |
| 8 | 125 |
| 9 scoped_ptr<ValidationMessageBubble> ValidationMessageBubble::CreateAndShow( | 126 scoped_ptr<ValidationMessageBubble> ValidationMessageBubble::CreateAndShow( |
| 10 content::RenderWidgetHost* widget_host, | 127 content::RenderWidgetHost* widget_host, |
| 11 const gfx::Rect& anchor_in_screen, | 128 const gfx::Rect& anchor_in_screen, |
| 12 const string16& main_text, | 129 const string16& main_text, |
| 13 const string16& sub_text) { | 130 const string16& sub_text) { |
| 14 // TODO(tkent): Implement this and enable it. crbug.com/235717. | 131 return scoped_ptr<ValidationMessageBubble>(new ValidationMessageBubbleGtk( |
| 15 return scoped_ptr<ValidationMessageBubble>().Pass(); | 132 widget_host, anchor_in_screen, main_text, sub_text)).Pass(); |
| 16 } | 133 } |
| 17 | 134 |
| 18 } | 135 } // namespace chrome |
| OLD | NEW |