summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorrouslan@chromium.org <rouslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-17 00:31:33 +0000
committerrouslan@chromium.org <rouslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-17 00:31:33 +0000
commiteb4bf166cb254650e7e371f792efc024df457e30 (patch)
tree3817a6e2096a14299aad856fc4a2ca7d2555d0a7 /chrome
parent1c0088fc6cfec7c21c20a147218f49b8e34e21c0 (diff)
downloadchromium_src-eb4bf166cb254650e7e371f792efc024df457e30.zip
chromium_src-eb4bf166cb254650e7e371f792efc024df457e30.tar.gz
chromium_src-eb4bf166cb254650e7e371f792efc024df457e30.tar.bz2
Make Web Intents picker in Views conform to latest mocks
BUG=148615 TBR=jhawkins Review URL: https://chromiumcodereview.appspot.com/11044020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162287 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/generated_resources.grd14
-rw-r--r--chrome/browser/ui/constrained_window_constants.cc22
-rw-r--r--chrome/browser/ui/constrained_window_constants.h27
-rw-r--r--chrome/browser/ui/intents/web_intent_picker.h4
-rw-r--r--chrome/browser/ui/intents/web_intent_picker_controller.cc5
-rw-r--r--chrome/browser/ui/intents/web_intent_picker_model.cc13
-rw-r--r--chrome/browser/ui/intents/web_intent_picker_model.h3
-rw-r--r--chrome/browser/ui/views/collected_cookies_views.cc3
-rw-r--r--chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc3
-rw-r--r--chrome/browser/ui/views/constrained_window_frame_simple.cc226
-rw-r--r--chrome/browser/ui/views/constrained_window_frame_simple.h33
-rw-r--r--chrome/browser/ui/views/constrained_window_views.cc118
-rw-r--r--chrome/browser/ui/views/constrained_window_views.h36
-rw-r--r--chrome/browser/ui/views/constrained_window_views_browsertest.cc15
-rw-r--r--chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc3
-rw-r--r--chrome/browser/ui/views/login_prompt_views.cc4
-rw-r--r--chrome/browser/ui/views/ssl_client_certificate_selector.cc6
-rw-r--r--chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc6
-rw-r--r--chrome/browser/ui/views/web_intent_picker_views.cc851
-rw-r--r--chrome/chrome_browser_ui.gypi1
20 files changed, 782 insertions, 611 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 895f365..c55801c 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -14078,7 +14078,7 @@ Some features may be unavailable. Please check that the profile exists and you
Complete action using:
</message>
<message name="IDS_FIND_MORE_INTENT_HANDLER_MESSAGE" desc="Text to show to inform the user that more intent services can be found in the web store.">
- Find more apps by visiting the Chrome Web Store.
+ Find more apps in the Chrome Web Store
</message>
<message name="IDS_FIND_MORE_INTENT_HANDLER_TOOLTIP" desc="Tooltip text for the web store plus button on the intent picker dialog.">
Find apps in the Chrome Web Store
@@ -14087,7 +14087,7 @@ Some features may be unavailable. Please check that the profile exists and you
No apps are registered for this action.
</message>
<message name="IDS_INTENT_PICKER_CHOOSE_SERVICE" desc="Prompt to the user to select one of the given services to complete a Web Intents action.">
- Which app do you want to use?
+ Choose an app&#8230;
</message>
<message name="IDS_INTENT_PICKER_CHOOSE_SERVICES_NONE_INSTALLED_TITLE" desc="Heading in the Web Intents picker box for a section containing suggested applications from the Chrome Web Store. Displayed only if there are no installed services.">
You have no apps installed.
@@ -14122,19 +14122,19 @@ Some features may be unavailable. Please check that the profile exists and you
<!-- Web Intents common actions -->
<message name="IDS_WEB_INTENTS_ACTION_SHARE" desc="Question asking the user to pick a service for the 'share' action.">
- Which app should be used for sharing?
+ Share with&#8230;
</message>
<message name="IDS_WEB_INTENTS_ACTION_EDIT" desc="Question asking the user to pick a service for the 'edit' action.">
- Which app should be used for editing?
+ Edit with&#8230;
</message>
<message name="IDS_WEB_INTENTS_ACTION_VIEW" desc="Question asking the user to pick a service for the 'viewing' action.">
- Which app should be used for viewing?
+ View with&#8230;
</message>
<message name="IDS_WEB_INTENTS_ACTION_SUBSCRIBE" desc="Question asking the user to pick a service for the 'subscribe' action.">
- Which app should be used for subscribing?
+ Subscribe with&#8230;
</message>
<message name="IDS_WEB_INTENTS_ACTION_SAVE" desc="Question asking the user to pick a service for the 'save' action.">
- Which app should be used for saving?
+ Save with&#8230;
</message>
<!-- Web Intents native services (titles) -->
diff --git a/chrome/browser/ui/constrained_window_constants.cc b/chrome/browser/ui/constrained_window_constants.cc
new file mode 100644
index 0000000..58817f7
--- /dev/null
+++ b/chrome/browser/ui/constrained_window_constants.cc
@@ -0,0 +1,22 @@
+// Copyright (c) 2012 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/constrained_window_constants.h"
+
+const int ConstrainedWindowConstants::kTitleTopPadding = 15;
+const int ConstrainedWindowConstants::kHorizontalPadding = 20;
+const int ConstrainedWindowConstants::kClientTopPadding = 15;
+const int ConstrainedWindowConstants::kClientBottomPadding = 20;
+const int ConstrainedWindowConstants::kCloseButtonPadding = 7;
+const int ConstrainedWindowConstants::kBorderRadius = 2;
+const int ConstrainedWindowConstants::kRowPadding = 20;
+
+const ui::ResourceBundle::FontStyle ConstrainedWindowConstants::kTextFontStyle =
+ ui::ResourceBundle::BaseFont;
+const ui::ResourceBundle::FontStyle
+ ConstrainedWindowConstants::kBoldTextFontStyle =
+ ui::ResourceBundle::BoldFont;
+const ui::ResourceBundle::FontStyle
+ ConstrainedWindowConstants::kTitleFontStyle =
+ ui::ResourceBundle::MediumFont;
diff --git a/chrome/browser/ui/constrained_window_constants.h b/chrome/browser/ui/constrained_window_constants.h
index 0d9d9ef..5a4e62a8 100644
--- a/chrome/browser/ui/constrained_window_constants.h
+++ b/chrome/browser/ui/constrained_window_constants.h
@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_UI_CONSTRAINED_WINDOW_CONSTANTS_H_
#define CHROME_BROWSER_UI_CONSTRAINED_WINDOW_CONSTANTS_H_
+#include "ui/base/resource/resource_bundle.h"
+
///////////////////////////////////////////////////////////////////////////////
// ConstrainedWindowConstants
//
@@ -12,23 +14,22 @@
//
class ConstrainedWindowConstants {
public:
- static const int kTitleTopPadding = 15; // Padding above the title.
- static const int kHorizontalPadding = 20; // Left and right padding.
- static const int kClientTopPadding = 18; // Padding above the client view.
- static const int kClientBottomPadding = 20; // Padding below the client view.
- static const int kCloseButtonPadding = 7; // Padding around the close button.
- static const int kBorderRadius = 2; // Border radius for dialog corners.
- static const int kRowPadding = 20; // Padding between rows of text.
+ static const int kTitleTopPadding; // Padding above the title.
+ static const int kHorizontalPadding; // Left and right padding.
+ static const int kClientTopPadding; // Padding above the client view.
+ static const int kClientBottomPadding; // Padding below the client view.
+ static const int kCloseButtonPadding; // Padding around the close button.
+ static const int kBorderRadius; // Border radius for dialog corners.
+ static const int kRowPadding; // Padding between rows of text.
// Font style for dialog text.
- static const ui::ResourceBundle::FontStyle kTextFontStyle =
- ui::ResourceBundle::BaseFont;
+ static const ui::ResourceBundle::FontStyle kTextFontStyle;
+
// Font style for bold dialog text.
- static const ui::ResourceBundle::FontStyle kBoldTextFontStyle =
- ui::ResourceBundle::BoldFont;
+ static const ui::ResourceBundle::FontStyle kBoldTextFontStyle;
+
// Font style for dialog title.
- static const ui::ResourceBundle::FontStyle kTitleFontStyle =
- ui::ResourceBundle::MediumFont;
+ static const ui::ResourceBundle::FontStyle kTitleFontStyle;
};
#endif // CHROME_BROWSER_UI_CONSTRAINED_WINDOW_CONSTANTS_H_
diff --git a/chrome/browser/ui/intents/web_intent_picker.h b/chrome/browser/ui/intents/web_intent_picker.h
index 3320b9b..38348ca 100644
--- a/chrome/browser/ui/intents/web_intent_picker.h
+++ b/chrome/browser/ui/intents/web_intent_picker.h
@@ -37,7 +37,7 @@ class WebIntentPicker {
static const int kTitleLinkMaxWidth = 130;
// The space in pixels between the top-level groups and the dialog border.
- static const int kContentAreaBorder = 10;
+ static const int kContentAreaBorder = 20;
// Vertical space above the separator.
static const int kHeaderSeparatorPaddingTop = 16;
@@ -52,7 +52,7 @@ class WebIntentPicker {
static const int kServiceIconHeight = 16;
// Space between icon and text.
- static const int kIconTextPadding = 6;
+ static const int kIconTextPadding = 10;
// Space between star rating and select button.
static const int kStarButtonPadding = 20;
diff --git a/chrome/browser/ui/intents/web_intent_picker_controller.cc b/chrome/browser/ui/intents/web_intent_picker_controller.cc
index 8223228..40b35fd 100644
--- a/chrome/browser/ui/intents/web_intent_picker_controller.cc
+++ b/chrome/browser/ui/intents/web_intent_picker_controller.cc
@@ -553,9 +553,8 @@ void WebIntentPickerController::DispatchToInstalledExtension(
// services. For now, just choose the first.
const webkit_glue::WebIntentServiceData& service_data = services[0];
- picker_model_->AddInstalledService(
- service_data.title, service_data.service_url,
- service_data.disposition);
+ picker_model_->RemoveSuggestedExtension(extension_id);
+ AddServiceToModel(service_data);
OnServiceChosen(service_data.service_url, service_data.disposition,
kEnableDefaults);
AsyncOperationFinished();
diff --git a/chrome/browser/ui/intents/web_intent_picker_model.cc b/chrome/browser/ui/intents/web_intent_picker_model.cc
index 16b0fb2..1a9bda8 100644
--- a/chrome/browser/ui/intents/web_intent_picker_model.cc
+++ b/chrome/browser/ui/intents/web_intent_picker_model.cc
@@ -114,6 +114,19 @@ void WebIntentPickerModel::AddSuggestedExtensions(
observer_->OnModelChanged(this);
}
+void WebIntentPickerModel::RemoveSuggestedExtension(const std::string& id) {
+ std::vector<SuggestedExtension>::iterator it;
+ for (it = suggested_extensions_.begin();
+ it < suggested_extensions_.end();
+ ++it) {
+ SuggestedExtension extension = *it;
+ if (extension.id == id) {
+ suggested_extensions_.erase(it);
+ break;
+ }
+ }
+}
+
const WebIntentPickerModel::SuggestedExtension&
WebIntentPickerModel::GetSuggestedExtensionAt(size_t index) const {
DCHECK_LT(index, suggested_extensions_.size());
diff --git a/chrome/browser/ui/intents/web_intent_picker_model.h b/chrome/browser/ui/intents/web_intent_picker_model.h
index f748a69..171e497 100644
--- a/chrome/browser/ui/intents/web_intent_picker_model.h
+++ b/chrome/browser/ui/intents/web_intent_picker_model.h
@@ -113,6 +113,9 @@ class WebIntentPickerModel {
void AddSuggestedExtensions(
const std::vector<SuggestedExtension>& suggestions);
+ // Remove the suggested extension with this id.
+ void RemoveSuggestedExtension(const std::string& id);
+
// Return the suggested extension at |index|.
const SuggestedExtension& GetSuggestedExtensionAt(size_t index) const;
diff --git a/chrome/browser/ui/views/collected_cookies_views.cc b/chrome/browser/ui/views/collected_cookies_views.cc
index b0a025d..9b1c38f 100644
--- a/chrome/browser/ui/views/collected_cookies_views.cc
+++ b/chrome/browser/ui/views/collected_cookies_views.cc
@@ -199,7 +199,8 @@ CollectedCookiesViews::CollectedCookiesViews(content::WebContents* web_contents)
TabSpecificContentSettings::FromWebContents(web_contents);
registrar_.Add(this, chrome::NOTIFICATION_COLLECTED_COOKIES_SHOWN,
content::Source<TabSpecificContentSettings>(content_settings));
- window_ = new ConstrainedWindowViews(web_contents, this, false);
+ window_ = new ConstrainedWindowViews(
+ web_contents, this, false, ConstrainedWindowViews::DEFAULT_INSETS);
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc b/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc
index 95edf10..1af7f4c 100644
--- a/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc
+++ b/chrome/browser/ui/views/constrained_web_dialog_delegate_views.cc
@@ -184,7 +184,8 @@ ConstrainedWebDialogDelegate* ui::CreateConstrainedWebDialog(
ConstrainedWindow* constrained_window =
new ConstrainedWindowViews(container->web_contents(),
constrained_delegate,
- false);
+ false,
+ ConstrainedWindowViews::DEFAULT_INSETS);
constrained_delegate->set_window(constrained_window);
return constrained_delegate;
}
diff --git a/chrome/browser/ui/views/constrained_window_frame_simple.cc b/chrome/browser/ui/views/constrained_window_frame_simple.cc
index 4107fe7..6768ac2 100644
--- a/chrome/browser/ui/views/constrained_window_frame_simple.cc
+++ b/chrome/browser/ui/views/constrained_window_frame_simple.cc
@@ -4,172 +4,118 @@
#include "chrome/browser/ui/views/constrained_window_frame_simple.h"
-#include "chrome/browser/ui/constrained_window.h"
#include "chrome/browser/ui/constrained_window_constants.h"
+#include "chrome/browser/ui/constrained_window.h"
#include "chrome/browser/ui/views/constrained_window_views.h"
-#include "grit/ui_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/google_chrome_strings.h"
#include "grit/shared_resources.h"
#include "grit/theme_resources.h"
+#include "grit/ui_resources.h"
#include "ui/base/hit_test.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
-#include "ui/gfx/rect.h"
#include "ui/gfx/path.h"
+#include "ui/gfx/rect.h"
#include "ui/views/background.h"
-#include "ui/views/controls/label.h"
#include "ui/views/controls/button/image_button.h"
+#include "ui/views/controls/label.h"
#include "ui/views/layout/grid_layout.h"
-#include "ui/views/layout/layout_manager.h"
#include "ui/views/layout/layout_constants.h"
-#include "ui/views/widget/widget.h"
+#include "ui/views/layout/layout_manager.h"
#include "ui/views/widget/widget_delegate.h"
-
-namespace {
-
-typedef ConstrainedWindowFrameSimple::HeaderViews HeaderViews;
-
-// A layout manager that lays out the header view with proper padding,
-// and sized to the widget's client view.
-class HeaderLayout : public views::LayoutManager {
- public:
- explicit HeaderLayout() {}
- virtual ~HeaderLayout() {}
-
- // Overridden from LayoutManager
- virtual void Layout(views::View* host);
- virtual gfx::Size GetPreferredSize(views::View* host);
-
- DISALLOW_COPY_AND_ASSIGN(HeaderLayout);
-};
-
-void HeaderLayout::Layout(views::View* host) {
- if (!host->has_children())
- return;
-
- int top_padding = ConstrainedWindowConstants::kCloseButtonPadding;
- int left_padding = ConstrainedWindowConstants::kHorizontalPadding;
- int right_padding = ConstrainedWindowConstants::kCloseButtonPadding;
-
- views::View* header = host->child_at(0);
- gfx::Size preferred_size = GetPreferredSize(host);
- int width = preferred_size.width() - left_padding - right_padding;
- int height = preferred_size.height() - top_padding;
-
- header->SetBounds(left_padding, top_padding, width, height);
-}
-
-gfx::Size HeaderLayout::GetPreferredSize(views::View* host) {
- int top_padding = ConstrainedWindowConstants::kCloseButtonPadding;
- int left_padding = ConstrainedWindowConstants::kHorizontalPadding;
- int right_padding = ConstrainedWindowConstants::kCloseButtonPadding;
-
- views::View* header = host->child_at(0);
- gfx::Size header_size = header ? header->GetPreferredSize() : gfx::Size();
- int width = std::max(host->GetPreferredSize().width(),
- left_padding + header_size.width() + right_padding);
- int height = header_size.height() + top_padding;
-
- return gfx::Size(width, height);
-}
-
-} // namespace
-
-ConstrainedWindowFrameSimple::HeaderViews::HeaderViews(
- views::View* header,
- views::Label* title_label,
- views::Button* close_button)
- : header(header),
- title_label(title_label),
- close_button(close_button) {
- DCHECK(header);
-}
+#include "ui/views/widget/widget.h"
ConstrainedWindowFrameSimple::ConstrainedWindowFrameSimple(
- ConstrainedWindowViews* container)
- : container_(container) {
+ ConstrainedWindowViews* container,
+ ConstrainedWindowViews::ChromeStyleClientInsets client_insets)
+ : container_(container),
+ title_label_(
+ new views::Label(container->widget_delegate()->GetWindowTitle())),
+ ALLOW_THIS_IN_INITIALIZER_LIST(close_button_(
+ new views::ImageButton(this))) {
container_->set_frame_type(views::Widget::FRAME_TYPE_FORCE_CUSTOM);
- layout_ = new HeaderLayout();
- SetLayoutManager(layout_);
+ views::GridLayout* layout = new views::GridLayout(this);
+ const int kHeaderTopPadding = std::min(
+ ConstrainedWindowConstants::kCloseButtonPadding,
+ ConstrainedWindowConstants::kTitleTopPadding);
+ layout->SetInsets(kHeaderTopPadding,
+ ConstrainedWindowConstants::kHorizontalPadding,
+ 0,
+ ConstrainedWindowConstants::kCloseButtonPadding);
+ SetLayoutManager(layout);
+ views::ColumnSet* cs = layout->AddColumnSet(0);
+ cs->AddColumn(views::GridLayout::FILL, views::GridLayout::LEADING, 1,
+ views::GridLayout::USE_PREF, 0, 0); // Title.
+ cs->AddPaddingColumn(0, ConstrainedWindowConstants::kCloseButtonPadding);
+ cs->AddColumn(views::GridLayout::TRAILING, views::GridLayout::LEADING, 0,
+ views::GridLayout::USE_PREF, 0, 0); // Close Button.
+
+ layout->StartRow(0, 0);
- SetHeaderView(CreateDefaultHeaderView());
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ title_label_->SetFont(rb.GetFont(
+ ConstrainedWindowConstants::kTitleFontStyle));
+ title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ title_label_->SetEnabledColor(ConstrainedWindow::GetTextColor());
+ title_label_->set_border(views::Border::CreateEmptyBorder(
+ ConstrainedWindowConstants::kTitleTopPadding - kHeaderTopPadding,
+ 0, 0, 0));
+ layout->AddView(title_label_);
+
+ close_button_->SetImage(views::CustomButton::BS_NORMAL,
+ rb.GetImageSkiaNamed(IDR_SHARED_IMAGES_X));
+ close_button_->SetImage(views::CustomButton::BS_HOT,
+ rb.GetImageSkiaNamed(IDR_SHARED_IMAGES_X_HOVER));
+ close_button_->SetImage(views::CustomButton::BS_PUSHED,
+ rb.GetImageSkiaNamed(IDR_SHARED_IMAGES_X_PRESSED));
+ close_button_->set_border(views::Border::CreateEmptyBorder(
+ ConstrainedWindowConstants::kCloseButtonPadding - kHeaderTopPadding,
+ 0, 0, 0));
+ layout->AddView(close_button_);
set_background(views::Background::CreateSolidBackground(
ConstrainedWindow::GetBackgroundColor()));
- set_border(views::Border::CreateEmptyBorder(
- ConstrainedWindowConstants::kClientTopPadding,
- ConstrainedWindowConstants::kHorizontalPadding,
- ConstrainedWindowConstants::kClientBottomPadding,
- ConstrainedWindowConstants::kHorizontalPadding));
+ // Client insets have no relation to header insets:
+ // - The client insets are the distance from the window border to the client
+ // view.
+ // - The header insets are the distance from the window border to the header
+ // elements.
+ //
+ // The NO_ISNETS consumers draw atop the views above.
+ if (client_insets == ConstrainedWindowViews::DEFAULT_INSETS) {
+ const int kTitleBuiltinBottomPadding = 4;
+ set_border(views::Border::CreateEmptyBorder(
+ ConstrainedWindowConstants::kClientTopPadding + kHeaderTopPadding +
+ std::max(close_button_->GetPreferredSize().height(),
+ title_label_->GetPreferredSize().height()) -
+ kTitleBuiltinBottomPadding,
+ ConstrainedWindowConstants::kHorizontalPadding,
+ ConstrainedWindowConstants::kClientBottomPadding,
+ ConstrainedWindowConstants::kHorizontalPadding));
+ }
}
ConstrainedWindowFrameSimple::~ConstrainedWindowFrameSimple() {
}
-void ConstrainedWindowFrameSimple::SetHeaderView(HeaderViews* header_views)
-{
- RemoveAllChildViews(true);
-
- header_views_.reset(header_views);
-
- AddChildView(header_views_->header);
-}
-
-HeaderViews* ConstrainedWindowFrameSimple::CreateDefaultHeaderView() {
- const int kTitleTopPadding = ConstrainedWindowConstants::kTitleTopPadding -
- ConstrainedWindowConstants::kCloseButtonPadding;
- const int kTitleLeftPadding = 0;
- const int kTitleBottomPadding = 0;
- const int kTitleRightPadding = 0;
-
- views::View* header_view = new views::View;
-
- views::GridLayout* grid_layout = new views::GridLayout(header_view);
- header_view->SetLayoutManager(grid_layout);
-
- views::ColumnSet* header_cs = grid_layout->AddColumnSet(0);
- header_cs->AddColumn(views::GridLayout::CENTER, views::GridLayout::CENTER, 0,
- views::GridLayout::USE_PREF, 0, 0); // Title.
- header_cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
- header_cs->AddColumn(views::GridLayout::TRAILING, views::GridLayout::LEADING,
- 0, views::GridLayout::USE_PREF, 0, 0); // Close Button.
-
- // Header row.
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- grid_layout->StartRow(0, 0);
-
- views::Label* title_label = new views::Label();
- title_label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- title_label->SetFont(rb.GetFont(ConstrainedWindowConstants::kTitleFontStyle));
- title_label->SetEnabledColor(ConstrainedWindow::GetTextColor());
- title_label->SetText(container_->widget_delegate()->GetWindowTitle());
- title_label->set_border(views::Border::CreateEmptyBorder(kTitleTopPadding,
- kTitleLeftPadding, kTitleBottomPadding, kTitleRightPadding));
- grid_layout->AddView(title_label);
-
- views::Button* close_button = CreateCloseButton();
- grid_layout->AddView(close_button);
-
- return new HeaderViews(header_view, title_label, close_button);
-}
-
gfx::Rect ConstrainedWindowFrameSimple::GetBoundsForClientView() const {
- gfx::Rect bounds(GetContentsBounds());
- if (header_views_->header)
- bounds.Inset(0, header_views_->header->GetPreferredSize().height(), 0, 0);
- return bounds;
+ return GetContentsBounds();
}
gfx::Rect ConstrainedWindowFrameSimple::GetWindowBoundsForClientBounds(
const gfx::Rect& client_bounds) const {
gfx::Rect bounds(client_bounds);
bounds.Inset(-GetInsets());
- if (header_views_->header)
- bounds.Inset(0, -header_views_->header->GetPreferredSize().height(), 0, 0);
+ bounds.set_width(std::max(
+ bounds.width(),
+ ConstrainedWindowConstants::kHorizontalPadding +
+ 2 * ConstrainedWindowConstants::kCloseButtonPadding +
+ title_label_->GetPreferredSize().width() +
+ close_button_->GetPreferredSize().width()));
return bounds;
}
@@ -205,32 +151,16 @@ void ConstrainedWindowFrameSimple::UpdateWindowIcon() {
}
void ConstrainedWindowFrameSimple::UpdateWindowTitle() {
- if (!header_views_->title_label)
- return;
-
- string16 text = container_->widget_delegate()->GetWindowTitle();
- header_views_->title_label->SetText(text);
+ title_label_->SetText(container_->widget_delegate()->GetWindowTitle());
}
gfx::Size ConstrainedWindowFrameSimple::GetPreferredSize() {
- return container_->non_client_view()->GetWindowBoundsForClientBounds(
+ return GetWindowBoundsForClientBounds(
gfx::Rect(container_->client_view()->GetPreferredSize())).size();
}
void ConstrainedWindowFrameSimple::ButtonPressed(views::Button* sender,
const ui::Event& event) {
- if (header_views_->close_button && sender == header_views_->close_button)
+ if (sender == close_button_)
sender->GetWidget()->Close();
}
-
-views::ImageButton* ConstrainedWindowFrameSimple::CreateCloseButton() {
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- views::ImageButton* close_button = new views::ImageButton(this);
- close_button->SetImage(views::CustomButton::BS_NORMAL,
- rb.GetImageSkiaNamed(IDR_SHARED_IMAGES_X));
- close_button->SetImage(views::CustomButton::BS_HOT,
- rb.GetImageSkiaNamed(IDR_SHARED_IMAGES_X_HOVER));
- close_button->SetImage(views::CustomButton::BS_PUSHED,
- rb.GetImageSkiaNamed(IDR_SHARED_IMAGES_X_PRESSED));
- return close_button;
-}
diff --git a/chrome/browser/ui/views/constrained_window_frame_simple.h b/chrome/browser/ui/views/constrained_window_frame_simple.h
index 3a141a5..552408c 100644
--- a/chrome/browser/ui/views/constrained_window_frame_simple.h
+++ b/chrome/browser/ui/views/constrained_window_frame_simple.h
@@ -6,15 +6,13 @@
#define CHROME_BROWSER_UI_VIEWS_CONSTRAINED_WINDOW_FRAME_SIMPLE_H_
#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/ui/views/constrained_window_views.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/window/non_client_view.h"
-class ConstrainedWindowViews;
-
namespace views {
class ImageButton;
class Label;
-class LayoutManager;
}
////////////////////////////////////////////////////////////////////////////////
@@ -24,24 +22,11 @@ class LayoutManager;
class ConstrainedWindowFrameSimple : public views::NonClientFrameView,
public views::ButtonListener {
public:
- // Contains references to relevant views in the header. The header
- // must be non-NULL.
- struct HeaderViews {
- HeaderViews(views::View* header,
- views::Label* title_label,
- views::Button* close_button);
-
- views::View* header;
- views::Label* title_label;
- views::Button* close_button;
- };
-
- explicit ConstrainedWindowFrameSimple(ConstrainedWindowViews* container);
+ explicit ConstrainedWindowFrameSimple(
+ ConstrainedWindowViews* container,
+ ConstrainedWindowViews::ChromeStyleClientInsets client_insets);
virtual ~ConstrainedWindowFrameSimple();
- // SetHeaderView assumes ownership of the passed parameter.
- void SetHeaderView(HeaderViews* header_views);
-
private:
// Overridden from views::NonClientFrameView:
virtual gfx::Rect GetBoundsForClientView() const OVERRIDE;
@@ -61,15 +46,9 @@ class ConstrainedWindowFrameSimple : public views::NonClientFrameView,
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE;
- HeaderViews* CreateDefaultHeaderView();
-
- views::ImageButton* CreateCloseButton();
-
ConstrainedWindowViews* container_;
-
- views::LayoutManager* layout_;
-
- scoped_ptr<HeaderViews> header_views_;
+ views::Label* title_label_;
+ views::ImageButton* close_button_;
DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowFrameSimple);
};
diff --git a/chrome/browser/ui/views/constrained_window_views.cc b/chrome/browser/ui/views/constrained_window_views.cc
index 6e0058a..63d2656 100644
--- a/chrome/browser/ui/views/constrained_window_views.cc
+++ b/chrome/browser/ui/views/constrained_window_views.cc
@@ -20,6 +20,10 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_source.h"
+#include "content/public/browser/notification_types.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "grit/chromium_strings.h"
@@ -163,9 +167,6 @@ class VistaWindowResources : public views::WindowResources {
gfx::ImageSkia* XPWindowResources::images_[];
gfx::ImageSkia* VistaWindowResources::images_[];
-////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowFrameView
-
class ConstrainedWindowFrameView : public views::NonClientFrameView,
public views::ButtonListener {
public:
@@ -285,9 +286,6 @@ const SkColor kContentsBorderShadow = SkColorSetARGB(51, 0, 0, 0);
} // namespace
-////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowFrameView, public:
-
ConstrainedWindowFrameView::ConstrainedWindowFrameView(
ConstrainedWindowViews* container)
: NonClientFrameView(),
@@ -320,9 +318,6 @@ void ConstrainedWindowFrameView::UpdateWindowTitle() {
SchedulePaintInRect(title_bounds_);
}
-////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowFrameView, views::NonClientFrameView implementation:
-
gfx::Rect ConstrainedWindowFrameView::GetBoundsForClientView() const {
return client_view_bounds_;
}
@@ -371,9 +366,6 @@ void ConstrainedWindowFrameView::GetWindowMask(const gfx::Size& size,
views::GetDefaultWindowMask(size, window_mask);
}
-////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowFrameView, views::View implementation:
-
void ConstrainedWindowFrameView::OnPaint(gfx::Canvas* canvas) {
PaintFrameBorder(canvas);
PaintTitleBar(canvas);
@@ -390,18 +382,12 @@ void ConstrainedWindowFrameView::OnThemeChanged() {
InitWindowResources();
}
-////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowFrameView, views::ButtonListener implementation:
-
void ConstrainedWindowFrameView::ButtonPressed(
views::Button* sender, const ui::Event& event) {
if (sender == close_button_)
container_->CloseConstrainedWindow();
}
-////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowFrameView, private:
-
int ConstrainedWindowFrameView::NonClientBorderThickness() const {
return kFrameBorderThickness + kClientEdgeThickness;
}
@@ -574,18 +560,17 @@ class ConstrainedWindowFrameViewAsh : public ash::CustomFrameViewAsh {
};
#endif // defined(USE_ASH)
-////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowViews, public:
-
ConstrainedWindowViews::ConstrainedWindowViews(
content::WebContents* web_contents,
views::WidgetDelegate* widget_delegate,
- bool enable_chrome_style)
+ bool enable_chrome_style,
+ ChromeStyleClientInsets chrome_style_client_insets)
: WebContentsObserver(web_contents),
web_contents_(web_contents),
+ enable_chrome_style_(enable_chrome_style),
+ chrome_style_client_insets_(chrome_style_client_insets),
ALLOW_THIS_IN_INITIALIZER_LIST(native_constrained_window_(
- NativeConstrainedWindow::CreateNativeConstrainedWindow(this))),
- enable_chrome_style_(enable_chrome_style) {
+ NativeConstrainedWindow::CreateNativeConstrainedWindow(this))) {
views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
params.delegate = widget_delegate;
params.native_widget = native_constrained_window_->AsNativeWidget();
@@ -594,9 +579,9 @@ ConstrainedWindowViews::ConstrainedWindowViews(
if (enable_chrome_style_) {
params.parent_widget = Widget::GetTopLevelWidgetForNativeView(
- web_contents->GetView()->GetNativeView());
+ web_contents_->GetView()->GetNativeView());
} else {
- params.parent = web_contents->GetNativeView();
+ params.parent = web_contents_->GetNativeView();
}
#if defined(USE_ASH)
@@ -622,7 +607,10 @@ ConstrainedWindowViews::ConstrainedWindowViews(
if (dialog_client_view)
dialog_client_view->set_background(background);
}
- PositionChromeStyleWindow();
+ PositionChromeStyleWindow(GetRootView()->bounds().size());
+ registrar_.Add(this,
+ content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED,
+ content::Source<content::WebContents>(web_contents));
}
ConstrainedWindowTabHelper* constrained_window_tab_helper =
@@ -636,9 +624,6 @@ ConstrainedWindowViews::ConstrainedWindowViews(
ConstrainedWindowViews::~ConstrainedWindowViews() {
}
-////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowViews, ConstrainedWindow implementation:
-
void ConstrainedWindowViews::ShowConstrainedWindow() {
Show();
FocusConstrainedWindow();
@@ -684,34 +669,27 @@ void ConstrainedWindowViews::NotifyTabHelperWillClose() {
constrained_window_tab_helper->WillClose(this);
}
-////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowViews, views::Widget overrides:
-
void ConstrainedWindowViews::CenterWindow(const gfx::Size& size) {
- Widget::CenterWindow(size);
if (enable_chrome_style_)
- PositionChromeStyleWindow();
+ PositionChromeStyleWindow(size);
+ else
+ Widget::CenterWindow(size);
}
views::NonClientFrameView* ConstrainedWindowViews::CreateNonClientFrameView() {
- if (enable_chrome_style_) {
- return new ConstrainedWindowFrameSimple(this);
- } else {
+ if (enable_chrome_style_)
+ return new ConstrainedWindowFrameSimple(this, chrome_style_client_insets_);
#if defined(USE_ASH)
- CommandLine* command_line = CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(ash::switches::kAuraGoogleDialogFrames))
- return ash::Shell::GetInstance()->CreateDefaultNonClientFrameView(this);
- ConstrainedWindowFrameViewAsh* frame = new ConstrainedWindowFrameViewAsh;
- frame->Init(this);
- return frame;
+ CommandLine* command_line = CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(ash::switches::kAuraGoogleDialogFrames))
+ return ash::Shell::GetInstance()->CreateDefaultNonClientFrameView(this);
+ ConstrainedWindowFrameViewAsh* frame = new ConstrainedWindowFrameViewAsh;
+ frame->Init(this);
+ return frame;
#endif
- return new ConstrainedWindowFrameView(this);
- }
+ return new ConstrainedWindowFrameView(this);
}
-////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowViews, NativeConstrainedWindowDelegate implementation:
-
void ConstrainedWindowViews::OnNativeConstrainedWindowDestroyed() {
NotifyTabHelperWillClose();
}
@@ -730,27 +708,35 @@ int ConstrainedWindowViews::GetNonClientComponent(const gfx::Point& point) {
return HTNOWHERE;
}
-void ConstrainedWindowViews::PositionChromeStyleWindow() {
+void ConstrainedWindowViews::WebContentsDestroyed(
+ content::WebContents* web_contents) {
+ web_contents_ = NULL;
+}
+
+void ConstrainedWindowViews::Observe(
+ int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ DCHECK(enable_chrome_style_);
+ DCHECK_EQ(type, content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED);
+ if (*content::Details<bool>(details).ptr())
+ Show();
+ else
+ Hide();
+}
+
+void ConstrainedWindowViews::PositionChromeStyleWindow(const gfx::Size& size) {
DCHECK(enable_chrome_style_);
- gfx::Rect bounds = GetRootView()->bounds();
+ gfx::Rect bounds(GetRootView()->bounds().origin(), size);
ConstrainedWindowTabHelperDelegate* tab_helper_delegate =
ConstrainedWindowTabHelper::FromWebContents(web_contents_)->delegate();
-
BrowserWindow* browser_window =
tab_helper_delegate ? tab_helper_delegate->GetBrowserWindow() : NULL;
- int top_y;
- if (browser_window && browser_window->GetConstrainedWindowTopY(&top_y)) {
- bounds.set_y(top_y);
- bounds.set_x(
- browser_window->GetBounds().width() / 2 - bounds.width() / 2);
- SetBounds(bounds);
+ if (browser_window) {
+ bounds.set_x(browser_window->GetBounds().width() / 2 - bounds.width() / 2);
+ int top_y;
+ if (browser_window->GetConstrainedWindowTopY(&top_y))
+ bounds.set_y(top_y);
}
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ConstrainedWindowViews, content::WebContentsObserver implementation:
-
-void ConstrainedWindowViews::WebContentsDestroyed(
- content::WebContents* web_contents) {
- web_contents_ = NULL;
+ SetBounds(bounds);
}
diff --git a/chrome/browser/ui/views/constrained_window_views.h b/chrome/browser/ui/views/constrained_window_views.h
index 97d5b604..2e20a54 100644
--- a/chrome/browser/ui/views/constrained_window_views.h
+++ b/chrome/browser/ui/views/constrained_window_views.h
@@ -7,6 +7,8 @@
#include "base/compiler_specific.h"
#include "chrome/browser/ui/constrained_window.h"
+#include "content/public/browser/notification_observer.h"
+#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/rect.h"
@@ -59,11 +61,19 @@ class NativeConstrainedWindow {
class ConstrainedWindowViews : public views::Widget,
public ConstrainedWindow,
public NativeConstrainedWindowDelegate,
- public content::WebContentsObserver {
+ public content::WebContentsObserver,
+ public content::NotificationObserver {
public:
+ // Types of insets to use with chrome style frame.
+ enum ChromeStyleClientInsets {
+ DEFAULT_INSETS,
+ NO_INSETS,
+ };
+
ConstrainedWindowViews(content::WebContents* web_contents,
views::WidgetDelegate* widget_delegate,
- bool enable_chrome_style);
+ bool enable_chrome_style,
+ ChromeStyleClientInsets chrome_style_client_insets);
virtual ~ConstrainedWindowViews();
// Returns the WebContents that constrains this Constrained Window.
@@ -78,6 +88,9 @@ class ConstrainedWindowViews : public views::Widget,
// Overridden from views::Widget:
void CenterWindow(const gfx::Size& size);
+ // Default insets for the dialog:
+ static gfx::Insets GetDefaultInsets();
+
private:
void NotifyTabHelperWillClose();
@@ -91,21 +104,30 @@ class ConstrainedWindowViews : public views::Widget,
AsNativeWidgetDelegate() OVERRIDE;
virtual int GetNonClientComponent(const gfx::Point& point) OVERRIDE;
- // Set the top of the window to overlap the browser chrome.
- void PositionChromeStyleWindow();
-
// Overridden from content::WebContentsObserver:
virtual void WebContentsDestroyed(content::WebContents* web_contents)
OVERRIDE;
- content::WebContents* web_contents_;
+ // Overridden from content::NotificationObserver:
+ virtual void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) OVERRIDE;
- NativeConstrainedWindow* native_constrained_window_;
+ // Set the top of the window to overlap the browser chrome.
+ void PositionChromeStyleWindow(const gfx::Size& size);
+
+ content::NotificationRegistrar registrar_;
+ content::WebContents* web_contents_;
// TODO(wittman): remove once all constrained window dialogs are moved
// over to Chrome style.
const bool enable_chrome_style_;
+ // Client insets to use when |enable_chrome_style_| is true.
+ ChromeStyleClientInsets chrome_style_client_insets_;
+
+ NativeConstrainedWindow* native_constrained_window_;
+
DISALLOW_COPY_AND_ASSIGN(ConstrainedWindowViews);
};
diff --git a/chrome/browser/ui/views/constrained_window_views_browsertest.cc b/chrome/browser/ui/views/constrained_window_views_browsertest.cc
index 82c0002..c98a4a3 100644
--- a/chrome/browser/ui/views/constrained_window_views_browsertest.cc
+++ b/chrome/browser/ui/views/constrained_window_views_browsertest.cc
@@ -114,8 +114,9 @@ IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest, FocusTest) {
// Create a constrained dialog. It will attach itself to tab_contents.
scoped_ptr<TestConstrainedDialog> test_dialog1(new TestConstrainedDialog);
- ConstrainedWindowViews* window1 =
- new ConstrainedWindowViews(web_contents, test_dialog1.get(), false);
+ ConstrainedWindowViews* window1 = new ConstrainedWindowViews(
+ web_contents, test_dialog1.get(), false,
+ ConstrainedWindowViews::DEFAULT_INSETS);
views::FocusManager* focus_manager = window1->GetFocusManager();
ASSERT_TRUE(focus_manager);
@@ -128,8 +129,9 @@ IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest, FocusTest) {
// tab_contents, but will remain hidden since the test_dialog1 is still
// showing.
scoped_ptr<TestConstrainedDialog> test_dialog2(new TestConstrainedDialog);
- ConstrainedWindowViews* window2 =
- new ConstrainedWindowViews(web_contents, test_dialog2.get(), false);
+ ConstrainedWindowViews* window2 = new ConstrainedWindowViews(
+ web_contents, test_dialog2.get(), false,
+ ConstrainedWindowViews::DEFAULT_INSETS);
// Should be the same focus_manager.
ASSERT_EQ(focus_manager, window2->GetFocusManager());
@@ -186,8 +188,9 @@ IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest, TabCloseTest) {
// Create a constrained dialog. It will attach itself to tab_contents.
scoped_ptr<TestConstrainedDialog> test_dialog(new TestConstrainedDialog);
- ConstrainedWindowViews* window =
- new ConstrainedWindowViews(web_contents, test_dialog.get(), true);
+ ConstrainedWindowViews* window = new ConstrainedWindowViews(
+ web_contents, test_dialog.get(), true,
+ ConstrainedWindowViews::DEFAULT_INSETS);
bool closed =
browser()->tab_strip_model()->CloseTabContentsAt(
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
index 7c8850c..30149c3 100644
--- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
+++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
@@ -56,7 +56,8 @@ MediaGalleriesDialogViews::MediaGalleriesDialogViews(
// Ownership of |contents_| is handed off by this call. |window_| will take
// care of deleting itself after calling DeleteDelegate().
window_ = new ConstrainedWindowViews(
- controller->tab_contents()->web_contents(), this, false);
+ controller->tab_contents()->web_contents(), this, false,
+ ConstrainedWindowViews::DEFAULT_INSETS);
}
MediaGalleriesDialogViews::~MediaGalleriesDialogViews() {}
diff --git a/chrome/browser/ui/views/login_prompt_views.cc b/chrome/browser/ui/views/login_prompt_views.cc
index babc4ec..345b993 100644
--- a/chrome/browser/ui/views/login_prompt_views.cc
+++ b/chrome/browser/ui/views/login_prompt_views.cc
@@ -127,7 +127,9 @@ class LoginHandlerViews : public LoginHandler,
// will occur via an InvokeLater on the UI thread, which is guaranteed
// to happen after this is called (since this was InvokeLater'd first).
WebContents* requesting_contents = GetWebContentsForLogin();
- SetDialog(new ConstrainedWindowViews(requesting_contents, this, false));
+ SetDialog(new ConstrainedWindowViews(
+ requesting_contents, this, false,
+ ConstrainedWindowViews::DEFAULT_INSETS));
NotifyAuthNeeded();
}
diff --git a/chrome/browser/ui/views/ssl_client_certificate_selector.cc b/chrome/browser/ui/views/ssl_client_certificate_selector.cc
index 74be4fe..1e5ed1d 100644
--- a/chrome/browser/ui/views/ssl_client_certificate_selector.cc
+++ b/chrome/browser/ui/views/ssl_client_certificate_selector.cc
@@ -140,9 +140,9 @@ void SSLClientCertificateSelector::Init() {
StartObserving();
- window_ = new ConstrainedWindowViews(tab_contents_->web_contents(),
- this,
- false);
+ window_ = new ConstrainedWindowViews(
+ tab_contents_->web_contents(), this, false,
+ ConstrainedWindowViews::DEFAULT_INSETS);
// Select the first row automatically. This must be done after the dialog has
// been created.
diff --git a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
index 95e094a..eda8164 100644
--- a/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
+++ b/chrome/browser/ui/views/tab_modal_confirm_dialog_views.cc
@@ -68,9 +68,9 @@ TabModalConfirmDialogViews::TabModalConfirmDialogViews(
message_box_view_(new views::MessageBoxView(
CreateMessageBoxViewInitParams(delegate->GetMessage(),
enable_chrome_style))) {
- delegate_->set_window(new ConstrainedWindowViews(tab_contents->web_contents(),
- this,
- enable_chrome_style));
+ delegate_->set_window(new ConstrainedWindowViews(
+ tab_contents->web_contents(), this, enable_chrome_style,
+ ConstrainedWindowViews::DEFAULT_INSETS));
}
TabModalConfirmDialogViews::~TabModalConfirmDialogViews() {
diff --git a/chrome/browser/ui/views/web_intent_picker_views.cc b/chrome/browser/ui/views/web_intent_picker_views.cc
index e208843..9341aad 100644
--- a/chrome/browser/ui/views/web_intent_picker_views.cc
+++ b/chrome/browser/ui/views/web_intent_picker_views.cc
@@ -7,10 +7,13 @@
#include "base/memory/scoped_vector.h"
#include "base/time.h"
+#include "base/timer.h"
#include "base/utf_string_conversions.h"
+#include "chrome/browser/download/download_util.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/constrained_window_constants.h"
#include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h"
#include "chrome/browser/ui/intents/web_intent_picker.h"
#include "chrome/browser/ui/intents/web_intent_picker_delegate.h"
@@ -46,6 +49,7 @@
#include "ui/views/controls/label.h"
#include "ui/views/controls/link.h"
#include "ui/views/controls/link_listener.h"
+#include "ui/views/controls/separator.h"
#include "ui/views/controls/throbber.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/layout/box_layout.h"
@@ -65,6 +69,12 @@ namespace {
// The color used to dim disabled elements.
const SkColor kHalfOpacityWhite = SkColorSetARGB(128, 255, 255, 255);
+// The color used to display an enabled label.
+const SkColor kEnabledLabelColor = SkColorSetRGB(51, 51, 51);
+
+// The color used to display an enabled link.
+const SkColor kEnabledLinkColor = SkColorSetRGB(17, 85, 204);
+
// The color used to display a disabled link.
const SkColor kDisabledLinkColor = SkColorSetRGB(128, 128, 128);
@@ -80,6 +90,9 @@ const int kMinRowCount = 4;
// Maximum number of action buttons - do not add suggestions to reach.
const int kMaxRowCount = 8;
+// The vertical padding around the UI elements in the waiting view.
+const int kWaitingViewVerticalPadding = 40;
+
// Enables or disables all child views of |view|.
void EnableChildViews(views::View* view, bool enabled) {
for (int i = 0; i < view->child_count(); ++i) {
@@ -100,7 +113,80 @@ views::ImageButton* CreateCloseButton(views::ButtonListener* listener) {
rb.GetImageSkiaNamed(IDR_SHARED_IMAGES_X_HOVER));
return close_button;
}
-// SarsView -------------------------------------------------------------------
+
+// Creates a label.
+views::Label* CreateLabel() {
+ views::Label* label = new views::Label();
+ label->SetEnabledColor(kEnabledLabelColor);
+ label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ return label;
+}
+
+// Creates a title-style label.
+views::Label* CreateTitleLabel() {
+ views::Label* label = CreateLabel();
+ label->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
+ ui::ResourceBundle::MediumFont));
+ const int kLabelBuiltinTopPadding = 5;
+ label->set_border(views::Border::CreateEmptyBorder(
+ WebIntentPicker::kContentAreaBorder -
+ ConstrainedWindowConstants::kCloseButtonPadding -
+ kLabelBuiltinTopPadding,
+ 0, 0, 0));
+ return label;
+}
+
+// Creates a link.
+views::Link* CreateLink() {
+ views::Link* link = new views::Link();
+ link->SetEnabledColor(kEnabledLinkColor);
+ link->SetDisabledColor(kDisabledLinkColor);
+ link->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ return link;
+}
+
+// Creates a header for the inline disposition dialog.
+views::View* CreateInlineDispositionHeader(
+ views::ImageView* app_icon,
+ views::Label* app_title,
+ views::Link* use_another_service_link) {
+ views::View* header = new views::View();
+ views::GridLayout* grid_layout = new views::GridLayout(header);
+ const int kIconBuiltinTopPadding = 6;
+ grid_layout->SetInsets(
+ WebIntentPicker::kContentAreaBorder -
+ ConstrainedWindowConstants::kCloseButtonPadding -
+ kIconBuiltinTopPadding,
+ 0, 0, 0);
+ header->SetLayoutManager(grid_layout);
+ views::ColumnSet* header_cs = grid_layout->AddColumnSet(0);
+ header_cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0); // App icon.
+ header_cs->AddPaddingColumn(0, WebIntentPicker::kIconTextPadding);
+ header_cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0); // App title.
+ header_cs->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing);
+ header_cs->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0); // Use another app link.
+ grid_layout->StartRow(0, 0);
+ grid_layout->AddView(app_icon);
+ grid_layout->AddView(app_title);
+ grid_layout->AddView(use_another_service_link);
+ header->Layout();
+ return header;
+}
+
+// Checks whether the inline disposition dialog should show the link for using
+// another service.
+bool IsUseAnotherServiceVisible(WebIntentPickerModel* model) {
+ DCHECK(model);
+ return model->show_use_another_service() &&
+ (model->GetInstalledServiceCount() > 1 ||
+ model->GetSuggestedExtensionCount());
+}
+
+
+// StarsView -------------------------------------------------------------------
// A view that displays 5 stars: empty, full or half full, given a rating in
// the range [0,5].
@@ -141,6 +227,7 @@ StarsView::StarsView(double rating)
StarsView::~StarsView() {
}
+
// ThrobberNativeTextButton ----------------------------------------------------
// A native text button that can display a throbber in place of its icon. Much
@@ -268,142 +355,169 @@ void ThrobberNativeTextButton::Run() {
SchedulePaint();
}
-// WaitingView ----------------------------------------------------------
-class WaitingView : public views::View {
+
+// SpinnerProgressIndicator ----------------------------------------------------
+class SpinnerProgressIndicator : public views::View {
public:
- WaitingView(views::ButtonListener* listener, bool use_close_button);
+ SpinnerProgressIndicator();
+ virtual ~SpinnerProgressIndicator();
+
+ void SetPercentDone(int percent);
+ void SetIndeterminate(bool indetereminate);
+
+ // Overridden from views::View.
+ virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
+ virtual gfx::Size GetPreferredSize() OVERRIDE;
private:
- DISALLOW_COPY_AND_ASSIGN(WaitingView);
+ void UpdateTimer();
+ int GetProgressAngle();
+
+ static const int kTimerIntervalMs = 1000 / 30;
+ static const int kSpinRateDegreesPerSecond = 270;
+
+ int percent_done_;
+ int indeterminate_;
+
+ base::TimeTicks start_time_;
+ base::RepeatingTimer<SpinnerProgressIndicator> timer_;
+
+ DISALLOW_COPY_AND_ASSIGN(SpinnerProgressIndicator);
};
-WaitingView::WaitingView(views::ButtonListener* listener,
- bool use_close_button) {
- views::GridLayout* layout = new views::GridLayout(this);
- layout->set_minimum_size(gfx::Size(WebIntentPicker::kWindowMinWidth, 0));
- layout->SetInsets(WebIntentPicker::kContentAreaBorder,
- WebIntentPicker::kContentAreaBorder,
- WebIntentPicker::kContentAreaBorder,
- WebIntentPicker::kContentAreaBorder);
- SetLayoutManager(layout);
+SpinnerProgressIndicator::SpinnerProgressIndicator()
+ : percent_done_(0),
+ indeterminate_(true) {}
- views::ColumnSet* cs = layout->AddColumnSet(0);
- views::ColumnSet* header_cs = NULL;
- if (use_close_button) {
- header_cs = layout->AddColumnSet(1);
- header_cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
- header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0); // Close Button.
- }
- cs->AddPaddingColumn(0, views::kPanelHorizIndentation);
- cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER,
- 1, GridLayout::USE_PREF, 0, 0);
- cs->AddPaddingColumn(0, views::kPanelHorizIndentation);
+SpinnerProgressIndicator::~SpinnerProgressIndicator() {
+}
- // Create throbber.
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- const gfx::ImageSkia* frames =
- rb.GetImageNamed(IDR_SPEECH_INPUT_SPINNER).ToImageSkia();
- views::Throbber* throbber = new views::Throbber(kThrobberFrameTimeMs, true);
- throbber->SetFrames(frames);
- throbber->Start();
+void SpinnerProgressIndicator::SetPercentDone(int percent) {
+ percent_done_ = percent;
+ SchedulePaint();
+ UpdateTimer();
+}
- // Create text.
- views::Label* label = new views::Label();
- label->SetHorizontalAlignment(views::Label::ALIGN_CENTER);
- label->SetFont(rb.GetFont(ui::ResourceBundle::MediumBoldFont));
- label->SetText(l10n_util::GetStringUTF16(IDS_INTENT_PICKER_WAIT_FOR_CWS));
+void SpinnerProgressIndicator::SetIndeterminate(bool indetereminate) {
+ indeterminate_ = indetereminate;
+ SchedulePaint();
+ UpdateTimer();
+}
- // Layout the view.
- if (use_close_button) {
- layout->StartRow(0, 1);
- layout->AddView(CreateCloseButton(listener));
+void SpinnerProgressIndicator::Paint(gfx::Canvas* canvas) {
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ gfx::ImageSkia* fg = rb.GetImageSkiaNamed(IDR_WEB_INTENT_PROGRESS_FOREGROUND);
+ gfx::ImageSkia* bg = rb.GetImageSkiaNamed(IDR_WEB_INTENT_PROGRESS_BACKGROUND);
+ download_util::PaintCustomDownloadProgress(
+ canvas,
+ *bg,
+ *fg,
+ fg->width(),
+ bounds(),
+ GetProgressAngle(),
+ indeterminate_ ? -1 : percent_done_);
+}
+
+gfx::Size SpinnerProgressIndicator::GetPreferredSize() {
+ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ gfx::ImageSkia* fg = rb.GetImageSkiaNamed(IDR_WEB_INTENT_PROGRESS_FOREGROUND);
+ return fg->size();
+}
+
+void SpinnerProgressIndicator::UpdateTimer() {
+ if (!parent() || !indeterminate_) {
+ timer_.Stop();
+ return;
}
- layout->AddPaddingRow(0, views::kUnrelatedControlLargeVerticalSpacing);
- layout->StartRow(0, 0);
- layout->AddView(throbber);
- layout->AddPaddingRow(0, views::kUnrelatedControlLargeVerticalSpacing);
- layout->StartRow(0, 0);
- layout->AddView(label);
- layout->AddPaddingRow(0, views::kUnrelatedControlLargeVerticalSpacing);
+ if (!timer_.IsRunning()) {
+ start_time_ = base::TimeTicks::Now();
+ timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimerIntervalMs),
+ this, &SpinnerProgressIndicator::SchedulePaint);
+ }
}
-// SuggestedExtensionsLayout ---------------------------------------------------
+int SpinnerProgressIndicator::GetProgressAngle() {
+ if (!indeterminate_)
+ return download_util::kStartAngleDegrees;
+ base::TimeDelta delta = base::TimeTicks::Now() - start_time_;
+ int angle = delta.InSecondsF() * kSpinRateDegreesPerSecond;
+ return angle % 360;
+}
-// TODO(groby): Extremely fragile code, relies on order and number of fields.
-// Would probably be better off as GridLayout or similar. Also see review
-// comments on http://codereview.chromium.org/10909183
-// A LayoutManager used by a row of the IntentsView. It is similar
-// to a BoxLayout, but it right aligns the rightmost view (which is the install
-// button). It also uses the maximum height of all views in the row as a
-// preferred height so it doesn't change when the install button is hidden.
-class SuggestedExtensionsLayout : public views::LayoutManager {
+// WaitingView ----------------------------------------------------------
+class WaitingView : public views::View {
public:
- SuggestedExtensionsLayout();
- virtual ~SuggestedExtensionsLayout();
-
- // Implementation of views::LayoutManager.
- virtual void Layout(views::View* host) OVERRIDE;
- virtual gfx::Size GetPreferredSize(views::View* host) OVERRIDE;
+ WaitingView(views::ButtonListener* listener, bool use_close_button);
+ virtual ~WaitingView();
private:
- DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsLayout);
+ DISALLOW_COPY_AND_ASSIGN(WaitingView);
};
-SuggestedExtensionsLayout::SuggestedExtensionsLayout() {
-}
-
-SuggestedExtensionsLayout::~SuggestedExtensionsLayout() {
-}
-
-void SuggestedExtensionsLayout::Layout(views::View* host) {
- gfx::Rect child_area(host->GetLocalBounds());
- child_area.Inset(host->GetInsets());
- int x = child_area.x();
- int y = child_area.y();
-
- for (int i = 0; i < host->child_count(); ++i) {
- views::View* child = host->child_at(i);
- if (!child->visible())
- continue;
- gfx::Size size(child->GetPreferredSize());
- gfx::Rect child_bounds(x, y, size.width(), child_area.height());
- if (i == host->child_count() - 1) {
- // Last child (the install button) should be right aligned.
- child_bounds.set_x(std::max(child_area.width() - size.width(), x));
- } else if (i == 1) {
- // Label is considered fixed width, to align ratings widget.
- DCHECK_LE(size.width(), WebIntentPicker::kTitleLinkMaxWidth);
- x += WebIntentPicker::kTitleLinkMaxWidth +
- views::kRelatedControlHorizontalSpacing;
- } else {
- x += size.width() + views::kRelatedControlHorizontalSpacing;
- }
- // Clamp child view bounds to |child_area|.
- child->SetBoundsRect(child_bounds.Intersect(child_area));
- }
+WaitingView::WaitingView(views::ButtonListener* listener,
+ bool use_close_button) {
+ views::GridLayout* layout = new views::GridLayout(this);
+ layout->set_minimum_size(gfx::Size(WebIntentPicker::kWindowMinWidth, 0));
+ const int kMessageBuiltinBottomPadding = 3;
+ layout->SetInsets(ConstrainedWindowConstants::kCloseButtonPadding,
+ 0,
+ kWaitingViewVerticalPadding - kMessageBuiltinBottomPadding,
+ 0);
+ SetLayoutManager(layout);
+
+ enum GridLayoutColumnSets {
+ HEADER_ROW,
+ CONTENT_ROW,
+ };
+ views::ColumnSet* header_cs = layout->AddColumnSet(HEADER_ROW);
+ header_cs->AddPaddingColumn(1, 1);
+ header_cs->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0,
+ GridLayout::USE_PREF, 0, 0);
+ header_cs->AddPaddingColumn(
+ 0, ConstrainedWindowConstants::kCloseButtonPadding);
+
+ views::ColumnSet* content_cs = layout->AddColumnSet(CONTENT_ROW);
+ content_cs->AddPaddingColumn(0, views::kPanelHorizIndentation);
+ content_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0);
+ content_cs->AddPaddingColumn(0, views::kPanelHorizIndentation);
+
+ // Close button
+ layout->StartRow(0, HEADER_ROW);
+ views::ImageButton* close_button = CreateCloseButton(listener);
+ layout->AddView(close_button);
+ close_button->SetVisible(use_close_button);
+
+ // Throbber
+ layout->AddPaddingRow(0,
+ kWaitingViewVerticalPadding -
+ ConstrainedWindowConstants::kCloseButtonPadding -
+ close_button->GetPreferredSize().height());
+ layout->StartRow(0, CONTENT_ROW);
+ SpinnerProgressIndicator* throbber = new SpinnerProgressIndicator();
+ layout->AddView(throbber);
+
+ // Message
+ const int kMessageBuiltinTopPadding = 5;
+ layout->AddPaddingRow(0,
+ ConstrainedWindowConstants::kRowPadding -
+ kMessageBuiltinTopPadding);
+ layout->StartRow(0, CONTENT_ROW);
+ views::Label* label = CreateLabel();
+ label->SetHorizontalAlignment(views::Label::ALIGN_CENTER);
+ label->SetText(l10n_util::GetStringUTF16(IDS_INTENT_PICKER_WAIT_FOR_CWS));
+ layout->AddView(label);
+
+ // Start the throbber.
+ throbber->SetIndeterminate(true);
}
-gfx::Size SuggestedExtensionsLayout::GetPreferredSize(views::View* host) {
- int width = 0;
- int height = 0;
- for (int i = 0; i < host->child_count(); ++i) {
- views::View* child = host->child_at(i);
- gfx::Size size(child->GetPreferredSize());
- // The preferred height includes visible and invisible children. This
- // prevents jank when a child is hidden.
- height = std::max(height, size.height());
- if (!child->visible())
- continue;
- if (i != 0)
- width += views::kRelatedControlHorizontalSpacing;
- }
- gfx::Insets insets(host->GetInsets());
- return gfx::Size(width + insets.width(), height + insets.height());
+WaitingView::~WaitingView() {
}
+
// IntentRowView --------------------------------------------------
// A view for each row in the IntentsView. It displays information
@@ -545,12 +659,14 @@ IntentRowView* IntentRowView::CreateHandlerRow(
if (service != NULL) {
view = new IntentRowView(ACTION_INVOKE, tag);
icon = service->favicon.ToImageSkia();
- label = new views::Label(elided_title);
+ label = CreateLabel();
+ label->SetText(elided_title);
} else {
view = new IntentRowView(ACTION_INSTALL, tag);
view->extension_id_ = extension->id;
icon = extension->icon.ToImageSkia();
- views::Link* link = new views::Link(elided_title);
+ views::Link* link = CreateLink();
+ link->SetText(elided_title);
link->set_listener(view);
label = link;
stars = new StarsView(extension->average_rating);
@@ -558,25 +674,43 @@ IntentRowView* IntentRowView::CreateHandlerRow(
view->delegate_ = delegate;
- view->SetLayoutManager(new SuggestedExtensionsLayout);
+ views::GridLayout* grid_layout = new views::GridLayout(view);
+ view->SetLayoutManager(grid_layout);
+
+ views::ColumnSet* columns = grid_layout->AddColumnSet(0);
+ columns->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0); // Icon.
+ columns->AddPaddingColumn(0, WebIntentPicker::kIconTextPadding);
+ columns->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
+ GridLayout::FIXED, WebIntentPicker::kTitleLinkMaxWidth, 0);
+ const int kStarRatingHorizontalSpacing = 20;
+ columns->AddPaddingColumn(0, kStarRatingHorizontalSpacing);
+ if (stars != NULL) {
+ columns->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
+ GridLayout::USE_PREF, 0, 0); // Star rating.
+ columns->AddPaddingColumn(0, kStarRatingHorizontalSpacing);
+ }
+ columns->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
+ GridLayout::FIXED, preferred_width, 0); // Button.
- view->icon_ = new views::ImageView();
+ grid_layout->StartRow(0, 0);
+ view->icon_ = new views::ImageView();
view->icon_->SetImage(icon);
- view->AddChildView(view->icon_);
+ grid_layout->AddView(view->icon_);
view->title_link_ = label;
- view->AddChildView(view->title_link_);
+ grid_layout->AddView(view->title_link_);
if (stars != NULL) {
view->stars_ = stars;
- view->AddChildView(view->stars_);
+ grid_layout->AddView(view->stars_);
}
view->install_button_ = new ThrobberNativeTextButton(
view, view->GetActionButtonMessage());
view->install_button_->set_preferred_width(preferred_width);
- view->AddChildView(view->install_button_);
+ grid_layout->AddView(view->install_button_);
return view;
}
@@ -641,6 +775,7 @@ string16 IntentRowView::GetActionButtonMessage() {
return l10n_util::GetStringUTF16(message_id);
}
+
// IntentsView -----------------------------------------------------
// A view that contains both installed services and suggested extensions
@@ -702,8 +837,9 @@ void IntentsView::Update() {
button_width_ = std::max(
kButtonWidth, size_helper.GetPreferredSize().width());
- views::BoxLayout* layout = new views::BoxLayout(
- views::BoxLayout::kVertical, 0, 0, views::kRelatedControlVerticalSpacing);
+ const int kAppRowVerticalSpacing = 10;
+ views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kVertical,
+ 0, 0, kAppRowVerticalSpacing);
SetLayoutManager(layout);
int available_rows = kMaxRowCount;
@@ -755,11 +891,12 @@ void IntentsView::OnEnabledChanged() {
} // namespace
+
// WebIntentPickerViews --------------------------------------------------------
// Views implementation of WebIntentPicker.
class WebIntentPickerViews : public views::ButtonListener,
- public views::DialogDelegate,
+ public views::WidgetDelegate,
public views::LinkListener,
public WebIntentPicker,
public WebIntentPickerModelObserver,
@@ -775,14 +912,12 @@ class WebIntentPickerViews : public views::ButtonListener,
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE;
- // views::DialogDelegate implementation.
+ // views::WidgetDelegate implementation.
virtual void WindowClosing() OVERRIDE;
virtual void DeleteDelegate() OVERRIDE;
virtual views::Widget* GetWidget() OVERRIDE;
virtual const views::Widget* GetWidget() const OVERRIDE;
virtual views::View* GetContentsView() OVERRIDE;
- virtual int GetDialogButtons() const OVERRIDE;
- virtual bool Cancel() OVERRIDE;
// LinkListener implementation.
virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
@@ -817,9 +952,21 @@ class WebIntentPickerViews : public views::ButtonListener,
size_t tag) OVERRIDE;
private:
+ enum WebIntentPickerViewsState {
+ INITIAL,
+ WAITING,
+ NO_SERVICES,
+ LIST_SERVICES,
+ INLINE_SERVICE,
+ } state_;
+
// Update picker contents to reflect the current state of the model.
void UpdateContents();
+ // Shows a spinner and notifies the user that we are waiting for information
+ // from the Chrome Web Store.
+ void ShowWaitingForSuggestions();
+
// Updates the dialog with the list of available services, suggestions,
// and a nice link to CWS to find more suggestions. This is the "Main"
// view of the picker.
@@ -842,6 +989,13 @@ class WebIntentPickerViews : public views::ButtonListener,
// of the picker.
const string16 GetActionTitle();
+ // Refresh the icon for the inline disposition service that is being
+ // displayed.
+ void RefreshInlineServiceIcon();
+
+ // Refresh the extensions control in the picker.
+ void RefreshExtensions();
+
// A weak pointer to the WebIntentPickerDelegate to notify when the user
// chooses a service or cancels.
WebIntentPickerDelegate* delegate_;
@@ -853,10 +1007,6 @@ class WebIntentPickerViews : public views::ButtonListener,
// Created locally, owned by Views.
views::Label* action_label_;
- // A weak pointer to the header label for the extension suggestions.
- // Created locally, owned by Views.
- views::Label* suggestions_label_;
-
// A weak pointer to the intents view.
// Created locally, owned by Views view hierarchy.
IntentsView* extensions_;
@@ -883,6 +1033,9 @@ class WebIntentPickerViews : public views::ButtonListener,
// Created locally, owned by Views.
views::Link* more_suggestions_link_;
+ // The icon for the inline disposition service.
+ views::ImageView* inline_service_icon_;
+
// A weak pointer to the choose another service link.
// Created locally, owned by Views.
views::Link* choose_another_service_link_;
@@ -890,10 +1043,6 @@ class WebIntentPickerViews : public views::ButtonListener,
// Weak pointer to "Waiting for CWS" display. Owned by parent view.
WaitingView* waiting_view_;
- // Set to true when displaying the inline disposition web contents. Used to
- // prevent laying out the inline disposition widgets twice.
- bool displaying_web_contents_;
-
// The text for the current action.
string16 action_text_;
@@ -922,29 +1071,31 @@ WebIntentPicker* WebIntentPicker::Create(content::WebContents* web_contents,
WebIntentPickerViews::WebIntentPickerViews(TabContents* tab_contents,
WebIntentPickerDelegate* delegate,
WebIntentPickerModel* model)
- : delegate_(delegate),
+ : state_(INITIAL),
+ delegate_(delegate),
model_(model),
action_label_(NULL),
- suggestions_label_(NULL),
extensions_(NULL),
tab_contents_(tab_contents),
webview_(new views::WebView(tab_contents->profile())),
window_(NULL),
more_suggestions_link_(NULL),
+ inline_service_icon_(NULL),
choose_another_service_link_(NULL),
waiting_view_(NULL),
- displaying_web_contents_(false),
can_close_(true) {
bool enable_chrome_style = chrome::IsFramelessConstrainedDialogEnabled();
use_close_button_ = enable_chrome_style;
model_->set_observer(this);
contents_ = new views::View();
- // Show the dialog.
- window_ = new ConstrainedWindowViews(tab_contents->web_contents(),
- this,
- enable_chrome_style);
+ contents_->set_background(views::Background::CreateSolidBackground(
+ ConstrainedWindow::GetBackgroundColor()));
+ // Show the dialog.
+ window_ = new ConstrainedWindowViews(tab_contents->web_contents(), this,
+ enable_chrome_style,
+ ConstrainedWindowViews::NO_INSETS);
if (model_->IsInlineDisposition())
OnInlineDisposition(string16(), model_->inline_disposition_url());
else
@@ -980,14 +1131,6 @@ views::View* WebIntentPickerViews::GetContentsView() {
return contents_;
}
-int WebIntentPickerViews::GetDialogButtons() const {
- return ui::DIALOG_BUTTON_NONE;
-}
-
-bool WebIntentPickerViews::Cancel() {
- return can_close_;
-}
-
void WebIntentPickerViews::LinkClicked(views::Link* source, int event_flags) {
if (source == more_suggestions_link_) {
delegate_->OnSuggestionsLinkClicked(
@@ -1007,11 +1150,11 @@ void WebIntentPickerViews::Close() {
void WebIntentPickerViews::SetActionString(const string16& action) {
action_text_ = action;
-
- if (action_label_)
+ if (action_label_) {
action_label_->SetText(GetActionTitle());
contents_->Layout();
SizeToContents();
+ }
}
void WebIntentPickerViews::OnExtensionInstallSuccess(const std::string& id) {
@@ -1020,6 +1163,7 @@ void WebIntentPickerViews::OnExtensionInstallSuccess(const std::string& id) {
void WebIntentPickerViews::OnExtensionInstallFailure(const std::string& id) {
extensions_->StopThrobber();
+ extensions_->SetEnabled(true);
more_suggestions_link_->SetEnabled(true);
can_close_ = true;
contents_->Layout();
@@ -1040,139 +1184,185 @@ void WebIntentPickerViews::OnPendingAsyncCompleted() {
}
void WebIntentPickerViews::ShowNoServicesMessage() {
- ClearContents();
-
- views::GridLayout* grid_layout = new views::GridLayout(contents_);
- contents_->SetLayoutManager(grid_layout);
-
- grid_layout->SetInsets(kContentAreaBorder, kContentAreaBorder,
- kContentAreaBorder, kContentAreaBorder);
- views::ColumnSet* main_cs = grid_layout->AddColumnSet(0);
- main_cs->AddColumn(GridLayout::FILL, GridLayout::LEADING, 1,
- GridLayout::USE_PREF, 0, 0);
-
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ if (state_ == NO_SERVICES)
+ return;
+ state_ = NO_SERVICES;
- grid_layout->StartRow(0, 0);
- views::Label* header = new views::Label();
- header->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- header->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont));
- header->SetText(l10n_util::GetStringUTF16(
+ ClearContents();
+ views::GridLayout* layout = new views::GridLayout(contents_);
+ layout->set_minimum_size(gfx::Size(WebIntentPicker::kWindowMinWidth, 0));
+ const int kContentBuiltinBottomPadding = 3;
+ layout->SetInsets(ConstrainedWindowConstants::kCloseButtonPadding,
+ 0,
+ ConstrainedWindowConstants::kClientBottomPadding -
+ kContentBuiltinBottomPadding,
+ 0);
+ contents_->SetLayoutManager(layout);
+
+ enum GridLayoutColumnSets {
+ HEADER_ROW,
+ CONTENT_ROW,
+ };
+ views::ColumnSet* header_cs = layout->AddColumnSet(HEADER_ROW);
+ header_cs->AddPaddingColumn(
+ 0, ConstrainedWindowConstants::kHorizontalPadding);
+ header_cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0); // Title
+ header_cs->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0,
+ GridLayout::USE_PREF, 0, 0); // Close button
+ header_cs->AddPaddingColumn(
+ 0, ConstrainedWindowConstants::kCloseButtonPadding);
+
+ views::ColumnSet* content_cs = layout->AddColumnSet(CONTENT_ROW);
+ content_cs->AddPaddingColumn(
+ 0, ConstrainedWindowConstants::kHorizontalPadding);
+ content_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0); // Body
+ content_cs->AddPaddingColumn(
+ 0, ConstrainedWindowConstants::kHorizontalPadding);
+
+ // Header
+ layout->StartRow(0, HEADER_ROW);
+ views::Label* title = CreateTitleLabel();
+ title->SetText(l10n_util::GetStringUTF16(
IDS_INTENT_PICKER_NO_SERVICES_TITLE));
- grid_layout->AddView(header);
-
- grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
-
- grid_layout->StartRow(0, 0);
- views::Label* body = new views::Label();
+ layout->AddView(title);
+
+ views::ImageButton* close_button = CreateCloseButton(this);
+ layout->AddView(close_button);
+ close_button->SetVisible(use_close_button_);
+
+ // Content
+ const int kHeaderBuiltinBottomPadding = 4;
+ const int kContentBuiltinTopPadding = 5;
+ layout->AddPaddingRow(0,
+ ConstrainedWindowConstants::kRowPadding -
+ kHeaderBuiltinBottomPadding -
+ kContentBuiltinTopPadding);
+ layout->StartRow(0, CONTENT_ROW);
+ views::Label* body = CreateLabel();
body->SetMultiLine(true);
- body->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
body->SetText(l10n_util::GetStringUTF16(IDS_INTENT_PICKER_NO_SERVICES));
- grid_layout->AddView(body);
+ layout->AddView(body);
- int height = contents_->GetHeightForWidth(kWindowMinWidth);
- contents_->SetSize(gfx::Size(kWindowMinWidth, height));
+ int height = contents_->GetHeightForWidth(WebIntentPicker::kWindowMinWidth);
+ contents_->SetSize(gfx::Size(WebIntentPicker::kWindowMinWidth, height));
+ contents_->Layout();
}
void WebIntentPickerViews::OnInlineDispositionWebContentsLoaded(
content::WebContents* web_contents) {
- if (displaying_web_contents_)
+ if (state_ == INLINE_SERVICE)
return;
+ state_ = INLINE_SERVICE;
// Replace the picker with the inline disposition.
ClearContents();
-
views::GridLayout* grid_layout = new views::GridLayout(contents_);
+ grid_layout->set_minimum_size(gfx::Size(WebIntentPicker::kWindowMinWidth, 0));
+ grid_layout->SetInsets(ConstrainedWindowConstants::kCloseButtonPadding, 0,
+ ConstrainedWindowConstants::kClientBottomPadding, 0);
contents_->SetLayoutManager(grid_layout);
- grid_layout->SetInsets(kContentAreaBorder, kContentAreaBorder,
- kContentAreaBorder, kContentAreaBorder);
- views::ColumnSet* header_cs = grid_layout->AddColumnSet(0);
- header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0); // Icon.
- header_cs->AddPaddingColumn(0, 4);
- header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0); // Title.
- header_cs->AddPaddingColumn(0, 4);
- header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0); // Link.
- header_cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
- if (use_close_button_) {
- header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0); // Close Button.
- }
-
- views::ColumnSet* full_cs = grid_layout->AddColumnSet(1);
- full_cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 1.0,
- GridLayout::USE_PREF, 0, 0);
+ enum GridLayoutColumnSets {
+ HEADER_ROW,
+ SEPARATOR_ROW,
+ WEB_CONTENTS_ROW,
+ };
+ views::ColumnSet* header_cs = grid_layout->AddColumnSet(HEADER_ROW);
+ header_cs->AddPaddingColumn(
+ 0, ConstrainedWindowConstants::kHorizontalPadding);
+ header_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0); // Icon, title, link.
+ header_cs->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
+ header_cs->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0,
+ GridLayout::USE_PREF, 0, 0); // Close button.
+ header_cs->AddPaddingColumn(
+ 0, ConstrainedWindowConstants::kCloseButtonPadding);
+
+ views::ColumnSet* sep_cs = grid_layout->AddColumnSet(SEPARATOR_ROW);
+ sep_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0); // Separator.
+
+ views::ColumnSet* contents_cs = grid_layout->AddColumnSet(WEB_CONTENTS_ROW);
+ contents_cs->AddPaddingColumn(0, 1);
+ contents_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0); // Web contents.
+ contents_cs->AddPaddingColumn(0, 1);
+
+ // Header.
+ grid_layout->StartRow(0, HEADER_ROW);
const WebIntentPickerModel::InstalledService* service =
model_->GetInstalledServiceWithURL(model_->inline_disposition_url());
- // Header row.
- grid_layout->StartRow(0, 0);
- views::ImageView* icon = new views::ImageView();
- icon->SetImage(service->favicon.ToImageSkia());
- grid_layout->AddView(icon);
-
- string16 elided_title = ui::ElideText(
- service->title, gfx::Font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END);
- views::Label* title = new views::Label(elided_title);
- grid_layout->AddView(title);
- // Add link for "choose another service" if other suggestions are available
- // or if more than one (the current) service is installed.
- if (model_->show_use_another_service() &&
- (model_->GetInstalledServiceCount() > 1 ||
- model_->GetSuggestedExtensionCount())) {
- choose_another_service_link_ = new views::Link(
- l10n_util::GetStringUTF16(IDS_INTENT_PICKER_USE_ALTERNATE_SERVICE));
- grid_layout->AddView(choose_another_service_link_);
- choose_another_service_link_->set_listener(this);
- }
-
- if (use_close_button_)
- grid_layout->AddView(CreateCloseButton(this));
+ if (!inline_service_icon_)
+ inline_service_icon_ = new views::ImageView();
+ inline_service_icon_->SetImage(service->favicon.ToImageSkia());
+
+ views::Label* title = CreateLabel();
+ title->SetText(ui::ElideText(
+ service->title, title->font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END));
+
+ if (!choose_another_service_link_)
+ choose_another_service_link_ = CreateLink();
+ choose_another_service_link_->SetText(l10n_util::GetStringUTF16(
+ IDS_INTENT_PICKER_USE_ALTERNATE_SERVICE));
+ choose_another_service_link_->set_listener(this);
+
+ grid_layout->AddView(CreateInlineDispositionHeader(
+ inline_service_icon_, title, choose_another_service_link_));
+ choose_another_service_link_->SetVisible(IsUseAnotherServiceVisible(model_));
+
+ views::ImageButton* close_button = CreateCloseButton(this);
+ grid_layout->AddView(close_button);
+ close_button->SetVisible(use_close_button_);
+
+ // Separator.
+ const int kHeaderBuiltinBottomPadding = 4;
+ grid_layout->AddPaddingRow(0,
+ ConstrainedWindowConstants::kRowPadding -
+ kHeaderBuiltinBottomPadding);
+ grid_layout->StartRow(0, SEPARATOR_ROW);
+ grid_layout->AddView(new views::Separator());
+
+ // Inline web contents.
+ const int kSeparatorBottomPadding = 3;
+ grid_layout->AddPaddingRow(0, kSeparatorBottomPadding);
+ grid_layout->StartRow(0, WEB_CONTENTS_ROW);
+ grid_layout->AddView(webview_);
- // Inline web contents row.
- grid_layout->StartRow(0, 1);
- grid_layout->AddView(webview_, 1, 1, GridLayout::CENTER,
- GridLayout::CENTER, 0, 0);
contents_->Layout();
SizeToContents();
- displaying_web_contents_ = true;
}
void WebIntentPickerViews::OnModelChanged(WebIntentPickerModel* model) {
- if (waiting_view_ && !model->IsWaitingForSuggestions())
+ if (state_ == WAITING && !model->IsWaitingForSuggestions())
UpdateContents();
- if (suggestions_label_) {
- string16 label_text = model->GetSuggestionsLinkText();
- suggestions_label_->SetText(label_text);
- suggestions_label_->SetVisible(!label_text.empty());
+ if (choose_another_service_link_) {
+ choose_another_service_link_->SetVisible(IsUseAnotherServiceVisible(model));
+ contents_->Layout();
+ SizeToContents();
}
if (extensions_)
- extensions_->Update();
- contents_->Layout();
- SizeToContents();
+ RefreshExtensions();
}
void WebIntentPickerViews::OnFaviconChanged(WebIntentPickerModel* model,
size_t index) {
// TODO(groby): Update favicons on extensions_;
- contents_->Layout();
- SizeToContents();
+ if (inline_service_icon_)
+ RefreshInlineServiceIcon();
+ if (extensions_)
+ RefreshExtensions();
}
void WebIntentPickerViews::OnExtensionIconChanged(
WebIntentPickerModel* model,
const std::string& extension_id) {
- if (extensions_)
- extensions_->Update();
-
- contents_->Layout();
- SizeToContents();
+ OnFaviconChanged(model, -1);
}
void WebIntentPickerViews::OnInlineDisposition(
@@ -1235,13 +1425,7 @@ void WebIntentPickerViews::UpdateContents() {
return;
if (model_ && model_->IsWaitingForSuggestions()) {
- ClearContents();
- contents_->SetLayoutManager(new views::FillLayout());
- waiting_view_ = new WaitingView(this, use_close_button_);
- contents_->AddChildView(waiting_view_);
- int height = contents_->GetHeightForWidth(kWindowMinWidth);
- contents_->SetSize(gfx::Size(kWindowMinWidth, height));
- contents_->Layout();
+ ShowWaitingForSuggestions();
} else if (model_ && (model_->GetInstalledServiceCount() ||
model_->GetSuggestedExtensionCount())) {
ShowAvailableServices();
@@ -1251,99 +1435,105 @@ void WebIntentPickerViews::UpdateContents() {
SizeToContents();
}
+void WebIntentPickerViews::ShowWaitingForSuggestions() {
+ if (state_ == WAITING)
+ return;
+ state_ = WAITING;
+ ClearContents();
+ contents_->SetLayoutManager(new views::FillLayout());
+ waiting_view_ = new WaitingView(this, use_close_button_);
+ contents_->AddChildView(waiting_view_);
+ int height = contents_->GetHeightForWidth(kWindowMinWidth);
+ contents_->SetSize(gfx::Size(kWindowMinWidth, height));
+ contents_->Layout();
+}
+
const string16 WebIntentPickerViews::GetActionTitle() {
- return (!action_text_.empty()) ?
- action_text_ :
- l10n_util::GetStringUTF16(IDS_INTENT_PICKER_CHOOSE_SERVICE);
+ return action_text_.empty() ?
+ l10n_util::GetStringUTF16(IDS_INTENT_PICKER_CHOOSE_SERVICE) :
+ action_text_;
}
void WebIntentPickerViews::ShowAvailableServices() {
- enum {
- kHeaderRowColumnSet, // Column set for header layout.
- kFullWidthColumnSet, // Column set with a single full-width column.
- kIndentedFullWidthColumnSet, // Single full-width column, indented.
- };
-
ClearContents();
- displaying_web_contents_ = false;
-
+ state_ = LIST_SERVICES;
extensions_ = new IntentsView(model_, this);
+ gfx::Size min_size = gfx::Size(extensions_->AdjustWidth(kWindowMinWidth), 0);
views::GridLayout* grid_layout = new views::GridLayout(contents_);
+ grid_layout->set_minimum_size(min_size);
+ const int kIconBuiltinBottomPadding = 4;
+ grid_layout->SetInsets(ConstrainedWindowConstants::kCloseButtonPadding,
+ 0,
+ ConstrainedWindowConstants::kClientBottomPadding -
+ kIconBuiltinBottomPadding,
+ 0);
contents_->SetLayoutManager(grid_layout);
- grid_layout->set_minimum_size(
- gfx::Size(extensions_->AdjustWidth(kWindowMinWidth), 0));
- grid_layout->SetInsets(kContentAreaBorder, kContentAreaBorder,
- kContentAreaBorder, kContentAreaBorder);
- views::ColumnSet* header_cs = grid_layout->AddColumnSet(kHeaderRowColumnSet);
+ enum GridLayoutColumnSets {
+ HEADER_ROW,
+ CONTENT_ROW,
+ };
+ views::ColumnSet* header_cs = grid_layout->AddColumnSet(HEADER_ROW);
+ header_cs->AddPaddingColumn(
+ 0, ConstrainedWindowConstants::kHorizontalPadding);
header_cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0); // Title.
- if (use_close_button_) {
- header_cs->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing);
- header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0); // Close Button.
- }
-
- views::ColumnSet* full_cs = grid_layout->AddColumnSet(kFullWidthColumnSet);
- full_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0);
-
- views::ColumnSet* indent_cs =
- grid_layout->AddColumnSet(kIndentedFullWidthColumnSet);
- indent_cs->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing);
- indent_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0);
-
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
-
- // Header row.
- grid_layout->StartRow(0, kHeaderRowColumnSet);
- action_label_ = new views::Label(GetActionTitle());
- action_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- action_label_->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont));
+ GridLayout::USE_PREF, 0, 0); // Action title
+ header_cs->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0,
+ GridLayout::USE_PREF, 0, 0); // Close button
+ header_cs->AddPaddingColumn(
+ 0, ConstrainedWindowConstants::kCloseButtonPadding);
+
+ views::ColumnSet* content_cs = grid_layout->AddColumnSet(CONTENT_ROW);
+ content_cs->AddPaddingColumn(
+ 0, ConstrainedWindowConstants::kHorizontalPadding);
+ content_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0); // Content.
+ content_cs->AddPaddingColumn(
+ 0, ConstrainedWindowConstants::kHorizontalPadding);
+
+ // Header.
+ grid_layout->StartRow(0, HEADER_ROW);
+ if (!action_label_)
+ action_label_ = CreateTitleLabel();
+ action_label_->SetText(GetActionTitle());
grid_layout->AddView(action_label_);
- if (use_close_button_)
- grid_layout->AddView(CreateCloseButton(this));
-
- // Padding row.
- grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+ views::ImageButton* close_button = CreateCloseButton(this);
+ grid_layout->AddView(close_button);
+ close_button->SetVisible(use_close_button_);
- // Row with app suggestions label.
- grid_layout->StartRow(0, kIndentedFullWidthColumnSet);
- suggestions_label_ = new views::Label();
- suggestions_label_->SetVisible(false);
- suggestions_label_->SetMultiLine(true);
- suggestions_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- grid_layout->AddView(suggestions_label_);
-
- // Padding row.
- grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
-
- // Row with extension suggestions.
- grid_layout->StartRow(0, kIndentedFullWidthColumnSet);
+ // Extensions.
+ const int kHeaderBuiltinBottomPadding = 4;
+ grid_layout->AddPaddingRow(0,
+ ConstrainedWindowConstants::kRowPadding -
+ kHeaderBuiltinBottomPadding);
+ grid_layout->StartRow(0, CONTENT_ROW);
grid_layout->AddView(extensions_);
- // Padding row.
- grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
// Row with "more suggestions" link.
- grid_layout->StartRow(0, kFullWidthColumnSet);
+ const int kIconBuiltinTopPadding = 6;
+ grid_layout->AddPaddingRow(0,
+ ConstrainedWindowConstants::kRowPadding -
+ kIconBuiltinTopPadding);
+ grid_layout->StartRow(0, CONTENT_ROW);
views::View* more_view = new views::View();
- more_view->SetLayoutManager(
- new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0,
- views::kRelatedControlHorizontalSpacing));
+ more_view->SetLayoutManager(new views::BoxLayout(
+ views::BoxLayout::kHorizontal, 0, 0, kIconTextPadding));
views::ImageView* icon = new views::ImageView();
- icon->SetImage(rb.GetImageNamed(IDR_WEBSTORE_ICON_16).ToImageSkia());
+ icon->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
+ IDR_WEBSTORE_ICON_16));
more_view->AddChildView(icon);
- more_suggestions_link_ = new views::Link(
- l10n_util::GetStringUTF16(IDS_FIND_MORE_INTENT_HANDLER_MESSAGE));
- more_suggestions_link_->SetDisabledColor(kDisabledLinkColor);
+ if (!more_suggestions_link_)
+ more_suggestions_link_ = CreateLink();
+ more_suggestions_link_->SetText(
+ l10n_util::GetStringUTF16(IDS_FIND_MORE_INTENT_HANDLER_MESSAGE));
more_suggestions_link_->set_listener(this);
more_view->AddChildView(more_suggestions_link_);
grid_layout->AddView(more_view, 1, 1,
GridLayout::LEADING, GridLayout::CENTER);
+
contents_->Layout();
}
@@ -1357,8 +1547,10 @@ void WebIntentPickerViews::ResetContents() {
UpdateContents();
// Restore previous state.
- extensions_->Update();
- action_label_->SetText(action_text_);
+ if (extensions_)
+ extensions_->Update();
+ if (action_label_)
+ action_label_->SetText(action_text_);
contents_->Layout();
SizeToContents();
}
@@ -1379,8 +1571,23 @@ void WebIntentPickerViews::ClearContents() {
// would cause hard-to-explain crashes.
contents_->RemoveAllChildViews(true);
action_label_ = NULL;
- suggestions_label_ = NULL;
extensions_ = NULL;
more_suggestions_link_ = NULL;
+ inline_service_icon_ = NULL;
choose_another_service_link_ = NULL;
}
+
+void WebIntentPickerViews::RefreshInlineServiceIcon() {
+ DCHECK(inline_service_icon_);
+ const WebIntentPickerModel::InstalledService* inline_service =
+ model_->GetInstalledServiceWithURL(model_->inline_disposition_url());
+ if (inline_service)
+ inline_service_icon_->SetImage(inline_service->favicon.ToImageSkia());
+}
+
+void WebIntentPickerViews::RefreshExtensions() {
+ DCHECK(extensions_);
+ extensions_->Update();
+ contents_->Layout();
+ SizeToContents();
+}
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index 8888f98..b58629e 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -787,6 +787,7 @@
'browser/ui/content_settings/content_setting_image_model.h',
'browser/ui/constrained_window.cc',
'browser/ui/constrained_window.h',
+ 'browser/ui/constrained_window_constants.cc',
'browser/ui/constrained_window_constants.h',
'browser/ui/constrained_window_tab_helper.cc',
'browser/ui/constrained_window_tab_helper.h',