Commit ca8d144f authored by binji@chromium.org's avatar binji@chromium.org

[Web Intents] Display throbber when loading inline disposition.

BUG=112615
TEST=none
TBR=sail@chromium.org
TBR=estade@chromium.org

Review URL: http://codereview.chromium.org/9959130

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@132490 0039d316-1c4b-4281-b951-d872f2087c98
parent 98566d7a
...@@ -162,7 +162,8 @@ void WebIntentPickerCocoa::OnInlineDisposition(WebIntentPickerModel* model, ...@@ -162,7 +162,8 @@ void WebIntentPickerCocoa::OnInlineDisposition(WebIntentPickerModel* model,
content::WebContents* web_contents = content::WebContents::Create( content::WebContents* web_contents = content::WebContents::Create(
browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL); browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
inline_disposition_tab_contents_.reset(new TabContentsWrapper(web_contents)); inline_disposition_tab_contents_.reset(new TabContentsWrapper(web_contents));
inline_disposition_delegate_.reset(new WebIntentInlineDispositionDelegate); inline_disposition_delegate_.reset(
new WebIntentInlineDispositionDelegate(this));
web_contents->SetDelegate(inline_disposition_delegate_.get()); web_contents->SetDelegate(inline_disposition_delegate_.get());
// Must call this immediately after WebContents creation to avoid race // Must call this immediately after WebContents creation to avoid race
......
...@@ -192,7 +192,8 @@ void WebIntentPickerGtk::OnInlineDisposition(WebIntentPickerModel* model, ...@@ -192,7 +192,8 @@ void WebIntentPickerGtk::OnInlineDisposition(WebIntentPickerModel* model,
content::WebContents* web_contents = content::WebContents::Create( content::WebContents* web_contents = content::WebContents::Create(
browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL); browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
inline_disposition_tab_contents_.reset(new TabContentsWrapper(web_contents)); inline_disposition_tab_contents_.reset(new TabContentsWrapper(web_contents));
inline_disposition_delegate_.reset(new WebIntentInlineDispositionDelegate); inline_disposition_delegate_.reset(
new WebIntentInlineDispositionDelegate(this));
web_contents->SetDelegate(inline_disposition_delegate_.get()); web_contents->SetDelegate(inline_disposition_delegate_.get());
// Must call this immediately after WebContents creation to avoid race // Must call this immediately after WebContents creation to avoid race
......
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
#include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h" #include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h"
#include "base/logging.h" #include "base/logging.h"
#include "chrome/browser/ui/intents/web_intent_picker.h"
#include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_controller.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
WebIntentInlineDispositionDelegate::WebIntentInlineDispositionDelegate() { WebIntentInlineDispositionDelegate::WebIntentInlineDispositionDelegate(
WebIntentPicker* picker)
: picker_(picker) {
} }
WebIntentInlineDispositionDelegate::~WebIntentInlineDispositionDelegate() { WebIntentInlineDispositionDelegate::~WebIntentInlineDispositionDelegate() {
...@@ -38,3 +41,10 @@ content::WebContents* WebIntentInlineDispositionDelegate::OpenURLFromTab( ...@@ -38,3 +41,10 @@ content::WebContents* WebIntentInlineDispositionDelegate::OpenURLFromTab(
return source; return source;
} }
void WebIntentInlineDispositionDelegate::LoadingStateChanged(
content::WebContents* source) {
if (!source->IsLoading())
picker_->OnInlineDispositionWebContentsLoaded(source);
}
...@@ -9,11 +9,15 @@ ...@@ -9,11 +9,15 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_delegate.h"
class WebIntentPicker;
// This class is the policy delegate for the rendered page in the intents // This class is the policy delegate for the rendered page in the intents
// inline disposition bubble. // inline disposition bubble.
class WebIntentInlineDispositionDelegate : public content::WebContentsDelegate { class WebIntentInlineDispositionDelegate : public content::WebContentsDelegate {
public: public:
WebIntentInlineDispositionDelegate(); // |picker| is notified when the web contents loading state changes. Must not
// be NULL.
explicit WebIntentInlineDispositionDelegate(WebIntentPicker* picker);
virtual ~WebIntentInlineDispositionDelegate(); virtual ~WebIntentInlineDispositionDelegate();
// WebContentsDelegate implementation. // WebContentsDelegate implementation.
...@@ -25,6 +29,11 @@ class WebIntentInlineDispositionDelegate : public content::WebContentsDelegate { ...@@ -25,6 +29,11 @@ class WebIntentInlineDispositionDelegate : public content::WebContentsDelegate {
virtual content::WebContents* OpenURLFromTab( virtual content::WebContents* OpenURLFromTab(
content::WebContents* source, content::WebContents* source,
const content::OpenURLParams& params) OVERRIDE; const content::OpenURLParams& params) OVERRIDE;
virtual void LoadingStateChanged(content::WebContents* source) OVERRIDE;
private:
// Picker to notify when loading state changes. Weak pointer.
WebIntentPicker* picker_;
}; };
#endif // CHROME_BROWSER_UI_INTENTS_WEB_INTENT_INLINE_DISPOSITION_DELEGATE_H_ #endif // CHROME_BROWSER_UI_INTENTS_WEB_INTENT_INLINE_DISPOSITION_DELEGATE_H_
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.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/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/test/base/browser_with_test_window_test.h" #include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
...@@ -12,6 +13,12 @@ ...@@ -12,6 +13,12 @@
#include "content/public/common/url_constants.h" #include "content/public/common/url_constants.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
class WebIntentPickerMock : public WebIntentPicker {
public:
virtual void Close() OVERRIDE {}
virtual void SetActionString(const string16& action) OVERRIDE {}
};
class WebIntentInlineDispositionBrowserTest class WebIntentInlineDispositionBrowserTest
: public BrowserWithTestWindowTest { : public BrowserWithTestWindowTest {
public: public:
...@@ -21,7 +28,7 @@ class WebIntentInlineDispositionBrowserTest ...@@ -21,7 +28,7 @@ class WebIntentInlineDispositionBrowserTest
content::WebContents* contents = content::WebContents::Create( content::WebContents* contents = content::WebContents::Create(
browser()->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL); browser()->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
wrapper_.reset(new TabContentsWrapper(contents)); wrapper_.reset(new TabContentsWrapper(contents));
delegate_.reset(new WebIntentInlineDispositionDelegate); delegate_.reset(new WebIntentInlineDispositionDelegate(&mock_));
contents->SetDelegate(delegate_.get()); contents->SetDelegate(delegate_.get());
} }
...@@ -29,6 +36,7 @@ class WebIntentInlineDispositionBrowserTest ...@@ -29,6 +36,7 @@ class WebIntentInlineDispositionBrowserTest
TestingProfile profile_; TestingProfile profile_;
scoped_ptr<TabContentsWrapper> wrapper_; scoped_ptr<TabContentsWrapper> wrapper_;
scoped_ptr<WebIntentInlineDispositionDelegate> delegate_; scoped_ptr<WebIntentInlineDispositionDelegate> delegate_;
WebIntentPickerMock mock_;
}; };
// Verifies delegate's OpenURLFromTab works. This allows navigation inside // Verifies delegate's OpenURLFromTab works. This allows navigation inside
......
...@@ -49,6 +49,10 @@ class WebIntentPicker { ...@@ -49,6 +49,10 @@ class WebIntentPicker {
// activities. // activities.
virtual void OnPendingAsyncCompleted() {} virtual void OnPendingAsyncCompleted() {}
// Called when the inline disposition's web contents have been loaded.
virtual void OnInlineDispositionWebContentsLoaded(
content::WebContents* web_contents) {}
// Get the default size of the inline disposition tab container. // Get the default size of the inline disposition tab container.
static gfx::Size GetDefaultInlineDispositionSize( static gfx::Size GetDefaultInlineDispositionSize(
content::WebContents* web_contents); content::WebContents* web_contents);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include "base/time.h"
#include "base/memory/scoped_vector.h" #include "base/memory/scoped_vector.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator.h"
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
#include "grit/generated_resources.h" #include "grit/generated_resources.h"
#include "grit/google_chrome_strings.h" #include "grit/google_chrome_strings.h"
#include "grit/theme_resources.h" #include "grit/theme_resources.h"
#include "grit/ui_resources.h"
#include "grit/ui_resources_standard.h" #include "grit/ui_resources_standard.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
...@@ -76,6 +78,9 @@ const SkColor kHalfOpacityWhite = SkColorSetARGB(128, 255, 255, 255); ...@@ -76,6 +78,9 @@ const SkColor kHalfOpacityWhite = SkColorSetARGB(128, 255, 255, 255);
// The color used to display a disabled link. // The color used to display a disabled link.
const SkColor kDisabledLinkColor = SkColorSetRGB(128, 128, 128); const SkColor kDisabledLinkColor = SkColorSetRGB(128, 128, 128);
// The time between successive throbber frames in milliseconds.
const int kThrobberFrameTimeMs = 50;
// Enables or disables all child views of |view|. // Enables or disables all child views of |view|.
void EnableChildViews(views::View* view, bool enabled) { void EnableChildViews(views::View* view, bool enabled) {
for (int i = 0; i < view->child_count(); ++i) { for (int i = 0; i < view->child_count(); ++i) {
...@@ -125,6 +130,117 @@ StarsView::StarsView(double rating) ...@@ -125,6 +130,117 @@ StarsView::StarsView(double rating)
StarsView::~StarsView() { StarsView::~StarsView() {
} }
// ThrobberNativeTextButton ----------------------------------------------------
// A native text button that can display a throbber in place of its icon. Much
// of the logic of this class is copied from ui/views/controls/throbber.h.
class ThrobberNativeTextButton : public views::NativeTextButton {
public:
ThrobberNativeTextButton(views::ButtonListener* listener,
const string16& text);
virtual ~ThrobberNativeTextButton();
// Start or stop the throbber.
void StartThrobber();
void StopThrobber();
// Set the throbber bitmap to use. IDR_THROBBER is used by default.
void SetFrames(const SkBitmap* frames);
protected:
virtual const SkBitmap& GetImageToPaint() const OVERRIDE;
private:
// The timer callback to schedule painting this view.
void Run();
// Bitmap that contains the throbber frames.
const SkBitmap* frames_;
// The currently displayed frame, given to GetImageToPaint.
mutable SkBitmap this_frame_;
// How long one frame is displayed.
base::TimeDelta frame_time_;
// Used to schedule Run calls.
base::RepeatingTimer<ThrobberNativeTextButton> timer_;
// How many frames we have.
int frame_count_;
// Time when StartThrobber was called.
base::TimeTicks start_time_;
// Whether the throbber is shown an animating.
bool running_;
DISALLOW_COPY_AND_ASSIGN(ThrobberNativeTextButton);
};
ThrobberNativeTextButton::ThrobberNativeTextButton(
views::ButtonListener* listener, const string16& text)
: NativeTextButton(listener, text),
frame_time_(base::TimeDelta::FromMilliseconds(kThrobberFrameTimeMs)),
frame_count_(0),
running_(false) {
SetFrames(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
IDR_THROBBER).ToSkBitmap());
}
ThrobberNativeTextButton::~ThrobberNativeTextButton() {
StopThrobber();
}
void ThrobberNativeTextButton::StartThrobber() {
if (running_)
return;
start_time_ = base::TimeTicks::Now();
timer_.Start(FROM_HERE, frame_time_, this, &ThrobberNativeTextButton::Run);
running_ = true;
SchedulePaint();
}
void ThrobberNativeTextButton::StopThrobber() {
if (!running_)
return;
timer_.Stop();
running_ = false;
}
void ThrobberNativeTextButton::SetFrames(const SkBitmap* frames) {
frames_ = frames;
DCHECK(frames_->width() > 0 && frames_->height() > 0);
DCHECK(frames_->width() % frames_->height() == 0);
frame_count_ = frames_->width() / frames_->height();
PreferredSizeChanged();
}
const SkBitmap& ThrobberNativeTextButton::GetImageToPaint() const {
if (!running_)
return NativeTextButton::GetImageToPaint();
const base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time_;
const int current_frame =
static_cast<int>(elapsed_time / frame_time_) % frame_count_;
const int image_size = frames_->height();
const int image_offset = current_frame * image_size;
SkIRect subset_rect = SkIRect::MakeXYWH(image_offset, 0,
image_size, image_size);
frames_->extractSubset(&this_frame_, subset_rect);
return this_frame_;
}
void ThrobberNativeTextButton::Run() {
DCHECK(running_);
SchedulePaint();
}
// ServiceButtonsView ---------------------------------------------------------- // ServiceButtonsView ----------------------------------------------------------
// A view that contains all service buttons (i.e. the installed services). // A view that contains all service buttons (i.e. the installed services).
...@@ -148,6 +264,10 @@ class ServiceButtonsView : public views::View, ...@@ -148,6 +264,10 @@ class ServiceButtonsView : public views::View,
// Updates the service button view with new model data. // Updates the service button view with new model data.
void Update(); void Update();
// Start a throbber on the service button that will launch the service at
// |url|.
void StartThrobber(const GURL& url);
// views::ButtonListener implementation. // views::ButtonListener implementation.
virtual void ButtonPressed(views::Button* sender, virtual void ButtonPressed(views::Button* sender,
const views::Event& event) OVERRIDE; const views::Event& event) OVERRIDE;
...@@ -194,8 +314,8 @@ void ServiceButtonsView::Update() { ...@@ -194,8 +314,8 @@ void ServiceButtonsView::Update() {
grid_layout->StartRow(0, 0); grid_layout->StartRow(0, 0);
views::NativeTextButton* button = ThrobberNativeTextButton* button =
new views::NativeTextButton(this, service.title); new ThrobberNativeTextButton(this, service.title);
button->set_alignment(views::TextButton::ALIGN_LEFT); button->set_alignment(views::TextButton::ALIGN_LEFT);
button->SetTooltipText(UTF8ToUTF16(service.url.spec().c_str())); button->SetTooltipText(UTF8ToUTF16(service.url.spec().c_str()));
button->SetIcon(*service.favicon.ToSkBitmap()); button->SetIcon(*service.favicon.ToSkBitmap());
...@@ -208,6 +328,20 @@ void ServiceButtonsView::Update() { ...@@ -208,6 +328,20 @@ void ServiceButtonsView::Update() {
grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
} }
void ServiceButtonsView::StartThrobber(const GURL& url) {
for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) {
const WebIntentPickerModel::InstalledService& service =
model_->GetInstalledServiceAt(i);
if (service.url != url)
continue;
ThrobberNativeTextButton* button =
static_cast<ThrobberNativeTextButton*>(child_at(i));
button->StartThrobber();
return;
}
}
void ServiceButtonsView::ButtonPressed(views::Button* sender, void ServiceButtonsView::ButtonPressed(views::Button* sender,
const views::Event& event) { const views::Event& event) {
size_t index = static_cast<size_t>(sender->tag()); size_t index = static_cast<size_t>(sender->tag());
...@@ -351,14 +485,11 @@ class SuggestedExtensionsRowView : public views::View, ...@@ -351,14 +485,11 @@ class SuggestedExtensionsRowView : public views::View,
// this extension. // this extension.
views::Link* title_link_; views::Link* title_link_;
// A throbber to display when the extension is being installed.
views::Throbber* throbber_;
// The star rating of this extension. // The star rating of this extension.
StarsView* stars_; StarsView* stars_;
// A button to install the extension. // A button to install the extension.
views::NativeTextButton* install_button_; ThrobberNativeTextButton* install_button_;
DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsRowView); DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsRowView);
}; };
...@@ -380,14 +511,10 @@ SuggestedExtensionsRowView::SuggestedExtensionsRowView( ...@@ -380,14 +511,10 @@ SuggestedExtensionsRowView::SuggestedExtensionsRowView(
title_link_->set_listener(this); title_link_->set_listener(this);
AddChildView(title_link_); AddChildView(title_link_);
throbber_ = new views::Throbber(60, true);
throbber_->SetVisible(false);
AddChildView(throbber_);
stars_ = new StarsView(extension_->average_rating); stars_ = new StarsView(extension_->average_rating);
AddChildView(stars_); AddChildView(stars_);
install_button_= new views::NativeTextButton( install_button_= new ThrobberNativeTextButton(
this, l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION)); this, l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION));
AddChildView(install_button_); AddChildView(install_button_);
} }
...@@ -406,25 +533,20 @@ void SuggestedExtensionsRowView::LinkClicked(views::Link* source, ...@@ -406,25 +533,20 @@ void SuggestedExtensionsRowView::LinkClicked(views::Link* source,
} }
void SuggestedExtensionsRowView::StartThrobber() { void SuggestedExtensionsRowView::StartThrobber() {
stars_->SetVisible(false); install_button_->StartThrobber();
install_button_->SetVisible(false); install_button_->SetText(string16());
throbber_->SetVisible(true);
throbber_->Start();
Layout();
} }
void SuggestedExtensionsRowView::StopThrobber() { void SuggestedExtensionsRowView::StopThrobber() {
stars_->SetVisible(true); install_button_->StopThrobber();
install_button_->SetVisible(true); install_button_->SetText(
throbber_->SetVisible(false); l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION));
throbber_->Stop();
Layout();
} }
void SuggestedExtensionsRowView::OnEnabledChanged() { void SuggestedExtensionsRowView::OnEnabledChanged() {
title_link_->SetEnabled(enabled()); title_link_->SetEnabled(enabled());
stars_->SetVisible(enabled()); stars_->SetEnabled(enabled());
install_button_->SetVisible(enabled()); install_button_->SetEnabled(enabled());
View::OnEnabledChanged(); View::OnEnabledChanged();
Layout(); Layout();
} }
...@@ -439,8 +561,6 @@ void SuggestedExtensionsRowView::PaintChildren(gfx::Canvas* canvas) { ...@@ -439,8 +561,6 @@ void SuggestedExtensionsRowView::PaintChildren(gfx::Canvas* canvas) {
// A view that contains suggested extensions from the Chrome Web Store that // A view that contains suggested extensions from the Chrome Web Store that
// provide an intent service matching the action/type pair. // provide an intent service matching the action/type pair.
// This view also displays the "More suggestions" link which searches the
// Chrome Web Store for more extensions.
class SuggestedExtensionsView : public views::View { class SuggestedExtensionsView : public views::View {
public: public:
SuggestedExtensionsView(const WebIntentPickerModel* model, SuggestedExtensionsView(const WebIntentPickerModel* model,
...@@ -460,6 +580,9 @@ class SuggestedExtensionsView : public views::View { ...@@ -460,6 +580,9 @@ class SuggestedExtensionsView : public views::View {
// Hide the install throbber. This function re-enables all buttons and links. // Hide the install throbber. This function re-enables all buttons and links.
void StopThrobber(); void StopThrobber();
protected:
virtual void OnEnabledChanged() OVERRIDE;
private: private:
const WebIntentPickerModel* model_; const WebIntentPickerModel* model_;
SuggestedExtensionsRowView::Delegate* delegate_; SuggestedExtensionsRowView::Delegate* delegate_;
...@@ -518,6 +641,11 @@ void SuggestedExtensionsView::StopThrobber() { ...@@ -518,6 +641,11 @@ void SuggestedExtensionsView::StopThrobber() {
} }
} }
void SuggestedExtensionsView::OnEnabledChanged() {
EnableChildViews(this, enabled());
View::OnEnabledChanged();
}
} // namespace } // namespace
// WebIntentPickerViews -------------------------------------------------------- // WebIntentPickerViews --------------------------------------------------------
...@@ -557,6 +685,8 @@ class WebIntentPickerViews : public views::ButtonListener, ...@@ -557,6 +685,8 @@ class WebIntentPickerViews : public views::ButtonListener,
virtual void SetActionString(const string16& action) OVERRIDE; virtual void SetActionString(const string16& action) OVERRIDE;
virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE; virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
virtual void OnExtensionInstallFailure(const std::string& id) OVERRIDE; virtual void OnExtensionInstallFailure(const std::string& id) OVERRIDE;
virtual void OnInlineDispositionWebContentsLoaded(
content::WebContents* web_contents) OVERRIDE;
// WebIntentPickerModelObserver implementation. // WebIntentPickerModelObserver implementation.
virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE; virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE;
...@@ -625,6 +755,10 @@ class WebIntentPickerViews : public views::ButtonListener, ...@@ -625,6 +755,10 @@ class WebIntentPickerViews : public views::ButtonListener,
// A weak pointer to the choose another service link. // A weak pointer to the choose another service link.
views::Link* choose_another_service_link_; views::Link* choose_another_service_link_;
// Set to true when displaying the inline disposition web contents. Used to
// prevent laying out the inline disposition widgets twice.
bool displaying_web_contents_;
DISALLOW_COPY_AND_ASSIGN(WebIntentPickerViews); DISALLOW_COPY_AND_ASSIGN(WebIntentPickerViews);
}; };
...@@ -653,7 +787,8 @@ WebIntentPickerViews::WebIntentPickerViews(Browser* browser, ...@@ -653,7 +787,8 @@ WebIntentPickerViews::WebIntentPickerViews(Browser* browser,
contents_(NULL), contents_(NULL),
window_(NULL), window_(NULL),
more_suggestions_link_(NULL), more_suggestions_link_(NULL),
choose_another_service_link_(NULL) { choose_another_service_link_(NULL),
displaying_web_contents_(false) {
model_->set_observer(this); model_->set_observer(this);
InitContents(); InitContents();
...@@ -733,58 +868,10 @@ void WebIntentPickerViews::OnExtensionInstallFailure(const std::string& id) { ...@@ -733,58 +868,10 @@ void WebIntentPickerViews::OnExtensionInstallFailure(const std::string& id) {
// TODO(binji): What to display to user on failure? // TODO(binji): What to display to user on failure?
} }
void WebIntentPickerViews::OnModelChanged(WebIntentPickerModel* model) { void WebIntentPickerViews::OnInlineDispositionWebContentsLoaded(
if (model->GetInstalledServiceCount() == 0) { content::WebContents* web_contents) {
suggestions_label_->SetText(l10n_util::GetStringUTF16( if (displaying_web_contents_)
IDS_INTENT_PICKER_GET_MORE_SERVICES_NONE_INSTALLED)); return;
} else {
suggestions_label_->SetText(
l10n_util::GetStringUTF16(IDS_INTENT_PICKER_GET_MORE_SERVICES));
}
service_buttons_->Update();
extensions_->Update();
contents_->Layout();
SizeToContents();
}
void WebIntentPickerViews::OnFaviconChanged(
WebIntentPickerModel* model, size_t index) {
service_buttons_->Update();
contents_->Layout();
SizeToContents();
}
void WebIntentPickerViews::OnExtensionIconChanged(
WebIntentPickerModel* model,
const string16& extension_id) {
extensions_->Update();
contents_->Layout();
SizeToContents();
}
void WebIntentPickerViews::OnInlineDisposition(
WebIntentPickerModel* model, const GURL& url) {
WebContents* web_contents = WebContents::Create(
browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
inline_disposition_delegate_.reset(new WebIntentInlineDispositionDelegate);
web_contents->SetDelegate(inline_disposition_delegate_.get());
const WebIntentPickerModel::InstalledService* service =
model->GetInstalledServiceWithURL(url);
DCHECK(service);
// Must call this immediately after WebContents creation to avoid race
// with load.
delegate_->OnInlineDispositionWebContentsCreated(web_contents);
TabContentsContainer* tab_contents_container = new TabContentsContainer;
web_contents->GetController().LoadURL(
url,
content::Referrer(),
content::PAGE_TRANSITION_START_PAGE,
std::string());
// Replace the picker with the inline disposition. // Replace the picker with the inline disposition.
contents_->RemoveAllChildViews(true); contents_->RemoveAllChildViews(true);
...@@ -813,6 +900,9 @@ void WebIntentPickerViews::OnInlineDisposition( ...@@ -813,6 +900,9 @@ void WebIntentPickerViews::OnInlineDisposition(
full_cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, full_cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
GridLayout::USE_PREF, 0, 0); GridLayout::USE_PREF, 0, 0);
const WebIntentPickerModel::InstalledService* service =
model_->GetInstalledServiceWithURL(model_->inline_disposition_url());
// Header row. // Header row.
grid_layout->StartRow(0, 0); grid_layout->StartRow(0, 0);
views::ImageView* icon = new views::ImageView(); views::ImageView* icon = new views::ImageView();
...@@ -834,17 +924,77 @@ void WebIntentPickerViews::OnInlineDisposition( ...@@ -834,17 +924,77 @@ void WebIntentPickerViews::OnInlineDisposition(
// Inline web contents row. // Inline web contents row.
grid_layout->StartRow(0, 1); grid_layout->StartRow(0, 1);
TabContentsContainer* tab_contents_container = new TabContentsContainer;
grid_layout->AddView(tab_contents_container, 1, 1, GridLayout::CENTER, grid_layout->AddView(tab_contents_container, 1, 1, GridLayout::CENTER,
GridLayout::CENTER, kDialogMinWidth, 140); GridLayout::CENTER, kDialogMinWidth, 140);
// The contents can only be changed after the child is added to view // The contents can only be changed after the child is added to view
// hierarchy. // hierarchy.
tab_contents_container->ChangeWebContents(web_contents); tab_contents_container->ChangeWebContents(web_contents);
contents_->Layout();
SizeToContents();
displaying_web_contents_ = true;
}
void WebIntentPickerViews::OnModelChanged(WebIntentPickerModel* model) {
if (model->GetInstalledServiceCount() == 0) {
suggestions_label_->SetText(l10n_util::GetStringUTF16(
IDS_INTENT_PICKER_GET_MORE_SERVICES_NONE_INSTALLED));
} else {
suggestions_label_->SetText(
l10n_util::GetStringUTF16(IDS_INTENT_PICKER_GET_MORE_SERVICES));
}
service_buttons_->Update();
extensions_->Update();
contents_->Layout();
SizeToContents();
}
void WebIntentPickerViews::OnFaviconChanged(
WebIntentPickerModel* model, size_t index) {
service_buttons_->Update();
contents_->Layout();
SizeToContents();
}
void WebIntentPickerViews::OnExtensionIconChanged(
WebIntentPickerModel* model,
const string16& extension_id) {
extensions_->Update();
contents_->Layout(); contents_->Layout();
SizeToContents(); SizeToContents();
} }
void WebIntentPickerViews::OnInlineDisposition(
WebIntentPickerModel* model, const GURL& url) {
WebContents* web_contents = WebContents::Create(
browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
inline_disposition_delegate_.reset(
new WebIntentInlineDispositionDelegate(this));
web_contents->SetDelegate(inline_disposition_delegate_.get());
const WebIntentPickerModel::InstalledService* service =
model->GetInstalledServiceWithURL(url);
DCHECK(service);
// Must call this immediately after WebContents creation to avoid race
// with load.
delegate_->OnInlineDispositionWebContentsCreated(web_contents);
web_contents->GetController().LoadURL(
url,
content::Referrer(),
content::PAGE_TRANSITION_START_PAGE,
std::string());
// Disable all buttons and show throbber.
service_buttons_->SetEnabled(false);
service_buttons_->StartThrobber(url);
extensions_->SetEnabled(false);
more_suggestions_link_->SetEnabled(false);
contents_->Layout();
}
void WebIntentPickerViews::OnServiceButtonClicked( void WebIntentPickerViews::OnServiceButtonClicked(
const WebIntentPickerModel::InstalledService& service) { const WebIntentPickerModel::InstalledService& service) {
delegate_->OnServiceChosen(service.url, service.disposition); delegate_->OnServiceChosen(service.url, service.disposition);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment