Chromium Code Reviews| Index: chrome/browser/ui/gtk/web_intent_picker_gtk.cc |
| diff --git a/chrome/browser/ui/gtk/web_intent_picker_gtk.cc b/chrome/browser/ui/gtk/web_intent_picker_gtk.cc |
| index a1e609bd4b9415fe03fbe153084964ff9c6cc90a..61236074d421f6ae647671a73371a8b1612cca9f 100644 |
| --- a/chrome/browser/ui/gtk/web_intent_picker_gtk.cc |
| +++ b/chrome/browser/ui/gtk/web_intent_picker_gtk.cc |
| @@ -20,6 +20,7 @@ |
| #include "chrome/browser/ui/gtk/location_bar_view_gtk.h" |
| #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h" |
| #include "chrome/browser/ui/gtk/theme_service_gtk.h" |
| +#include "chrome/browser/ui/gtk/throbber_gtk.h" |
| #include "chrome/browser/ui/intents/web_intent_picker_controller.h" |
| #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" |
| #include "chrome/browser/ui/intents/web_intent_picker_model.h" |
| @@ -60,6 +61,14 @@ const int kHeaderLabelPixelSize = 15; |
| // The maximum width in pixels of a suggested extension's title link. |
| const int kTitleLinkMaxWidth = 130; |
| +// Indices of the extension row widgets. |
| +enum { |
| + kIconIndex, |
| + kTitleLinkIndex, |
| + kStarsIndex, |
| + kInstallButtonIndex, |
| +}; |
| + |
| ThemeServiceGtk *GetThemeService(TabContentsWrapper* wrapper) { |
| return ThemeServiceGtk::GetFrom(wrapper->profile()); |
| } |
| @@ -85,6 +94,37 @@ size_t GetExtensionWidgetRow(GtkWidget* widget) { |
| return index; |
| } |
| +// A gtk_container_foreach callback to enable/disable a widget. |
| +void EnableWidgetCallback(GtkWidget* widget, gpointer data) { |
| + gtk_widget_set_sensitive(widget, *static_cast<gboolean*>(data)); |
| +} |
| + |
| +// A gtk_container_foreach callback to show/hide the stars and install button |
| +// widgets of an extension hbox. |
| +void SetStarsAndIntallButtonVisibility(GtkWidget* extension_hbox, |
| + gpointer data) { |
| + gboolean visible = *static_cast<gboolean*>(data); |
| + GList* list = gtk_container_get_children(GTK_CONTAINER(extension_hbox)); |
| + GtkWidget* stars = GTK_WIDGET(g_list_nth_data(list, kStarsIndex)); |
| + GtkWidget* install_button = |
| + GTK_WIDGET(g_list_nth_data(list, kInstallButtonIndex)); |
| + |
| + if (visible) { |
| + // Reset the size requisition to use the "natural" size. |
| + gtk_widget_set_size_request(extension_hbox, -1, -1); |
| + gtk_widget_show(stars); |
| + gtk_widget_show(install_button); |
| + } else { |
| + GtkRequisition requisition; |
| + gtk_widget_size_request(extension_hbox, &requisition); |
| + gtk_widget_hide(stars); |
| + gtk_widget_hide(install_button); |
| + // Ask for the new size to be the same as before stuff was hidden. |
| + gtk_widget_set_size_request(extension_hbox, requisition.width, |
| + requisition.height); |
| + } |
| +} |
| + |
| } // namespace |
| // static |
| @@ -135,6 +175,15 @@ void WebIntentPickerGtk::Close() { |
| inline_disposition_tab_contents_->web_contents()->OnCloseStarted(); |
| } |
| +void WebIntentPickerGtk::OnExtensionInstallSuccess(const std::string& id) { |
| + RemoveThrobber(); |
| +} |
| + |
| +void WebIntentPickerGtk::OnExtensionInstallFailure(const std::string& id) { |
| + RemoveThrobber(); |
| + SetWidgetsEnabled(true); |
| +} |
| + |
| void WebIntentPickerGtk::OnModelChanged(WebIntentPickerModel* model) { |
| UpdateInstalledServices(); |
| UpdateCWSLabel(); |
| @@ -261,7 +310,20 @@ void WebIntentPickerGtk::OnExtensionLinkClick(GtkWidget* link) { |
| } |
| void WebIntentPickerGtk::OnExtensionInstallButtonClick(GtkWidget* button) { |
| - // TODO(binji): Install the extension. |
| + size_t index = GetExtensionWidgetRow(button); |
| + const WebIntentPickerModel::SuggestedExtension& extension = |
| + model_->GetSuggestedExtensionAt(index); |
| + |
| + delegate_->OnExtensionInstallRequested(UTF16ToUTF8(extension.id)); |
| + SetWidgetsEnabled(false); |
| + // Re-enable the clicked extension row. |
| + GList* vbox_list = |
| + gtk_container_get_children(GTK_CONTAINER(extensions_vbox_)); |
| + GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index)); |
| + gboolean enabled = TRUE; |
| + 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.
|
| + |
| + AddThrobberToExtensionAt(index); |
| } |
| void WebIntentPickerGtk::OnMoreSuggestionsLinkClick(GtkWidget* link) { |
| @@ -318,7 +380,9 @@ void WebIntentPickerGtk::InitContents() { |
| FALSE, FALSE, 0); |
| // Alignment for service button vbox. |
| - GtkWidget* button_alignment = gtk_alignment_new(0.5f, 0.5f, 0.3f, 0); |
| + GtkWidget* button_alignment = gtk_alignment_new(0, 0.5f, 0.3f, 0); |
| + gtk_alignment_set_padding(GTK_ALIGNMENT(button_alignment), 0, 0, |
| + ui::kGroupIndent, 0); |
| gtk_widget_set_no_show_all(button_alignment, TRUE); |
| // Vbox containing all service buttons. |
| @@ -335,17 +399,38 @@ void WebIntentPickerGtk::InitContents() { |
| gtk_widget_set_no_show_all(cws_label_, TRUE); |
| gtk_util::SetLabelWidth(cws_label_, kWebStoreLabelLength); |
| - g_signal_connect(contents_, "destroy", G_CALLBACK(&OnDestroyThunk), this); |
| - |
| // Suggested extensions vbox. |
| - extensions_vbox_ = gtk_vbox_new(FALSE, ui::kContentAreaSpacing); |
| - gtk_box_pack_start(GTK_BOX(contents_), |
| - gtk_util::IndentWidget(extensions_vbox_), TRUE, TRUE, 0); |
| + extensions_vbox_ = gtk_vbox_new(FALSE, ui::kControlSpacing); |
| + GtkWidget* indent_extensions = gtk_util::IndentWidget(extensions_vbox_); |
| + gtk_widget_set_no_show_all(indent_extensions, TRUE); |
| + gtk_box_pack_start(GTK_BOX(contents_), indent_extensions, TRUE, TRUE, 0); |
| + |
| + // Left-aligned link button. |
| + GtkWidget* link_alignment = gtk_alignment_new(0, 0.5f, 0, 0); |
| + GtkWidget* more_suggestions_link = theme_service->BuildChromeLinkButton( |
| + l10n_util::GetStringUTF8(IDS_INTENT_PICKER_MORE_SUGGESTIONS).c_str()); |
| + gtk_container_add(GTK_CONTAINER(link_alignment), more_suggestions_link); |
| + gtk_chrome_link_button_set_use_gtk_theme( |
| + GTK_CHROME_LINK_BUTTON(more_suggestions_link), |
| + 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.
|
| + g_signal_connect(more_suggestions_link, "clicked", |
| + G_CALLBACK(OnMoreSuggestionsLinkClickThunk), this); |
| + gtk_box_pack_start(GTK_BOX(contents_), link_alignment, FALSE, FALSE, 0); |
| + |
| + // 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.
|
| + throbber_.reset(new ThrobberGtk(theme_service)); |
| + |
| + g_signal_connect(contents_, "destroy", G_CALLBACK(&OnDestroyThunk), this); |
| } |
| void WebIntentPickerGtk::UpdateInstalledServices() { |
| gtk_util::RemoveAllChildren(button_vbox_); |
| + if (model_->GetInstalledServiceCount() == 0) { |
| + gtk_widget_hide(gtk_widget_get_parent(button_vbox_)); |
| + return; |
| + } |
| + |
| for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) { |
| const WebIntentPickerModel::InstalledService& installed_service = |
| model_->GetInstalledServiceAt(i); |
| @@ -367,6 +452,7 @@ void WebIntentPickerGtk::UpdateInstalledServices() { |
| } |
| gtk_widget_show_all(button_vbox_); |
| + gtk_widget_show(gtk_widget_get_parent(button_vbox_)); |
| } |
| void WebIntentPickerGtk::UpdateCWSLabel() { |
| @@ -390,8 +476,13 @@ void WebIntentPickerGtk::UpdateSuggestedExtensions() { |
| ThemeServiceGtk* theme_service = GetThemeService(wrapper_); |
| gtk_util::RemoveAllChildren(extensions_vbox_); |
| - if (model_->GetSuggestedExtensionCount() == 0) |
| + |
| + if (model_->GetSuggestedExtensionCount() == 0) { |
| + gtk_widget_hide(gtk_widget_get_parent(extensions_vbox_)); |
| return; |
| + } |
| + |
| + gtk_widget_show(gtk_widget_get_parent(extensions_vbox_)); |
| for (size_t i = 0; i < model_->GetSuggestedExtensionCount(); ++i) { |
| const WebIntentPickerModel::SuggestedExtension& extension = |
| @@ -431,31 +522,42 @@ void WebIntentPickerGtk::UpdateSuggestedExtensions() { |
| gtk_box_pack_end(GTK_BOX(hbox), install_button, FALSE, FALSE, 0); |
| } |
| - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| - |
| - GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing); |
| - |
| - // Chrome Web Store icon. |
| - gtk_box_pack_start( |
| - GTK_BOX(hbox), |
| - gtk_image_new_from_pixbuf( |
| - rb.GetRTLEnabledPixbufNamed(IDR_WEBSTORE_ICON_16)), |
| - FALSE, FALSE, 0); |
| + gtk_widget_show_all(extensions_vbox_); |
| + gtk_widget_show(gtk_widget_get_parent(extensions_vbox_)); |
| +} |
| - // Left-aligned link button. |
| - GtkWidget* more_suggestions_link = theme_service->BuildChromeLinkButton( |
| - l10n_util::GetStringUTF8(IDS_INTENT_PICKER_MORE_SUGGESTIONS).c_str()); |
| - gtk_chrome_link_button_set_use_gtk_theme( |
| - GTK_CHROME_LINK_BUTTON(more_suggestions_link), |
| - theme_service->UsingNativeTheme()); |
| - g_signal_connect(more_suggestions_link, "clicked", |
| - G_CALLBACK(OnMoreSuggestionsLinkClickThunk), this); |
| - gtk_box_pack_start(GTK_BOX(hbox), more_suggestions_link, |
| - FALSE, FALSE, 0); |
| +void WebIntentPickerGtk::SetWidgetsEnabled(bool enabled) { |
| + gboolean data = enabled; |
| + gtk_container_foreach(GTK_CONTAINER(button_vbox_), |
| + EnableWidgetCallback, |
| + &data); |
| + gtk_container_foreach(GTK_CONTAINER(extensions_vbox_), |
| + EnableWidgetCallback, |
| + &data); |
| + gtk_container_foreach(GTK_CONTAINER(extensions_vbox_), |
| + SetStarsAndIntallButtonVisibility, |
| + &data); |
| +} |
| - gtk_box_pack_start(GTK_BOX(extensions_vbox_), hbox, FALSE, FALSE, 0); |
| +void WebIntentPickerGtk::AddThrobberToExtensionAt(size_t index) { |
| + // The throbber should be unparented. |
| + DCHECK(!gtk_widget_get_parent(throbber_->widget())); |
| + GList* vbox_list = |
| + gtk_container_get_children(GTK_CONTAINER(extensions_vbox_)); |
| + GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index)); |
| + GtkWidget* alignment = gtk_alignment_new(0, 0.5, 0, 0); |
| + gtk_container_add(GTK_CONTAINER(alignment), throbber_->widget()); |
| + gtk_box_pack_start(GTK_BOX(hbox), alignment, FALSE, FALSE, 0); |
| + gtk_widget_show_all(alignment); |
| + throbber_->Start(); |
| +} |
| - gtk_widget_show_all(extensions_vbox_); |
| +void WebIntentPickerGtk::RemoveThrobber() { |
| + GtkWidget* alignment = gtk_widget_get_parent(throbber_->widget()); |
| + DCHECK(alignment); |
| + gtk_container_remove(GTK_CONTAINER(alignment), throbber_->widget()); |
| + gtk_widget_destroy(alignment); |
| + throbber_->Stop(); |
| } |
| GtkWidget* WebIntentPickerGtk::CreateStarsWidget(double rating) { |