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

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

Issue 9837011: [Web Intents] CWS inline install for GTK (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 8 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/web_intent_picker_gtk.h" 5 #include "chrome/browser/ui/gtk/web_intent_picker_gtk.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/i18n/rtl.h" 9 #include "base/i18n/rtl.h"
10 #include "base/utf_string_conversions.h" 10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/favicon/favicon_service.h" 11 #include "chrome/browser/favicon/favicon_service.h"
12 #include "chrome/browser/profiles/profile.h" 12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/browser.h" 13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_window.h" 14 #include "chrome/browser/ui/browser_window.h"
15 #include "chrome/browser/ui/gtk/browser_toolbar_gtk.h" 15 #include "chrome/browser/ui/gtk/browser_toolbar_gtk.h"
16 #include "chrome/browser/ui/gtk/browser_window_gtk.h" 16 #include "chrome/browser/ui/gtk/browser_window_gtk.h"
17 #include "chrome/browser/ui/gtk/custom_button.h" 17 #include "chrome/browser/ui/gtk/custom_button.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_util.h" 19 #include "chrome/browser/ui/gtk/gtk_util.h"
20 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h" 20 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h"
21 #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h" 21 #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h"
22 #include "chrome/browser/ui/gtk/theme_service_gtk.h" 22 #include "chrome/browser/ui/gtk/theme_service_gtk.h"
23 #include "chrome/browser/ui/gtk/throbber_gtk.h"
23 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" 24 #include "chrome/browser/ui/intents/web_intent_picker_controller.h"
24 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" 25 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h"
25 #include "chrome/browser/ui/intents/web_intent_picker_model.h" 26 #include "chrome/browser/ui/intents/web_intent_picker_model.h"
26 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 27 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
27 #include "chrome/common/chrome_notification_types.h" 28 #include "chrome/common/chrome_notification_types.h"
28 #include "content/public/browser/notification_source.h" 29 #include "content/public/browser/notification_source.h"
29 #include "content/public/browser/notification_types.h" 30 #include "content/public/browser/notification_types.h"
30 #include "content/public/browser/render_view_host.h" 31 #include "content/public/browser/render_view_host.h"
31 #include "content/public/browser/render_widget_host_view.h" 32 #include "content/public/browser/render_widget_host_view.h"
32 #include "content/public/browser/web_contents.h" 33 #include "content/public/browser/web_contents.h"
(...skipping 20 matching lines...) Expand all
53 // The length in pixels of the label at the bottom of the picker. Text longer 54 // The length in pixels of the label at the bottom of the picker. Text longer
54 // than this width will wrap. 55 // than this width will wrap.
55 const int kWebStoreLabelLength = 400; 56 const int kWebStoreLabelLength = 400;
56 57
57 // The pixel size of the header label when using a non-native theme. 58 // The pixel size of the header label when using a non-native theme.
58 const int kHeaderLabelPixelSize = 15; 59 const int kHeaderLabelPixelSize = 15;
59 60
60 // The maximum width in pixels of a suggested extension's title link. 61 // The maximum width in pixels of a suggested extension's title link.
61 const int kTitleLinkMaxWidth = 130; 62 const int kTitleLinkMaxWidth = 130;
62 63
64 // Indices of the extension row widgets.
65 enum {
66 kIconIndex,
67 kTitleLinkIndex,
68 kStarsIndex,
69 kInstallButtonIndex,
70 };
71
63 ThemeServiceGtk *GetThemeService(TabContentsWrapper* wrapper) { 72 ThemeServiceGtk *GetThemeService(TabContentsWrapper* wrapper) {
64 return ThemeServiceGtk::GetFrom(wrapper->profile()); 73 return ThemeServiceGtk::GetFrom(wrapper->profile());
65 } 74 }
66 75
67 // Set the image of |button| to |pixbuf|. 76 // Set the image of |button| to |pixbuf|.
68 void SetServiceButtonImage(GtkWidget* button, GdkPixbuf* pixbuf) { 77 void SetServiceButtonImage(GtkWidget* button, GdkPixbuf* pixbuf) {
69 gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_pixbuf(pixbuf)); 78 gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_pixbuf(pixbuf));
70 gtk_button_set_image_position(GTK_BUTTON(button), GTK_POS_LEFT); 79 gtk_button_set_image_position(GTK_BUTTON(button), GTK_POS_LEFT);
71 } 80 }
72 81
73 // Get the index of the row containing |widget|. Assume the widget is the child 82 // Get the index of the row containing |widget|. Assume the widget is the child
74 // of an hbox, which is a child of a vbox. The hbox represents a row, and the 83 // of an hbox, which is a child of a vbox. The hbox represents a row, and the
75 // vbox the full table. 84 // vbox the full table.
76 size_t GetExtensionWidgetRow(GtkWidget* widget) { 85 size_t GetExtensionWidgetRow(GtkWidget* widget) {
77 GtkWidget* hbox = gtk_widget_get_parent(widget); 86 GtkWidget* hbox = gtk_widget_get_parent(widget);
78 DCHECK(hbox); 87 DCHECK(hbox);
79 GtkWidget* vbox = gtk_widget_get_parent(hbox); 88 GtkWidget* vbox = gtk_widget_get_parent(hbox);
80 DCHECK(vbox); 89 DCHECK(vbox);
81 GList* hbox_list = gtk_container_get_children(GTK_CONTAINER(vbox)); 90 GList* hbox_list = gtk_container_get_children(GTK_CONTAINER(vbox));
82 gint index = g_list_index(hbox_list, hbox); 91 gint index = g_list_index(hbox_list, hbox);
83 DCHECK(index != -1); 92 DCHECK(index != -1);
84 93
85 return index; 94 return index;
86 } 95 }
87 96
97 // A gtk_container_foreach callback to enable/disable a widget.
98 void EnableWidgetCallback(GtkWidget* widget, gpointer data) {
99 gtk_widget_set_sensitive(widget, *static_cast<gboolean*>(data));
100 }
101
102 // A gtk_container_foreach callback to show/hide the stars and install button
103 // widgets of an extension hbox.
104 void SetStarsAndIntallButtonVisibility(GtkWidget* extension_hbox,
105 gpointer data) {
106 gboolean visible = *static_cast<gboolean*>(data);
107 GList* list = gtk_container_get_children(GTK_CONTAINER(extension_hbox));
108 GtkWidget* stars = GTK_WIDGET(g_list_nth_data(list, kStarsIndex));
109 GtkWidget* install_button =
110 GTK_WIDGET(g_list_nth_data(list, kInstallButtonIndex));
111
112 if (visible) {
113 // Reset the size requisition to use the "natural" size.
114 gtk_widget_set_size_request(extension_hbox, -1, -1);
115 gtk_widget_show(stars);
116 gtk_widget_show(install_button);
117 } else {
118 GtkRequisition requisition;
119 gtk_widget_size_request(extension_hbox, &requisition);
120 gtk_widget_hide(stars);
121 gtk_widget_hide(install_button);
122 // Ask for the new size to be the same as before stuff was hidden.
123 gtk_widget_set_size_request(extension_hbox, requisition.width,
124 requisition.height);
125 }
126 }
127
88 } // namespace 128 } // namespace
89 129
90 // static 130 // static
91 WebIntentPicker* WebIntentPicker::Create(Browser* browser, 131 WebIntentPicker* WebIntentPicker::Create(Browser* browser,
92 TabContentsWrapper* wrapper, 132 TabContentsWrapper* wrapper,
93 WebIntentPickerDelegate* delegate, 133 WebIntentPickerDelegate* delegate,
94 WebIntentPickerModel* model) { 134 WebIntentPickerModel* model) {
95 return new WebIntentPickerGtk(browser, wrapper, delegate, model); 135 return new WebIntentPickerGtk(browser, wrapper, delegate, model);
96 } 136 }
97 137
(...skipping 30 matching lines...) Expand all
128 168
129 WebIntentPickerGtk::~WebIntentPickerGtk() { 169 WebIntentPickerGtk::~WebIntentPickerGtk() {
130 } 170 }
131 171
132 void WebIntentPickerGtk::Close() { 172 void WebIntentPickerGtk::Close() {
133 window_->CloseConstrainedWindow(); 173 window_->CloseConstrainedWindow();
134 if (inline_disposition_tab_contents_.get()) 174 if (inline_disposition_tab_contents_.get())
135 inline_disposition_tab_contents_->web_contents()->OnCloseStarted(); 175 inline_disposition_tab_contents_->web_contents()->OnCloseStarted();
136 } 176 }
137 177
178 void WebIntentPickerGtk::OnExtensionInstallSuccess(const std::string& id) {
179 RemoveThrobber();
180 }
181
182 void WebIntentPickerGtk::OnExtensionInstallFailure(const std::string& id) {
183 RemoveThrobber();
184 SetWidgetsEnabled(true);
185 }
186
138 void WebIntentPickerGtk::OnModelChanged(WebIntentPickerModel* model) { 187 void WebIntentPickerGtk::OnModelChanged(WebIntentPickerModel* model) {
139 UpdateInstalledServices(); 188 UpdateInstalledServices();
140 UpdateCWSLabel(); 189 UpdateCWSLabel();
141 UpdateSuggestedExtensions(); 190 UpdateSuggestedExtensions();
142 } 191 }
143 192
144 void WebIntentPickerGtk::OnFaviconChanged(WebIntentPickerModel* model, 193 void WebIntentPickerGtk::OnFaviconChanged(WebIntentPickerModel* model,
145 size_t index) { 194 size_t index) {
146 UpdateInstalledServices(); 195 UpdateInstalledServices();
147 } 196 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 GURL extension_url(extension_urls::GetWebstoreItemDetailURLPrefix() + 303 GURL extension_url(extension_urls::GetWebstoreItemDetailURLPrefix() +
255 UTF16ToUTF8(extension.id)); 304 UTF16ToUTF8(extension.id));
256 browser::NavigateParams params(browser_, 305 browser::NavigateParams params(browser_,
257 extension_url, 306 extension_url,
258 content::PAGE_TRANSITION_AUTO_BOOKMARK); 307 content::PAGE_TRANSITION_AUTO_BOOKMARK);
259 params.disposition = NEW_FOREGROUND_TAB; 308 params.disposition = NEW_FOREGROUND_TAB;
260 browser::Navigate(&params); 309 browser::Navigate(&params);
261 } 310 }
262 311
263 void WebIntentPickerGtk::OnExtensionInstallButtonClick(GtkWidget* button) { 312 void WebIntentPickerGtk::OnExtensionInstallButtonClick(GtkWidget* button) {
264 // TODO(binji): Install the extension. 313 size_t index = GetExtensionWidgetRow(button);
314 const WebIntentPickerModel::SuggestedExtension& extension =
315 model_->GetSuggestedExtensionAt(index);
316
317 delegate_->OnExtensionInstallRequested(UTF16ToUTF8(extension.id));
318 SetWidgetsEnabled(false);
319 // Re-enable the clicked extension row.
320 GList* vbox_list =
321 gtk_container_get_children(GTK_CONTAINER(extensions_vbox_));
322 GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index));
323 gboolean enabled = TRUE;
324 EnableWidgetCallback(hbox, &enabled);
Evan Stade 2012/03/30 21:38:25 not really necessary; imo decreases readability as
binji 2012/03/30 23:03:51 Done.
325
326 AddThrobberToExtensionAt(index);
265 } 327 }
266 328
267 void WebIntentPickerGtk::OnMoreSuggestionsLinkClick(GtkWidget* link) { 329 void WebIntentPickerGtk::OnMoreSuggestionsLinkClick(GtkWidget* link) {
268 // TODO(binji): This should link to a CWS search, based on the current 330 // TODO(binji): This should link to a CWS search, based on the current
269 // action/type pair. 331 // action/type pair.
270 browser::NavigateParams params( 332 browser::NavigateParams params(
271 browser_, 333 browser_,
272 GURL(extension_urls::GetWebstoreLaunchURL()), 334 GURL(extension_urls::GetWebstoreLaunchURL()),
273 content::PAGE_TRANSITION_AUTO_BOOKMARK); 335 content::PAGE_TRANSITION_AUTO_BOOKMARK);
274 params.disposition = NEW_FOREGROUND_TAB; 336 params.disposition = NEW_FOREGROUND_TAB;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 CustomDrawButton::CloseButton(GetThemeService(wrapper_))); 373 CustomDrawButton::CloseButton(GetThemeService(wrapper_)));
312 g_signal_connect(close_button_->widget(), 374 g_signal_connect(close_button_->widget(),
313 "clicked", 375 "clicked",
314 G_CALLBACK(OnCloseButtonClickThunk), 376 G_CALLBACK(OnCloseButtonClickThunk),
315 this); 377 this);
316 gtk_widget_set_can_focus(close_button_->widget(), FALSE); 378 gtk_widget_set_can_focus(close_button_->widget(), FALSE);
317 gtk_box_pack_end(GTK_BOX(header_hbox), close_button_->widget(), 379 gtk_box_pack_end(GTK_BOX(header_hbox), close_button_->widget(),
318 FALSE, FALSE, 0); 380 FALSE, FALSE, 0);
319 381
320 // Alignment for service button vbox. 382 // Alignment for service button vbox.
321 GtkWidget* button_alignment = gtk_alignment_new(0.5f, 0.5f, 0.3f, 0); 383 GtkWidget* button_alignment = gtk_alignment_new(0, 0.5f, 0.3f, 0);
384 gtk_alignment_set_padding(GTK_ALIGNMENT(button_alignment), 0, 0,
385 ui::kGroupIndent, 0);
322 gtk_widget_set_no_show_all(button_alignment, TRUE); 386 gtk_widget_set_no_show_all(button_alignment, TRUE);
323 387
324 // Vbox containing all service buttons. 388 // Vbox containing all service buttons.
325 button_vbox_ = gtk_vbox_new(FALSE, ui::kControlSpacing); 389 button_vbox_ = gtk_vbox_new(FALSE, ui::kControlSpacing);
326 gtk_container_add(GTK_CONTAINER(button_alignment), button_vbox_); 390 gtk_container_add(GTK_CONTAINER(button_alignment), button_vbox_);
327 gtk_box_pack_start(GTK_BOX(contents_), button_alignment, TRUE, TRUE, 0); 391 gtk_box_pack_start(GTK_BOX(contents_), button_alignment, TRUE, TRUE, 0);
328 392
329 // Chrome Web Store label. 393 // Chrome Web Store label.
330 cws_label_ = theme_service->BuildLabel( 394 cws_label_ = theme_service->BuildLabel(
331 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_GET_MORE_SERVICES).c_str(), 395 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_GET_MORE_SERVICES).c_str(),
332 ui::kGdkBlack); 396 ui::kGdkBlack);
333 gtk_box_pack_start(GTK_BOX(contents_), cws_label_, TRUE, TRUE, 0); 397 gtk_box_pack_start(GTK_BOX(contents_), cws_label_, TRUE, TRUE, 0);
334 gtk_misc_set_alignment(GTK_MISC(cws_label_), 0, 0); 398 gtk_misc_set_alignment(GTK_MISC(cws_label_), 0, 0);
335 gtk_widget_set_no_show_all(cws_label_, TRUE); 399 gtk_widget_set_no_show_all(cws_label_, TRUE);
336 gtk_util::SetLabelWidth(cws_label_, kWebStoreLabelLength); 400 gtk_util::SetLabelWidth(cws_label_, kWebStoreLabelLength);
337 401
402 // Suggested extensions vbox.
403 extensions_vbox_ = gtk_vbox_new(FALSE, ui::kControlSpacing);
404 GtkWidget* indent_extensions = gtk_util::IndentWidget(extensions_vbox_);
405 gtk_widget_set_no_show_all(indent_extensions, TRUE);
406 gtk_box_pack_start(GTK_BOX(contents_), indent_extensions, TRUE, TRUE, 0);
407
408 // Left-aligned link button.
409 GtkWidget* link_alignment = gtk_alignment_new(0, 0.5f, 0, 0);
410 GtkWidget* more_suggestions_link = theme_service->BuildChromeLinkButton(
411 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_MORE_SUGGESTIONS).c_str());
412 gtk_container_add(GTK_CONTAINER(link_alignment), more_suggestions_link);
413 gtk_chrome_link_button_set_use_gtk_theme(
414 GTK_CHROME_LINK_BUTTON(more_suggestions_link),
415 theme_service->UsingNativeTheme());
Evan Stade 2012/03/30 21:38:25 AFAIK the picker is always natively themed (does t
binji 2012/03/30 23:03:51 Yes, when I click through GTK themes, it changes t
Evan Stade 2012/03/31 01:24:35 those are native themes. It is always natively the
binji 2012/04/02 18:22:36 OK, removed.
416 g_signal_connect(more_suggestions_link, "clicked",
417 G_CALLBACK(OnMoreSuggestionsLinkClickThunk), this);
418 gtk_box_pack_start(GTK_BOX(contents_), link_alignment, FALSE, FALSE, 0);
419
420 // Throbber, which will be added to the heirarchy when necessary.
Evan Stade 2012/03/30 21:38:25 sp.
binji 2012/03/30 23:03:51 Done.
421 throbber_.reset(new ThrobberGtk(theme_service));
422
338 g_signal_connect(contents_, "destroy", G_CALLBACK(&OnDestroyThunk), this); 423 g_signal_connect(contents_, "destroy", G_CALLBACK(&OnDestroyThunk), this);
339
340 // Suggested extensions vbox.
341 extensions_vbox_ = gtk_vbox_new(FALSE, ui::kContentAreaSpacing);
342 gtk_box_pack_start(GTK_BOX(contents_),
343 gtk_util::IndentWidget(extensions_vbox_), TRUE, TRUE, 0);
344 } 424 }
345 425
346 void WebIntentPickerGtk::UpdateInstalledServices() { 426 void WebIntentPickerGtk::UpdateInstalledServices() {
347 gtk_util::RemoveAllChildren(button_vbox_); 427 gtk_util::RemoveAllChildren(button_vbox_);
348 428
429 if (model_->GetInstalledServiceCount() == 0) {
430 gtk_widget_hide(gtk_widget_get_parent(button_vbox_));
431 return;
432 }
433
349 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) { 434 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) {
350 const WebIntentPickerModel::InstalledService& installed_service = 435 const WebIntentPickerModel::InstalledService& installed_service =
351 model_->GetInstalledServiceAt(i); 436 model_->GetInstalledServiceAt(i);
352 437
353 GtkWidget* button = gtk_button_new(); 438 GtkWidget* button = gtk_button_new();
354 439
355 gtk_widget_set_tooltip_text(button, installed_service.url.spec().c_str()); 440 gtk_widget_set_tooltip_text(button, installed_service.url.spec().c_str());
356 gtk_button_set_label(GTK_BUTTON(button), 441 gtk_button_set_label(GTK_BUTTON(button),
357 UTF16ToUTF8(installed_service.title).c_str()); 442 UTF16ToUTF8(installed_service.title).c_str());
358 gtk_button_set_alignment(GTK_BUTTON(button), 0, 0); 443 gtk_button_set_alignment(GTK_BUTTON(button), 0, 0);
359 444
360 gtk_box_pack_start(GTK_BOX(button_vbox_), button, FALSE, FALSE, 0); 445 gtk_box_pack_start(GTK_BOX(button_vbox_), button, FALSE, FALSE, 0);
361 g_signal_connect(button, 446 g_signal_connect(button,
362 "clicked", 447 "clicked",
363 G_CALLBACK(OnServiceButtonClickThunk), 448 G_CALLBACK(OnServiceButtonClickThunk),
364 this); 449 this);
365 450
366 SetServiceButtonImage(button, installed_service.favicon.ToGdkPixbuf()); 451 SetServiceButtonImage(button, installed_service.favicon.ToGdkPixbuf());
367 } 452 }
368 453
369 gtk_widget_show_all(button_vbox_); 454 gtk_widget_show_all(button_vbox_);
455 gtk_widget_show(gtk_widget_get_parent(button_vbox_));
370 } 456 }
371 457
372 void WebIntentPickerGtk::UpdateCWSLabel() { 458 void WebIntentPickerGtk::UpdateCWSLabel() {
373 if (model_->GetInstalledServiceCount() == 0) { 459 if (model_->GetInstalledServiceCount() == 0) {
374 gtk_widget_hide(gtk_widget_get_parent(button_vbox_)); 460 gtk_widget_hide(gtk_widget_get_parent(button_vbox_));
375 gtk_label_set_text(GTK_LABEL(cws_label_), l10n_util::GetStringUTF8( 461 gtk_label_set_text(GTK_LABEL(cws_label_), l10n_util::GetStringUTF8(
376 IDS_INTENT_PICKER_GET_MORE_SERVICES_NONE_INSTALLED).c_str()); 462 IDS_INTENT_PICKER_GET_MORE_SERVICES_NONE_INSTALLED).c_str());
377 } else { 463 } else {
378 gtk_label_set_text(GTK_LABEL(cws_label_), 464 gtk_label_set_text(GTK_LABEL(cws_label_),
379 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_GET_MORE_SERVICES).c_str()); 465 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_GET_MORE_SERVICES).c_str());
380 gtk_widget_show(gtk_widget_get_parent(button_vbox_)); 466 gtk_widget_show(gtk_widget_get_parent(button_vbox_));
381 } 467 }
382 468
383 if (model_->GetSuggestedExtensionCount() == 0) 469 if (model_->GetSuggestedExtensionCount() == 0)
384 gtk_widget_hide(cws_label_); 470 gtk_widget_hide(cws_label_);
385 else 471 else
386 gtk_widget_show(cws_label_); 472 gtk_widget_show(cws_label_);
387 } 473 }
388 474
389 void WebIntentPickerGtk::UpdateSuggestedExtensions() { 475 void WebIntentPickerGtk::UpdateSuggestedExtensions() {
390 ThemeServiceGtk* theme_service = GetThemeService(wrapper_); 476 ThemeServiceGtk* theme_service = GetThemeService(wrapper_);
391 477
392 gtk_util::RemoveAllChildren(extensions_vbox_); 478 gtk_util::RemoveAllChildren(extensions_vbox_);
393 if (model_->GetSuggestedExtensionCount() == 0) 479
480 if (model_->GetSuggestedExtensionCount() == 0) {
481 gtk_widget_hide(gtk_widget_get_parent(extensions_vbox_));
394 return; 482 return;
483 }
484
485 gtk_widget_show(gtk_widget_get_parent(extensions_vbox_));
395 486
396 for (size_t i = 0; i < model_->GetSuggestedExtensionCount(); ++i) { 487 for (size_t i = 0; i < model_->GetSuggestedExtensionCount(); ++i) {
397 const WebIntentPickerModel::SuggestedExtension& extension = 488 const WebIntentPickerModel::SuggestedExtension& extension =
398 model_->GetSuggestedExtensionAt(i); 489 model_->GetSuggestedExtensionAt(i);
399 490
400 GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing); 491 GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing);
401 gtk_box_pack_start(GTK_BOX(extensions_vbox_), hbox, FALSE, FALSE, 0); 492 gtk_box_pack_start(GTK_BOX(extensions_vbox_), hbox, FALSE, FALSE, 0);
402 493
403 // Icon. 494 // Icon.
404 GtkWidget* icon = gtk_image_new_from_pixbuf(extension.icon.ToGdkPixbuf()); 495 GtkWidget* icon = gtk_image_new_from_pixbuf(extension.icon.ToGdkPixbuf());
(...skipping 19 matching lines...) Expand all
424 // Install button. 515 // Install button.
425 GtkWidget* install_button = gtk_button_new(); 516 GtkWidget* install_button = gtk_button_new();
426 gtk_button_set_label( 517 gtk_button_set_label(
427 GTK_BUTTON(install_button), 518 GTK_BUTTON(install_button),
428 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_INSTALL_EXTENSION).c_str()); 519 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_INSTALL_EXTENSION).c_str());
429 g_signal_connect(install_button, "clicked", 520 g_signal_connect(install_button, "clicked",
430 G_CALLBACK(OnExtensionInstallButtonClickThunk), this); 521 G_CALLBACK(OnExtensionInstallButtonClickThunk), this);
431 gtk_box_pack_end(GTK_BOX(hbox), install_button, FALSE, FALSE, 0); 522 gtk_box_pack_end(GTK_BOX(hbox), install_button, FALSE, FALSE, 0);
432 } 523 }
433 524
434 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 525 gtk_widget_show_all(extensions_vbox_);
526 gtk_widget_show(gtk_widget_get_parent(extensions_vbox_));
527 }
435 528
436 GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing); 529 void WebIntentPickerGtk::SetWidgetsEnabled(bool enabled) {
530 gboolean data = enabled;
531 gtk_container_foreach(GTK_CONTAINER(button_vbox_),
532 EnableWidgetCallback,
533 &data);
534 gtk_container_foreach(GTK_CONTAINER(extensions_vbox_),
535 EnableWidgetCallback,
536 &data);
537 gtk_container_foreach(GTK_CONTAINER(extensions_vbox_),
538 SetStarsAndIntallButtonVisibility,
539 &data);
540 }
437 541
438 // Chrome Web Store icon. 542 void WebIntentPickerGtk::AddThrobberToExtensionAt(size_t index) {
439 gtk_box_pack_start( 543 // The throbber should be unparented.
440 GTK_BOX(hbox), 544 DCHECK(!gtk_widget_get_parent(throbber_->widget()));
441 gtk_image_new_from_pixbuf( 545 GList* vbox_list =
442 rb.GetRTLEnabledPixbufNamed(IDR_WEBSTORE_ICON_16)), 546 gtk_container_get_children(GTK_CONTAINER(extensions_vbox_));
443 FALSE, FALSE, 0); 547 GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index));
548 GtkWidget* alignment = gtk_alignment_new(0, 0.5, 0, 0);
549 gtk_container_add(GTK_CONTAINER(alignment), throbber_->widget());
550 gtk_box_pack_start(GTK_BOX(hbox), alignment, FALSE, FALSE, 0);
551 gtk_widget_show_all(alignment);
552 throbber_->Start();
553 }
444 554
445 // Left-aligned link button. 555 void WebIntentPickerGtk::RemoveThrobber() {
446 GtkWidget* more_suggestions_link = theme_service->BuildChromeLinkButton( 556 GtkWidget* alignment = gtk_widget_get_parent(throbber_->widget());
447 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_MORE_SUGGESTIONS).c_str()); 557 DCHECK(alignment);
448 gtk_chrome_link_button_set_use_gtk_theme( 558 gtk_container_remove(GTK_CONTAINER(alignment), throbber_->widget());
449 GTK_CHROME_LINK_BUTTON(more_suggestions_link), 559 gtk_widget_destroy(alignment);
450 theme_service->UsingNativeTheme()); 560 throbber_->Stop();
451 g_signal_connect(more_suggestions_link, "clicked",
452 G_CALLBACK(OnMoreSuggestionsLinkClickThunk), this);
453 gtk_box_pack_start(GTK_BOX(hbox), more_suggestions_link,
454 FALSE, FALSE, 0);
455
456 gtk_box_pack_start(GTK_BOX(extensions_vbox_), hbox, FALSE, FALSE, 0);
457
458 gtk_widget_show_all(extensions_vbox_);
459 } 561 }
460 562
461 GtkWidget* WebIntentPickerGtk::CreateStarsWidget(double rating) { 563 GtkWidget* WebIntentPickerGtk::CreateStarsWidget(double rating) {
462 const int kStarSpacing = 1; // Spacing between stars in pixels. 564 const int kStarSpacing = 1; // Spacing between stars in pixels.
463 GtkWidget* hbox = gtk_hbox_new(FALSE, kStarSpacing); 565 GtkWidget* hbox = gtk_hbox_new(FALSE, kStarSpacing);
464 566
465 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 567 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
466 for (int i = 0; i < 5; ++i) { 568 for (int i = 0; i < 5; ++i) {
467 gtk_box_pack_start( 569 gtk_box_pack_start(
468 GTK_BOX(hbox), 570 GTK_BOX(hbox),
469 gtk_image_new_from_pixbuf(rb.GetRTLEnabledPixbufNamed( 571 gtk_image_new_from_pixbuf(rb.GetRTLEnabledPixbufNamed(
470 WebIntentPicker::GetNthStarImageIdFromCWSRating(rating, i))), 572 WebIntentPicker::GetNthStarImageIdFromCWSRating(rating, i))),
471 FALSE, FALSE, 0); 573 FALSE, FALSE, 0);
472 } 574 }
473 575
474 return hbox; 576 return hbox;
475 } 577 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698