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

Unified Diff: chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc

Issue 327743002: Re-styled the App Info Dialog according to UI feedback (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
new file mode 100644
index 0000000000000000000000000000000000000000..584d51e631c5f9dfefb0ddecef2ddfc9d948689d
--- /dev/null
+++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.cc
@@ -0,0 +1,323 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.h"
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_uninstall_dialog.h"
+#include "chrome/browser/extensions/extension_util.h"
+#include "chrome/browser/extensions/image_loader.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/extensions/manifest_url_handler.h"
+#include "extensions/browser/extension_system.h"
+#include "extensions/browser/management_policy.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/extension.h"
+#include "extensions/common/extension_icon_set.h"
+#include "extensions/common/extension_resource.h"
+#include "extensions/common/manifest_handlers/icons_handler.h"
+#include "extensions/common/manifest_handlers/shared_module_info.h"
+#include "grit/generated_resources.h"
+#include "net/base/url_util.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/image/image_skia_rep.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/text_constants.h"
+#include "ui/views/controls/image_view.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/controls/link.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/grid_layout.h"
+#include "ui/views/layout/layout_constants.h"
+#include "ui/views/widget/widget.h"
+#include "url/gurl.h"
+
+// Size of extension icon in top left of dialog.
+const int kIconSize = 64;
+
+AppInfoSummaryPanel::AppInfoSummaryPanel(gfx::NativeWindow parent_window,
+ Profile* profile,
+ const extensions::Extension* app,
+ const base::Closure& close_callback)
+ : app_icon_(NULL),
+ app_name_label_(NULL),
+ app_version_label_(NULL),
+ view_in_store_link_(NULL),
+ remove_link_(NULL),
+ licenses_link_(NULL),
+ parent_window_(parent_window),
+ profile_(profile),
+ app_(app),
+ close_callback_(close_callback),
+ weak_ptr_factory_(this) {
+ CreateControls();
+
+ SetLayoutManager(
+ new views::BoxLayout(views::BoxLayout::kHorizontal,
+ views::kButtonHEdgeMargin,
+ views::kButtonVEdgeMargin,
+ views::kRelatedControlHorizontalSpacing));
+
+ LayoutControls();
+}
+
+AppInfoSummaryPanel::~AppInfoSummaryPanel() {
+}
+
+void AppInfoSummaryPanel::CreateControls() {
+ app_name_label_ =
+ new views::Label(base::UTF8ToUTF16(app_->name()),
+ ui::ResourceBundle::GetSharedInstance().GetFontList(
+ ui::ResourceBundle::BoldFont));
+ app_name_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+
+ // The version number doesn't make sense for bookmarked apps.
+ if (!app_->from_bookmark()) {
+ app_version_label_ =
+ new views::Label(base::UTF8ToUTF16(app_->VersionString()));
+ app_version_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ }
+
+ app_icon_ = new views::ImageView();
+ app_icon_->SetImageSize(gfx::Size(kIconSize, kIconSize));
+ LoadAppImageAsync();
+
+ if (CanShowAppInWebStore()) {
+ view_in_store_link_ = new views::Link(
+ l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_WEB_STORE_LINK));
+ view_in_store_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ view_in_store_link_->set_listener(this);
+ }
+
+ if (CanUninstallApp()) {
+ remove_link_ = new views::Link(
+ l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_UNINSTALL_BUTTON_TEXT));
+ remove_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ remove_link_->set_listener(this);
+ }
+
+ if (CanDisplayLicenses()) {
+ licenses_link_ = new views::Link(
+ l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_LICENSES_BUTTON_TEXT));
+ licenses_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ licenses_link_->set_listener(this);
+ }
+}
+
+void AppInfoSummaryPanel::LayoutAppNameAndVersionInto(
+ views::View* parent_view) {
+ views::View* view = new views::View();
+ // We need a horizontal BoxLayout here to ensure that the GridLayout does
+ // not stretch beyond the size of its content.
+ view->SetLayoutManager(
+ new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
+
+ views::View* container_view = new views::View();
+ view->AddChildView(container_view);
+ views::GridLayout* layout = new views::GridLayout(container_view);
+ container_view->SetLayoutManager(layout);
+
+ static const int kColumnId = 1;
+ views::ColumnSet* column_set = layout->AddColumnSet(kColumnId);
+ column_set->AddColumn(views::GridLayout::LEADING,
+ views::GridLayout::LEADING,
+ 1, // Stretch the title to as wide as needed
+ views::GridLayout::USE_PREF,
+ 0,
+ 0);
+ column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
+ column_set->AddColumn(views::GridLayout::LEADING,
+ views::GridLayout::LEADING,
+ 0, // Do not stretch the version
+ views::GridLayout::USE_PREF,
+ 0,
+ 0);
+
+ layout->StartRow(1, kColumnId);
+ layout->AddView(app_name_label_);
+ if (app_version_label_)
+ layout->AddView(app_version_label_);
+
+ parent_view->AddChildView(view);
+}
+
+void AppInfoSummaryPanel::LayoutControls() {
+ AddChildView(app_icon_);
+
+ if (!app_version_label_ && !view_in_store_link_) {
+ // If there's no link to the webstore _and_ no version, allow the app's name
+ // to take up multiple lines.
+ app_name_label_->SetMultiLine(true);
+ AddChildView(app_name_label_);
+ } else {
+ // Create a vertical container to store the app's name and info.
+ views::View* vertical_info_container = new views::View();
+ views::BoxLayout* vertical_container_layout =
+ new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
+ vertical_container_layout->set_main_axis_alignment(
+ views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
+ vertical_info_container->SetLayoutManager(vertical_container_layout);
+
+ // Create a horizontal container to store the app's links.
+ views::View* horizontal_links_container = new views::View();
+ horizontal_links_container->SetLayoutManager(
+ new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 3));
+
+ if (view_in_store_link_)
+ horizontal_links_container->AddChildView(view_in_store_link_);
+ if (remove_link_)
+ horizontal_links_container->AddChildView(remove_link_);
+ if (licenses_link_)
+ horizontal_links_container->AddChildView(licenses_link_);
+
+ // First line: title and (possibly) version. Second line: links (if any).
+ if (app_version_label_) {
+ LayoutAppNameAndVersionInto(vertical_info_container);
+ } else {
+ vertical_info_container->AddChildView(app_name_label_);
+ }
+
+ if (vertical_info_container->child_count() > 0)
+ vertical_info_container->AddChildView(horizontal_links_container);
+
+ AddChildView(vertical_info_container);
+ }
+}
+
+void AppInfoSummaryPanel::LinkClicked(views::Link* source, int event_flags) {
+ if (source == view_in_store_link_) {
+ ShowAppInWebStore();
+ } else if (source == remove_link_) {
+ UninstallApp();
+ } else if (source == licenses_link_) {
+ DisplayLicenses();
+ } else {
+ NOTREACHED();
+ }
+}
+
+void AppInfoSummaryPanel::ExtensionUninstallAccepted() {
+ ExtensionService* service =
+ extensions::ExtensionSystem::Get(profile_)->extension_service();
+ service->UninstallExtension(app_->id(), false, NULL);
+
+ // Close the App Info dialog as well (which will free the dialog too).
+ GetWidget()->Close();
+}
+
+void AppInfoSummaryPanel::ExtensionUninstallCanceled() {
+ extension_uninstall_dialog_.reset();
+}
+
+void AppInfoSummaryPanel::LoadAppImageAsync() {
+ extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
+ app_,
+ extension_misc::EXTENSION_ICON_LARGE,
+ ExtensionIconSet::MATCH_BIGGER);
+ int pixel_size =
+ static_cast<int>(kIconSize * gfx::ImageSkia::GetMaxSupportedScale());
+ extensions::ImageLoader::Get(profile_)->LoadImageAsync(
+ app_,
+ image,
+ gfx::Size(pixel_size, pixel_size),
+ base::Bind(&AppInfoSummaryPanel::OnAppImageLoaded, AsWeakPtr()));
+}
+
+void AppInfoSummaryPanel::OnAppImageLoaded(const gfx::Image& image) {
+ const SkBitmap* bitmap;
+ if (image.IsEmpty()) {
+ bitmap = &extensions::util::GetDefaultAppIcon()
+ .GetRepresentation(gfx::ImageSkia::GetMaxSupportedScale())
+ .sk_bitmap();
+ } else {
+ bitmap = image.ToSkBitmap();
+ }
+
+ app_icon_->SetImage(gfx::ImageSkia::CreateFrom1xBitmap(*bitmap));
+}
+
+void AppInfoSummaryPanel::ShowAppInWebStore() const {
+ DCHECK(CanShowAppInWebStore());
+ const GURL url = extensions::ManifestURL::GetDetailsURL(app_);
+ DCHECK_NE(url, GURL::EmptyGURL());
+ chrome::NavigateParams params(
+ profile_,
+ net::AppendQueryParameter(url,
+ extension_urls::kWebstoreSourceField,
+ extension_urls::kLaunchSourceAppListInfoDialog),
+ content::PAGE_TRANSITION_LINK);
+ chrome::Navigate(&params);
+}
+
+bool AppInfoSummaryPanel::CanShowAppInWebStore() const {
+ return app_->from_webstore();
+}
+
+void AppInfoSummaryPanel::UninstallApp() {
+ DCHECK(CanUninstallApp());
+ extension_uninstall_dialog_.reset(
+ extensions::ExtensionUninstallDialog::Create(profile_, NULL, this));
+ extension_uninstall_dialog_->ConfirmUninstall(app_);
+}
+
+bool AppInfoSummaryPanel::CanUninstallApp() const {
+ return extensions::ExtensionSystem::Get(profile_)
+ ->management_policy()
+ ->UserMayModifySettings(app_, NULL);
+}
+
+void AppInfoSummaryPanel::DisplayLicenses() {
+ // Find the first shared module for this app, and display it's options page
+ // as an 'about' link.
+ // TODO(sashab): Revisit UI layout once shared module usage becomes more
+ // common.
+ DCHECK(CanDisplayLicenses());
+ ExtensionService* service =
+ extensions::ExtensionSystem::Get(profile_)->extension_service();
+ DCHECK(service);
+ const std::vector<extensions::SharedModuleInfo::ImportInfo>& imports =
+ extensions::SharedModuleInfo::GetImports(app_);
+ const extensions::Extension* imported_module =
+ service->GetExtensionById(imports[0].extension_id, true);
+ DCHECK(imported_module);
+
+ GURL about_page = extensions::ManifestURL::GetOptionsPage(imported_module);
+ DCHECK(about_page != GURL::EmptyGURL());
+
+ chrome::NavigateParams params(
+ profile_, about_page, content::PAGE_TRANSITION_LINK);
+ chrome::Navigate(&params);
+}
+
+bool AppInfoSummaryPanel::CanDisplayLicenses() {
+ if (!extensions::SharedModuleInfo::ImportsModules(app_))
+ return false;
+
+ ExtensionService* service =
+ extensions::ExtensionSystem::Get(profile_)->extension_service();
+ DCHECK(service);
+
+ const std::vector<extensions::SharedModuleInfo::ImportInfo>& imports =
+ extensions::SharedModuleInfo::GetImports(app_);
+ const extensions::Extension* imported_module =
+ service->GetExtensionById(imports[0].extension_id, true);
+ DCHECK(imported_module);
+
+ GURL about_page = extensions::ManifestURL::GetOptionsPage(imported_module);
+ if (about_page == GURL::EmptyGURL())
+ return false;
+
+ return true;
+}

Powered by Google App Engine
This is Rietveld 408576698