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

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: addressed the final comments. 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/stl_util.h"
12 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/content_settings/host_content_settings_map.h" 15 #include "chrome/browser/content_settings/host_content_settings_map.h"
14 #include "chrome/browser/plugins/plugin_finder.h" 16 #include "chrome/browser/plugins/plugin_finder.h"
15 #include "chrome/browser/plugins/plugin_metadata.h" 17 #include "chrome/browser/plugins/plugin_metadata.h"
16 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" 19 #include "chrome/browser/ui/content_settings/content_setting_bubble_model.h"
20 #include "chrome/browser/ui/content_settings/content_setting_media_menu_model.h"
18 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" 21 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
19 #include "chrome/browser/ui/gtk/gtk_theme_service.h" 22 #include "chrome/browser/ui/gtk/gtk_theme_service.h"
20 #include "chrome/browser/ui/gtk/gtk_util.h" 23 #include "chrome/browser/ui/gtk/gtk_util.h"
21 #include "chrome/common/content_settings.h" 24 #include "chrome/common/content_settings.h"
22 #include "content/public/browser/notification_source.h" 25 #include "content/public/browser/notification_source.h"
23 #include "content/public/browser/notification_types.h" 26 #include "content/public/browser/notification_types.h"
24 #include "content/public/browser/plugin_service.h" 27 #include "content/public/browser/plugin_service.h"
25 #include "content/public/browser/web_contents.h" 28 #include "content/public/browser/web_contents.h"
26 #include "grit/generated_resources.h" 29 #include "grit/generated_resources.h"
27 #include "grit/ui_resources.h" 30 #include "grit/ui_resources.h"
28 #include "ui/base/gtk/gtk_hig_constants.h" 31 #include "ui/base/gtk/gtk_hig_constants.h"
29 #include "ui/base/l10n/l10n_util.h" 32 #include "ui/base/l10n/l10n_util.h"
33 #include "ui/base/models/simple_menu_model.h"
30 #include "ui/base/text/text_elider.h" 34 #include "ui/base/text/text_elider.h"
31 #include "ui/gfx/gtk_util.h" 35 #include "ui/gfx/gtk_util.h"
32 36
33 using content::PluginService; 37 using content::PluginService;
34 using content::WebContents; 38 using content::WebContents;
35 39
36 namespace { 40 namespace {
37 41
38 // The maximum width of a title entry in the content box. We elide anything 42 // The maximum width of a title entry in the content box. We elide anything
39 // longer than this. 43 // longer than this.
40 const int kMaxLinkPixelSize = 500; 44 const int kMaxLinkPixelSize = 500;
41 45
46 // The minimum and maximum width of the media menu buttons.
47 const int kMinMediaMenuButtonWidth = 100;
48 const int kMaxMediaMenuButtonWidth = 600;
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 gtk_menu->type,
254 content_setting_bubble_model_.get(),
255 base::Bind(&ContentSettingBubbleGtk::UpdateMenuLabel,
256 base::Unretained(this))));
257 gtk_menu->menu.reset(new MenuGtk(NULL, gtk_menu->menu_model.get()));
258 media_menus_[button] = gtk_menu;
259
260 // Use the longest width of the menus as the width of the menu buttons.
261 GtkRequisition menu_req;
262 gtk_widget_size_request(gtk_menu->menu->widget(), &menu_req);
263 menu_width = std::max(menu_width, menu_req.width);
264
265 g_signal_connect(button, "clicked", G_CALLBACK(OnMenuButtonClickedThunk),
266 this);
267 gtk_table_attach(GTK_TABLE(table), button, 1, 2, row, row + 1,
268 GTK_FILL, GTK_FILL, ui::kControlSpacing * 2,
269 ui::kControlSpacing / 2);
270 }
271
272 // Make sure the width is within [kMinMediaMenuButtonWidth,
273 // kMaxMediaMenuButtonWidth].
274 menu_width = std::max(kMinMediaMenuButtonWidth, menu_width);
275 menu_width = std::min(kMaxMediaMenuButtonWidth, menu_width);
276
277 // Set all the menu buttons to the width we calculated above.
278 for (GtkMediaMenuMap::const_iterator i = media_menus_.begin();
279 i != media_menus_.end(); ++i)
280 gtk_widget_set_size_request(i->first, menu_width, -1);
281
282 gtk_box_pack_start(GTK_BOX(bubble_content), table, FALSE, FALSE, 0);
283 }
284
199 for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i = 285 for (std::vector<ContentSettingBubbleModel::DomainList>::const_iterator i =
200 content.domain_lists.begin(); 286 content.domain_lists.begin();
201 i != content.domain_lists.end(); ++i) { 287 i != content.domain_lists.end(); ++i) {
202 // Put each list into its own vbox to allow spacing between lists. 288 // Put each list into its own vbox to allow spacing between lists.
203 GtkWidget* list_content = gtk_vbox_new(FALSE, ui::kControlSpacing); 289 GtkWidget* list_content = gtk_vbox_new(FALSE, ui::kControlSpacing);
204 290
205 GtkWidget* label = theme_provider->BuildLabel( 291 GtkWidget* label = theme_provider->BuildLabel(
206 BuildElidedText(i->title).c_str(), ui::kGdkBlack); 292 BuildElidedText(i->title).c_str(), ui::kGdkBlack);
207 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); 293 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
208 GtkWidget* label_box = gtk_hbox_new(FALSE, 0); 294 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()); 332 theme_provider->BuildChromeLinkButton(content.manage_link.c_str());
247 g_signal_connect(manage_link, "clicked", G_CALLBACK(OnManageLinkClickedThunk), 333 g_signal_connect(manage_link, "clicked", G_CALLBACK(OnManageLinkClickedThunk),
248 this); 334 this);
249 gtk_box_pack_start(GTK_BOX(bottom_box), manage_link, FALSE, FALSE, 0); 335 gtk_box_pack_start(GTK_BOX(bottom_box), manage_link, FALSE, FALSE, 0);
250 336
251 GtkWidget* button = gtk_button_new_with_label( 337 GtkWidget* button = gtk_button_new_with_label(
252 l10n_util::GetStringUTF8(IDS_DONE).c_str()); 338 l10n_util::GetStringUTF8(IDS_DONE).c_str());
253 g_signal_connect(button, "clicked", G_CALLBACK(OnCloseButtonClickedThunk), 339 g_signal_connect(button, "clicked", G_CALLBACK(OnCloseButtonClickedThunk),
254 this); 340 this);
255 gtk_box_pack_end(GTK_BOX(bottom_box), button, FALSE, FALSE, 0); 341 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); 342 gtk_box_pack_start(GTK_BOX(bubble_content), bottom_box, FALSE, FALSE, 0);
258 gtk_widget_grab_focus(bottom_box); 343 gtk_widget_grab_focus(bottom_box);
259 gtk_widget_grab_focus(button); 344 gtk_widget_grab_focus(button);
260 345
261 bubble_ = BubbleGtk::Show(anchor_, 346 bubble_ = BubbleGtk::Show(anchor_,
262 NULL, 347 NULL,
263 bubble_content, 348 bubble_content,
264 BubbleGtk::ANCHOR_TOP_RIGHT, 349 BubbleGtk::ANCHOR_TOP_RIGHT,
265 BubbleGtk::MATCH_SYSTEM_THEME | 350 BubbleGtk::MATCH_SYSTEM_THEME |
266 BubbleGtk::POPUP_WINDOW | 351 BubbleGtk::POPUP_WINDOW |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 394
310 void ContentSettingBubbleGtk::OnCustomLinkClicked(GtkWidget* button) { 395 void ContentSettingBubbleGtk::OnCustomLinkClicked(GtkWidget* button) {
311 content_setting_bubble_model_->OnCustomLinkClicked(); 396 content_setting_bubble_model_->OnCustomLinkClicked();
312 Close(); 397 Close();
313 } 398 }
314 399
315 void ContentSettingBubbleGtk::OnManageLinkClicked(GtkWidget* button) { 400 void ContentSettingBubbleGtk::OnManageLinkClicked(GtkWidget* button) {
316 content_setting_bubble_model_->OnManageLinkClicked(); 401 content_setting_bubble_model_->OnManageLinkClicked();
317 Close(); 402 Close();
318 } 403 }
404
405 void ContentSettingBubbleGtk::OnMenuButtonClicked(GtkWidget* button) {
406 GtkMediaMenuMap::iterator i(media_menus_.find(button));
407 DCHECK(i != media_menus_.end());
408 i->second->menu->PopupForWidget(button, 1, gtk_get_current_event_time());
409 }
410
411 ContentSettingBubbleGtk::MediaMenuGtk::MediaMenuGtk(
412 content::MediaStreamType type)
413 : type(type) {}
414
415 ContentSettingBubbleGtk::MediaMenuGtk::~MediaMenuGtk() {}
OLDNEW
« no previous file with comments | « chrome/browser/ui/gtk/content_setting_bubble_gtk.h ('k') | chrome/browser/ui/views/content_setting_bubble_contents.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698