summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk/infobar_gtk.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/gtk/infobar_gtk.cc')
-rw-r--r--chrome/browser/gtk/infobar_gtk.cc235
1 files changed, 128 insertions, 107 deletions
diff --git a/chrome/browser/gtk/infobar_gtk.cc b/chrome/browser/gtk/infobar_gtk.cc
index a389853..1af4315 100644
--- a/chrome/browser/gtk/infobar_gtk.cc
+++ b/chrome/browser/gtk/infobar_gtk.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,6 +9,7 @@
#include "base/utf_string_conversions.h"
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
+#include "chrome/browser/gtk/gtk_chrome_shrinkable_hbox.h"
#include "chrome/browser/gtk/gtk_theme_provider.h"
#include "chrome/browser/gtk/gtk_util.h"
#include "chrome/browser/gtk/infobar_container_gtk.h"
@@ -17,10 +18,10 @@
namespace {
-const double kBackgroundColorTop[3] =
- {255.0 / 255.0, 242.0 / 255.0, 183.0 / 255.0};
-const double kBackgroundColorBottom[3] =
- {250.0 / 255.0, 230.0 / 255.0, 145.0 / 255.0};
+// Spacing after message (and before buttons).
+const int kEndOfLabelSpacing = 6;
+// Spacing between buttons.
+const int kButtonButtonSpacing = 3;
// The total height of the info bar.
const int kInfoBarHeight = 37;
@@ -145,21 +146,53 @@ void InfoBar::Observe(NotificationType type,
UpdateBorderColor();
}
+void InfoBar::AddLabelWithInlineLink(const string16& display_text,
+ const string16& link_text,
+ size_t link_offset,
+ GCallback callback) {
+ GtkWidget* link_button = gtk_chrome_link_button_new(
+ UTF16ToUTF8(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);
+
+ // Need to insert the link inside the display text.
+ GtkWidget* initial_label = gtk_label_new(
+ UTF16ToUTF8(display_text.substr(0, link_offset)).c_str());
+ GtkWidget* trailing_label = gtk_label_new(
+ UTF16ToUTF8(display_text.substr(link_offset)).c_str());
+
+ // TODO(joth): Unlike the AddLabalAndLink below, 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, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), trailing_label, FALSE, FALSE, 0);
+}
+
// 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,
+void InfoBar::AddLabelAndLink(const string16& display_text,
+ const string16& link_text,
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 (!link_text.empty()) {
// If we have some link text, create the link button.
- link_button = gtk_chrome_link_button_new(WideToUTF8(link_text).c_str());
+ link_button = gtk_chrome_link_button_new(UTF16ToUTF8(link_text).c_str());
gtk_chrome_link_button_set_use_gtk_theme(
GTK_CHROME_LINK_BUTTON(link_button), FALSE);
DCHECK(callback);
@@ -173,39 +206,16 @@ void InfoBar::AddLabelAndLink(const std::wstring& display_text,
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);
- }
+ if (link_button)
+ gtk_box_pack_end(GTK_BOX(hbox), link_button, FALSE, FALSE, 0);
+ GtkWidget* label = gtk_label_new(UTF16ToUTF8(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);
}
void InfoBar::GetTopColor(InfoBarDelegate::Type type,
@@ -214,13 +224,7 @@ void InfoBar::GetTopColor(InfoBarDelegate::Type type,
// browser/views/infobars/infobars.cc, and then changed into 0-1 ranged
// values for cairo.
switch (type) {
- case InfoBarDelegate::INFO_TYPE:
- *r = 170.0 / 255.0;
- *g = 214.0 / 255.0;
- *b = 112.0 / 255.0;
- break;
case InfoBarDelegate::WARNING_TYPE:
- case InfoBarDelegate::ERROR_TYPE:
*r = 255.0 / 255.0;
*g = 242.0 / 255.0;
*b = 183.0 / 255.0;
@@ -236,13 +240,7 @@ void InfoBar::GetTopColor(InfoBarDelegate::Type type,
void InfoBar::GetBottomColor(InfoBarDelegate::Type type,
double* r, double* g, double *b) {
switch (type) {
- case InfoBarDelegate::INFO_TYPE:
- *r = 146.0 / 255.0;
- *g = 205.0 / 255.0;
- *b = 114.0 / 255.0;
- break;
case InfoBarDelegate::WARNING_TYPE:
- case InfoBarDelegate::ERROR_TYPE:
*r = 250.0 / 255.0;
*g = 230.0 / 255.0;
*b = 145.0 / 255.0;
@@ -299,7 +297,7 @@ class AlertInfoBar : public InfoBar {
public:
explicit AlertInfoBar(AlertInfoBarDelegate* delegate)
: InfoBar(delegate) {
- AddLabelAndLink(delegate->GetMessageText(), std::wstring(), 0, 0, NULL);
+ AddLabelAndLink(delegate->GetMessageText(), string16(), NULL);
gtk_widget_show_all(border_bin_.get());
}
};
@@ -311,11 +309,10 @@ class LinkInfoBar : public InfoBar {
explicit LinkInfoBar(LinkInfoBarDelegate* delegate)
: InfoBar(delegate) {
size_t link_offset;
- std::wstring display_text =
- delegate->GetMessageTextWithOffset(&link_offset);
- std::wstring link_text = delegate->GetLinkText();
- AddLabelAndLink(display_text, link_text, link_offset, 0,
- G_CALLBACK(OnLinkClick));
+ string16 display_text = delegate->GetMessageTextWithOffset(&link_offset);
+ string16 link_text = delegate->GetLinkText();
+ AddLabelWithInlineLink(display_text, link_text, link_offset,
+ G_CALLBACK(OnLinkClick));
gtk_widget_show_all(border_bin_.get());
}
@@ -332,64 +329,88 @@ class LinkInfoBar : public InfoBar {
class ConfirmInfoBar : public InfoBar {
public:
- explicit ConfirmInfoBar(ConfirmInfoBarDelegate* 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());
- }
+ explicit ConfirmInfoBar(ConfirmInfoBarDelegate* delegate);
private:
// Adds a button to the info bar by type. It will do nothing if the delegate
// doesn't specify a button of the given type.
- void AddConfirmButton(ConfirmInfoBarDelegate::InfoBarButton type) {
- if (delegate_->AsConfirmInfoBarDelegate()->GetButtons() & type) {
- GtkWidget* button = gtk_button_new_with_label(WideToUTF8(
- delegate_->AsConfirmInfoBarDelegate()->GetButtonLabel(type)).c_str());
- gtk_util::CenterWidgetInHBox(hbox_, button, true, 0);
- g_signal_connect(button, "clicked",
- G_CALLBACK(type == ConfirmInfoBarDelegate::BUTTON_OK ?
- OnOkButton : OnCancelButton),
- this);
- }
- }
+ void AddButton(ConfirmInfoBarDelegate::InfoBarButton type);
- static void OnCancelButton(GtkWidget* button, ConfirmInfoBar* info_bar) {
- if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Cancel())
- info_bar->RemoveInfoBar();
- }
+ CHROMEGTK_CALLBACK_0(ConfirmInfoBar, void, OnOkButton);
+ CHROMEGTK_CALLBACK_0(ConfirmInfoBar, void, OnCancelButton);
+ CHROMEGTK_CALLBACK_0(ConfirmInfoBar, void, OnLinkClicked);
- static void OnOkButton(GtkWidget* button, ConfirmInfoBar* info_bar) {
- if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Accept())
- info_bar->RemoveInfoBar();
- }
+ GtkWidget* confirm_hbox_;
- static void OnLinkClick(GtkWidget* button, ConfirmInfoBar* link_info_bar) {
- if (link_info_bar->delegate_->AsConfirmInfoBarDelegate()->
- LinkClicked(gtk_util::DispositionForCurrentButtonPressEvent())) {
- link_info_bar->RemoveInfoBar();
- }
- }
+ DISALLOW_COPY_AND_ASSIGN(ConfirmInfoBar);
};
-// AlertInfoBarDelegate, InfoBarDelegate overrides: ----------------------------
+ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate)
+ : InfoBar(delegate) {
+ confirm_hbox_ = gtk_chrome_shrinkable_hbox_new(FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(hbox_), confirm_hbox_, TRUE, TRUE, 0);
+ gtk_widget_set_size_request(confirm_hbox_, 0, -1);
+
+ std::string label_text = UTF16ToUTF8(delegate->GetMessageText());
+ GtkWidget* label = gtk_label_new(label_text.c_str());
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_util::CenterWidgetInHBox(confirm_hbox_, label, false, kEndOfLabelSpacing);
+ g_signal_connect(label, "map",
+ G_CALLBACK(gtk_util::InitLabelSizeRequestAndEllipsizeMode),
+ NULL);
+
+ AddButton(ConfirmInfoBarDelegate::BUTTON_CANCEL);
+ AddButton(ConfirmInfoBarDelegate::BUTTON_OK);
+
+ std::string link_text = UTF16ToUTF8(delegate->GetLinkText());
+ GtkWidget* link = gtk_chrome_link_button_new(link_text.c_str());
+ gtk_misc_set_alignment(GTK_MISC(GTK_CHROME_LINK_BUTTON(link)->label), 0, 0.5);
+ g_signal_connect(link, "clicked", G_CALLBACK(OnLinkClickedThunk), this);
+ gtk_util::SetButtonTriggersNavigation(link);
+ // Until we switch to vector graphics, force the font size.
+ // 13.4px == 10pt @ 96dpi
+ gtk_util::ForceFontSizePixels(GTK_CHROME_LINK_BUTTON(link)->label, 13.4);
+ gtk_util::CenterWidgetInHBox(hbox_, link, true, kEndOfLabelSpacing);
+
+ gtk_widget_show_all(border_bin_.get());
+}
-InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
- return new AlertInfoBar(this);
+void ConfirmInfoBar::AddButton(ConfirmInfoBarDelegate::InfoBarButton type) {
+ if (delegate_->AsConfirmInfoBarDelegate()->GetButtons() & type) {
+ GtkWidget* button = gtk_button_new_with_label(UTF16ToUTF8(
+ delegate_->AsConfirmInfoBarDelegate()->GetButtonLabel(type)).c_str());
+ gtk_util::CenterWidgetInHBox(confirm_hbox_, button, false,
+ kButtonButtonSpacing);
+ g_signal_connect(button, "clicked",
+ G_CALLBACK(type == ConfirmInfoBarDelegate::BUTTON_OK ?
+ OnOkButtonThunk : OnCancelButtonThunk),
+ this);
+ }
}
-// LinkInfoBarDelegate, InfoBarDelegate overrides: -----------------------------
+void ConfirmInfoBar::OnCancelButton(GtkWidget* widget) {
+ if (delegate_->AsConfirmInfoBarDelegate()->Cancel())
+ RemoveInfoBar();
+}
-InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
- return new LinkInfoBar(this);
+void ConfirmInfoBar::OnOkButton(GtkWidget* widget) {
+ if (delegate_->AsConfirmInfoBarDelegate()->Accept())
+ RemoveInfoBar();
}
-// ConfirmInfoBarDelegate, InfoBarDelegate overrides: --------------------------
+void ConfirmInfoBar::OnLinkClicked(GtkWidget* widget) {
+ if (delegate_->AsConfirmInfoBarDelegate()->LinkClicked(
+ gtk_util::DispositionForCurrentButtonPressEvent())) {
+ RemoveInfoBar();
+ }
+}
+InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
+ return new AlertInfoBar(this);
+}
+InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
+ return new LinkInfoBar(this);
+}
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
return new ConfirmInfoBar(this);
}