Chromium Code Reviews| Index: chrome/browser/ui/gtk/content_setting_bubble_gtk.cc |
| diff --git a/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc b/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc |
| index 6430802bc681250bf961a288d1c077e789fa75d9..fb100ac3e2950fe2044e3685dbb3b6be5c034452 100644 |
| --- a/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc |
| +++ b/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc |
| @@ -8,13 +8,17 @@ |
| #include <string> |
| #include <vector> |
| +#include "base/bind.h" |
| #include "base/i18n/rtl.h" |
| +#include "base/prefs/pref_service.h" |
| +#include "base/stl_util.h" |
| #include "base/utf_string_conversions.h" |
| #include "chrome/browser/content_settings/host_content_settings_map.h" |
| #include "chrome/browser/plugins/plugin_finder.h" |
| #include "chrome/browser/plugins/plugin_metadata.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" |
| +#include "chrome/browser/ui/content_settings/content_setting_media_menu_model.h" |
| #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" |
| #include "chrome/browser/ui/gtk/gtk_theme_service.h" |
| #include "chrome/browser/ui/gtk/gtk_util.h" |
| @@ -27,6 +31,7 @@ |
| #include "grit/ui_resources.h" |
| #include "ui/base/gtk/gtk_hig_constants.h" |
| #include "ui/base/l10n/l10n_util.h" |
| +#include "ui/base/models/simple_menu_model.h" |
| #include "ui/base/text/text_elider.h" |
| #include "ui/gfx/gtk_util.h" |
| @@ -39,6 +44,9 @@ namespace { |
| // longer than this. |
| const int kMaxLinkPixelSize = 500; |
| +// The minimum width of the media menu button. |
| +const int kMinMediaMenuButtonWidth = 100; |
| + |
| std::string BuildElidedText(const std::string& input) { |
| return UTF16ToUTF8(ui::ElideText( |
| UTF8ToUTF16(input), |
| @@ -70,10 +78,24 @@ ContentSettingBubbleGtk::~ContentSettingBubbleGtk() { |
| } |
| void ContentSettingBubbleGtk::Close() { |
| + STLDeleteValues(&media_menus_); |
| + |
| if (bubble_) |
| bubble_->Close(); |
| } |
| +void ContentSettingBubbleGtk::UpdateMenuLabel(content::MediaStreamType type, |
| + const std::string& label) { |
| + GtkMediaMenuMap::const_iterator it = media_menus_.begin(); |
| + for (; it != media_menus_.end(); ++it) { |
| + if (it->second->type == type) { |
| + gtk_label_set_text(GTK_LABEL(it->second->label.get()), label.c_str()); |
| + return; |
| + } |
| + } |
| + NOTREACHED(); |
| +} |
| + |
| void ContentSettingBubbleGtk::BubbleClosing(BubbleGtk* bubble, |
| bool closed_by_escape) { |
| delegate_->BubbleClosing(bubble, closed_by_escape); |
| @@ -196,6 +218,67 @@ void ContentSettingBubbleGtk::BuildBubble() { |
| g_signal_connect(*i, "toggled", G_CALLBACK(OnRadioToggledThunk), this); |
| } |
| + // Layout code for the media device menus. |
| + if (content_setting_bubble_model_->content_type() == |
| + CONTENT_SETTINGS_TYPE_MEDIASTREAM) { |
| + GtkWidget* table = gtk_table_new(content.media_menus.size(), 2, FALSE); |
| + int menu_width = 0; |
| + int row = 0; |
| + for (ContentSettingBubbleModel::MediaMenuMap::const_iterator |
| + i(content.media_menus.begin()); |
| + i != content.media_menus.end(); |
| + ++i, ++row) { |
| + GtkWidget* label = theme_provider->BuildLabel( |
| + i->second.label.c_str(), ui::kGdkBlack); |
| + gtk_table_attach(GTK_TABLE(table), gtk_util::LeftAlignMisc(label), 0, 1, |
| + row, row + 1, GTK_FILL, GTK_FILL, |
| + ui::kControlSpacing / 2, ui::kControlSpacing / 2); |
| + |
| + // Build up the gtk menu button. |
| + MediaMenuGtk* gtk_menu = new MediaMenuGtk(i->first); |
| + gtk_menu->label.Own( |
| + gtk_label_new(i->second.selected_device.name.c_str())); |
| + GtkWidget* button = gtk_button_new(); |
| + GtkWidget* button_content = gtk_hbox_new(FALSE, 0); |
| + gtk_box_pack_start(GTK_BOX(button_content), |
| + gtk_util::LeftAlignMisc(gtk_menu->label.get()), |
| + FALSE, FALSE, 0); |
| + GtkWidget* arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE); |
| + gtk_box_pack_end(GTK_BOX(button_content), arrow, FALSE, FALSE, 0); |
| + |
| + gtk_container_add(GTK_CONTAINER(button), button_content); |
| + |
| + // Store the gtk menu to the map. |
| + gtk_menu->menu_model.reset(new ContentSettingMediaMenuModel( |
| + profile_->GetPrefs(), |
| + gtk_menu->type, |
| + content_setting_bubble_model_.get(), |
| + base::Bind(&ContentSettingBubbleGtk::UpdateMenuLabel, |
| + base::Unretained(this)))); |
| + gtk_menu->menu.reset(new MenuGtk(NULL, gtk_menu->menu_model.get())); |
| + media_menus_[button] = gtk_menu; |
| + |
| + // Calculate the optimal width for the menu buttons. |
|
Peter Kasting
2013/02/18 18:23:18
You should apply my comments about the views code
no longer working on chromium
2013/02/19 14:37:36
Done.
|
| + GtkRequisition menu_req; |
| + gtk_widget_size_request(gtk_menu->menu->widget(), &menu_req); |
| + menu_width = std::max(menu_width, menu_req.width); |
| + menu_width = std::max(menu_width, kMinMediaMenuButtonWidth); |
| + |
| + g_signal_connect(button, "clicked", G_CALLBACK(OnMenuButtonClickedThunk), |
| + this); |
| + gtk_table_attach(GTK_TABLE(table), button, 1, 2, row, row + 1, |
| + GTK_FILL, GTK_FILL, ui::kControlSpacing * 2, |
| + ui::kControlSpacing / 2); |
| + } |
| + |
| + // Set the optimal width for the menu buttons. |
| + for (GtkMediaMenuMap::const_iterator i = media_menus_.begin(); |
| + i != media_menus_.end(); ++i) |
| + gtk_widget_set_size_request(i->first, menu_width, -1); |
| + |
| + gtk_box_pack_start(GTK_BOX(bubble_content), table, FALSE, FALSE, 0); |
| + } |
| + |
| for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i = |
| content.domain_lists.begin(); |
| i != content.domain_lists.end(); ++i) { |
| @@ -253,7 +336,6 @@ void ContentSettingBubbleGtk::BuildBubble() { |
| g_signal_connect(button, "clicked", G_CALLBACK(OnCloseButtonClickedThunk), |
| this); |
| gtk_box_pack_end(GTK_BOX(bottom_box), button, FALSE, FALSE, 0); |
| - |
| gtk_box_pack_start(GTK_BOX(bubble_content), bottom_box, FALSE, FALSE, 0); |
| gtk_widget_grab_focus(bottom_box); |
| gtk_widget_grab_focus(button); |
| @@ -316,3 +398,15 @@ void ContentSettingBubbleGtk::OnManageLinkClicked(GtkWidget* button) { |
| content_setting_bubble_model_->OnManageLinkClicked(); |
| Close(); |
| } |
| + |
| +void ContentSettingBubbleGtk::OnMenuButtonClicked(GtkWidget* button) { |
| + GtkMediaMenuMap::iterator i(media_menus_.find(button)); |
| + DCHECK(i != media_menus_.end()); |
| + i->second->menu->PopupForWidget(button, 1, gtk_get_current_event_time()); |
| +} |
| + |
| +ContentSettingBubbleGtk::MediaMenuGtk::MediaMenuGtk( |
| + content::MediaStreamType type) |
| + : type(type) {} |
| + |
| +ContentSettingBubbleGtk::MediaMenuGtk::~MediaMenuGtk() {} |