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

Side by Side Diff: chrome/browser/ui/gtk/content_setting_bubble_gtk.cc

Issue 12208010: Adding device selection menus to the content setting bubble (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Used callback instead of inheriting from a virtual interface Created 7 years, 10 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/gtk/content_setting_bubble_gtk.h" 5 #include "chrome/browser/ui/gtk/content_setting_bubble_gtk.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h"
11 #include "base/i18n/rtl.h" 12 #include "base/i18n/rtl.h"
12 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/content_settings/host_content_settings_map.h" 14 #include "chrome/browser/content_settings/host_content_settings_map.h"
14 #include "chrome/browser/plugins/plugin_finder.h" 15 #include "chrome/browser/plugins/plugin_finder.h"
15 #include "chrome/browser/plugins/plugin_metadata.h" 16 #include "chrome/browser/plugins/plugin_metadata.h"
16 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" 18 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
19 #include "chrome/browser/ui/content_settings/content_setting_media_menu_model.h"
18 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" 20 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
19 #include "chrome/browser/ui/gtk/gtk_theme_service.h" 21 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
20 #include "chrome/browser/ui/gtk/gtk_util.h" 22 #include "chrome/browser/ui/gtk/gtk_util.h"
21 #include "chrome/common/content_settings.h" 23 #include "chrome/common/content_settings.h"
22 #include "content/public/browser/notification_source.h" 24 #include "content/public/browser/notification_source.h"
23 #include "content/public/browser/notification_types.h" 25 #include "content/public/browser/notification_types.h"
24 #include "content/public/browser/plugin_service.h" 26 #include "content/public/browser/plugin_service.h"
25 #include "content/public/browser/web_contents.h" 27 #include "content/public/browser/web_contents.h"
26 #include "grit/generated_resources.h" 28 #include "grit/generated_resources.h"
27 #include "grit/ui_resources.h" 29 #include "grit/ui_resources.h"
28 #include "ui/base/gtk/gtk_hig_constants.h" 30 #include "ui/base/gtk/gtk_hig_constants.h"
29 #include "ui/base/l10n/l10n_util.h" 31 #include "ui/base/l10n/l10n_util.h"
32 #include "ui/base/models/simple_menu_model.h"
30 #include "ui/base/text/text_elider.h" 33 #include "ui/base/text/text_elider.h"
31 #include "ui/gfx/gtk_util.h" 34 #include "ui/gfx/gtk_util.h"
32 35
33 using content::PluginService; 36 using content::PluginService;
34 using content::WebContents; 37 using content::WebContents;
35 38
36 namespace { 39 namespace {
37 40
38 // The maximum width of a title entry in the content box. We elide anything 41 // The maximum width of a title entry in the content box. We elide anything
39 // longer than this. 42 // longer than this.
40 const int kMaxLinkPixelSize = 500; 43 const int kMaxLinkPixelSize = 500;
41 44
45 // The width in characters of the label of media menu button.
46 const int kMediaMenuButtonLabelWidthInChars = 16;
47
48 // The width of the media menu button.
49 const int kMediaMenuButtonWidth = 150;
50
42 std::string BuildElidedText(const std::string& input) { 51 std::string BuildElidedText(const std::string& input) {
43 return UTF16ToUTF8(ui::ElideText( 52 return UTF16ToUTF8(ui::ElideText(
44 UTF8ToUTF16(input), 53 UTF8ToUTF16(input),
45 gfx::Font(), 54 gfx::Font(),
46 kMaxLinkPixelSize, 55 kMaxLinkPixelSize,
47 ui::ELIDE_AT_END)); 56 ui::ELIDE_AT_END));
48 } 57 }
49 58
50 } // namespace 59 } // namespace
51 60
(...skipping 11 matching lines...) Expand all
63 bubble_(NULL) { 72 bubble_(NULL) {
64 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 73 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
65 content::Source<WebContents>(web_contents)); 74 content::Source<WebContents>(web_contents));
66 BuildBubble(); 75 BuildBubble();
67 } 76 }
68 77
69 ContentSettingBubbleGtk::~ContentSettingBubbleGtk() { 78 ContentSettingBubbleGtk::~ContentSettingBubbleGtk() {
70 } 79 }
71 80
72 void ContentSettingBubbleGtk::Close() { 81 void ContentSettingBubbleGtk::Close() {
82 // Free any MediaMenuGtk objects left over.
83 for (GtkMediaMenuMap::const_iterator it = media_menus_.begin();
84 it != media_menus_.end(); ++it) {
85 it->second->label.Destroy();
86 delete it->second;
87 }
88
73 if (bubble_) 89 if (bubble_)
74 bubble_->Close(); 90 bubble_->Close();
75 } 91 }
76 92
93 void ContentSettingBubbleGtk::UpdateMenuLabel(content::MediaStreamType type,
94 const std::string& label) {
95 GtkMediaMenuMap::const_iterator it = media_menus_.begin();
96 for (; it != media_menus_.end(); ++it) {
97 if (it->second->type == type) {
98 gtk_label_set_text(GTK_LABEL(it->second->label.get()), label.c_str());
99 break;
100 }
101 }
102 DCHECK(it != media_menus_.end());
103 }
104
77 void ContentSettingBubbleGtk::BubbleClosing(BubbleGtk* bubble, 105 void ContentSettingBubbleGtk::BubbleClosing(BubbleGtk* bubble,
78 bool closed_by_escape) { 106 bool closed_by_escape) {
79 delegate_->BubbleClosing(bubble, closed_by_escape); 107 delegate_->BubbleClosing(bubble, closed_by_escape);
80 delete this; 108 delete this;
81 } 109 }
82 110
83 void ContentSettingBubbleGtk::Observe( 111 void ContentSettingBubbleGtk::Observe(
84 int type, 112 int type,
85 const content::NotificationSource& source, 113 const content::NotificationSource& source,
86 const content::NotificationDetails& details) { 114 const content::NotificationDetails& details) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 if (!content.radio_group_enabled) 217 if (!content.radio_group_enabled)
190 gtk_widget_set_sensitive(radio, FALSE); 218 gtk_widget_set_sensitive(radio, FALSE);
191 radio_group_gtk_.push_back(radio); 219 radio_group_gtk_.push_back(radio);
192 } 220 }
193 for (std::vector<GtkWidget*>::const_iterator i = radio_group_gtk_.begin(); 221 for (std::vector<GtkWidget*>::const_iterator i = radio_group_gtk_.begin();
194 i != radio_group_gtk_.end(); ++i) { 222 i != radio_group_gtk_.end(); ++i) {
195 // We can attach signal handlers now that all defaults are set. 223 // We can attach signal handlers now that all defaults are set.
196 g_signal_connect(*i, "toggled", G_CALLBACK(OnRadioToggledThunk), this); 224 g_signal_connect(*i, "toggled", G_CALLBACK(OnRadioToggledThunk), this);
197 } 225 }
198 226
227 // Layout code for the media device menus.
228 if (content_setting_bubble_model_->content_type() ==
229 CONTENT_SETTINGS_TYPE_MEDIASTREAM) {
230 GtkWidget* table = gtk_table_new(content.media_menus.size(), 2, FALSE);
231 int row = 0;
232 for (ContentSettingBubbleModel::MediaMenuMap::const_iterator
233 i(content.media_menus.begin()); i != content.media_menus.end();
234 ++i, ++row) {
235 GtkWidget* label = theme_provider->BuildLabel(
236 i->second.label.c_str(), ui::kGdkBlack);
237 gtk_table_attach(GTK_TABLE(table), gtk_util::LeftAlignMisc(label), 0, 1,
238 row, row + 1, GTK_FILL, GTK_FILL,
239 ui::kControlSpacing / 2, ui::kControlSpacing / 2);
240
241 // Build up the gtk menu button.
242 MediaMenuGtk* gtk_menu = new MediaMenuGtk(i->first);
243 gtk_menu->label.Own(
244 gtk_label_new(i->second.selected_device.name.c_str()));
245
246 GtkWidget* button = gtk_button_new();
247 GtkWidget* button_content = gtk_hbox_new(FALSE, 0);
248 gtk_box_pack_start(GTK_BOX(button_content),
249 gtk_util::LeftAlignMisc(gtk_menu->label.get()),
250 FALSE, FALSE, 0);
251 gtk_label_set_width_chars(GTK_LABEL(gtk_menu->label.get()),
252 kMediaMenuButtonLabelWidthInChars);
253 GtkWidget* arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
254 gtk_box_pack_end(GTK_BOX(button_content), arrow, FALSE, FALSE, 0);
255 gtk_widget_set_size_request(button_content, kMediaMenuButtonWidth, -1);
256 gtk_container_add(GTK_CONTAINER(button), button_content);
257
258 // Store the gtk menu to the map.
259 media_menus_[button] = gtk_menu;
260
261 g_signal_connect(button, "clicked", G_CALLBACK(OnMenuButtonClickedThunk),
262 this);
263 gtk_table_attach(GTK_TABLE(table), button, 1, 2, row, row + 1,
264 GTK_FILL, GTK_FILL, ui::kControlSpacing * 2,
265 ui::kControlSpacing / 2);
266 }
267
268 gtk_box_pack_start(GTK_BOX(bubble_content), table, FALSE, FALSE, 0);
269 }
270
199 for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i = 271 for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i =
200 content.domain_lists.begin(); 272 content.domain_lists.begin();
201 i != content.domain_lists.end(); ++i) { 273 i != content.domain_lists.end(); ++i) {
202 // Put each list into its own vbox to allow spacing between lists. 274 // Put each list into its own vbox to allow spacing between lists.
203 GtkWidget* list_content = gtk_vbox_new(FALSE, ui::kControlSpacing); 275 GtkWidget* list_content = gtk_vbox_new(FALSE, ui::kControlSpacing);
204 276
205 GtkWidget* label = theme_provider->BuildLabel( 277 GtkWidget* label = theme_provider->BuildLabel(
206 BuildElidedText(i->title).c_str(), ui::kGdkBlack); 278 BuildElidedText(i->title).c_str(), ui::kGdkBlack);
207 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); 279 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
208 GtkWidget* label_box = gtk_hbox_new(FALSE, 0); 280 GtkWidget* label_box = gtk_hbox_new(FALSE, 0);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 theme_provider->BuildChromeLinkButton(content.manage_link.c_str()); 318 theme_provider->BuildChromeLinkButton(content.manage_link.c_str());
247 g_signal_connect(manage_link, "clicked", G_CALLBACK(OnManageLinkClickedThunk), 319 g_signal_connect(manage_link, "clicked", G_CALLBACK(OnManageLinkClickedThunk),
248 this); 320 this);
249 gtk_box_pack_start(GTK_BOX(bottom_box), manage_link, FALSE, FALSE, 0); 321 gtk_box_pack_start(GTK_BOX(bottom_box), manage_link, FALSE, FALSE, 0);
250 322
251 GtkWidget* button = gtk_button_new_with_label( 323 GtkWidget* button = gtk_button_new_with_label(
252 l10n_util::GetStringUTF8(IDS_DONE).c_str()); 324 l10n_util::GetStringUTF8(IDS_DONE).c_str());
253 g_signal_connect(button, "clicked", G_CALLBACK(OnCloseButtonClickedThunk), 325 g_signal_connect(button, "clicked", G_CALLBACK(OnCloseButtonClickedThunk),
254 this); 326 this);
255 gtk_box_pack_end(GTK_BOX(bottom_box), button, FALSE, FALSE, 0); 327 gtk_box_pack_end(GTK_BOX(bottom_box), button, FALSE, FALSE, 0);
256
257 gtk_box_pack_start(GTK_BOX(bubble_content), bottom_box, FALSE, FALSE, 0); 328 gtk_box_pack_start(GTK_BOX(bubble_content), bottom_box, FALSE, FALSE, 0);
258 gtk_widget_grab_focus(bottom_box); 329 gtk_widget_grab_focus(bottom_box);
259 gtk_widget_grab_focus(button); 330 gtk_widget_grab_focus(button);
260 331
261 bubble_ = BubbleGtk::Show(anchor_, 332 bubble_ = BubbleGtk::Show(anchor_,
262 NULL, 333 NULL,
263 bubble_content, 334 bubble_content,
264 BubbleGtk::ANCHOR_TOP_RIGHT, 335 BubbleGtk::ANCHOR_TOP_RIGHT,
265 BubbleGtk::MATCH_SYSTEM_THEME | 336 BubbleGtk::MATCH_SYSTEM_THEME |
266 BubbleGtk::POPUP_WINDOW | 337 BubbleGtk::POPUP_WINDOW |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 380
310 void ContentSettingBubbleGtk::OnCustomLinkClicked(GtkWidget* button) { 381 void ContentSettingBubbleGtk::OnCustomLinkClicked(GtkWidget* button) {
311 content_setting_bubble_model_->OnCustomLinkClicked(); 382 content_setting_bubble_model_->OnCustomLinkClicked();
312 Close(); 383 Close();
313 } 384 }
314 385
315 void ContentSettingBubbleGtk::OnManageLinkClicked(GtkWidget* button) { 386 void ContentSettingBubbleGtk::OnManageLinkClicked(GtkWidget* button) {
316 content_setting_bubble_model_->OnManageLinkClicked(); 387 content_setting_bubble_model_->OnManageLinkClicked();
317 Close(); 388 Close();
318 } 389 }
390
391 void ContentSettingBubbleGtk::OnMenuButtonClicked(GtkWidget* button) {
392 GtkMediaMenuMap::iterator i(media_menus_.find(button));
393 DCHECK(i != media_menus_.end());
394 i->second->menu_model.reset(new ContentSettingMediaMenuModel(
395 profile_,
396 i->second->type,
397 content_setting_bubble_model_.get(),
398 base::Bind(&ContentSettingBubbleGtk::UpdateMenuLabel,
399 base::Unretained(this))));
400 i->second->menu.reset(new MenuGtk(NULL, i->second->menu_model.get()));
401 i->second->menu->PopupForWidget(button, 1, gtk_get_current_event_time());
402 }
403
404 ContentSettingBubbleGtk::MediaMenuGtk::MediaMenuGtk(
405 content::MediaStreamType type)
406 : type(type) {
407 }
408
409 ContentSettingBubbleGtk::MediaMenuGtk::~MediaMenuGtk() {
410 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698