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

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: 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"
13 #include "base/prefs/pref_service.h"
14 #include "base/stl_util.h"
12 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/content_settings/host_content_settings_map.h" 16 #include "chrome/browser/content_settings/host_content_settings_map.h"
14 #include "chrome/browser/plugins/plugin_finder.h" 17 #include "chrome/browser/plugins/plugin_finder.h"
15 #include "chrome/browser/plugins/plugin_metadata.h" 18 #include "chrome/browser/plugins/plugin_metadata.h"
16 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" 20 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
21 #include "chrome/browser/ui/content_settings/content_setting_media_menu_model.h"
18 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" 22 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
19 #include "chrome/browser/ui/gtk/gtk_theme_service.h" 23 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
20 #include "chrome/browser/ui/gtk/gtk_util.h" 24 #include "chrome/browser/ui/gtk/gtk_util.h"
21 #include "chrome/common/content_settings.h" 25 #include "chrome/common/content_settings.h"
22 #include "content/public/browser/notification_source.h" 26 #include "content/public/browser/notification_source.h"
23 #include "content/public/browser/notification_types.h" 27 #include "content/public/browser/notification_types.h"
24 #include "content/public/browser/plugin_service.h" 28 #include "content/public/browser/plugin_service.h"
25 #include "content/public/browser/web_contents.h" 29 #include "content/public/browser/web_contents.h"
26 #include "grit/generated_resources.h" 30 #include "grit/generated_resources.h"
27 #include "grit/ui_resources.h" 31 #include "grit/ui_resources.h"
28 #include "ui/base/gtk/gtk_hig_constants.h" 32 #include "ui/base/gtk/gtk_hig_constants.h"
29 #include "ui/base/l10n/l10n_util.h" 33 #include "ui/base/l10n/l10n_util.h"
34 #include "ui/base/models/simple_menu_model.h"
30 #include "ui/base/text/text_elider.h" 35 #include "ui/base/text/text_elider.h"
31 #include "ui/gfx/gtk_util.h" 36 #include "ui/gfx/gtk_util.h"
32 37
33 using content::PluginService; 38 using content::PluginService;
34 using content::WebContents; 39 using content::WebContents;
35 40
36 namespace { 41 namespace {
37 42
38 // The maximum width of a title entry in the content box. We elide anything 43 // The maximum width of a title entry in the content box. We elide anything
39 // longer than this. 44 // longer than this.
40 const int kMaxLinkPixelSize = 500; 45 const int kMaxLinkPixelSize = 500;
41 46
47 // The minimum width of the media menu button.
48 const int kMinMediaMenuButtonWidth = 100;
49
42 std::string BuildElidedText(const std::string& input) { 50 std::string BuildElidedText(const std::string& input) {
43 return UTF16ToUTF8(ui::ElideText( 51 return UTF16ToUTF8(ui::ElideText(
44 UTF8ToUTF16(input), 52 UTF8ToUTF16(input),
45 gfx::Font(), 53 gfx::Font(),
46 kMaxLinkPixelSize, 54 kMaxLinkPixelSize,
47 ui::ELIDE_AT_END)); 55 ui::ELIDE_AT_END));
48 } 56 }
49 57
50 } // namespace 58 } // namespace
51 59
(...skipping 11 matching lines...) Expand all
63 bubble_(NULL) { 71 bubble_(NULL) {
64 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 72 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
65 content::Source<WebContents>(web_contents)); 73 content::Source<WebContents>(web_contents));
66 BuildBubble(); 74 BuildBubble();
67 } 75 }
68 76
69 ContentSettingBubbleGtk::~ContentSettingBubbleGtk() { 77 ContentSettingBubbleGtk::~ContentSettingBubbleGtk() {
70 } 78 }
71 79
72 void ContentSettingBubbleGtk::Close() { 80 void ContentSettingBubbleGtk::Close() {
81 STLDeleteValues(&media_menus_);
82
73 if (bubble_) 83 if (bubble_)
74 bubble_->Close(); 84 bubble_->Close();
75 } 85 }
76 86
87 void ContentSettingBubbleGtk::UpdateMenuLabel(content::MediaStreamType type,
88 const std::string& label) {
89 GtkMediaMenuMap::const_iterator it = media_menus_.begin();
90 for (; it != media_menus_.end(); ++it) {
91 if (it->second->type == type) {
92 gtk_label_set_text(GTK_LABEL(it->second->label.get()), label.c_str());
93 return;
94 }
95 }
96 NOTREACHED();
97 }
98
77 void ContentSettingBubbleGtk::BubbleClosing(BubbleGtk* bubble, 99 void ContentSettingBubbleGtk::BubbleClosing(BubbleGtk* bubble,
78 bool closed_by_escape) { 100 bool closed_by_escape) {
79 delegate_->BubbleClosing(bubble, closed_by_escape); 101 delegate_->BubbleClosing(bubble, closed_by_escape);
80 delete this; 102 delete this;
81 } 103 }
82 104
83 void ContentSettingBubbleGtk::Observe( 105 void ContentSettingBubbleGtk::Observe(
84 int type, 106 int type,
85 const content::NotificationSource& source, 107 const content::NotificationSource& source,
86 const content::NotificationDetails& details) { 108 const content::NotificationDetails& details) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 if (!content.radio_group_enabled) 211 if (!content.radio_group_enabled)
190 gtk_widget_set_sensitive(radio, FALSE); 212 gtk_widget_set_sensitive(radio, FALSE);
191 radio_group_gtk_.push_back(radio); 213 radio_group_gtk_.push_back(radio);
192 } 214 }
193 for (std::vector<GtkWidget*>::const_iterator i = radio_group_gtk_.begin(); 215 for (std::vector<GtkWidget*>::const_iterator i = radio_group_gtk_.begin();
194 i != radio_group_gtk_.end(); ++i) { 216 i != radio_group_gtk_.end(); ++i) {
195 // We can attach signal handlers now that all defaults are set. 217 // We can attach signal handlers now that all defaults are set.
196 g_signal_connect(*i, "toggled", G_CALLBACK(OnRadioToggledThunk), this); 218 g_signal_connect(*i, "toggled", G_CALLBACK(OnRadioToggledThunk), this);
197 } 219 }
198 220
221 // Layout code for the media device menus.
222 if (content_setting_bubble_model_->content_type() ==
223 CONTENT_SETTINGS_TYPE_MEDIASTREAM) {
224 GtkWidget* table = gtk_table_new(content.media_menus.size(), 2, FALSE);
225 int menu_width = 0;
226 int row = 0;
227 for (ContentSettingBubbleModel::MediaMenuMap::const_iterator
228 i(content.media_menus.begin());
229 i != content.media_menus.end();
230 ++i, ++row) {
231 GtkWidget* label = theme_provider->BuildLabel(
232 i->second.label.c_str(), ui::kGdkBlack);
233 gtk_table_attach(GTK_TABLE(table), gtk_util::LeftAlignMisc(label), 0, 1,
234 row, row + 1, GTK_FILL, GTK_FILL,
235 ui::kControlSpacing / 2, ui::kControlSpacing / 2);
236
237 // Build up the gtk menu button.
238 MediaMenuGtk* gtk_menu = new MediaMenuGtk(i->first);
239 gtk_menu->label.Own(
240 gtk_label_new(i->second.selected_device.name.c_str()));
241 GtkWidget* button = gtk_button_new();
242 GtkWidget* button_content = gtk_hbox_new(FALSE, 0);
243 gtk_box_pack_start(GTK_BOX(button_content),
244 gtk_util::LeftAlignMisc(gtk_menu->label.get()),
245 FALSE, FALSE, 0);
246 GtkWidget* arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
247 gtk_box_pack_end(GTK_BOX(button_content), arrow, FALSE, FALSE, 0);
248
249 gtk_container_add(GTK_CONTAINER(button), button_content);
250
251 // Store the gtk menu to the map.
252 gtk_menu->menu_model.reset(new ContentSettingMediaMenuModel(
253 profile_->GetPrefs(),
254 gtk_menu->type,
255 content_setting_bubble_model_.get(),
256 base::Bind(&ContentSettingBubbleGtk::UpdateMenuLabel,
257 base::Unretained(this))));
258 gtk_menu->menu.reset(new MenuGtk(NULL, gtk_menu->menu_model.get()));
259 media_menus_[button] = gtk_menu;
260
261 // 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.
262 GtkRequisition menu_req;
263 gtk_widget_size_request(gtk_menu->menu->widget(), &menu_req);
264 menu_width = std::max(menu_width, menu_req.width);
265 menu_width = std::max(menu_width, kMinMediaMenuButtonWidth);
266
267 g_signal_connect(button, "clicked", G_CALLBACK(OnMenuButtonClickedThunk),
268 this);
269 gtk_table_attach(GTK_TABLE(table), button, 1, 2, row, row + 1,
270 GTK_FILL, GTK_FILL, ui::kControlSpacing * 2,
271 ui::kControlSpacing / 2);
272 }
273
274 // Set the optimal width for the menu buttons.
275 for (GtkMediaMenuMap::const_iterator i = media_menus_.begin();
276 i != media_menus_.end(); ++i)
277 gtk_widget_set_size_request(i->first, menu_width, -1);
278
279 gtk_box_pack_start(GTK_BOX(bubble_content), table, FALSE, FALSE, 0);
280 }
281
199 for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i = 282 for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i =
200 content.domain_lists.begin(); 283 content.domain_lists.begin();
201 i != content.domain_lists.end(); ++i) { 284 i != content.domain_lists.end(); ++i) {
202 // Put each list into its own vbox to allow spacing between lists. 285 // Put each list into its own vbox to allow spacing between lists.
203 GtkWidget* list_content = gtk_vbox_new(FALSE, ui::kControlSpacing); 286 GtkWidget* list_content = gtk_vbox_new(FALSE, ui::kControlSpacing);
204 287
205 GtkWidget* label = theme_provider->BuildLabel( 288 GtkWidget* label = theme_provider->BuildLabel(
206 BuildElidedText(i->title).c_str(), ui::kGdkBlack); 289 BuildElidedText(i->title).c_str(), ui::kGdkBlack);
207 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); 290 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
208 GtkWidget* label_box = gtk_hbox_new(FALSE, 0); 291 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()); 329 theme_provider->BuildChromeLinkButton(content.manage_link.c_str());
247 g_signal_connect(manage_link, "clicked", G_CALLBACK(OnManageLinkClickedThunk), 330 g_signal_connect(manage_link, "clicked", G_CALLBACK(OnManageLinkClickedThunk),
248 this); 331 this);
249 gtk_box_pack_start(GTK_BOX(bottom_box), manage_link, FALSE, FALSE, 0); 332 gtk_box_pack_start(GTK_BOX(bottom_box), manage_link, FALSE, FALSE, 0);
250 333
251 GtkWidget* button = gtk_button_new_with_label( 334 GtkWidget* button = gtk_button_new_with_label(
252 l10n_util::GetStringUTF8(IDS_DONE).c_str()); 335 l10n_util::GetStringUTF8(IDS_DONE).c_str());
253 g_signal_connect(button, "clicked", G_CALLBACK(OnCloseButtonClickedThunk), 336 g_signal_connect(button, "clicked", G_CALLBACK(OnCloseButtonClickedThunk),
254 this); 337 this);
255 gtk_box_pack_end(GTK_BOX(bottom_box), button, FALSE, FALSE, 0); 338 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); 339 gtk_box_pack_start(GTK_BOX(bubble_content), bottom_box, FALSE, FALSE, 0);
258 gtk_widget_grab_focus(bottom_box); 340 gtk_widget_grab_focus(bottom_box);
259 gtk_widget_grab_focus(button); 341 gtk_widget_grab_focus(button);
260 342
261 bubble_ = BubbleGtk::Show(anchor_, 343 bubble_ = BubbleGtk::Show(anchor_,
262 NULL, 344 NULL,
263 bubble_content, 345 bubble_content,
264 BubbleGtk::ANCHOR_TOP_RIGHT, 346 BubbleGtk::ANCHOR_TOP_RIGHT,
265 BubbleGtk::MATCH_SYSTEM_THEME | 347 BubbleGtk::MATCH_SYSTEM_THEME |
266 BubbleGtk::POPUP_WINDOW | 348 BubbleGtk::POPUP_WINDOW |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 391
310 void ContentSettingBubbleGtk::OnCustomLinkClicked(GtkWidget* button) { 392 void ContentSettingBubbleGtk::OnCustomLinkClicked(GtkWidget* button) {
311 content_setting_bubble_model_->OnCustomLinkClicked(); 393 content_setting_bubble_model_->OnCustomLinkClicked();
312 Close(); 394 Close();
313 } 395 }
314 396
315 void ContentSettingBubbleGtk::OnManageLinkClicked(GtkWidget* button) { 397 void ContentSettingBubbleGtk::OnManageLinkClicked(GtkWidget* button) {
316 content_setting_bubble_model_->OnManageLinkClicked(); 398 content_setting_bubble_model_->OnManageLinkClicked();
317 Close(); 399 Close();
318 } 400 }
401
402 void ContentSettingBubbleGtk::OnMenuButtonClicked(GtkWidget* button) {
403 GtkMediaMenuMap::iterator i(media_menus_.find(button));
404 DCHECK(i != media_menus_.end());
405 i->second->menu->PopupForWidget(button, 1, gtk_get_current_event_time());
406 }
407
408 ContentSettingBubbleGtk::MediaMenuGtk::MediaMenuGtk(
409 content::MediaStreamType type)
410 : type(type) {}
411
412 ContentSettingBubbleGtk::MediaMenuGtk::~MediaMenuGtk() {}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698