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

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

Issue 11044020: Make Web Intents picker in Views conform to latest mocks (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Include changes from CL 11077006 Created 8 years, 2 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
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/command_line.h" 8 #include "base/command_line.h"
9 #include "base/memory/scoped_vector.h" 9 #include "base/memory/scoped_vector.h"
10 #include "base/time.h" 10 #include "base/time.h"
11 #include "base/timer.h"
11 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/download/download_util.h"
12 #include "chrome/browser/tab_contents/tab_util.h" 14 #include "chrome/browser/tab_contents/tab_util.h"
13 #include "chrome/browser/ui/browser_finder.h" 15 #include "chrome/browser/ui/browser_finder.h"
14 #include "chrome/browser/ui/browser_navigator.h" 16 #include "chrome/browser/ui/browser_navigator.h"
15 #include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h" 17 #include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h"
16 #include "chrome/browser/ui/intents/web_intent_picker.h" 18 #include "chrome/browser/ui/intents/web_intent_picker.h"
17 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" 19 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h"
18 #include "chrome/browser/ui/intents/web_intent_picker_model.h" 20 #include "chrome/browser/ui/intents/web_intent_picker_model.h"
19 #include "chrome/browser/ui/intents/web_intent_picker_model_observer.h" 21 #include "chrome/browser/ui/intents/web_intent_picker_model_observer.h"
20 #include "chrome/browser/ui/tab_contents/tab_contents.h" 22 #include "chrome/browser/ui/tab_contents/tab_contents.h"
21 #include "chrome/browser/ui/views/constrained_window_views.h" 23 #include "chrome/browser/ui/views/constrained_window_views.h"
(...skipping 18 matching lines...) Expand all
40 #include "ui/gfx/canvas.h" 42 #include "ui/gfx/canvas.h"
41 #include "ui/gfx/image/image.h" 43 #include "ui/gfx/image/image.h"
42 #include "ui/gfx/image/image_skia_operations.h" 44 #include "ui/gfx/image/image_skia_operations.h"
43 #include "ui/views/border.h" 45 #include "ui/views/border.h"
44 #include "ui/views/controls/button/image_button.h" 46 #include "ui/views/controls/button/image_button.h"
45 #include "ui/views/controls/button/text_button.h" 47 #include "ui/views/controls/button/text_button.h"
46 #include "ui/views/controls/image_view.h" 48 #include "ui/views/controls/image_view.h"
47 #include "ui/views/controls/label.h" 49 #include "ui/views/controls/label.h"
48 #include "ui/views/controls/link.h" 50 #include "ui/views/controls/link.h"
49 #include "ui/views/controls/link_listener.h" 51 #include "ui/views/controls/link_listener.h"
52 #include "ui/views/controls/separator.h"
50 #include "ui/views/controls/throbber.h" 53 #include "ui/views/controls/throbber.h"
51 #include "ui/views/controls/webview/webview.h" 54 #include "ui/views/controls/webview/webview.h"
52 #include "ui/views/layout/box_layout.h" 55 #include "ui/views/layout/box_layout.h"
53 #include "ui/views/layout/fill_layout.h" 56 #include "ui/views/layout/fill_layout.h"
54 #include "ui/views/layout/grid_layout.h" 57 #include "ui/views/layout/grid_layout.h"
55 #include "ui/views/layout/layout_constants.h" 58 #include "ui/views/layout/layout_constants.h"
56 #include "ui/views/view.h" 59 #include "ui/views/view.h"
57 #include "ui/views/widget/widget.h" 60 #include "ui/views/widget/widget.h"
58 #include "ui/views/window/dialog_delegate.h" 61 #include "ui/views/window/dialog_delegate.h"
59 #include "ui/views/window/non_client_view.h" 62 #include "ui/views/window/non_client_view.h"
60 63
61 using content::WebContents; 64 using content::WebContents;
62 using views::GridLayout; 65 using views::GridLayout;
63 66
64 namespace { 67 namespace {
65 68
66 // The color used to dim disabled elements. 69 // The color used to dim disabled elements.
67 const SkColor kHalfOpacityWhite = SkColorSetARGB(128, 255, 255, 255); 70 const SkColor kHalfOpacityWhite = SkColorSetARGB(128, 255, 255, 255);
68 71
72 // The color used to display an enabled label.
73 const SkColor kEnabledLabelColor = SkColorSetRGB(51, 51, 51);
74
75 // The color used to display an enabled link.
76 const SkColor kEnabledLinkColor = SkColorSetRGB(17, 85, 204);
77
69 // The color used to display a disabled link. 78 // The color used to display a disabled link.
70 const SkColor kDisabledLinkColor = SkColorSetRGB(128, 128, 128); 79 const SkColor kDisabledLinkColor = SkColorSetRGB(128, 128, 128);
71 80
72 // The time between successive throbber frames in milliseconds. 81 // The time between successive throbber frames in milliseconds.
73 const int kThrobberFrameTimeMs = 50; 82 const int kThrobberFrameTimeMs = 50;
74 83
75 // Width of IntentView action button in pixels 84 // Width of IntentView action button in pixels
76 const int kButtonWidth = 130; 85 const int kButtonWidth = 130;
77 86
78 // Minimum number of action buttons - fill up with suggestions as needed. 87 // Minimum number of action buttons - fill up with suggestions as needed.
79 const int kMinRowCount = 4; 88 const int kMinRowCount = 4;
80 89
81 // Maximum number of action buttons - do not add suggestions to reach. 90 // Maximum number of action buttons - do not add suggestions to reach.
82 const int kMaxRowCount = 8; 91 const int kMaxRowCount = 8;
83 92
93 // Custom client insets for the constrained window.
94 const int kConstrainedWindowClientTopInset = 10;
95 const int kConstrainedWindowClientLeftInset = 0;
96 const int kConstrainedWindowClientBottomInset = 0;
97 const int kConstrainedWindowClientRightInset = 0;
98
84 // Enables or disables all child views of |view|. 99 // Enables or disables all child views of |view|.
85 void EnableChildViews(views::View* view, bool enabled) { 100 void EnableChildViews(views::View* view, bool enabled) {
86 for (int i = 0; i < view->child_count(); ++i) { 101 for (int i = 0; i < view->child_count(); ++i) {
87 views::View* child = view->child_at(i); 102 views::View* child = view->child_at(i);
88 child->SetEnabled(enabled); 103 child->SetEnabled(enabled);
89 } 104 }
90 } 105 }
91 106
92 // Create a "close" button. 107 // Creates a label.
93 views::ImageButton* CreateCloseButton(views::ButtonListener* listener) { 108 views::Label* CreateLabel() {
109 views::Label* label = new views::Label();
110 label->SetEnabledColor(kEnabledLabelColor);
111 label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
Peter Kasting 2012/10/12 03:23:32 Wow, I'm amazed this isn't the default. I don't k
please use gerrit instead 2012/10/14 18:40:45 Filed http://crbug.com/155526.
112 return label;
113 }
114
115 // Creates a title-style label.
116 views::Label* CreateTitleLabel() {
117 views::Label* label = CreateLabel();
94 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 118 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
Peter Kasting 2012/10/12 03:23:32 Nit: Or just inline into next line (I know this is
please use gerrit instead 2012/10/14 18:40:45 Done.
95 views::ImageButton* close_button = new views::ImageButton(listener); 119 label->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont));
96 close_button->SetImage(views::CustomButton::BS_NORMAL, 120 return label;
97 rb.GetImageSkiaNamed(IDR_SHARED_IMAGES_X));
98 close_button->SetImage(views::CustomButton::BS_HOT,
99 rb.GetImageSkiaNamed(IDR_SHARED_IMAGES_X_HOVER));
100 close_button->SetImage(views::CustomButton::BS_PUSHED,
101 rb.GetImageSkiaNamed(IDR_SHARED_IMAGES_X_HOVER));
102 return close_button;
103 } 121 }
122
123 // Creates a link.
124 views::Link* CreateLink() {
125 views::Link* link = new views::Link();
126 link->SetEnabledColor(kEnabledLinkColor);
127 link->SetDisabledColor(kDisabledLinkColor);
128 link->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
129 link->SetUnderlineOnHover(true);
130 return link;
131 }
132
104 // SarsView ------------------------------------------------------------------- 133 // SarsView -------------------------------------------------------------------
Peter Kasting 2012/10/12 03:23:32 Nit: While here, can you fix Sars -> Stars? "Sars
please use gerrit instead 2012/10/14 18:40:45 Done.
105 134
106 // A view that displays 5 stars: empty, full or half full, given a rating in 135 // A view that displays 5 stars: empty, full or half full, given a rating in
107 // the range [0,5]. 136 // the range [0,5].
108 class StarsView : public views::View { 137 class StarsView : public views::View {
109 public: 138 public:
110 explicit StarsView(double rating); 139 explicit StarsView(double rating);
111 virtual ~StarsView(); 140 virtual ~StarsView();
112 141
113 private: 142 private:
114 // The star rating to display, in the range [0,5]. 143 // The star rating to display, in the range [0,5].
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 this_frame_ = gfx::ImageSkiaOperations::ExtractSubset(*frames_, subset_rect); 291 this_frame_ = gfx::ImageSkiaOperations::ExtractSubset(*frames_, subset_rect);
263 return this_frame_; 292 return this_frame_;
264 } 293 }
265 294
266 void ThrobberNativeTextButton::Run() { 295 void ThrobberNativeTextButton::Run() {
267 DCHECK(running_); 296 DCHECK(running_);
268 297
269 SchedulePaint(); 298 SchedulePaint();
270 } 299 }
271 300
301 // SpinnerProgressIndicator ----------------------------------------------------
302 class SpinnerProgressIndicator : public views::View {
Peter Kasting 2012/10/12 03:23:32 How does this differ from the similar-looking prog
please use gerrit instead 2012/10/14 18:40:45 The downloads tab is Javascript: this.canvasProgr
Peter Kasting 2012/10/15 18:24:23 Yeah, having the code here call download_util seem
please use gerrit instead 2012/10/15 20:24:04 Filed for follow up work for myself: http://crbug.
303 public:
304 SpinnerProgressIndicator();
305 void SetPercentDone(int percent);
306 void SetIndeterminate(bool indetereminate);
307
308 // Overridden from views::View.
309 virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
310 virtual gfx::Size GetPreferredSize() OVERRIDE;
311
312 private:
313 void UpdateTimer();
314 int GetProgressAngle();
315
316 static const int kTimerIntervalMs = 1000 / 30;
317 static const int kSpinRateDegreesPerSecond = 270;
318
319 int percentDone_;
Peter Kasting 2012/10/12 03:23:32 Never use camelCase member variables please
please use gerrit instead 2012/10/14 18:40:45 Done.
320 int isIndeterminate_;
321
322 base::TimeTicks startTime_;
323 base::RepeatingTimer<SpinnerProgressIndicator> timer_;
324 };
325
326 SpinnerProgressIndicator::SpinnerProgressIndicator()
327 : percentDone_(0),
328 isIndeterminate_(true) {}
329
330 void SpinnerProgressIndicator::SetPercentDone(int percent) {
331 percentDone_ = percent;
332 SchedulePaint();
333 UpdateTimer();
334 }
335
336 void SpinnerProgressIndicator::SetIndeterminate(bool indetereminate) {
337 isIndeterminate_ = indetereminate;
338 SchedulePaint();
339 UpdateTimer();
340 }
341
342 void SpinnerProgressIndicator::Paint(gfx::Canvas* canvas) {
343 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
344 gfx::ImageSkia* fg = rb.GetImageSkiaNamed(IDR_WEB_INTENT_PROGRESS_FOREGROUND);
345 gfx::ImageSkia* bg = rb.GetImageSkiaNamed(IDR_WEB_INTENT_PROGRESS_BACKGROUND);
346 download_util::PaintCustomDownloadProgress(
347 canvas,
348 *bg,
349 *fg,
350 fg->width(),
351 bounds(),
352 GetProgressAngle(),
353 isIndeterminate_ ? -1 : percentDone_);
354 }
355
356 gfx::Size SpinnerProgressIndicator::GetPreferredSize() {
357 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
358 gfx::ImageSkia* fg = rb.GetImageSkiaNamed(IDR_WEB_INTENT_PROGRESS_FOREGROUND);
359 return fg->size();
360 }
361
362 void SpinnerProgressIndicator::UpdateTimer() {
363 if (!parent() || !isIndeterminate_) {
364 timer_.Stop();
365 return;
366 }
367
368 if (!timer_.IsRunning()) {
369 startTime_ = base::TimeTicks::Now();
370 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimerIntervalMs),
371 this, &SpinnerProgressIndicator::SchedulePaint);
372 }
373 }
374
375 int SpinnerProgressIndicator::GetProgressAngle() {
376 if (!isIndeterminate_)
377 return download_util::kStartAngleDegrees;
378 base::TimeDelta delta = base::TimeTicks::Now() - startTime_;
379 int angle = delta.InSecondsF() * kSpinRateDegreesPerSecond;
380 return angle % 360;
381 }
382
272 // WaitingView ---------------------------------------------------------- 383 // WaitingView ----------------------------------------------------------
273 class WaitingView : public views::View { 384 class WaitingView : public views::View {
274 public: 385 public:
275 WaitingView(views::ButtonListener* listener, bool use_close_button); 386 WaitingView();
276 387
277 private: 388 private:
389 static const int kTopBorder = 16;
390 static const int kBottomBorder = 37;
391 static const int kLeftBorder = 0;
392 static const int kRightBorder = 0;
393 static const int kThrobberTextPadding = 15;
394
278 DISALLOW_COPY_AND_ASSIGN(WaitingView); 395 DISALLOW_COPY_AND_ASSIGN(WaitingView);
279 }; 396 };
280 397
281 WaitingView::WaitingView(views::ButtonListener* listener, 398 WaitingView::WaitingView() {
282 bool use_close_button) { 399 enum {
400 kContentRowColumnSet, // Column set for the main content.
401 };
402
283 views::GridLayout* layout = new views::GridLayout(this); 403 views::GridLayout* layout = new views::GridLayout(this);
284 layout->set_minimum_size(gfx::Size(WebIntentPicker::kWindowMinWidth, 0)); 404 layout->set_minimum_size(gfx::Size(WebIntentPicker::kWindowMinWidth, 0));
285 layout->SetInsets(WebIntentPicker::kContentAreaBorder, 405 layout->SetInsets(kTopBorder, kLeftBorder, kBottomBorder, kRightBorder);
286 WebIntentPicker::kContentAreaBorder,
287 WebIntentPicker::kContentAreaBorder,
288 WebIntentPicker::kContentAreaBorder);
289 SetLayoutManager(layout); 406 SetLayoutManager(layout);
290 407
291 views::ColumnSet* cs = layout->AddColumnSet(0); 408 views::ColumnSet* cs = layout->AddColumnSet(kContentRowColumnSet);
292 views::ColumnSet* header_cs = NULL;
293 if (use_close_button) {
294 header_cs = layout->AddColumnSet(1);
295 header_cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
296 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
297 GridLayout::USE_PREF, 0, 0); // Close Button.
298 }
299 cs->AddPaddingColumn(0, views::kPanelHorizIndentation); 409 cs->AddPaddingColumn(0, views::kPanelHorizIndentation);
300 cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 410 cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 1,
301 1, GridLayout::USE_PREF, 0, 0); 411 GridLayout::USE_PREF, 0, 0);
302 cs->AddPaddingColumn(0, views::kPanelHorizIndentation); 412 cs->AddPaddingColumn(0, views::kPanelHorizIndentation);
303 413
304 // Create throbber. 414 // Create throbber.
305 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 415 SpinnerProgressIndicator* throbber = new SpinnerProgressIndicator();
306 const gfx::ImageSkia* frames =
307 rb.GetImageNamed(IDR_SPEECH_INPUT_SPINNER).ToImageSkia();
308 views::Throbber* throbber = new views::Throbber(kThrobberFrameTimeMs, true);
309 throbber->SetFrames(frames);
310 throbber->Start();
311 416
312 // Create text. 417 // Create text.
313 views::Label* label = new views::Label(); 418 views::Label* label = CreateLabel();
314 label->SetHorizontalAlignment(views::Label::ALIGN_CENTER); 419 label->SetHorizontalAlignment(views::Label::ALIGN_CENTER);
315 label->SetFont(rb.GetFont(ui::ResourceBundle::MediumBoldFont));
316 label->SetText(l10n_util::GetStringUTF16(IDS_INTENT_PICKER_WAIT_FOR_CWS)); 420 label->SetText(l10n_util::GetStringUTF16(IDS_INTENT_PICKER_WAIT_FOR_CWS));
317 421
318 // Layout the view. 422 // Layout the view.
319 if (use_close_button) { 423 layout->StartRow(0, kContentRowColumnSet);
320 layout->StartRow(0, 1); 424 layout->AddView(throbber);
321 layout->AddView(CreateCloseButton(listener));
322 }
323 425
324 layout->AddPaddingRow(0, views::kUnrelatedControlLargeVerticalSpacing); 426 layout->AddPaddingRow(0, kThrobberTextPadding);
325 layout->StartRow(0, 0); 427
326 layout->AddView(throbber); 428 layout->StartRow(0, kContentRowColumnSet);
327 layout->AddPaddingRow(0, views::kUnrelatedControlLargeVerticalSpacing);
328 layout->StartRow(0, 0);
329 layout->AddView(label); 429 layout->AddView(label);
330 layout->AddPaddingRow(0, views::kUnrelatedControlLargeVerticalSpacing);
331 }
332 430
333 // SuggestedExtensionsLayout --------------------------------------------------- 431 // Start the throbber.
334 432 throbber->SetIndeterminate(true);
335 // TODO(groby): Extremely fragile code, relies on order and number of fields.
336 // Would probably be better off as GridLayout or similar. Also see review
337 // comments on http://codereview.chromium.org/10909183
338
339 // A LayoutManager used by a row of the IntentsView. It is similar
340 // to a BoxLayout, but it right aligns the rightmost view (which is the install
341 // button). It also uses the maximum height of all views in the row as a
342 // preferred height so it doesn't change when the install button is hidden.
343 class SuggestedExtensionsLayout : public views::LayoutManager {
344 public:
345 SuggestedExtensionsLayout();
346 virtual ~SuggestedExtensionsLayout();
347
348 // Implementation of views::LayoutManager.
349 virtual void Layout(views::View* host) OVERRIDE;
350 virtual gfx::Size GetPreferredSize(views::View* host) OVERRIDE;
351
352 private:
353 DISALLOW_COPY_AND_ASSIGN(SuggestedExtensionsLayout);
354 };
355
356 SuggestedExtensionsLayout::SuggestedExtensionsLayout() {
357 }
358
359 SuggestedExtensionsLayout::~SuggestedExtensionsLayout() {
360 }
361
362 void SuggestedExtensionsLayout::Layout(views::View* host) {
363 gfx::Rect child_area(host->GetLocalBounds());
364 child_area.Inset(host->GetInsets());
365 int x = child_area.x();
366 int y = child_area.y();
367
368 for (int i = 0; i < host->child_count(); ++i) {
369 views::View* child = host->child_at(i);
370 if (!child->visible())
371 continue;
372 gfx::Size size(child->GetPreferredSize());
373 gfx::Rect child_bounds(x, y, size.width(), child_area.height());
374 if (i == host->child_count() - 1) {
375 // Last child (the install button) should be right aligned.
376 child_bounds.set_x(std::max(child_area.width() - size.width(), x));
377 } else if (i == 1) {
378 // Label is considered fixed width, to align ratings widget.
379 DCHECK_LE(size.width(), WebIntentPicker::kTitleLinkMaxWidth);
380 x += WebIntentPicker::kTitleLinkMaxWidth +
381 views::kRelatedControlHorizontalSpacing;
382 } else {
383 x += size.width() + views::kRelatedControlHorizontalSpacing;
384 }
385 // Clamp child view bounds to |child_area|.
386 child->SetBoundsRect(child_bounds.Intersect(child_area));
387 }
388 }
389
390 gfx::Size SuggestedExtensionsLayout::GetPreferredSize(views::View* host) {
391 int width = 0;
392 int height = 0;
393 for (int i = 0; i < host->child_count(); ++i) {
394 views::View* child = host->child_at(i);
395 gfx::Size size(child->GetPreferredSize());
396 // The preferred height includes visible and invisible children. This
397 // prevents jank when a child is hidden.
398 height = std::max(height, size.height());
399 if (!child->visible())
400 continue;
401 if (i != 0)
402 width += views::kRelatedControlHorizontalSpacing;
403 }
404 gfx::Insets insets(host->GetInsets());
405 return gfx::Size(width + insets.width(), height + insets.height());
406 } 433 }
407 434
408 // IntentRowView -------------------------------------------------- 435 // IntentRowView --------------------------------------------------
409 436
410 // A view for each row in the IntentsView. It displays information 437 // A view for each row in the IntentsView. It displays information
411 // for both installed and suggested intent handlers. 438 // for both installed and suggested intent handlers.
412 class IntentRowView : public views::View, 439 class IntentRowView : public views::View,
413 public views::ButtonListener, 440 public views::ButtonListener,
414 public views::LinkListener { 441 public views::LinkListener {
415 public: 442 public:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 // Stop the throbber for this row, and show the star rating and the install 492 // Stop the throbber for this row, and show the star rating and the install
466 // button. 493 // button.
467 void StopThrobber(); 494 void StopThrobber();
468 495
469 protected: 496 protected:
470 virtual void OnEnabledChanged() OVERRIDE; 497 virtual void OnEnabledChanged() OVERRIDE;
471 498
472 virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE; 499 virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE;
473 500
474 private: 501 private:
502 static const int kStarRatingHorizontalSpacing = 20;
503
475 IntentRowView(ActionType type, size_t tag); 504 IntentRowView(ActionType type, size_t tag);
476 505
477 // Gets the proper message string associated with |type_|. 506 // Gets the proper message string associated with |type_|.
478 string16 GetActionButtonMessage(); 507 string16 GetActionButtonMessage();
479 508
480 // Identifier for the suggested extension displayed in this row. 509 // Identifier for the suggested extension displayed in this row.
481 std::string extension_id_; 510 std::string extension_id_;
482 511
483 // A delegate to respond to button presses and clicked links. 512 // A delegate to respond to button presses and clicked links.
484 Delegate* delegate_; 513 Delegate* delegate_;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 ui::ELIDE_AT_END); 569 ui::ELIDE_AT_END);
541 570
542 const gfx::ImageSkia* icon = NULL; 571 const gfx::ImageSkia* icon = NULL;
543 StarsView* stars = NULL; 572 StarsView* stars = NULL;
544 views::Label* label = NULL; 573 views::Label* label = NULL;
545 IntentRowView* view; 574 IntentRowView* view;
546 if (service != NULL) { 575 if (service != NULL) {
547 view = new IntentRowView(ACTION_INVOKE, tag); 576 view = new IntentRowView(ACTION_INVOKE, tag);
548 icon = service->favicon.ToImageSkia(); 577 icon = service->favicon.ToImageSkia();
549 label = new views::Label(elided_title); 578 label = new views::Label(elided_title);
579 label->SetEnabledColor(kEnabledLabelColor);
550 } else { 580 } else {
551 view = new IntentRowView(ACTION_INSTALL, tag); 581 view = new IntentRowView(ACTION_INSTALL, tag);
552 view->extension_id_ = extension->id; 582 view->extension_id_ = extension->id;
553 icon = extension->icon.ToImageSkia(); 583 icon = extension->icon.ToImageSkia();
554 views::Link* link = new views::Link(elided_title); 584 views::Link* link = new views::Link(elided_title);
585 link->SetUnderlineOnHover(true);
586 link->SetEnabledColor(kEnabledLinkColor);
555 link->set_listener(view); 587 link->set_listener(view);
556 label = link; 588 label = link;
557 stars = new StarsView(extension->average_rating); 589 stars = new StarsView(extension->average_rating);
558 } 590 }
559 591
560 view->delegate_ = delegate; 592 view->delegate_ = delegate;
561 593
562 view->SetLayoutManager(new SuggestedExtensionsLayout); 594 views::GridLayout* grid_layout = new views::GridLayout(view);
595 view->SetLayoutManager(grid_layout);
596
597 views::ColumnSet* columns = grid_layout->AddColumnSet(0);
598 columns->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
599 GridLayout::USE_PREF, 0, 0); // Icon.
600 columns->AddPaddingColumn(0, WebIntentPicker::kIconLabelHorizontalSpacing);
601 columns->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
602 GridLayout::FIXED, WebIntentPicker::kTitleLinkMaxWidth, 0);
603 columns->AddPaddingColumn(0, kStarRatingHorizontalSpacing);
604 if (stars != NULL) {
605 columns->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
606 GridLayout::USE_PREF, 0, 0); // Star rating.
607 columns->AddPaddingColumn(0, kStarRatingHorizontalSpacing);
608 }
609 columns->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
610 GridLayout::FIXED, preferred_width, 0); // Button.
611
612 grid_layout->StartRow(0, 0);
563 613
564 view->icon_ = new views::ImageView(); 614 view->icon_ = new views::ImageView();
565
566 view->icon_->SetImage(icon); 615 view->icon_->SetImage(icon);
567 view->AddChildView(view->icon_); 616 grid_layout->AddView(view->icon_);
568 617
569 view->title_link_ = label; 618 view->title_link_ = label;
570 view->AddChildView(view->title_link_); 619 grid_layout->AddView(view->title_link_);
571 620
572 if (stars != NULL) { 621 if (stars != NULL) {
573 view->stars_ = stars; 622 view->stars_ = stars;
574 view->AddChildView(view->stars_); 623 grid_layout->AddView(view->stars_);
575 } 624 }
576 625
577 view->install_button_ = new ThrobberNativeTextButton( 626 view->install_button_ = new ThrobberNativeTextButton(view,
578 view, view->GetActionButtonMessage()); 627 view->GetActionButtonMessage());
579 view->install_button_->set_preferred_width(preferred_width); 628 view->install_button_->set_preferred_width(preferred_width);
580 view->AddChildView(view->install_button_); 629 grid_layout->AddView(view->install_button_);
581 630
582 return view; 631 return view;
583 } 632 }
584 633
585 IntentRowView::~IntentRowView() {} 634 IntentRowView::~IntentRowView() {}
586 635
587 void IntentRowView::ButtonPressed(views::Button* sender, 636 void IntentRowView::ButtonPressed(views::Button* sender,
588 const ui::Event& event) { 637 const ui::Event& event) {
589 if (type_ == ACTION_INSTALL) 638 if (type_ == ACTION_INSTALL)
590 delegate_->OnExtensionInstallClicked(extension_id_); 639 delegate_->OnExtensionInstallClicked(extension_id_);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 // Hide the install throbber. This function re-enables all buttons and links. 713 // Hide the install throbber. This function re-enables all buttons and links.
665 void StopThrobber(); 714 void StopThrobber();
666 715
667 // Adjusts a given width to account for language-specific strings. 716 // Adjusts a given width to account for language-specific strings.
668 int AdjustWidth(int old_width); 717 int AdjustWidth(int old_width);
669 718
670 protected: 719 protected:
671 virtual void OnEnabledChanged() OVERRIDE; 720 virtual void OnEnabledChanged() OVERRIDE;
672 721
673 private: 722 private:
723 static const int kAppRowVerticalSpacing = 10;
Peter Kasting 2012/10/12 03:23:32 Nit: Just declare this in the function it's used i
please use gerrit instead 2012/10/14 18:40:45 Done.
724
674 const WebIntentPickerModel* model_; 725 const WebIntentPickerModel* model_;
675 IntentRowView::Delegate* delegate_; 726 IntentRowView::Delegate* delegate_;
676 727
677 // Width for the action button, adjusted to be wide enough for all possible 728 // Width for the action button, adjusted to be wide enough for all possible
678 // strings. 729 // strings.
679 int button_width_; 730 int button_width_;
680 731
681 DISALLOW_COPY_AND_ASSIGN(IntentsView); 732 DISALLOW_COPY_AND_ASSIGN(IntentsView);
682 }; 733 };
683 734
(...skipping 12 matching lines...) Expand all
696 void IntentsView::Update() { 747 void IntentsView::Update() {
697 RemoveAllChildViews(true); 748 RemoveAllChildViews(true);
698 749
699 ThrobberNativeTextButton size_helper( 750 ThrobberNativeTextButton size_helper(
700 NULL, l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION)); 751 NULL, l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION));
701 size_helper.SetText( 752 size_helper.SetText(
702 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_SELECT_INTENT)); 753 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_SELECT_INTENT));
703 button_width_ = std::max( 754 button_width_ = std::max(
704 kButtonWidth, size_helper.GetPreferredSize().width()); 755 kButtonWidth, size_helper.GetPreferredSize().width());
705 756
706 views::BoxLayout* layout = new views::BoxLayout( 757 views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kVertical,
707 views::BoxLayout::kVertical, 0, 0, views::kRelatedControlVerticalSpacing); 758 0, 0, kAppRowVerticalSpacing);
Peter Kasting 2012/10/12 03:23:32 Nit: Align with first arg in line above or else mo
please use gerrit instead 2012/10/14 18:40:45 Done.
708 SetLayoutManager(layout); 759 SetLayoutManager(layout);
709 760
710 int available_rows = kMaxRowCount; 761 int available_rows = kMaxRowCount;
711 762
712 for (size_t i = 0; 763 for (size_t i = 0;
713 available_rows > 0 && i < model_->GetInstalledServiceCount(); 764 available_rows > 0 && i < model_->GetInstalledServiceCount();
714 ++i, --available_rows) { 765 ++i, --available_rows) {
715 const WebIntentPickerModel::InstalledService& service = 766 const WebIntentPickerModel::InstalledService& service =
716 model_->GetInstalledServiceAt(i); 767 model_->GetInstalledServiceAt(i);
717 AddChildView(IntentRowView::CreateHandlerRow(&service, NULL, i, 768 AddChildView(IntentRowView::CreateHandlerRow(&service, NULL, i,
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 // This method is called when the user cancels the picker dialog. 826 // This method is called when the user cancels the picker dialog.
776 virtual void ButtonPressed(views::Button* sender, 827 virtual void ButtonPressed(views::Button* sender,
777 const ui::Event& event) OVERRIDE; 828 const ui::Event& event) OVERRIDE;
778 829
779 // views::DialogDelegate implementation. 830 // views::DialogDelegate implementation.
780 virtual void WindowClosing() OVERRIDE; 831 virtual void WindowClosing() OVERRIDE;
781 virtual void DeleteDelegate() OVERRIDE; 832 virtual void DeleteDelegate() OVERRIDE;
782 virtual views::Widget* GetWidget() OVERRIDE; 833 virtual views::Widget* GetWidget() OVERRIDE;
783 virtual const views::Widget* GetWidget() const OVERRIDE; 834 virtual const views::Widget* GetWidget() const OVERRIDE;
784 virtual views::View* GetContentsView() OVERRIDE; 835 virtual views::View* GetContentsView() OVERRIDE;
836 virtual views::View* GetHeaderView() OVERRIDE;
Peter Kasting 2012/10/12 03:23:32 I don't think we should add this concept of a "hea
please use gerrit instead 2012/10/14 18:40:45 Done.
785 virtual int GetDialogButtons() const OVERRIDE; 837 virtual int GetDialogButtons() const OVERRIDE;
786 virtual bool Cancel() OVERRIDE; 838 virtual bool Cancel() OVERRIDE;
787 839
788 // LinkListener implementation. 840 // LinkListener implementation.
789 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; 841 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
790 842
791 // WebIntentPicker implementation. 843 // WebIntentPicker implementation.
792 virtual void Close() OVERRIDE; 844 virtual void Close() OVERRIDE;
793 virtual void SetActionString(const string16& action) OVERRIDE; 845 virtual void SetActionString(const string16& action) OVERRIDE;
794 virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE; 846 virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
(...skipping 19 matching lines...) Expand all
814 const std::string& extension_id, 866 const std::string& extension_id,
815 WindowOpenDisposition disposition) OVERRIDE; 867 WindowOpenDisposition disposition) OVERRIDE;
816 virtual void OnActionButtonClicked( 868 virtual void OnActionButtonClicked(
817 IntentRowView::ActionType type, 869 IntentRowView::ActionType type,
818 size_t tag) OVERRIDE; 870 size_t tag) OVERRIDE;
819 871
820 private: 872 private:
821 // Update picker contents to reflect the current state of the model. 873 // Update picker contents to reflect the current state of the model.
822 void UpdateContents(); 874 void UpdateContents();
823 875
876 // Shows a spinner and notifies the user that we are waiting for information
877 // from the Chrome Web Store.
878 void ShowWaitingForSuggestions();
879
824 // Updates the dialog with the list of available services, suggestions, 880 // Updates the dialog with the list of available services, suggestions,
825 // and a nice link to CWS to find more suggestions. This is the "Main" 881 // and a nice link to CWS to find more suggestions. This is the "Main"
826 // view of the picker. 882 // view of the picker.
827 void ShowAvailableServices(); 883 void ShowAvailableServices();
828 884
829 // Informs the user that there are no services available to handle 885 // Informs the user that there are no services available to handle
830 // the intent, and that there are no suggestions from the Chrome Web Store. 886 // the intent, and that there are no suggestions from the Chrome Web Store.
831 void ShowNoServicesMessage(); 887 void ShowNoServicesMessage();
832 888
833 // Restore the contents of the picker to the initial contents. 889 // Restore the contents of the picker to the initial contents.
(...skipping 13 matching lines...) Expand all
847 // chooses a service or cancels. 903 // chooses a service or cancels.
848 WebIntentPickerDelegate* delegate_; 904 WebIntentPickerDelegate* delegate_;
849 905
850 // A weak pointer to the picker model. 906 // A weak pointer to the picker model.
851 WebIntentPickerModel* model_; 907 WebIntentPickerModel* model_;
852 908
853 // A weak pointer to the action string label. 909 // A weak pointer to the action string label.
854 // Created locally, owned by Views. 910 // Created locally, owned by Views.
855 views::Label* action_label_; 911 views::Label* action_label_;
856 912
913 // Label for the no-services dialog.
914 views::Label* no_services_title_;
915
857 // A weak pointer to the header label for the extension suggestions. 916 // A weak pointer to the header label for the extension suggestions.
858 // Created locally, owned by Views. 917 // Created locally, owned by Views.
859 views::Label* suggestions_label_; 918 views::Label* suggestions_label_;
860 919
861 // A weak pointer to the intents view. 920 // A weak pointer to the intents view.
862 // Created locally, owned by Views view hierarchy. 921 // Created locally, owned by Views view hierarchy.
863 IntentsView* extensions_; 922 IntentsView* extensions_;
864 923
865 // Delegate for inline disposition tab contents. 924 // Delegate for inline disposition tab contents.
866 scoped_ptr<WebIntentInlineDispositionDelegate> inline_disposition_delegate_; 925 scoped_ptr<WebIntentInlineDispositionDelegate> inline_disposition_delegate_;
867 926
868 // A weak pointer to the TabContents this picker is in. 927 // A weak pointer to the TabContents this picker is in.
869 TabContents* tab_contents_; 928 TabContents* tab_contents_;
870 929
871 // A weak pointer to the WebView that hosts the WebContents being displayed. 930 // A weak pointer to the WebView that hosts the WebContents being displayed.
872 // Created locally, owned by Views. 931 // Created locally, owned by Views.
873 views::WebView* webview_; 932 views::WebView* webview_;
874 933
875 // A weak pointer to the view that contains all other views in the picker. 934 // A weak pointer to the view that contains all other views in the picker.
876 // Created locally, owned by Views. 935 // Created locally, owned by Views.
877 views::View* contents_; 936 views::View* contents_;
878 937
938 // The view that contains the header for the picker.
939 views::View* header_;
940
879 // A weak pointer to the constrained window. 941 // A weak pointer to the constrained window.
880 // Created locally, owned by Views. 942 // Created locally, owned by Views.
881 ConstrainedWindowViews* window_; 943 ConstrainedWindowViews* window_;
882 944
883 // A weak pointer to the more suggestions link. 945 // A weak pointer to the more suggestions link.
884 // Created locally, owned by Views. 946 // Created locally, owned by Views.
885 views::Link* more_suggestions_link_; 947 views::Link* more_suggestions_link_;
886 948
887 // A weak pointer to the choose another service link. 949 // A weak pointer to the choose another service link.
888 // Created locally, owned by Views. 950 // Created locally, owned by Views.
889 views::Link* choose_another_service_link_; 951 views::Link* choose_another_service_link_;
890 952
953 // The icon for the inline intent.
954 views::ImageView* inline_intent_icon_;
955
956 // The label for the inline intent.
957 views::Label* inline_intent_label_;
958
891 // Weak pointer to "Waiting for CWS" display. Owned by parent view. 959 // Weak pointer to "Waiting for CWS" display. Owned by parent view.
892 WaitingView* waiting_view_; 960 WaitingView* waiting_view_;
893 961
894 // Set to true when displaying the inline disposition web contents. Used to 962 // Set to true when displaying the inline disposition web contents. Used to
895 // prevent laying out the inline disposition widgets twice. 963 // prevent laying out the inline disposition widgets twice.
896 bool displaying_web_contents_; 964 bool displaying_web_contents_;
897 965
898 // The text for the current action. 966 // The text for the current action.
899 string16 action_text_; 967 string16 action_text_;
900 968
901 // Ownership of the WebContents we are displaying in the inline disposition. 969 // Ownership of the WebContents we are displaying in the inline disposition.
902 scoped_ptr<WebContents> inline_web_contents_; 970 scoped_ptr<WebContents> inline_web_contents_;
903 971
904 // Indicate if dialog should display its own close button.
905 // TODO(groby): Only relevant until new ConstrainedWindow is implemented,
906 // from then on always true.
907 bool use_close_button_;
908
909 // Signals if the picker can be closed. False during extension install. 972 // Signals if the picker can be closed. False during extension install.
910 bool can_close_; 973 bool can_close_;
911 974
912 DISALLOW_COPY_AND_ASSIGN(WebIntentPickerViews); 975 DISALLOW_COPY_AND_ASSIGN(WebIntentPickerViews);
913 }; 976 };
914 977
915 // static 978 // static
916 WebIntentPicker* WebIntentPicker::Create(content::WebContents* web_contents, 979 WebIntentPicker* WebIntentPicker::Create(content::WebContents* web_contents,
917 WebIntentPickerDelegate* delegate, 980 WebIntentPickerDelegate* delegate,
918 WebIntentPickerModel* model) { 981 WebIntentPickerModel* model) {
919 TabContents* tab_contents = TabContents::FromWebContents(web_contents); 982 TabContents* tab_contents = TabContents::FromWebContents(web_contents);
920 return new WebIntentPickerViews(tab_contents, delegate, model); 983 return new WebIntentPickerViews(tab_contents, delegate, model);
921 } 984 }
922 985
923 WebIntentPickerViews::WebIntentPickerViews(TabContents* tab_contents, 986 WebIntentPickerViews::WebIntentPickerViews(TabContents* tab_contents,
924 WebIntentPickerDelegate* delegate, 987 WebIntentPickerDelegate* delegate,
925 WebIntentPickerModel* model) 988 WebIntentPickerModel* model)
926 : delegate_(delegate), 989 : delegate_(delegate),
927 model_(model), 990 model_(model),
928 action_label_(NULL),
929 suggestions_label_(NULL), 991 suggestions_label_(NULL),
930 extensions_(NULL), 992 extensions_(NULL),
931 tab_contents_(tab_contents), 993 tab_contents_(tab_contents),
932 webview_(new views::WebView(tab_contents->profile())), 994 webview_(new views::WebView(tab_contents->profile())),
933 window_(NULL), 995 window_(NULL),
934 more_suggestions_link_(NULL), 996 more_suggestions_link_(NULL),
935 choose_another_service_link_(NULL), 997 choose_another_service_link_(NULL),
936 waiting_view_(NULL), 998 waiting_view_(NULL),
937 displaying_web_contents_(false), 999 displaying_web_contents_(false),
938 can_close_(true) { 1000 can_close_(true) {
939 bool enable_chrome_style = CommandLine::ForCurrentProcess()->HasSwitch(
940 switches::kEnableFramelessConstrainedDialogs);
941 use_close_button_ = enable_chrome_style;
942
943 model_->set_observer(this); 1001 model_->set_observer(this);
944 contents_ = new views::View(); 1002 contents_ = new views::View();
1003 header_ = new views::View();
1004
1005 action_label_ = CreateTitleLabel();
1006 action_label_->SetText(GetActionTitle());
1007 no_services_title_ = CreateTitleLabel();
1008 inline_intent_icon_ = new views::ImageView();
1009 inline_intent_label_ = CreateLabel();
1010 choose_another_service_link_ = CreateLink();
1011
1012 gfx::Insets client_insets(kConstrainedWindowClientTopInset,
1013 kConstrainedWindowClientLeftInset,
1014 kConstrainedWindowClientBottomInset,
1015 kConstrainedWindowClientRightInset);
945 // Show the dialog. 1016 // Show the dialog.
946 window_ = new ConstrainedWindowViews(tab_contents->web_contents(), 1017 window_ = new ConstrainedWindowViews(tab_contents->web_contents(), this, true,
947 this, 1018 client_insets);
948 enable_chrome_style);
949
950 UpdateContents(); 1019 UpdateContents();
951 } 1020 }
952 1021
953 WebIntentPickerViews::~WebIntentPickerViews() { 1022 WebIntentPickerViews::~WebIntentPickerViews() {
954 model_->set_observer(NULL); 1023 model_->set_observer(NULL);
955 } 1024 }
956 1025
957 void WebIntentPickerViews::ButtonPressed(views::Button* sender, 1026 void WebIntentPickerViews::ButtonPressed(views::Button* sender,
958 const ui::Event& event) { 1027 const ui::Event& event) {
959 delegate_->OnUserCancelledPickerDialog(); 1028 delegate_->OnUserCancelledPickerDialog();
(...skipping 12 matching lines...) Expand all
972 } 1041 }
973 1042
974 const views::Widget* WebIntentPickerViews::GetWidget() const { 1043 const views::Widget* WebIntentPickerViews::GetWidget() const {
975 return contents_->GetWidget(); 1044 return contents_->GetWidget();
976 } 1045 }
977 1046
978 views::View* WebIntentPickerViews::GetContentsView() { 1047 views::View* WebIntentPickerViews::GetContentsView() {
979 return contents_; 1048 return contents_;
980 } 1049 }
981 1050
1051 views::View* WebIntentPickerViews::GetHeaderView() {
1052 return header_;
1053 }
1054
982 int WebIntentPickerViews::GetDialogButtons() const { 1055 int WebIntentPickerViews::GetDialogButtons() const {
983 return ui::DIALOG_BUTTON_NONE; 1056 return ui::DIALOG_BUTTON_NONE;
984 } 1057 }
985 1058
986 bool WebIntentPickerViews::Cancel() { 1059 bool WebIntentPickerViews::Cancel() {
987 return can_close_; 1060 return can_close_;
988 } 1061 }
989 1062
990 void WebIntentPickerViews::LinkClicked(views::Link* source, int event_flags) { 1063 void WebIntentPickerViews::LinkClicked(views::Link* source, int event_flags) {
991 if (source == more_suggestions_link_) { 1064 if (source == more_suggestions_link_) {
992 delegate_->OnSuggestionsLinkClicked( 1065 delegate_->OnSuggestionsLinkClicked(
993 chrome::DispositionFromEventFlags(event_flags)); 1066 chrome::DispositionFromEventFlags(event_flags));
994 } else if (source == choose_another_service_link_) { 1067 } else if (source == choose_another_service_link_) {
995 // Signal cancellation of inline disposition. 1068 // Signal cancellation of inline disposition.
996 delegate_->OnChooseAnotherService(); 1069 delegate_->OnChooseAnotherService();
997 ResetContents(); 1070 ResetContents();
998 } else { 1071 } else {
999 NOTREACHED(); 1072 NOTREACHED();
1000 } 1073 }
1001 } 1074 }
1002 1075
1003 void WebIntentPickerViews::Close() { 1076 void WebIntentPickerViews::Close() {
1004 window_->CloseConstrainedWindow(); 1077 window_->CloseConstrainedWindow();
1005 } 1078 }
1006 1079
1007 void WebIntentPickerViews::SetActionString(const string16& action) { 1080 void WebIntentPickerViews::SetActionString(const string16& action) {
1008 action_text_ = action; 1081 action_text_ = action;
1009 1082
1010 if (action_label_) 1083 action_label_->SetText(GetActionTitle());
1011 action_label_->SetText(GetActionTitle()); 1084
1012 contents_->Layout(); 1085 contents_->Layout();
1013 SizeToContents(); 1086 SizeToContents();
1014 } 1087 }
1015 1088
1016 void WebIntentPickerViews::OnExtensionInstallSuccess(const std::string& id) { 1089 void WebIntentPickerViews::OnExtensionInstallSuccess(const std::string& id) {
1017 can_close_ = true; 1090 can_close_ = true;
1018 } 1091 }
1019 1092
1020 void WebIntentPickerViews::OnExtensionInstallFailure(const std::string& id) { 1093 void WebIntentPickerViews::OnExtensionInstallFailure(const std::string& id) {
1021 extensions_->StopThrobber(); 1094 extensions_->StopThrobber();
1022 more_suggestions_link_->SetEnabled(true); 1095 more_suggestions_link_->SetEnabled(true);
1023 can_close_ = true; 1096 can_close_ = true;
1024 contents_->Layout(); 1097 contents_->Layout();
1025 SizeToContents(); 1098 SizeToContents();
1026 1099
1027 // TODO(binji): What to display to user on failure? 1100 // TODO(binji): What to display to user on failure?
1028 } 1101 }
1029 1102
1030 void WebIntentPickerViews::OnInlineDispositionAutoResize( 1103 void WebIntentPickerViews::OnInlineDispositionAutoResize(
1031 const gfx::Size& size) { 1104 const gfx::Size& size) {
1032 webview_->SetPreferredSize(size); 1105 webview_->SetPreferredSize(size);
1033 contents_->Layout(); 1106 contents_->Layout();
1034 SizeToContents(); 1107 SizeToContents();
1035 } 1108 }
1036 1109
1037 void WebIntentPickerViews::OnPendingAsyncCompleted() { 1110 void WebIntentPickerViews::OnPendingAsyncCompleted() {
1038 UpdateContents(); 1111 UpdateContents();
1039 } 1112 }
1040 1113
1041 void WebIntentPickerViews::ShowNoServicesMessage() { 1114 void WebIntentPickerViews::ShowNoServicesMessage() {
1115 static const int kTopPadding = 20;
Peter Kasting 2012/10/12 03:23:32 Nit: I'd just have: const int kPadding = 20;
please use gerrit instead 2012/10/14 18:40:45 Partially done. (1) I am now using as many global
Peter Kasting 2012/10/15 18:24:23 Normally weird paddings happen because we want som
please use gerrit instead 2012/10/15 20:24:04 Done. I am now using mostly paddings from Constari
1116 static const int kLeftPadding = 20;
1117 static const int kBottomPadding = 20;
1118 static const int kRightPadding = 20;
1119
1120 static const int kHeaderTopPadding = 11;
1121 static const int kHeaderLeftPadding = 0;
1122 static const int kHeaderBottomPadding = 0;
1123 static const int kHeaderRightPadding = 0;
1124
1042 ClearContents(); 1125 ClearContents();
1043 1126
1044 views::GridLayout* grid_layout = new views::GridLayout(contents_); 1127 // Header.
1045 contents_->SetLayoutManager(grid_layout); 1128 no_services_title_->SetText(l10n_util::GetStringUTF16(
1129 IDS_INTENT_PICKER_NO_SERVICES_TITLE));
1130 views::GridLayout* header_layout = new views::GridLayout(header_);
1131 header_->SetLayoutManager(header_layout);
1132 header_layout->SetInsets(kHeaderTopPadding, kHeaderLeftPadding,
1133 kHeaderBottomPadding, kHeaderRightPadding);
1134 header_layout->AddColumnSet(0)->AddColumn(GridLayout::LEADING,
1135 GridLayout::CENTER, 1, GridLayout::USE_PREF, 0, 0);
1136 header_layout->StartRow(0, 0);
1137 header_layout->AddView(no_services_title_);
1046 1138
1047 grid_layout->SetInsets(kContentAreaBorder, kContentAreaBorder, 1139 // Contents.
1048 kContentAreaBorder, kContentAreaBorder); 1140 views::GridLayout* layout = new views::GridLayout(contents_);
Peter Kasting 2012/10/12 03:23:32 Let's kill the header view entirely and avoid havi
please use gerrit instead 2012/10/14 18:40:45 Done.
1049 views::ColumnSet* main_cs = grid_layout->AddColumnSet(0); 1141 layout->set_minimum_size(gfx::Size(WebIntentPicker::kWindowMinWidth, 0));
1050 main_cs->AddColumn(GridLayout::FILL, GridLayout::LEADING, 1, 1142 layout->SetInsets(kTopPadding, kLeftPadding, kBottomPadding, kRightPadding);
1051 GridLayout::USE_PREF, 0, 0); 1143 contents_->SetLayoutManager(layout);
1052 1144
1053 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1145 layout->AddColumnSet(0)->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
1146 GridLayout::USE_PREF, 0, 0);
1054 1147
1055 grid_layout->StartRow(0, 0); 1148 // Content row.
1056 views::Label* header = new views::Label(); 1149 layout->StartRow(0, 0);
1057 header->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 1150 views::Label* body = CreateLabel();
1058 header->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont)); 1151 body->SetMultiLine(true);
1059 header->SetText(l10n_util::GetStringUTF16( 1152 body->SetText(l10n_util::GetStringUTF16(IDS_INTENT_PICKER_NO_SERVICES));
1060 IDS_INTENT_PICKER_NO_SERVICES_TITLE)); 1153 layout->AddView(body);
1061 grid_layout->AddView(header);
1062 1154
1063 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 1155 int height = contents_->GetHeightForWidth(WebIntentPicker::kWindowMinWidth);
1064 1156 contents_->SetSize(gfx::Size(WebIntentPicker::kWindowMinWidth, height));
1065 grid_layout->StartRow(0, 0); 1157 contents_->Layout();
1066 views::Label* body = new views::Label();
1067 body->SetMultiLine(true);
1068 body->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
1069 body->SetText(l10n_util::GetStringUTF16(IDS_INTENT_PICKER_NO_SERVICES));
1070 grid_layout->AddView(body);
1071
1072 int height = contents_->GetHeightForWidth(kWindowMinWidth);
1073 contents_->SetSize(gfx::Size(kWindowMinWidth, height));
1074 } 1158 }
1075 1159
1076 void WebIntentPickerViews::OnInlineDispositionWebContentsLoaded( 1160 void WebIntentPickerViews::OnInlineDispositionWebContentsLoaded(
1077 content::WebContents* web_contents) { 1161 content::WebContents* web_contents) {
1162 enum {
1163 kSeparatorRowColumnSet, // Column set for separator layout.
1164 kWebContentsRowColumnSet, // Column set for main content layout.
1165 };
1166
1078 if (displaying_web_contents_) 1167 if (displaying_web_contents_)
1079 return; 1168 return;
1080 1169
1170 const int kHeaderTopPadding = 7;
1171 const int kHeaderLeftPadding = 0;
1172 const int kHeaderBottomPadding = 0;
1173 const int kHeaderRightPadding = 1;
1174
1175 const int kTopPadding = 13;
1176 const int kLeftPadding = 0;
1177 const int kBottomPadding = 20;
1178 const int kRightPadding = 0;
1179
1180 const int kWebContentsTopPadding = 3;
1181 const int kWebContentsLeftPadding = 1;
1182 const int kWebContentsRightPadding = 1;
1183
1184 bool show_use_another = (model_->GetInstalledServiceCount() > 1 ||
1185 model_->GetSuggestedExtensionCount());
Peter Kasting 2012/10/12 03:23:32 Nit: Strange indenting, only indent even for comma
please use gerrit instead 2012/10/14 18:40:45 Done.
1186
1081 // Replace the picker with the inline disposition. 1187 // Replace the picker with the inline disposition.
1082 ClearContents(); 1188 ClearContents();
1083 1189
1084 views::GridLayout* grid_layout = new views::GridLayout(contents_);
1085 contents_->SetLayoutManager(grid_layout);
1086
1087 grid_layout->SetInsets(kContentAreaBorder, kContentAreaBorder,
1088 kContentAreaBorder, kContentAreaBorder);
1089 views::ColumnSet* header_cs = grid_layout->AddColumnSet(0);
1090 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
1091 GridLayout::USE_PREF, 0, 0); // Icon.
1092 header_cs->AddPaddingColumn(0, 4);
1093 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
1094 GridLayout::USE_PREF, 0, 0); // Title.
1095 header_cs->AddPaddingColumn(0, 4);
1096 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
1097 GridLayout::USE_PREF, 0, 0); // Link.
1098 header_cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
1099 if (use_close_button_) {
1100 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
1101 GridLayout::USE_PREF, 0, 0); // Close Button.
1102 }
1103
1104 views::ColumnSet* full_cs = grid_layout->AddColumnSet(1);
1105 full_cs->AddColumn(GridLayout::FILL, GridLayout::FILL, 1.0,
1106 GridLayout::USE_PREF, 0, 0);
1107
1108 const WebIntentPickerModel::InstalledService* service = 1190 const WebIntentPickerModel::InstalledService* service =
1109 model_->GetInstalledServiceWithURL(model_->inline_disposition_url()); 1191 model_->GetInstalledServiceWithURL(model_->inline_disposition_url());
1110 1192
1111 // Header row. 1193 // Header.
1112 grid_layout->StartRow(0, 0); 1194 views::GridLayout* header_layout = new views::GridLayout(header_);
1113 views::ImageView* icon = new views::ImageView(); 1195 header_layout->SetInsets(kHeaderTopPadding, kHeaderLeftPadding,
1114 icon->SetImage(service->favicon.ToImageSkia()); 1196 kHeaderBottomPadding, kHeaderRightPadding);
1115 grid_layout->AddView(icon); 1197 header_->SetLayoutManager(header_layout);
1198 views::ColumnSet* header_view_cs = header_layout->AddColumnSet(0);
1199 header_view_cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
1200 GridLayout::USE_PREF, 0, 0); // Icon.
1201 header_view_cs->AddPaddingColumn(0, kIconLabelHorizontalSpacing);
1202 header_view_cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
1203 GridLayout::USE_PREF, 0, 0); // Title.
1204 if (show_use_another) {
1205 header_view_cs->AddPaddingColumn(0,
1206 views::kUnrelatedControlHorizontalSpacing);
1207 header_view_cs->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
1208 GridLayout::USE_PREF, 0, 0); // Use another app.
1209 }
1116 1210
1117 string16 elided_title = ui::ElideText( 1211 header_layout->StartRow(0, 0);
1118 service->title, gfx::Font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END); 1212 inline_intent_icon_->SetImage(service->favicon.ToImageSkia());
1119 views::Label* title = new views::Label(elided_title); 1213 header_layout->AddView(inline_intent_icon_);
1120 grid_layout->AddView(title); 1214 inline_intent_label_->SetText(ui::ElideText(service->title,
1215 inline_intent_label_->font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END));
1216 header_layout->AddView(inline_intent_label_);
1121 // Add link for "choose another service" if other suggestions are available 1217 // Add link for "choose another service" if other suggestions are available
1122 // or if more than one (the current) service is installed. 1218 // or if more than one (the current) service is installed.
1123 if (model_->GetInstalledServiceCount() > 1 || 1219 if (show_use_another) {
1124 model_->GetSuggestedExtensionCount()) { 1220 choose_another_service_link_->SetText(
1125 choose_another_service_link_ = new views::Link(
1126 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_USE_ALTERNATE_SERVICE)); 1221 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_USE_ALTERNATE_SERVICE));
1127 grid_layout->AddView(choose_another_service_link_);
1128 choose_another_service_link_->set_listener(this); 1222 choose_another_service_link_->set_listener(this);
1223 header_layout->AddView(choose_another_service_link_);
1129 } 1224 }
1130 1225
1131 if (use_close_button_) 1226 // Content.
1132 grid_layout->AddView(CreateCloseButton(this)); 1227 views::GridLayout* grid_layout = new views::GridLayout(contents_);
1228 grid_layout->SetInsets(kTopPadding, kLeftPadding, kBottomPadding,
1229 kRightPadding);
1230 contents_->SetLayoutManager(grid_layout);
1231
1232 grid_layout->AddColumnSet(kSeparatorRowColumnSet)->AddColumn(
1233 GridLayout::FILL, GridLayout::CENTER, 1, GridLayout::USE_PREF, 0, 0);
1234
1235 views::ColumnSet* full_cs =
1236 grid_layout->AddColumnSet(kWebContentsRowColumnSet);
1237 full_cs->AddPaddingColumn(0, kWebContentsLeftPadding);
1238 full_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 1,
1239 GridLayout::USE_PREF, 0, 0);
1240 full_cs->AddPaddingColumn(0, kWebContentsRightPadding);
1241
1242 // Separator row.
1243 grid_layout->StartRow(0, kSeparatorRowColumnSet);
1244 grid_layout->AddView(new views::Separator());
1245
1246 // Padding row.
1247 grid_layout->AddPaddingRow(0, kWebContentsTopPadding);
1133 1248
1134 // Inline web contents row. 1249 // Inline web contents row.
1135 grid_layout->StartRow(0, 1); 1250 grid_layout->StartRow(0, kWebContentsRowColumnSet);
1136 grid_layout->AddView(webview_, 1, 1, GridLayout::CENTER, 1251 grid_layout->AddView(webview_);
1137 GridLayout::CENTER, 0, 0); 1252
1138 contents_->Layout(); 1253 contents_->Layout();
1139 SizeToContents(); 1254 SizeToContents();
1140 displaying_web_contents_ = true; 1255 displaying_web_contents_ = true;
1141 } 1256 }
1142 1257
1143 void WebIntentPickerViews::OnModelChanged(WebIntentPickerModel* model) { 1258 void WebIntentPickerViews::OnModelChanged(WebIntentPickerModel* model) {
1144 if (waiting_view_ && !model->IsWaitingForSuggestions()) 1259 if (waiting_view_ && !model->IsWaitingForSuggestions())
1145 UpdateContents(); 1260 UpdateContents();
1146 1261
1262 string16 suggestions_label_text = model->GetSuggestionsLinkText();
1147 if (suggestions_label_) { 1263 if (suggestions_label_) {
1148 string16 label_text = model->GetSuggestionsLinkText(); 1264 suggestions_label_->SetText(suggestions_label_text);
1149 suggestions_label_->SetText(label_text); 1265 suggestions_label_->SetVisible(!suggestions_label_text.empty());
Peter Kasting 2012/10/12 03:23:32 Nit: It's really weird to have a view that is both
please use gerrit instead 2012/10/14 18:40:45 Done.
1150 suggestions_label_->SetVisible(!label_text.empty());
1151 } 1266 }
1152 1267
1153 if (extensions_) 1268 if (extensions_)
1154 extensions_->Update(); 1269 extensions_->Update();
1155 contents_->Layout(); 1270 contents_->Layout();
1156 SizeToContents(); 1271 SizeToContents();
1157 } 1272 }
1158 1273
1159 void WebIntentPickerViews::OnFaviconChanged(WebIntentPickerModel* model, 1274 void WebIntentPickerViews::OnFaviconChanged(WebIntentPickerModel* model,
1160 size_t index) { 1275 size_t index) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 void WebIntentPickerViews::OnActionButtonClicked( 1335 void WebIntentPickerViews::OnActionButtonClicked(
1221 IntentRowView::ActionType type, size_t tag) { 1336 IntentRowView::ActionType type, size_t tag) {
1222 DCHECK_EQ(IntentRowView::ACTION_INVOKE, type); 1337 DCHECK_EQ(IntentRowView::ACTION_INVOKE, type);
1223 const WebIntentPickerModel::InstalledService& service = 1338 const WebIntentPickerModel::InstalledService& service =
1224 model_->GetInstalledServiceAt(tag); 1339 model_->GetInstalledServiceAt(tag);
1225 delegate_->OnServiceChosen(service.url, service.disposition); 1340 delegate_->OnServiceChosen(service.url, service.disposition);
1226 } 1341 }
1227 1342
1228 void WebIntentPickerViews::UpdateContents() { 1343 void WebIntentPickerViews::UpdateContents() {
1229 if (model_ && model_->IsWaitingForSuggestions()) { 1344 if (model_ && model_->IsWaitingForSuggestions()) {
1230 ClearContents(); 1345 ShowWaitingForSuggestions();
1231 contents_->SetLayoutManager(new views::FillLayout());
1232 waiting_view_ = new WaitingView(this, use_close_button_);
1233 contents_->AddChildView(waiting_view_);
1234 int height = contents_->GetHeightForWidth(kWindowMinWidth);
1235 contents_->SetSize(gfx::Size(kWindowMinWidth, height));
1236 contents_->Layout();
1237 } else if (model_->GetInstalledServiceCount() || 1346 } else if (model_->GetInstalledServiceCount() ||
1238 model_->GetSuggestedExtensionCount()) { 1347 model_->GetSuggestedExtensionCount()) {
1239 ShowAvailableServices(); 1348 ShowAvailableServices();
1240 } else { 1349 } else {
1241 ShowNoServicesMessage(); 1350 ShowNoServicesMessage();
1242 } 1351 }
1243 SizeToContents(); 1352 SizeToContents();
1244 } 1353 }
1245 1354
1355 void WebIntentPickerViews::ShowWaitingForSuggestions() {
1356 ClearContents();
1357 contents_->SetLayoutManager(new views::FillLayout());
1358 waiting_view_ = new WaitingView();
1359 contents_->AddChildView(waiting_view_);
1360 int height = contents_->GetHeightForWidth(kWindowMinWidth);
1361 contents_->SetSize(gfx::Size(kWindowMinWidth, height));
1362 contents_->Layout();
1363 }
1364
1246 const string16 WebIntentPickerViews::GetActionTitle() { 1365 const string16 WebIntentPickerViews::GetActionTitle() {
1247 return (!action_text_.empty()) ? 1366 return (!action_text_.empty()) ? action_text_ :
1248 action_text_ :
1249 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_CHOOSE_SERVICE); 1367 l10n_util::GetStringUTF16(IDS_INTENT_PICKER_CHOOSE_SERVICE);
1250 } 1368 }
1251 1369
1252 void WebIntentPickerViews::ShowAvailableServices() { 1370 void WebIntentPickerViews::ShowAvailableServices() {
1253 enum { 1371 const int kHeaderTopBorder = 8;
1254 kHeaderRowColumnSet, // Column set for header layout. 1372 const int kHeaderLeftBorder = 0;
1255 kFullWidthColumnSet, // Column set with a single full-width column. 1373 const int kHeaderBottomBorder = 0;
1256 kIndentedFullWidthColumnSet, // Single full-width column, indented. 1374 const int kHeaderRightBorder = 0;
1257 }; 1375
1376 const int kTopPadding = 13;
1377 const int kLeftPadding = 20;
1378 const int kBottomPadding = 16;
1379 const int kRightPadding = 20;
1380
1381 const int kAppsSuggestionsSpacing = 14;
1258 1382
1259 ClearContents(); 1383 ClearContents();
1260 displaying_web_contents_ = false; 1384 displaying_web_contents_ = false;
1261
1262 extensions_ = new IntentsView(model_, this); 1385 extensions_ = new IntentsView(model_, this);
1263 1386
1387 // Header view.
1388 action_label_->SetText(GetActionTitle());
1389
1390 views::GridLayout* header_layout = new views::GridLayout(header_);
1391 header_->SetLayoutManager(header_layout);
1392 header_layout->SetInsets(kHeaderTopBorder, kHeaderLeftBorder,
1393 kHeaderBottomBorder, kHeaderRightBorder);
1394 header_layout->AddColumnSet(0)->AddColumn(GridLayout::LEADING,
1395 GridLayout::CENTER, 1, GridLayout::USE_PREF, 0, 0); // Action label
1396 header_layout->StartRow(0, 0);
1397 header_layout->AddView(action_label_);
1398
1399 // Content view.
1264 views::GridLayout* grid_layout = new views::GridLayout(contents_); 1400 views::GridLayout* grid_layout = new views::GridLayout(contents_);
1401 grid_layout->set_minimum_size(
1402 gfx::Size(extensions_->AdjustWidth(kWindowMinWidth), 0));
1403 grid_layout->SetInsets(kTopPadding, kLeftPadding, kBottomPadding,
1404 kRightPadding);
1265 contents_->SetLayoutManager(grid_layout); 1405 contents_->SetLayoutManager(grid_layout);
1266 1406
1267 grid_layout->set_minimum_size( 1407 grid_layout->AddColumnSet(0)->AddColumn(GridLayout::FILL, GridLayout::CENTER,
1268 gfx::Size(extensions_->AdjustWidth(kWindowMinWidth), 0)); 1408 1, GridLayout::USE_PREF, 0, 0); // Content.
1269 grid_layout->SetInsets(kContentAreaBorder, kContentAreaBorder,
1270 kContentAreaBorder, kContentAreaBorder);
1271 views::ColumnSet* header_cs = grid_layout->AddColumnSet(kHeaderRowColumnSet);
1272 header_cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
1273 GridLayout::USE_PREF, 0, 0); // Title.
1274 if (use_close_button_) {
1275 header_cs->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing);
1276 header_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
1277 GridLayout::USE_PREF, 0, 0); // Close Button.
1278 }
1279 1409
1280 views::ColumnSet* full_cs = grid_layout->AddColumnSet(kFullWidthColumnSet); 1410 // Row with extension suggestions.
1281 full_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, 1411 grid_layout->StartRow(0, 0);
1282 GridLayout::USE_PREF, 0, 0); 1412 grid_layout->AddView(extensions_);
1283 1413
1284 views::ColumnSet* indent_cs = 1414 // Padding row.
1285 grid_layout->AddColumnSet(kIndentedFullWidthColumnSet); 1415 grid_layout->AddPaddingRow(0, kAppsSuggestionsSpacing);
1286 indent_cs->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing);
1287 indent_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
1288 GridLayout::USE_PREF, 0, 0);
1289 1416
1290 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 1417 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1291 1418
1292 // Header row.
1293 grid_layout->StartRow(0, kHeaderRowColumnSet);
1294 action_label_ = new views::Label(GetActionTitle());
1295 action_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
1296 action_label_->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont));
1297 grid_layout->AddView(action_label_);
1298
1299 if (use_close_button_)
1300 grid_layout->AddView(CreateCloseButton(this));
1301
1302 // Padding row.
1303 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1304
1305 // Row with app suggestions label.
1306 grid_layout->StartRow(0, kIndentedFullWidthColumnSet);
1307 suggestions_label_ = new views::Label();
1308 suggestions_label_->SetVisible(false);
1309 suggestions_label_->SetMultiLine(true);
1310 suggestions_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
1311 grid_layout->AddView(suggestions_label_);
1312
1313 // Padding row.
1314 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1315
1316 // Row with extension suggestions.
1317 grid_layout->StartRow(0, kIndentedFullWidthColumnSet);
1318 grid_layout->AddView(extensions_);
1319
1320 // Padding row.
1321 grid_layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1322
1323 // Row with "more suggestions" link. 1419 // Row with "more suggestions" link.
1324 grid_layout->StartRow(0, kFullWidthColumnSet); 1420 grid_layout->StartRow(0, 0);
1325 views::View* more_view = new views::View(); 1421 views::View* more_view = new views::View();
1326 more_view->SetLayoutManager( 1422 more_view->SetLayoutManager(
1327 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 1423 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0,
1328 views::kRelatedControlHorizontalSpacing)); 1424 kIconLabelHorizontalSpacing));
1329 views::ImageView* icon = new views::ImageView(); 1425 views::ImageView* icon = new views::ImageView();
1330 icon->SetImage(rb.GetImageNamed(IDR_WEBSTORE_ICON_16).ToImageSkia()); 1426 icon->SetImage(rb.GetImageNamed(IDR_WEBSTORE_ICON_16).ToImageSkia());
1331 more_view->AddChildView(icon); 1427 more_view->AddChildView(icon);
1332 more_suggestions_link_ = new views::Link( 1428 more_suggestions_link_ = CreateLink();
1333 l10n_util::GetStringUTF16(IDS_FIND_MORE_INTENT_HANDLER_MESSAGE)); 1429 more_suggestions_link_->SetText(
1334 more_suggestions_link_->SetDisabledColor(kDisabledLinkColor); 1430 l10n_util::GetStringUTF16(IDS_FIND_MORE_INTENT_HANDLER_MESSAGE));
1335 more_suggestions_link_->set_listener(this); 1431 more_suggestions_link_->set_listener(this);
1336 more_view->AddChildView(more_suggestions_link_); 1432 more_view->AddChildView(more_suggestions_link_);
1337 grid_layout->AddView(more_view, 1, 1, 1433 grid_layout->AddView(more_view, 1, 1,
1338 GridLayout::LEADING, GridLayout::CENTER); 1434 GridLayout::LEADING, GridLayout::CENTER);
1435
1339 contents_->Layout(); 1436 contents_->Layout();
1340 } 1437 }
1341 1438
1342 void WebIntentPickerViews::ResetContents() { 1439 void WebIntentPickerViews::ResetContents() {
1343 // Abandon both web contents and webview. 1440 // Abandon both web contents and webview.
1344 webview_->SetWebContents(NULL); 1441 webview_->SetWebContents(NULL);
1345 inline_web_contents_.reset(); 1442 inline_web_contents_.reset();
1346 webview_ = NULL; 1443 webview_ = NULL;
1347 1444
1348 // Re-initialize the UI. 1445 // Re-initialize the UI.
1349 UpdateContents(); 1446 UpdateContents();
1350 1447
1351 // Restore previous state. 1448 // Restore previous state.
1352 extensions_->Update(); 1449 extensions_->Update();
1353 action_label_->SetText(action_text_); 1450 action_label_->SetText(action_text_);
1354 contents_->Layout(); 1451 contents_->Layout();
1355 SizeToContents(); 1452 SizeToContents();
1356 } 1453 }
1357 1454
1358 void WebIntentPickerViews::SizeToContents() { 1455 void WebIntentPickerViews::SizeToContents() {
1359 gfx::Size client_size = contents_->GetPreferredSize(); 1456 gfx::Size client_size = contents_->GetPreferredSize();
1360 gfx::Rect client_bounds(client_size); 1457 gfx::Rect client_bounds(client_size);
1361 gfx::Rect new_window_bounds = window_->non_client_view()->frame_view()-> 1458 gfx::Rect new_window_bounds = window_->non_client_view()->frame_view()->
1362 GetWindowBoundsForClientBounds(client_bounds); 1459 GetWindowBoundsForClientBounds(client_bounds);
1363 window_->CenterWindow(new_window_bounds.size()); 1460 window_->CenterWindow(new_window_bounds.size());
1364 } 1461 }
1365 1462
1366 void WebIntentPickerViews::ClearContents() { 1463 void WebIntentPickerViews::ClearContents() {
1367 DCHECK(contents_); 1464 DCHECK(contents_);
1465 DCHECK(header_);
1368 // The call RemoveAllChildViews(true) deletes all children of |contents|. If 1466 // The call RemoveAllChildViews(true) deletes all children of |contents|. If
1369 // we do not set our weak pointers to NULL, then they will continue to point 1467 // we do not set our weak pointers to NULL, then they will continue to point
1370 // to where the deleted objects used to be, i.e. unitialized memory. This 1468 // to where the deleted objects used to be, i.e. unitialized memory. This
1371 // would cause hard-to-explain crashes. 1469 // would cause hard-to-explain crashes.
1372 contents_->RemoveAllChildViews(true); 1470 contents_->RemoveAllChildViews(true);
1373 action_label_ = NULL; 1471 header_->RemoveAllChildViews(false);
1374 suggestions_label_ = NULL; 1472 suggestions_label_ = NULL;
1375 extensions_ = NULL; 1473 extensions_ = NULL;
1376 more_suggestions_link_ = NULL; 1474 more_suggestions_link_ = NULL;
1377 choose_another_service_link_ = NULL;
1378 } 1475 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698