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..4f73496627d34246cc64ca9e9dbc127859eef29f 100644 |
| --- a/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc |
| +++ b/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc |
| @@ -8,6 +8,7 @@ |
| #include <string> |
| #include <vector> |
| +#include "base/bind.h" |
| #include "base/i18n/rtl.h" |
| #include "base/utf_string_conversions.h" |
| #include "chrome/browser/content_settings/host_content_settings_map.h" |
| @@ -15,6 +16,7 @@ |
| #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 +29,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 +42,12 @@ namespace { |
| // longer than this. |
| const int kMaxLinkPixelSize = 500; |
| +// The width in characters of the label of media menu button. |
| +const int kMediaMenuButtonLabelWidthInChars = 16; |
| + |
| +// The width of the media menu button. |
| +const int kMediaMenuButtonWidth = 150; |
| + |
| std::string BuildElidedText(const std::string& input) { |
| return UTF16ToUTF8(ui::ElideText( |
| UTF8ToUTF16(input), |
| @@ -70,10 +79,29 @@ ContentSettingBubbleGtk::~ContentSettingBubbleGtk() { |
| } |
| void ContentSettingBubbleGtk::Close() { |
| + // Free any MediaMenuGtk objects left over. |
| + for (GtkMediaMenuMap::const_iterator it = media_menus_.begin(); |
| + it != media_menus_.end(); ++it) { |
| + it->second->label.Destroy(); |
|
Evan Stade
2013/02/06 22:07:07
I don't think this should be necessary, and instea
no longer working on chromium
2013/02/07 16:25:19
I changed the code to use STLDeleteValues.
The com
Evan Stade
2013/02/11 20:40:15
yea, sounds like it.
|
| + delete it->second; |
| + } |
| + |
| 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()); |
| + break; |
|
Evan Stade
2013/02/06 22:07:07
make this a return and put a NOTREACHED at the end
no longer working on chromium
2013/02/07 16:25:19
Done.
|
| + } |
| + } |
| + DCHECK(it != media_menus_.end()); |
| +} |
| + |
| void ContentSettingBubbleGtk::BubbleClosing(BubbleGtk* bubble, |
| bool closed_by_escape) { |
| delegate_->BubbleClosing(bubble, closed_by_escape); |
| @@ -196,6 +224,50 @@ 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 row = 0; |
| + for (ContentSettingBubbleModel::MediaMenuMap::const_iterator |
| + i(content.media_menus.begin()); i != content.media_menus.end(); |
|
Evan Stade
2013/02/06 22:07:07
4 more indent and put the termination condition on
no longer working on chromium
2013/02/07 16:25:19
Done.
|
| + ++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); |
| + gtk_label_set_width_chars(GTK_LABEL(gtk_menu->label.get()), |
| + kMediaMenuButtonLabelWidthInChars); |
| + GtkWidget* arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE); |
| + gtk_box_pack_end(GTK_BOX(button_content), arrow, FALSE, FALSE, 0); |
| + gtk_widget_set_size_request(button_content, kMediaMenuButtonWidth, -1); |
| + gtk_container_add(GTK_CONTAINER(button), button_content); |
| + |
| + // Store the gtk menu to the map. |
| + media_menus_[button] = gtk_menu; |
| + |
| + 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); |
| + } |
| + |
| + 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 +325,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 +387,24 @@ 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_model.reset(new ContentSettingMediaMenuModel( |
| + profile_, |
| + i->second->type, |
| + content_setting_bubble_model_.get(), |
| + base::Bind(&ContentSettingBubbleGtk::UpdateMenuLabel, |
| + base::Unretained(this)))); |
| + i->second->menu.reset(new MenuGtk(NULL, i->second->menu_model.get())); |
| + i->second->menu->PopupForWidget(button, 1, gtk_get_current_event_time()); |
| +} |
| + |
| +ContentSettingBubbleGtk::MediaMenuGtk::MediaMenuGtk( |
| + content::MediaStreamType type) |
| + : type(type) { |
| +} |
| + |
| +ContentSettingBubbleGtk::MediaMenuGtk::~MediaMenuGtk() { |
| +} |