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

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

Powered by Google App Engine
This is Rietveld 408576698