Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1072)

Unified Diff: chrome/browser/gtk/infobar_gtk.cc

Issue 160084: Chaos geolocation demo, non-WebKit part. Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/gtk/infobar_gtk.h ('k') | chrome/browser/gtk/standard_menus.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/gtk/infobar_gtk.cc
===================================================================
--- chrome/browser/gtk/infobar_gtk.cc (revision 23543)
+++ chrome/browser/gtk/infobar_gtk.cc (working copy)
@@ -10,7 +10,10 @@
#include "base/string_util.h"
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/browser/gtk/gtk_chrome_link_button.h"
+#include "chrome/browser/gtk/gtk_skinny_button.h"
#include "chrome/browser/gtk/infobar_container_gtk.h"
+#include "chrome/browser/tab_contents/customize_geoloc_infobar_delegate.h"
+#include "chrome/browser/tab_contents/geoloc_infobar_delegate.h"
#include "chrome/browser/tab_contents/infobar_delegate.h"
#include "chrome/common/gtk_util.h"
@@ -35,7 +38,8 @@
const int kRightPadding = 5;
static gboolean OnBackgroundExpose(GtkWidget* widget, GdkEventExpose* event,
- gpointer unused) {
+ InfoBarStyle *style) {
+ CHECK(style);
const int height = widget->allocation.height;
cairo_t* cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
@@ -46,11 +50,13 @@
cairo_pattern_t* pattern = cairo_pattern_create_linear(0, 0, 0, height);
cairo_pattern_add_color_stop_rgb(
pattern, 0.0,
- kBackgroundColorTop[0], kBackgroundColorTop[1], kBackgroundColorTop[2]);
+ style->gradient_top_[0], style->gradient_top_[1],
+ style->gradient_top_[2]);
cairo_pattern_add_color_stop_rgb(
pattern, 1.0,
- kBackgroundColorBottom[0], kBackgroundColorBottom[1],
- kBackgroundColorBottom[2]);
+ style->gradient_bottom_[0], style->gradient_bottom_[1],
+ style->gradient_bottom_[2]);
+
cairo_set_source(cr, pattern);
cairo_paint(cr);
cairo_pattern_destroy(pattern);
@@ -61,10 +67,39 @@
}
} // namespace
+InfoBarStyle::InfoBarStyle(const double top[3],
+ const double bottom[3],
+ int height,
+ GdkColor text_color,
+ bool even)
+ : height_(height),
+ text_color_(text_color),
+ even_(even) {
+ memcpy(gradient_top_, top, sizeof(gradient_top_));
+ memcpy(gradient_bottom_, bottom, sizeof(gradient_bottom_));
+}
+InfoBarStyle::InfoBarStyle() : height_(0), even_(true) {
+ memset(gradient_top_, 0, sizeof(gradient_top_));
+ memset(gradient_bottom_, 0, sizeof(gradient_bottom_));
+}
InfoBar::InfoBar(InfoBarDelegate* delegate)
: container_(NULL),
delegate_(delegate) {
+ GtkWidget* outer_hbox = gtk_hbox_new(FALSE, kElementPadding);
+
+ if (!delegate->GetStyle()) {
+ InfoBarStyle def(kBackgroundColorTop,
+ kBackgroundColorBottom,
+ kInfoBarHeight,
+ gfx::kGdkBlack,
+ true);
+ style_ = def;
+ } else {
+ style_ = *(delegate->GetStyle());
+ }
+
+ vbox_ = gtk_vbox_new(style_.even_, 0);
// Create |hbox_| and pad the sides.
hbox_ = gtk_hbox_new(FALSE, kElementPadding);
GtkWidget* padding = gtk_alignment_new(0, 0, 1, 1);
@@ -74,11 +109,11 @@
GtkWidget* bg_box = gtk_event_box_new();
gtk_widget_set_app_paintable(bg_box, TRUE);
g_signal_connect(bg_box, "expose-event",
- G_CALLBACK(OnBackgroundExpose), NULL);
- gtk_container_add(GTK_CONTAINER(padding), hbox_);
+ G_CALLBACK(OnBackgroundExpose), &style_);
+ gtk_container_add(GTK_CONTAINER(padding), outer_hbox);
gtk_container_add(GTK_CONTAINER(bg_box), padding);
// The -1 on the kInfoBarHeight is to account for the border.
- gtk_widget_set_size_request(bg_box, -1, kInfoBarHeight - 1);
+ gtk_widget_set_size_request(bg_box, -1, style_.height_ - 1);
border_bin_.Own(gtk_util::CreateGtkBorderBin(bg_box, &kBorderColor,
0, 1, 0, 0));
@@ -89,9 +124,12 @@
GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(icon);
GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf);
g_object_unref(pixbuf);
- gtk_box_pack_start(GTK_BOX(hbox_), image, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(outer_hbox), image, FALSE, FALSE, 0);
}
+ gtk_box_pack_start(GTK_BOX(outer_hbox), vbox_, true, true, 0);
+ gtk_box_pack_start(GTK_BOX(vbox_), hbox_, false, false, style_.even_ ? 0 : kElementPadding);
+
// TODO(erg): GTK theme the info bar.
close_button_.reset(CustomDrawButton::CloseButton(NULL));
gtk_util::CenterWidgetInHBox(hbox_, close_button_->widget(), true, 0);
@@ -162,12 +200,16 @@
AlertInfoBar(AlertInfoBarDelegate* delegate)
: InfoBar(delegate) {
std::wstring text = delegate->GetMessageText();
- GtkWidget* label = gtk_label_new(WideToUTF8(text).c_str());
- gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
- gtk_box_pack_start(GTK_BOX(hbox_), label, FALSE, FALSE, 0);
+ label_ = gtk_label_new(WideToUTF8(text).c_str());
+ gtk_widget_modify_fg(label_, GTK_STATE_NORMAL, &(style_.text_color_));
+ //gtk_box_pack_start(GTK_BOX(hbox_), label_, FALSE, FALSE, 0);
+ gtk_util::CenterWidgetInHBox(hbox_, label_, false, 0);
gtk_widget_show_all(border_bin_.get());
}
+ protected:
+ // The label for the alert.
+ GtkWidget* label_;
};
// LinkInfoBar -----------------------------------------------------------------
@@ -195,7 +237,7 @@
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());
- gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
+ gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &(style_.text_color_));
gtk_box_pack_start(GTK_BOX(hbox_), label, FALSE, FALSE, 0);
} else {
GtkWidget* initial_label = gtk_label_new(
@@ -203,8 +245,12 @@
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);
+ gtk_widget_modify_fg(initial_label,
+ GTK_STATE_NORMAL,
+ &(style_.text_color_));
+ gtk_widget_modify_fg(trailing_label,
+ GTK_STATE_NORMAL,
+ &(style_.text_color_));
// We don't want any spacing between the elements, so we pack them into
// this hbox that doesn't use kElementPadding.
@@ -259,6 +305,7 @@
G_CALLBACK(type == ConfirmInfoBarDelegate::BUTTON_OK ?
OnOkButton : OnCancelButton),
this);
+ gtk_container_set_border_width(GTK_CONTAINER(button), 0);
}
}
@@ -273,6 +320,223 @@
}
};
+// GeolocInfoBar ---------------------------------------------------------------
+
+class GeolocInfoBar : public AlertInfoBar {
+ public:
+ GeolocInfoBar(GeolocInfoBarDelegate* delegate)
+ : AlertInfoBar(delegate) {
+ button_box_ = gtk_hbox_new(FALSE, kElementPadding);
+ AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_OK);
+ AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_CANCEL);
+ gtk_box_pack_start(GTK_BOX(vbox_), button_box_, FALSE, FALSE, 0);
+
+ std::wstring text = delegate->GetMessageText();
+ gtk_label_set_markup(GTK_LABEL(label_), WideToUTF8(text).c_str());
+
+ GtkWidget* linkbox = CreateLinkButtons(delegate);
+ GtkWidget* checkbox = CreateRememberCheckbox(delegate);
+
+ gtk_box_pack_start(GTK_BOX(button_box_), checkbox, FALSE, FALSE, 0);
+ gtk_box_pack_end(GTK_BOX(button_box_), linkbox, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(border_bin_.get());
+ }
+
+ private:
+ GtkWidget* CreateLinkButtons(GeolocInfoBarDelegate* delegate) {
+ std::wstring customize_text = delegate->GetCustomizeText();
+ std::wstring learn_more_text = delegate->GetLearnMoreText();
+
+ GtkWidget* linkbox = gtk_hbox_new(FALSE, kElementPadding);
+ GtkWidget* customize_link = gtk_chrome_link_button_new_with_markup(
+ WideToUTF8(customize_text).c_str());
+ GtkWidget* learn_more_link = gtk_chrome_link_button_new_with_markup(
+ WideToUTF8(learn_more_text).c_str());
+
+ g_signal_connect(customize_link, "clicked",
+ G_CALLBACK(OnCustomizeClick), this);
+ g_signal_connect(learn_more_link, "clicked",
+ G_CALLBACK(OnLearnMoreClick), this);
+
+ gtk_box_pack_end(GTK_BOX(linkbox), customize_link, FALSE, FALSE, 0);
+ gtk_box_pack_end(GTK_BOX(linkbox), learn_more_link, FALSE, FALSE, 0);
+ return linkbox;
+ }
+
+ GtkWidget* CreateRememberCheckbox(GeolocInfoBarDelegate* delegate) {
+ GtkWidget* checkbox = gtk_hbox_new(FALSE, kElementPadding);
+ GtkWidget* check_button = gtk_check_button_new();
+ GtkWidget* remember = gtk_label_new("Remember for this site");
+ gtk_box_pack_start(GTK_BOX(checkbox), check_button, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(checkbox), remember, FALSE, FALSE, 0);
+ gtk_widget_modify_fg(remember, GTK_STATE_NORMAL, &(style_.text_color_));
+ return checkbox;
+ }
+
+ // 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) {
+ GeolocInfoBarDelegate *delegate = delegate_->AsGeolocInfoBarDelegate();
+ if (delegate->GetButtons() & type) {
+ GtkWidget* button = gtk_skinny_button_new_with_label(WideToUTF8(
+ delegate->GetButtonLabel(type)).c_str());
+ gtk_util::CenterWidgetInHBox(button_box_, button, false, 0);
+ g_signal_connect(button, "clicked",
+ G_CALLBACK(type == ConfirmInfoBarDelegate::BUTTON_OK ?
+ OnOkButton : OnCancelButton),
+ this);
+ }
+ }
+
+ static void OnCancelButton(GtkWidget* button, GeolocInfoBar* info_bar) {
+ if (info_bar->delegate_->AsGeolocInfoBarDelegate()->Cancel())
+ info_bar->RemoveInfoBar();
+ }
+
+ static void OnOkButton(GtkWidget* button, GeolocInfoBar* info_bar) {
+ if (info_bar->delegate_->AsGeolocInfoBarDelegate()->Accept())
+ info_bar->RemoveInfoBar();
+ }
+
+
+
+ private:
+ static WindowOpenDisposition GetDisposition(GtkWidget* button) {
+ const GdkEventButton* button_click_event =
+ reinterpret_cast<GdkEventButton*>(gtk_get_current_event());
+ WindowOpenDisposition disposition = CURRENT_TAB;
+ if (button_click_event) {
+ disposition = event_utils::DispositionFromEventFlags(
+ button_click_event->state);
+ }
+ return disposition;
+ }
+ static void OnCustomizeClick(GtkWidget* button, GeolocInfoBar* info_bar) {
+ WindowOpenDisposition disposition = GetDisposition(button);
+ if (info_bar->delegate_->AsGeolocInfoBarDelegate()->
+ CustomizeClicked(disposition)) {
+ info_bar->RemoveInfoBar();
+ }
+ }
+ static void OnLearnMoreClick(GtkWidget* button, GeolocInfoBar* info_bar) {
+ WindowOpenDisposition disposition = GetDisposition(button);
+ if (info_bar->delegate_->AsGeolocInfoBarDelegate()->
+ LearnMoreClicked(disposition)) {
+ info_bar->RemoveInfoBar();
+ }
+ }
+
+ // The hbox that holds the buttons.
+ GtkWidget* button_box_;
+};
+
+class CustomizeGeolocInfoBar : public AlertInfoBar {
+ public:
+ CustomizeGeolocInfoBar(CustomizeGeolocInfoBarDelegate* delegate)
+ : AlertInfoBar(delegate) {
+ std::wstring text = delegate->GetMessageText();
+ gtk_label_set_markup(GTK_LABEL(label_), WideToUTF8(text).c_str());
+
+
+ GtkWidget *hbox = gtk_hbox_new(FALSE, kElementPadding);
+ text = delegate->GetAuxiliaryText();
+ GtkWidget *label = gtk_label_new(WideToUTF8(text).c_str());
+ gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &(style_.text_color_));
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox_), hbox, false, false, 0);
+
+ button_box_ = gtk_hbox_new(FALSE, kElementPadding);
+ AddCustomizeButton(CustomizeGeolocInfoBarDelegate::BUTTON_BEST);
+ AddCustomizeButton(CustomizeGeolocInfoBarDelegate::BUTTON_CITY);
+ AddCustomizeButton(CustomizeGeolocInfoBarDelegate::BUTTON_NONE);
+
+ gtk_box_pack_start(GTK_BOX(vbox_), button_box_, FALSE, FALSE, kElementPadding*2);
+
+ GtkWidget* checkbox = CreateRememberCheckbox(delegate);
+ gtk_box_pack_start(GTK_BOX(hbox), checkbox, FALSE, FALSE, 0);
+
+ gtk_widget_show_all(border_bin_.get());
+ }
+
+ 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 AddCustomizeButton(CustomizeGeolocInfoBarDelegate::GeolocButton type) {
+ GtkWidget* box = gtk_vbox_new(FALSE, kElementPadding);
+
+ CustomizeGeolocInfoBarDelegate *delegate =
+ delegate_->AsCustomizeGeolocInfoBarDelegate();
+ GtkWidget* button = gtk_button_new();
+ GtkWidget* label = gtk_label_new(WideToUTF8(
+ delegate->GetGeolocButtonLabel(type)).c_str());
+ gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &(style_.text_color_));
+
+ SkBitmap* icon = delegate->GetGeolocButtonImage(type);
+ if (icon) {
+ GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(icon);
+ gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_pixbuf(pixbuf));
+ g_object_unref(pixbuf);
+ }
+ gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(button_box_), box, true, FALSE, 0);
+ ConnectButton(button, type);
+ gtk_container_set_border_width(GTK_CONTAINER(button), 0);
+ }
+
+ GtkWidget* CreateRememberCheckbox(CustomizeGeolocInfoBarDelegate* delegate) {
+ GtkWidget* checkbox = gtk_hbox_new(FALSE, kElementPadding);
+ GtkWidget* check_button = gtk_check_button_new();
+ GtkWidget* remember = gtk_label_new("Remember for this site");
+ gtk_box_pack_start(GTK_BOX(checkbox), check_button, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(checkbox), remember, FALSE, FALSE, 0);
+ gtk_widget_modify_fg(remember, GTK_STATE_NORMAL, &(style_.text_color_));
+ return checkbox;
+ }
+
+ void ConnectButton(GtkWidget *button,
+ CustomizeGeolocInfoBarDelegate::GeolocButton type) {
+ switch(type) {
+ case CustomizeGeolocInfoBarDelegate::BUTTON_BEST:
+ g_signal_connect(button, "clicked", G_CALLBACK(OnBestClick), this);
+ break;
+ case CustomizeGeolocInfoBarDelegate::BUTTON_CITY:
+ g_signal_connect(button, "clicked", G_CALLBACK(OnCityClick), this);
+ break;
+ case CustomizeGeolocInfoBarDelegate::BUTTON_NONE:
+ g_signal_connect(button, "clicked", G_CALLBACK(OnNoneClick), this);
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+
+ static void OnBestClick(GtkWidget* button, CustomizeGeolocInfoBar* info_bar) {
+ if (info_bar->delegate_->AsCustomizeGeolocInfoBarDelegate()
+ ->OnGeolocButtonClick(CustomizeGeolocInfoBarDelegate::BUTTON_BEST))
+ info_bar->RemoveInfoBar();
+ }
+
+ static void OnCityClick(GtkWidget* button, CustomizeGeolocInfoBar* info_bar) {
+ if (info_bar->delegate_->AsCustomizeGeolocInfoBarDelegate()
+ ->OnGeolocButtonClick(CustomizeGeolocInfoBarDelegate::BUTTON_CITY))
+ info_bar->RemoveInfoBar();
+ }
+
+ static void OnNoneClick(GtkWidget* button, CustomizeGeolocInfoBar* info_bar) {
+ if (info_bar->delegate_->AsCustomizeGeolocInfoBarDelegate()
+ ->OnGeolocButtonClick(CustomizeGeolocInfoBarDelegate::BUTTON_NONE))
+ info_bar->RemoveInfoBar();
+ }
+
+ // The hbox that holds the buttons.
+ GtkWidget* button_box_;
+
+};
+
// AlertInfoBarDelegate, InfoBarDelegate overrides: ----------------------------
InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
@@ -290,3 +554,15 @@
InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
return new ConfirmInfoBar(this);
}
+
+// GeolocInfoBarDelegate, InfoBarDelegate overrides: --------------------_------
+
+InfoBar* GeolocInfoBarDelegate::CreateInfoBar() {
+ return new GeolocInfoBar(this);
+}
+
+// CustomizeGeolocInfoBarDelegate, InfoBarDelegate overrides: ------------------
+
+InfoBar* CustomizeGeolocInfoBarDelegate::CreateInfoBar() {
+ return new CustomizeGeolocInfoBar(this);
+}
« no previous file with comments | « chrome/browser/gtk/infobar_gtk.h ('k') | chrome/browser/gtk/standard_menus.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698