Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |