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

Side by Side Diff: chrome/browser/ui/views/web_intent_picker_views.cc

Issue 9959130: [Web Intents] Display throbber when loading inline disposition. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/time.h"
8 #include "base/memory/scoped_vector.h" 9 #include "base/memory/scoped_vector.h"
9 #include "chrome/browser/ui/browser.h" 10 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/browser_navigator.h" 11 #include "chrome/browser/ui/browser_navigator.h"
11 #include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h" 12 #include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h"
12 #include "chrome/browser/ui/intents/web_intent_picker.h" 13 #include "chrome/browser/ui/intents/web_intent_picker.h"
13 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" 14 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h"
14 #include "chrome/browser/ui/intents/web_intent_picker_model.h" 15 #include "chrome/browser/ui/intents/web_intent_picker_model.h"
15 #include "chrome/browser/ui/intents/web_intent_picker_model_observer.h" 16 #include "chrome/browser/ui/intents/web_intent_picker_model_observer.h"
16 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 17 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
17 #include "chrome/browser/ui/views/constrained_window_views.h" 18 #include "chrome/browser/ui/views/constrained_window_views.h"
18 #include "chrome/browser/ui/views/frame/browser_view.h" 19 #include "chrome/browser/ui/views/frame/browser_view.h"
19 #include "chrome/browser/ui/views/location_bar/location_icon_view.h" 20 #include "chrome/browser/ui/views/location_bar/location_icon_view.h"
20 #include "chrome/browser/ui/views/tab_contents/tab_contents_container.h" 21 #include "chrome/browser/ui/views/tab_contents/tab_contents_container.h"
21 #include "chrome/browser/ui/views/toolbar_view.h" 22 #include "chrome/browser/ui/views/toolbar_view.h"
22 #include "chrome/browser/ui/views/window.h" 23 #include "chrome/browser/ui/views/window.h"
23 #include "chrome/common/extensions/extension_constants.h" 24 #include "chrome/common/extensions/extension_constants.h"
24 #include "content/public/browser/web_contents.h" 25 #include "content/public/browser/web_contents.h"
25 #include "content/public/browser/web_contents_view.h" 26 #include "content/public/browser/web_contents_view.h"
26 #include "grit/chromium_strings.h" 27 #include "grit/chromium_strings.h"
27 #include "grit/generated_resources.h" 28 #include "grit/generated_resources.h"
28 #include "grit/google_chrome_strings.h" 29 #include "grit/google_chrome_strings.h"
29 #include "grit/theme_resources.h" 30 #include "grit/theme_resources.h"
31 #include "grit/ui_resources.h"
30 #include "grit/ui_resources_standard.h" 32 #include "grit/ui_resources_standard.h"
31 #include "third_party/skia/include/core/SkColor.h" 33 #include "third_party/skia/include/core/SkColor.h"
32 #include "ui/base/l10n/l10n_util.h" 34 #include "ui/base/l10n/l10n_util.h"
33 #include "ui/base/resource/resource_bundle.h" 35 #include "ui/base/resource/resource_bundle.h"
34 #include "ui/base/text/text_elider.h" 36 #include "ui/base/text/text_elider.h"
35 #include "ui/gfx/canvas.h" 37 #include "ui/gfx/canvas.h"
36 #include "ui/gfx/image/image.h" 38 #include "ui/gfx/image/image.h"
37 #include "ui/views/border.h" 39 #include "ui/views/border.h"
38 #include "ui/views/controls/button/image_button.h" 40 #include "ui/views/controls/button/image_button.h"
39 #include "ui/views/controls/button/text_button.h" 41 #include "ui/views/controls/button/text_button.h"
(...skipping 29 matching lines...) Expand all
69 71
70 // The maximum width in pixels of a suggested extension's title link. 72 // The maximum width in pixels of a suggested extension's title link.
71 const int kTitleLinkMaxWidth = 130; 73 const int kTitleLinkMaxWidth = 130;
72 74
73 // The color used to dim disabled elements. 75 // The color used to dim disabled elements.
74 const SkColor kHalfOpacityWhite = SkColorSetARGB(128, 255, 255, 255); 76 const SkColor kHalfOpacityWhite = SkColorSetARGB(128, 255, 255, 255);
75 77
76 // The color used to display a disabled link. 78 // The color used to display a disabled link.
77 const SkColor kDisabledLinkColor = SkColorSetRGB(128, 128, 128); 79 const SkColor kDisabledLinkColor = SkColorSetRGB(128, 128, 128);
78 80
81 // The time between successive throbber frames in milliseconds.
82 const int kThrobberFrameTimeMs = 60;
83
79 // Enables or disables all child views of |view|. 84 // Enables or disables all child views of |view|.
80 void EnableChildViews(views::View* view, bool enabled) { 85 void EnableChildViews(views::View* view, bool enabled) {
81 for (int i = 0; i < view->child_count(); ++i) { 86 for (int i = 0; i < view->child_count(); ++i) {
82 views::View* child = view->child_at(i); 87 views::View* child = view->child_at(i);
83 child->SetEnabled(enabled); 88 child->SetEnabled(enabled);
84 } 89 }
85 } 90 }
86 91
87 // StarsView ------------------------------------------------------------------- 92 // StarsView -------------------------------------------------------------------
88 93
(...skipping 29 matching lines...) Expand all
118 // TODO(binji): Add tooltip with text rating 123 // TODO(binji): Add tooltip with text rating
119 // "Average Rating: X.XX stars (YYYYY)" 124 // "Average Rating: X.XX stars (YYYYY)"
120 // Y = "1: Hated it, 2: Disliked it, 3: It was okay, 4: Liked it, 125 // Y = "1: Hated it, 2: Disliked it, 3: It was okay, 4: Liked it,
121 // 5: Loved it" 126 // 5: Loved it"
122 // Choose Y based on rounded X. 127 // Choose Y based on rounded X.
123 } 128 }
124 129
125 StarsView::~StarsView() { 130 StarsView::~StarsView() {
126 } 131 }
127 132
133 // ThrobberNativeTextButton ----------------------------------------------------
134
135 // A native text button that can display a throbber in place of its icon. Much
136 // of the logic of this class is copied from ui/views/controls/throbber.h.
137 class ThrobberNativeTextButton : public views::NativeTextButton {
138 public:
139 ThrobberNativeTextButton(views::ButtonListener* listener,
140 const string16& text);
141 ~ThrobberNativeTextButton();
142
143 // Start or stop the throbber.
144 void StartThrobber();
145 void StopThrobber();
146
147 // Set the throbber bitmap to use. IDR_THROBBER is used by default.
148 void SetFrames(const SkBitmap* frames);
149
150 protected:
151 virtual const SkBitmap& GetImageToPaint() const OVERRIDE;
152
153 private:
154 // The timer callback to schedule painting this view.
155 void Run();
156
157 // Bitmap that contains the throbber frames.
158 const SkBitmap* frames_;
159
160 // The currently displayed frame, given to GetImageToPaint.
161 mutable SkBitmap this_frame_;
162
163 // How long one frame is displayed.
164 base::TimeDelta frame_time_;
165
166 // Used to schedule Run calls.
167 base::RepeatingTimer<ThrobberNativeTextButton> timer_;
168
169 // How many frames we have.
170 int frame_count_;
171
172 // Time when StartThrobber was called.
173 base::Time start_time_;
174
175 // Whether the throbber is shown an animating.
176 bool running_;
177 };
178
179 ThrobberNativeTextButton::ThrobberNativeTextButton(
180 views::ButtonListener* listener, const string16& text)
181 : NativeTextButton(listener, text),
182 frame_time_(base::TimeDelta::FromMilliseconds(kThrobberFrameTimeMs)),
183 frame_count_(0),
184 running_(false) {
185 SetFrames(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
186 IDR_THROBBER).ToSkBitmap());
187 }
188
189 ThrobberNativeTextButton::~ThrobberNativeTextButton() {
190 StopThrobber();
191 }
192
193 void ThrobberNativeTextButton::StartThrobber() {
194 if (running_)
195 return;
196
197 start_time_ = base::Time::Now();
198 timer_.Start(FROM_HERE, frame_time_ - base::TimeDelta::FromMilliseconds(10),
199 this, &ThrobberNativeTextButton::Run);
200 running_ = true;
201
202 SchedulePaint();
203 }
204
205 void ThrobberNativeTextButton::StopThrobber() {
206 if (!running_)
207 return;
208
209 timer_.Stop();
210 running_ = false;
211 }
212
213 void ThrobberNativeTextButton::SetFrames(const SkBitmap* frames) {
214 frames_ = frames;
215 DCHECK(frames_->width() > 0 && frames_->height() > 0);
216 DCHECK(frames_->width() % frames_->height() == 0);
217 frame_count_ = frames_->width() / frames_->height();
218 PreferredSizeChanged();
219 }
220
221 const SkBitmap& ThrobberNativeTextButton::GetImageToPaint() const {
222 if (!running_)
223 return NativeTextButton::GetImageToPaint();
224
225 const base::TimeDelta elapsed_time = base::Time::Now() - start_time_;
226 const int current_frame =
227 static_cast<int>(elapsed_time / frame_time_) % frame_count_;
228 const int image_size = frames_->height();
229 const int image_offset = current_frame * image_size;
230
231 SkIRect subset_rect = SkIRect::MakeXYWH(image_offset, 0,
232 image_size, image_size);
233 frames_->extractSubset(&this_frame_, subset_rect);
234 return this_frame_;
235 }
236
237 void ThrobberNativeTextButton::Run() {
238 DCHECK(running_);
239
240 SchedulePaint();
241 }
242
128 // ServiceButtonsView ---------------------------------------------------------- 243 // ServiceButtonsView ----------------------------------------------------------
129 244
130 // A view that contains all service buttons (i.e. the installed services). 245 // A view that contains all service buttons (i.e. the installed services).
131 class ServiceButtonsView : public views::View, 246 class ServiceButtonsView : public views::View,
132 public views::ButtonListener { 247 public views::ButtonListener {
133 public: 248 public:
134 class Delegate { 249 class Delegate {
135 public: 250 public:
136 // Called when a service button is clicked. |index| is the index of the 251 // Called when a service button is clicked. |index| is the index of the
137 // service button in the model. 252 // service button in the model.
138 virtual void OnServiceButtonClicked( 253 virtual void OnServiceButtonClicked(
139 const WebIntentPickerModel::InstalledService& service) = 0; 254 const WebIntentPickerModel::InstalledService& service) = 0;
140 255
141 protected: 256 protected:
142 virtual ~Delegate() {} 257 virtual ~Delegate() {}
143 }; 258 };
144 259
145 ServiceButtonsView(const WebIntentPickerModel* model, Delegate* delegate); 260 ServiceButtonsView(const WebIntentPickerModel* model, Delegate* delegate);
146 virtual ~ServiceButtonsView(); 261 virtual ~ServiceButtonsView();
147 262
148 // Updates the service button view with new model data. 263 // Updates the service button view with new model data.
149 void Update(); 264 void Update();
150 265
266 // Start a throbber on the service button that will launch the service at
267 // |url|.
268 void StartThrobber(const GURL& url);
269
151 // views::ButtonListener implementation. 270 // views::ButtonListener implementation.
152 virtual void ButtonPressed(views::Button* sender, 271 virtual void ButtonPressed(views::Button* sender,
153 const views::Event& event) OVERRIDE; 272 const views::Event& event) OVERRIDE;
154 273
155 virtual gfx::Size GetPreferredSize() OVERRIDE; 274 virtual gfx::Size GetPreferredSize() OVERRIDE;
156 275
157 protected: 276 protected:
158 virtual void OnEnabledChanged() OVERRIDE; 277 virtual void OnEnabledChanged() OVERRIDE;
159 278
160 private: 279 private:
(...skipping 26 matching lines...) Expand all
187 cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, GridLayout::USE_PREF, 306 cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, GridLayout::USE_PREF,
188 0, 0); 307 0, 0);
189 cs->AddPaddingColumn(1, 0); 308 cs->AddPaddingColumn(1, 0);
190 309
191 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) { 310 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) {
192 const WebIntentPickerModel::InstalledService& service = 311 const WebIntentPickerModel::InstalledService& service =
193 model_->GetInstalledServiceAt(i); 312 model_->GetInstalledServiceAt(i);
194 313
195 grid_layout->StartRow(0, 0); 314 grid_layout->StartRow(0, 0);
196 315
197 views::NativeTextButton* button = 316 ThrobberNativeTextButton* button =
198 new views::NativeTextButton(this, service.title); 317 new ThrobberNativeTextButton(this, service.title);
199 button->set_alignment(views::TextButton::ALIGN_LEFT); 318 button->set_alignment(views::TextButton::ALIGN_LEFT);
200 button->SetTooltipText(UTF8ToUTF16(service.url.spec().c_str())); 319 button->SetTooltipText(UTF8ToUTF16(service.url.spec().c_str()));
201 button->SetIcon(*service.favicon.ToSkBitmap()); 320 button->SetIcon(*service.favicon.ToSkBitmap());
202 button->set_tag(static_cast<int>(i)); 321 button->set_tag(static_cast<int>(i));
203 grid_layout->AddView(button); 322 grid_layout->AddView(button);
204 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 323 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
205 } 324 }
206 325
207 // Additional space to separate the buttons from the suggestions. 326 // Additional space to separate the buttons from the suggestions.
208 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 327 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
209 } 328 }
210 329
330 void ServiceButtonsView::StartThrobber(const GURL& url) {
331 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) {
332 const WebIntentPickerModel::InstalledService& service =
333 model_->GetInstalledServiceAt(i);
334 if (service.url != url)
335 continue;
336
337 ThrobberNativeTextButton* button =
338 static_cast<ThrobberNativeTextButton*>(child_at(i));
339 button->StartThrobber();
340 return;
341 }
342 }
343
211 void ServiceButtonsView::ButtonPressed(views::Button* sender, 344 void ServiceButtonsView::ButtonPressed(views::Button* sender,
212 const views::Event& event) { 345 const views::Event& event) {
213 size_t index = static_cast<size_t>(sender->tag()); 346 size_t index = static_cast<size_t>(sender->tag());
214 delegate_->OnServiceButtonClicked(model_->GetInstalledServiceAt(index)); 347 delegate_->OnServiceButtonClicked(model_->GetInstalledServiceAt(index));
215 } 348 }
216 349
217 gfx::Size ServiceButtonsView::GetPreferredSize() { 350 gfx::Size ServiceButtonsView::GetPreferredSize() {
218 // If there are no service buttons, hide this view. 351 // If there are no service buttons, hide this view.
219 if (model_->GetInstalledServiceCount() == 0) 352 if (model_->GetInstalledServiceCount() == 0)
220 return gfx::Size(); 353 return gfx::Size();
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 // A delegate to respond to button presses and clicked links. 477 // A delegate to respond to button presses and clicked links.
345 Delegate* delegate_; 478 Delegate* delegate_;
346 479
347 // The icon of the extension. 480 // The icon of the extension.
348 views::ImageView* icon_; 481 views::ImageView* icon_;
349 482
350 // The title of the extension, which links to the CWS detailed description of 483 // The title of the extension, which links to the CWS detailed description of
351 // this extension. 484 // this extension.
352 views::Link* title_link_; 485 views::Link* title_link_;
353 486
354 // A throbber to display when the extension is being installed.
355 views::Throbber* throbber_;
356
357 // The star rating of this extension. 487 // The star rating of this extension.
358 StarsView* stars_; 488 StarsView* stars_;
359 489
360 // A button to install the extension. 490 // A button to install the extension.
361 views::NativeTextButton* install_button_; 491 ThrobberNativeTextButton* install_button_;
362 492
363 DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsRowView); 493 DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsRowView);
364 }; 494 };
365 495
366 SuggestedExtensionsRowView::SuggestedExtensionsRowView( 496 SuggestedExtensionsRowView::SuggestedExtensionsRowView(
367 const WebIntentPickerModel::SuggestedExtension* extension, 497 const WebIntentPickerModel::SuggestedExtension* extension,
368 Delegate* delegate) 498 Delegate* delegate)
369 : extension_(extension), 499 : extension_(extension),
370 delegate_(delegate) { 500 delegate_(delegate) {
371 SetLayoutManager(new SuggestedExtensionsLayout); 501 SetLayoutManager(new SuggestedExtensionsLayout);
372 502
373 icon_ = new views::ImageView(); 503 icon_ = new views::ImageView();
374 icon_->SetImage(extension_->icon.ToSkBitmap()); 504 icon_->SetImage(extension_->icon.ToSkBitmap());
375 AddChildView(icon_); 505 AddChildView(icon_);
376 506
377 string16 elided_title = ui::ElideText( 507 string16 elided_title = ui::ElideText(
378 extension_->title, gfx::Font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END); 508 extension_->title, gfx::Font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END);
379 title_link_ = new views::Link(elided_title); 509 title_link_ = new views::Link(elided_title);
380 title_link_->set_listener(this); 510 title_link_->set_listener(this);
381 AddChildView(title_link_); 511 AddChildView(title_link_);
382 512
383 throbber_ = new views::Throbber(60, true);
384 throbber_->SetVisible(false);
385 AddChildView(throbber_);
386
387 stars_ = new StarsView(extension_->average_rating); 513 stars_ = new StarsView(extension_->average_rating);
388 AddChildView(stars_); 514 AddChildView(stars_);
389 515
390 install_button_= new views::NativeTextButton( 516 install_button_= new ThrobberNativeTextButton(
391 this, l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION)); 517 this, l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION));
392 AddChildView(install_button_); 518 AddChildView(install_button_);
393 } 519 }
394 520
395 SuggestedExtensionsRowView::~SuggestedExtensionsRowView() { 521 SuggestedExtensionsRowView::~SuggestedExtensionsRowView() {
396 } 522 }
397 523
398 void SuggestedExtensionsRowView::ButtonPressed(views::Button* sender, 524 void SuggestedExtensionsRowView::ButtonPressed(views::Button* sender,
399 const views::Event& event) { 525 const views::Event& event) {
400 delegate_->OnExtensionInstallClicked(extension_->id); 526 delegate_->OnExtensionInstallClicked(extension_->id);
401 } 527 }
402 528
403 void SuggestedExtensionsRowView::LinkClicked(views::Link* source, 529 void SuggestedExtensionsRowView::LinkClicked(views::Link* source,
404 int event_flags) { 530 int event_flags) {
405 delegate_->OnExtensionLinkClicked(extension_->id); 531 delegate_->OnExtensionLinkClicked(extension_->id);
406 } 532 }
407 533
408 void SuggestedExtensionsRowView::StartThrobber() { 534 void SuggestedExtensionsRowView::StartThrobber() {
409 stars_->SetVisible(false); 535 install_button_->StartThrobber();
410 install_button_->SetVisible(false); 536 install_button_->SetText(string16());
411 throbber_->SetVisible(true);
412 throbber_->Start();
413 Layout();
414 } 537 }
415 538
416 void SuggestedExtensionsRowView::StopThrobber() { 539 void SuggestedExtensionsRowView::StopThrobber() {
417 stars_->SetVisible(true); 540 install_button_->StopThrobber();
418 install_button_->SetVisible(true); 541 install_button_->SetText(
419 throbber_->SetVisible(false); 542 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION));
420 throbber_->Stop();
421 Layout();
422 } 543 }
423 544
424 void SuggestedExtensionsRowView::OnEnabledChanged() { 545 void SuggestedExtensionsRowView::OnEnabledChanged() {
425 title_link_->SetEnabled(enabled()); 546 title_link_->SetEnabled(enabled());
426 stars_->SetVisible(enabled()); 547 stars_->SetEnabled(enabled());
427 install_button_->SetVisible(enabled()); 548 install_button_->SetEnabled(enabled());
428 View::OnEnabledChanged(); 549 View::OnEnabledChanged();
429 Layout(); 550 Layout();
430 } 551 }
431 552
432 void SuggestedExtensionsRowView::PaintChildren(gfx::Canvas* canvas) { 553 void SuggestedExtensionsRowView::PaintChildren(gfx::Canvas* canvas) {
433 View::PaintChildren(canvas); 554 View::PaintChildren(canvas);
434 if (!enabled()) 555 if (!enabled())
435 canvas->FillRect(GetLocalBounds(), kHalfOpacityWhite); 556 canvas->FillRect(GetLocalBounds(), kHalfOpacityWhite);
436 } 557 }
437 558
438 // SuggestedExtensionsView ----------------------------------------------------- 559 // SuggestedExtensionsView -----------------------------------------------------
439 560
440 // A view that contains suggested extensions from the Chrome Web Store that 561 // A view that contains suggested extensions from the Chrome Web Store that
441 // provide an intent service matching the action/type pair. 562 // provide an intent service matching the action/type pair.
442 // This view also displays the "More suggestions" link which searches the
443 // Chrome Web Store for more extensions.
444 class SuggestedExtensionsView : public views::View { 563 class SuggestedExtensionsView : public views::View {
445 public: 564 public:
446 SuggestedExtensionsView(const WebIntentPickerModel* model, 565 SuggestedExtensionsView(const WebIntentPickerModel* model,
447 SuggestedExtensionsRowView::Delegate* delegate); 566 SuggestedExtensionsRowView::Delegate* delegate);
448 567
449 virtual ~SuggestedExtensionsView(); 568 virtual ~SuggestedExtensionsView();
450 569
451 void Clear(); 570 void Clear();
452 571
453 // Update the view to the new model data. 572 // Update the view to the new model data.
454 void Update(); 573 void Update();
455 574
456 // Show the install throbber for the row containing |extension_id|. This 575 // Show the install throbber for the row containing |extension_id|. This
457 // function also hides hides and disables other buttons and links. 576 // function also hides hides and disables other buttons and links.
458 void StartThrobber(const string16& extension_id); 577 void StartThrobber(const string16& extension_id);
459 578
460 // Hide the install throbber. This function re-enables all buttons and links. 579 // Hide the install throbber. This function re-enables all buttons and links.
461 void StopThrobber(); 580 void StopThrobber();
462 581
582 protected:
583 virtual void OnEnabledChanged() OVERRIDE;
584
463 private: 585 private:
464 const WebIntentPickerModel* model_; 586 const WebIntentPickerModel* model_;
465 SuggestedExtensionsRowView::Delegate* delegate_; 587 SuggestedExtensionsRowView::Delegate* delegate_;
466 588
467 DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsView); 589 DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsView);
468 }; 590 };
469 591
470 SuggestedExtensionsView::SuggestedExtensionsView( 592 SuggestedExtensionsView::SuggestedExtensionsView(
471 const WebIntentPickerModel* model, 593 const WebIntentPickerModel* model,
472 SuggestedExtensionsRowView::Delegate* delegate) 594 SuggestedExtensionsRowView::Delegate* delegate)
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 633
512 void SuggestedExtensionsView::StopThrobber() { 634 void SuggestedExtensionsView::StopThrobber() {
513 for (size_t i = 0; i < model_->GetSuggestedExtensionCount(); ++i) { 635 for (size_t i = 0; i < model_->GetSuggestedExtensionCount(); ++i) {
514 SuggestedExtensionsRowView* row = 636 SuggestedExtensionsRowView* row =
515 static_cast<SuggestedExtensionsRowView*>(child_at(i)); 637 static_cast<SuggestedExtensionsRowView*>(child_at(i));
516 row->SetEnabled(true); 638 row->SetEnabled(true);
517 row->StopThrobber(); 639 row->StopThrobber();
518 } 640 }
519 } 641 }
520 642
643 void SuggestedExtensionsView::OnEnabledChanged() {
644 EnableChildViews(this, enabled());
645 View::OnEnabledChanged();
646 }
647
521 } // namespace 648 } // namespace
522 649
523 // WebIntentPickerViews -------------------------------------------------------- 650 // WebIntentPickerViews --------------------------------------------------------
524 651
525 // Views implementation of WebIntentPicker. 652 // Views implementation of WebIntentPicker.
526 class WebIntentPickerViews : public views::ButtonListener, 653 class WebIntentPickerViews : public views::ButtonListener,
527 public views::DialogDelegate, 654 public views::DialogDelegate,
528 public views::LinkListener, 655 public views::LinkListener,
529 public WebIntentPicker, 656 public WebIntentPicker,
530 public WebIntentPickerModelObserver, 657 public WebIntentPickerModelObserver,
(...skipping 18 matching lines...) Expand all
549 virtual views::View* GetContentsView() OVERRIDE; 676 virtual views::View* GetContentsView() OVERRIDE;
550 virtual int GetDialogButtons() const OVERRIDE; 677 virtual int GetDialogButtons() const OVERRIDE;
551 678
552 // LinkListener implementation. 679 // LinkListener implementation.
553 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; 680 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
554 681
555 // WebIntentPicker implementation. 682 // WebIntentPicker implementation.
556 virtual void Close() OVERRIDE; 683 virtual void Close() OVERRIDE;
557 virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE; 684 virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
558 virtual void OnExtensionInstallFailure(const std::string& id) OVERRIDE; 685 virtual void OnExtensionInstallFailure(const std::string& id) OVERRIDE;
686 virtual void OnInlineDispositionWebContentsLoaded(
687 content::WebContents* web_contents) OVERRIDE;
559 688
560 // WebIntentPickerModelObserver implementation. 689 // WebIntentPickerModelObserver implementation.
561 virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE; 690 virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE;
562 virtual void OnFaviconChanged(WebIntentPickerModel* model, 691 virtual void OnFaviconChanged(WebIntentPickerModel* model,
563 size_t index) OVERRIDE; 692 size_t index) OVERRIDE;
564 virtual void OnExtensionIconChanged(WebIntentPickerModel* model, 693 virtual void OnExtensionIconChanged(WebIntentPickerModel* model,
565 const string16& extension_id) OVERRIDE; 694 const string16& extension_id) OVERRIDE;
566 virtual void OnInlineDisposition(WebIntentPickerModel* model, 695 virtual void OnInlineDisposition(WebIntentPickerModel* model,
567 const GURL& url) OVERRIDE; 696 const GURL& url) OVERRIDE;
568 697
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 743
615 // A weak pointer to the constrained window. 744 // A weak pointer to the constrained window.
616 ConstrainedWindowViews* window_; 745 ConstrainedWindowViews* window_;
617 746
618 // A weak pointer to the more suggestions link. 747 // A weak pointer to the more suggestions link.
619 views::Link* more_suggestions_link_; 748 views::Link* more_suggestions_link_;
620 749
621 // A weak pointer to the choose another service link. 750 // A weak pointer to the choose another service link.
622 views::Link* choose_another_service_link_; 751 views::Link* choose_another_service_link_;
623 752
753 // Set to true when displaying the inline disposition web contents. Used to
754 // prevent laying out the inline disposition widgets twice.
755 bool displaying_web_contents_;
756
624 DISALLOW_COPY_AND_ASSIGN(WebIntentPickerViews); 757 DISALLOW_COPY_AND_ASSIGN(WebIntentPickerViews);
625 }; 758 };
626 759
627 // static 760 // static
628 WebIntentPicker* WebIntentPicker::Create(Browser* browser, 761 WebIntentPicker* WebIntentPicker::Create(Browser* browser,
629 TabContentsWrapper* wrapper, 762 TabContentsWrapper* wrapper,
630 WebIntentPickerDelegate* delegate, 763 WebIntentPickerDelegate* delegate,
631 WebIntentPickerModel* model) { 764 WebIntentPickerModel* model) {
632 WebIntentPickerViews* picker = 765 WebIntentPickerViews* picker =
633 new WebIntentPickerViews(browser, wrapper, delegate, model); 766 new WebIntentPickerViews(browser, wrapper, delegate, model);
634 767
635 return picker; 768 return picker;
636 } 769 }
637 770
638 WebIntentPickerViews::WebIntentPickerViews(Browser* browser, 771 WebIntentPickerViews::WebIntentPickerViews(Browser* browser,
639 TabContentsWrapper* wrapper, 772 TabContentsWrapper* wrapper,
640 WebIntentPickerDelegate* delegate, 773 WebIntentPickerDelegate* delegate,
641 WebIntentPickerModel* model) 774 WebIntentPickerModel* model)
642 : delegate_(delegate), 775 : delegate_(delegate),
643 model_(model), 776 model_(model),
644 service_buttons_(NULL), 777 service_buttons_(NULL),
645 suggestions_label_(NULL), 778 suggestions_label_(NULL),
646 extensions_(NULL), 779 extensions_(NULL),
647 browser_(browser), 780 browser_(browser),
648 contents_(NULL), 781 contents_(NULL),
649 window_(NULL), 782 window_(NULL),
650 more_suggestions_link_(NULL), 783 more_suggestions_link_(NULL),
651 choose_another_service_link_(NULL) { 784 choose_another_service_link_(NULL),
785 displaying_web_contents_(false) {
652 model_->set_observer(this); 786 model_->set_observer(this);
653 InitContents(); 787 InitContents();
654 788
655 // Show the dialog. 789 // Show the dialog.
656 window_ = new ConstrainedWindowViews(wrapper, this); 790 window_ = new ConstrainedWindowViews(wrapper, this);
657 } 791 }
658 792
659 WebIntentPickerViews::~WebIntentPickerViews() { 793 WebIntentPickerViews::~WebIntentPickerViews() {
660 model_->set_observer(NULL); 794 model_->set_observer(NULL);
661 } 795 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 851
718 void WebIntentPickerViews::OnExtensionInstallFailure(const std::string& id) { 852 void WebIntentPickerViews::OnExtensionInstallFailure(const std::string& id) {
719 service_buttons_->SetEnabled(true); 853 service_buttons_->SetEnabled(true);
720 extensions_->StopThrobber(); 854 extensions_->StopThrobber();
721 more_suggestions_link_->SetEnabled(true); 855 more_suggestions_link_->SetEnabled(true);
722 contents_->Layout(); 856 contents_->Layout();
723 857
724 // TODO(binji): What to display to user on failure? 858 // TODO(binji): What to display to user on failure?
725 } 859 }
726 860
727 void WebIntentPickerViews::OnModelChanged(WebIntentPickerModel* model) { 861 void WebIntentPickerViews::OnInlineDispositionWebContentsLoaded(
728 if (model->GetInstalledServiceCount() == 0) { 862 content::WebContents* web_contents) {
729 suggestions_label_->SetText(l10n_util::GetStringUTF16( 863 if (displaying_web_contents_)
730 IDS_INTENT_PICKER_GET_MORE_SERVICES_NONE_INSTALLED)); 864 return;
731 } else {
732 suggestions_label_->SetText(
733 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_GET_MORE_SERVICES));
734 }
735
736 service_buttons_->Update();
737 extensions_->Update();
738 contents_->Layout();
739 SizeToContents();
740 }
741
742 void WebIntentPickerViews::OnFaviconChanged(
743 WebIntentPickerModel* model, size_t index) {
744 service_buttons_->Update();
745 contents_->Layout();
746 SizeToContents();
747 }
748
749 void WebIntentPickerViews::OnExtensionIconChanged(
750 WebIntentPickerModel* model,
751 const string16& extension_id) {
752 extensions_->Update();
753 contents_->Layout();
754 SizeToContents();
755 }
756
757 void WebIntentPickerViews::OnInlineDisposition(
758 WebIntentPickerModel* model, const GURL& url) {
759 WebContents* web_contents = WebContents::Create(
760 browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
761 inline_disposition_delegate_.reset(new WebIntentInlineDispositionDelegate);
762 web_contents->SetDelegate(inline_disposition_delegate_.get());
763
764 const WebIntentPickerModel::InstalledService* service =
765 model->GetInstalledServiceWithURL(url);
766 DCHECK(service);
767
768 // Must call this immediately after WebContents creation to avoid race
769 // with load.
770 delegate_->OnInlineDispositionWebContentsCreated(web_contents);
771
772 TabContentsContainer* tab_contents_container = new TabContentsContainer;
773
774 web_contents->GetController().LoadURL(
775 url,
776 content::Referrer(),
777 content::PAGE_TRANSITION_START_PAGE,
778 std::string());
779 865
780 // Replace the picker with the inline disposition. 866 // Replace the picker with the inline disposition.
781 contents_->RemoveAllChildViews(true); 867 contents_->RemoveAllChildViews(true);
782 868
783 views::GridLayout* grid_layout = new views::GridLayout(contents_); 869 views::GridLayout* grid_layout = new views::GridLayout(contents_);
784 contents_->SetLayoutManager(grid_layout); 870 contents_->SetLayoutManager(grid_layout);
785 871
786 grid_layout->SetInsets(kContentAreaBorder, kContentAreaBorder, 872 grid_layout->SetInsets(kContentAreaBorder, kContentAreaBorder,
787 kContentAreaBorder, kContentAreaBorder); 873 kContentAreaBorder, kContentAreaBorder);
788 views::ColumnSet* header_cs = grid_layout->AddColumnSet(0); 874 views::ColumnSet* header_cs = grid_layout->AddColumnSet(0);
789 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, 875 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
790 GridLayout::USE_PREF, 0, 0); // Icon. 876 GridLayout::USE_PREF, 0, 0); // Icon.
791 header_cs->AddPaddingColumn(0, 4); 877 header_cs->AddPaddingColumn(0, 4);
792 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, 878 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
793 GridLayout::USE_PREF, 0, 0); // Title. 879 GridLayout::USE_PREF, 0, 0); // Title.
794 header_cs->AddPaddingColumn(0, 4); 880 header_cs->AddPaddingColumn(0, 4);
795 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, 881 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
796 GridLayout::USE_PREF, 0, 0); // Link. 882 GridLayout::USE_PREF, 0, 0); // Link.
797 header_cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing); 883 header_cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
798 #if defined(USE_CLOSE_BUTTON) 884 #if defined(USE_CLOSE_BUTTON)
799 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0, 885 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
800 GridLayout::USE_PREF, 0, 0); // Close Button. 886 GridLayout::USE_PREF, 0, 0); // Close Button.
801 #endif 887 #endif
802 888
803 views::ColumnSet* full_cs = grid_layout->AddColumnSet(1); 889 views::ColumnSet* full_cs = grid_layout->AddColumnSet(1);
804 full_cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0, 890 full_cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 0,
805 GridLayout::USE_PREF, 0, 0); 891 GridLayout::USE_PREF, 0, 0);
806 892
893 const WebIntentPickerModel::InstalledService* service =
894 model_->GetInstalledServiceWithURL(model_->inline_disposition_url());
895
807 // Header row. 896 // Header row.
808 grid_layout->StartRow(0, 0); 897 grid_layout->StartRow(0, 0);
809 views::ImageView* icon = new views::ImageView(); 898 views::ImageView* icon = new views::ImageView();
810 icon->SetImage(service->favicon.ToSkBitmap()); 899 icon->SetImage(service->favicon.ToSkBitmap());
811 grid_layout->AddView(icon); 900 grid_layout->AddView(icon);
812 901
813 string16 elided_title = ui::ElideText( 902 string16 elided_title = ui::ElideText(
814 service->title, gfx::Font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END); 903 service->title, gfx::Font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END);
815 views::Label* title = new views::Label(elided_title); 904 views::Label* title = new views::Label(elided_title);
816 grid_layout->AddView(title); 905 grid_layout->AddView(title);
817 906
818 choose_another_service_link_ = new views::Link( 907 choose_another_service_link_ = new views::Link(
819 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_USE_ALTERNATE_SERVICE)); 908 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_USE_ALTERNATE_SERVICE));
820 grid_layout->AddView(choose_another_service_link_); 909 grid_layout->AddView(choose_another_service_link_);
821 910
822 #if defined(USE_CLOSE_BUTTON) 911 #if defined(USE_CLOSE_BUTTON)
823 grid_layout->AddView(CreateCloseButton()); 912 grid_layout->AddView(CreateCloseButton());
824 #endif 913 #endif
825 914
826 // Inline web contents row. 915 // Inline web contents row.
827 grid_layout->StartRow(0, 1); 916 grid_layout->StartRow(0, 1);
917 TabContentsContainer* tab_contents_container = new TabContentsContainer;
828 grid_layout->AddView(tab_contents_container, 1, 1, GridLayout::CENTER, 918 grid_layout->AddView(tab_contents_container, 1, 1, GridLayout::CENTER,
829 GridLayout::CENTER, kDialogMinWidth, 140); 919 GridLayout::CENTER, kDialogMinWidth, 140);
830 920
831 // The contents can only be changed after the child is added to view 921 // The contents can only be changed after the child is added to view
832 // hierarchy. 922 // hierarchy.
833 tab_contents_container->ChangeWebContents(web_contents); 923 tab_contents_container->ChangeWebContents(web_contents);
834
835 contents_->Layout(); 924 contents_->Layout();
836 SizeToContents(); 925 SizeToContents();
926 displaying_web_contents_ = true;
927 }
928
929 void WebIntentPickerViews::OnModelChanged(WebIntentPickerModel* model) {
930 if (model->GetInstalledServiceCount() == 0) {
931 suggestions_label_->SetText(l10n_util::GetStringUTF16(
932 IDS_INTENT_PICKER_GET_MORE_SERVICES_NONE_INSTALLED));
933 } else {
934 suggestions_label_->SetText(
935 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_GET_MORE_SERVICES));
936 }
937
938 service_buttons_->Update();
939 extensions_->Update();
940 contents_->Layout();
941 SizeToContents();
942 }
943
944 void WebIntentPickerViews::OnFaviconChanged(
945 WebIntentPickerModel* model, size_t index) {
946 service_buttons_->Update();
947 contents_->Layout();
948 SizeToContents();
949 }
950
951 void WebIntentPickerViews::OnExtensionIconChanged(
952 WebIntentPickerModel* model,
953 const string16& extension_id) {
954 extensions_->Update();
955 contents_->Layout();
956 SizeToContents();
957 }
958
959 void WebIntentPickerViews::OnInlineDisposition(
960 WebIntentPickerModel* model, const GURL& url) {
961 WebContents* web_contents = WebContents::Create(
962 browser_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL);
963 inline_disposition_delegate_.reset(
964 new WebIntentInlineDispositionDelegate(this));
965 web_contents->SetDelegate(inline_disposition_delegate_.get());
966
967 const WebIntentPickerModel::InstalledService* service =
968 model->GetInstalledServiceWithURL(url);
969 DCHECK(service);
970
971 // Must call this immediately after WebContents creation to avoid race
972 // with load.
973 delegate_->OnInlineDispositionWebContentsCreated(web_contents);
974 web_contents->GetController().LoadURL(
975 url,
976 content::Referrer(),
977 content::PAGE_TRANSITION_START_PAGE,
978 std::string());
979
980 // Disable all buttons and show throbber.
981 service_buttons_->SetEnabled(false);
982 service_buttons_->StartThrobber(url);
983 extensions_->SetEnabled(false);
984 more_suggestions_link_->SetEnabled(false);
985 contents_->Layout();
837 } 986 }
838 987
839 void WebIntentPickerViews::OnServiceButtonClicked( 988 void WebIntentPickerViews::OnServiceButtonClicked(
840 const WebIntentPickerModel::InstalledService& service) { 989 const WebIntentPickerModel::InstalledService& service) {
841 delegate_->OnServiceChosen(service.url, service.disposition); 990 delegate_->OnServiceChosen(service.url, service.disposition);
842 } 991 }
843 992
844 void WebIntentPickerViews::OnExtensionInstallClicked( 993 void WebIntentPickerViews::OnExtensionInstallClicked(
845 const string16& extension_id) { 994 const string16& extension_id) {
846 service_buttons_->SetEnabled(false); 995 service_buttons_->SetEnabled(false);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 views::ImageButton* close_button = new views::ImageButton(this); 1107 views::ImageButton* close_button = new views::ImageButton(this);
959 close_button->SetImage(views::CustomButton::BS_NORMAL, 1108 close_button->SetImage(views::CustomButton::BS_NORMAL,
960 rb.GetBitmapNamed(IDR_CLOSE_BAR)); 1109 rb.GetBitmapNamed(IDR_CLOSE_BAR));
961 close_button->SetImage(views::CustomButton::BS_HOT, 1110 close_button->SetImage(views::CustomButton::BS_HOT,
962 rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); 1111 rb.GetBitmapNamed(IDR_CLOSE_BAR_H));
963 close_button->SetImage(views::CustomButton::BS_PUSHED, 1112 close_button->SetImage(views::CustomButton::BS_PUSHED,
964 rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); 1113 rb.GetBitmapNamed(IDR_CLOSE_BAR_P));
965 return close_button; 1114 return close_button;
966 } 1115 }
967 #endif 1116 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698