| 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..91348b366e20832bc1b104062c1ea66ddbef902d 100644
|
| --- a/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc
|
| +++ b/chrome/browser/ui/gtk/content_setting_bubble_gtk.cc
|
| @@ -27,6 +27,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 +40,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 +77,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();
|
| + 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;
|
| + }
|
| + }
|
| + DCHECK(it != media_menus_.end());
|
| +}
|
| +
|
| void ContentSettingBubbleGtk::BubbleClosing(BubbleGtk* bubble,
|
| bool closed_by_escape) {
|
| delegate_->BubbleClosing(bubble, closed_by_escape);
|
| @@ -196,6 +222,51 @@ 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();
|
| + ++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();
|
| + gtk_menu->type = 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 +324,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 +386,21 @@ 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(),
|
| + 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() {
|
| +}
|
| +
|
| +ContentSettingBubbleGtk::MediaMenuGtk::~MediaMenuGtk() {
|
| +}
|
|
|