diff options
author | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-23 11:45:19 +0000 |
---|---|---|
committer | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-23 11:45:19 +0000 |
commit | 1bdb3530e57466f251f5c9a3f7d608b92fd7fe08 (patch) | |
tree | 7581da736e9fb7de36fb5a4931ec0c2df4bbc8c0 | |
parent | 33d3e01eb859cac6565c82b9be459a4fdfce054a (diff) | |
download | chromium_src-1bdb3530e57466f251f5c9a3f7d608b92fd7fe08.zip chromium_src-1bdb3530e57466f251f5c9a3f7d608b92fd7fe08.tar.gz chromium_src-1bdb3530e57466f251f5c9a3f7d608b92fd7fe08.tar.bz2 |
Implement ConfirmInfoBar link support on GTK
this is the follow up to http://codereview.chromium.org/1037006 which added it on windows, and http://codereview.chromium.org/1127001 which added it to Mac.
BUG=11246
TEST=run browser with --enable-geolocation, open maps.google.com and click my location.
Review URL: http://codereview.chromium.org/1081007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42337 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/gtk/infobar_gtk.cc | 135 | ||||
-rw-r--r-- | chrome/browser/gtk/infobar_gtk.h | 11 |
2 files changed, 90 insertions, 56 deletions
diff --git a/chrome/browser/gtk/infobar_gtk.cc b/chrome/browser/gtk/infobar_gtk.cc index 3b96319..8c28695 100644 --- a/chrome/browser/gtk/infobar_gtk.cc +++ b/chrome/browser/gtk/infobar_gtk.cc @@ -167,6 +167,69 @@ void InfoBar::Observe(NotificationType type, UpdateBorderColor(); } +// TODO(joth): This method factors out some common functionality between the +// various derived infobar classes, however the class hierarchy itself could +// use refactoring to reduce this duplication. http://crbug.com/38924 +void InfoBar::AddLabelAndLink(const std::wstring& display_text, + const std::wstring& link_text, + size_t link_offset, + guint link_padding, + GCallback callback) { + GtkWidget* link_button = NULL; + if (link_text.empty()) { + // No link text, so skip creating the link and splitting display_text. + link_offset = std::wstring::npos; + } else { + // If we have some link text, create the link button. + link_button = gtk_chrome_link_button_new(WideToUTF8(link_text).c_str()); + gtk_chrome_link_button_set_use_gtk_theme( + GTK_CHROME_LINK_BUTTON(link_button), FALSE); + DCHECK(callback); + g_signal_connect(link_button, "clicked", callback, this); + gtk_util::SetButtonTriggersNavigation(link_button); + } + + GtkWidget* hbox = gtk_hbox_new(FALSE, 0); + // We want the link to be horizontally shrinkable, so that the Chrome + // window can be resized freely even with a very long link. + gtk_widget_set_size_request(hbox, 0, -1); + gtk_box_pack_start(GTK_BOX(hbox_), hbox, TRUE, TRUE, 0); + + // If link_offset is npos, we right-align the link instead of embedding it + // in the text. + if (link_offset == std::wstring::npos) { + if (link_button) + gtk_box_pack_end(GTK_BOX(hbox), link_button, FALSE, FALSE, 0); + GtkWidget* label = gtk_label_new(WideToUTF8(display_text).c_str()); + // In order to avoid the link_button and the label overlapping with each + // other, we make the label shrinkable. + gtk_widget_set_size_request(label, 0, -1); + gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack); + gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); + } else { + DCHECK(link_button); + // Need to insert the link inside the display text. + GtkWidget* initial_label = gtk_label_new( + WideToUTF8(display_text.substr(0, link_offset)).c_str()); + GtkWidget* trailing_label = gtk_label_new( + WideToUTF8(display_text.substr(link_offset)).c_str()); + + // TODO(joth): Unlike the right-align case above, none of the label widgets + // are set as shrinkable here, meaning the text will run under the close + // button etc. when the width is restricted, rather than eliding. + gtk_widget_modify_fg(initial_label, GTK_STATE_NORMAL, &gfx::kGdkBlack); + gtk_widget_modify_fg(trailing_label, GTK_STATE_NORMAL, &gfx::kGdkBlack); + + // We don't want any spacing between the elements, so we pack them into + // this hbox that doesn't use kElementPadding. + gtk_box_pack_start(GTK_BOX(hbox), initial_label, FALSE, FALSE, 0); + gtk_util::CenterWidgetInHBox(hbox, link_button, false, link_padding); + gtk_box_pack_start(GTK_BOX(hbox), trailing_label, FALSE, FALSE, 0); + } +} + void InfoBar::UpdateBorderColor() { GdkColor border_color = theme_provider_->GetBorderColor(); gtk_widget_modify_bg(border_bin_.get(), GTK_STATE_NORMAL, &border_color); @@ -185,16 +248,7 @@ class AlertInfoBar : public InfoBar { public: explicit AlertInfoBar(AlertInfoBarDelegate* delegate) : InfoBar(delegate) { - std::wstring text = delegate->GetMessageText(); - GtkWidget* label = gtk_label_new(WideToUTF8(text).c_str()); - // We want the label to be horizontally shrinkable, so that the Chrome - // window can be resized freely even with a very long message. - gtk_widget_set_size_request(label, 0, -1); - gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack); - gtk_box_pack_start(GTK_BOX(hbox_), label, TRUE, TRUE, 0); - + AddLabelAndLink(delegate->GetMessageText(), std::wstring(), 0, 0, NULL); gtk_widget_show_all(border_bin_.get()); } }; @@ -209,49 +263,8 @@ class LinkInfoBar : public InfoBar { std::wstring display_text = delegate->GetMessageTextWithOffset(&link_offset); std::wstring link_text = delegate->GetLinkText(); - - // Create the link button. - GtkWidget* link_button = - gtk_chrome_link_button_new(WideToUTF8(link_text).c_str()); - gtk_chrome_link_button_set_use_gtk_theme( - GTK_CHROME_LINK_BUTTON(link_button), FALSE); - g_signal_connect(link_button, "clicked", - G_CALLBACK(OnLinkClick), this); - gtk_util::SetButtonTriggersNavigation(link_button); - - GtkWidget* hbox = gtk_hbox_new(FALSE, 0); - // We want the link to be horizontally shrinkable, so that the Chrome - // window can be resized freely even with a very long link. - gtk_widget_set_size_request(hbox, 0, -1); - gtk_box_pack_start(GTK_BOX(hbox_), hbox, TRUE, TRUE, 0); - // If link_offset is npos, we right-align the link instead of embedding it - // in the text. - if (link_offset == std::wstring::npos) { - gtk_box_pack_end(GTK_BOX(hbox), link_button, FALSE, FALSE, 0); - GtkWidget* label = gtk_label_new(WideToUTF8(display_text).c_str()); - // In order to avoid the link_button and the label overlapping with each - // other, we make the label shrinkable. - gtk_widget_set_size_request(label, 0, -1); - gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); - gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack); - gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); - } else { - GtkWidget* initial_label = gtk_label_new( - WideToUTF8(display_text.substr(0, link_offset)).c_str()); - GtkWidget* trailing_label = gtk_label_new( - WideToUTF8(display_text.substr(link_offset)).c_str()); - - gtk_widget_modify_fg(initial_label, GTK_STATE_NORMAL, &gfx::kGdkBlack); - gtk_widget_modify_fg(trailing_label, GTK_STATE_NORMAL, &gfx::kGdkBlack); - - // We don't want any spacing between the elements, so we pack them into - // this hbox that doesn't use kElementPadding. - gtk_box_pack_start(GTK_BOX(hbox), initial_label, FALSE, FALSE, 0); - gtk_util::CenterWidgetInHBox(hbox, link_button, false, 0); - gtk_box_pack_start(GTK_BOX(hbox), trailing_label, FALSE, FALSE, 0); - } - + AddLabelAndLink(display_text, link_text, link_offset, 0, + G_CALLBACK(OnLinkClick)); gtk_widget_show_all(border_bin_.get()); } @@ -266,13 +279,16 @@ class LinkInfoBar : public InfoBar { // ConfirmInfoBar -------------------------------------------------------------- -class ConfirmInfoBar : public AlertInfoBar { +class ConfirmInfoBar : public InfoBar { public: explicit ConfirmInfoBar(ConfirmInfoBarDelegate* delegate) - : AlertInfoBar(delegate) { + : InfoBar(delegate) { AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_CANCEL); AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_OK); - + std::wstring display_text = delegate->GetMessageText(); + std::wstring link_text = delegate->GetLinkText(); + AddLabelAndLink(display_text, link_text, display_text.size(), + kElementPadding, G_CALLBACK(OnLinkClick)); gtk_widget_show_all(border_bin_.get()); } @@ -300,6 +316,13 @@ class ConfirmInfoBar : public AlertInfoBar { if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Accept()) info_bar->RemoveInfoBar(); } + + static void OnLinkClick(GtkWidget* button, ConfirmInfoBar* link_info_bar) { + if (link_info_bar->delegate_->AsConfirmInfoBarDelegate()-> + LinkClicked(gtk_util::DispositionForCurrentButtonPressEvent())) { + link_info_bar->RemoveInfoBar(); + } + } }; // AlertInfoBarDelegate, InfoBarDelegate overrides: ---------------------------- diff --git a/chrome/browser/gtk/infobar_gtk.h b/chrome/browser/gtk/infobar_gtk.h index ff907c1..62b5f21 100644 --- a/chrome/browser/gtk/infobar_gtk.h +++ b/chrome/browser/gtk/infobar_gtk.h @@ -65,6 +65,17 @@ class InfoBar : public SlideAnimatorGtk::Delegate, // (Will lead to this InfoBar being closed). void RemoveInfoBar() const; + // Adds |display_text| to the infobar. If |link_text| is not empty, it is + // rendered as a hyperlink and inserted into |display_text| at |link_offset|, + // or right aligned in the infobar if |link_offset| is |npos|. |link_padding| + // pixels are inserted around the link (pass 0 for not padding). If a link + // is supplied, |link_callback| must not be null. It will be invoked on click. + void AddLabelAndLink(const std::wstring& display_text, + const std::wstring& link, + size_t link_offset, + guint link_padding, + GCallback link_callback); + // The top level widget of the infobar. scoped_ptr<SlideAnimatorGtk> slide_widget_; |