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 "chrome/browser/ui/views/download/download_item_view_md.h" | 5 #include "chrome/browser/ui/views/download/download_item_view_md.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 using content::DownloadItem; | 65 using content::DownloadItem; |
66 using extensions::ExperienceSamplingEvent; | 66 using extensions::ExperienceSamplingEvent; |
67 | 67 |
68 namespace { | 68 namespace { |
69 | 69 |
70 // All values in dp. | 70 // All values in dp. |
71 const int kTextWidth = 140; | 71 const int kTextWidth = 140; |
72 const int kDangerousTextWidth = 200; | 72 const int kDangerousTextWidth = 200; |
73 | 73 |
74 // The normal height of the item which may be exceeded if text is large. | 74 // The normal height of the item which may be exceeded if text is large. |
75 const int kDefaultHeight = 36; | 75 const int kDefaultHeight = 48; |
| 76 |
| 77 // The vertical distance between the item's visual upper bound (as delineated by |
| 78 // the separator on the right) and the edge of the shelf. |
| 79 const int kTopBottomPadding = 6; |
76 | 80 |
77 // The minimum vertical padding above and below contents of the download item. | 81 // The minimum vertical padding above and below contents of the download item. |
78 // This is only used when the text size is large. | 82 // This is only used when the text size is large. |
79 const int kMinimumVerticalPadding = 2; | 83 const int kMinimumVerticalPadding = 2 + kTopBottomPadding; |
80 | 84 |
81 // Vertical padding between filename and status text. | 85 // Vertical padding between filename and status text. |
82 const int kVerticalTextPadding = 1; | 86 const int kVerticalTextPadding = 1; |
83 | 87 |
84 const int kTooltipMaxWidth = 800; | 88 const int kTooltipMaxWidth = 800; |
85 | 89 |
86 // Padding before the icon and at end of the item. TODO(estade): this needs to | 90 // Padding before the icon and at end of the item. |
87 // be used when drawing the non-warning dialog state. Currently we just use the | |
88 // built in padding for the progress indicator. | |
89 const int kStartPadding = 12; | 91 const int kStartPadding = 12; |
90 const int kEndPadding = 19; | 92 const int kEndPadding = 19; |
91 | 93 |
| 94 // Horizontal padding between progress indicator and filename/status text. |
| 95 const int kProgressTextPadding = 8; |
| 96 |
92 // The space between the Save and Discard buttons when prompting for a dangerous | 97 // The space between the Save and Discard buttons when prompting for a dangerous |
93 // download. | 98 // download. |
94 const int kButtonPadding = 5; | 99 const int kButtonPadding = 5; |
95 | 100 |
96 // The space on the left and right side of the dangerous download label. | 101 // The space on the left and right side of the dangerous download label. |
97 const int kLabelPadding = 8; | 102 const int kLabelPadding = 8; |
98 | 103 |
99 const SkColor kFileNameDisabledColor = SkColorSetRGB(171, 192, 212); | 104 const SkColor kFileNameDisabledColor = SkColorSetRGB(171, 192, 212); |
100 | 105 |
101 // How long the 'download complete' animation should last for. | 106 // How long the 'download complete' animation should last for. |
102 const int kCompleteAnimationDurationMs = 2500; | 107 const int kCompleteAnimationDurationMs = 2500; |
103 | 108 |
104 // How long the 'download interrupted' animation should last for. | 109 // How long the 'download interrupted' animation should last for. |
105 const int kInterruptedAnimationDurationMs = 2500; | 110 const int kInterruptedAnimationDurationMs = 2500; |
106 | 111 |
107 // How long we keep the item disabled after the user clicked it to open the | 112 // How long we keep the item disabled after the user clicked it to open the |
108 // downloaded item. | 113 // downloaded item. |
109 const int kDisabledOnOpenDuration = 3000; | 114 const int kDisabledOnOpenDuration = 3000; |
110 | 115 |
| 116 // The separator is drawn as a border. It's one dp wide. |
| 117 class SeparatorBorder : public views::Border { |
| 118 public: |
| 119 explicit SeparatorBorder(SkColor color) : color_(color) {} |
| 120 ~SeparatorBorder() override {} |
| 121 |
| 122 void Paint(const views::View& view, gfx::Canvas* canvas) override { |
| 123 int end_x = base::i18n::IsRTL() ? 0 : view.width() - 1; |
| 124 canvas->DrawLine(gfx::Point(end_x, kTopBottomPadding), |
| 125 gfx::Point(end_x, view.height() - kTopBottomPadding), |
| 126 color_); |
| 127 } |
| 128 |
| 129 gfx::Insets GetInsets() const override { return gfx::Insets(0, 0, 0, 1); } |
| 130 |
| 131 gfx::Size GetMinimumSize() const override { |
| 132 return gfx::Size(1, 2 * kTopBottomPadding + 1); |
| 133 } |
| 134 |
| 135 private: |
| 136 SkColor color_; |
| 137 |
| 138 DISALLOW_COPY_AND_ASSIGN(SeparatorBorder); |
| 139 }; |
| 140 |
111 } // namespace | 141 } // namespace |
112 | 142 |
113 DownloadItemViewMd::DownloadItemViewMd(DownloadItem* download_item, | 143 DownloadItemViewMd::DownloadItemViewMd(DownloadItem* download_item, |
114 DownloadShelfView* parent) | 144 DownloadShelfView* parent) |
115 : warning_icon_(nullptr), | 145 : warning_icon_(nullptr), |
116 shelf_(parent), | 146 shelf_(parent), |
117 status_text_(l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING)), | 147 status_text_(l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_STARTING)), |
118 dropdown_state_(NORMAL), | 148 dropdown_state_(NORMAL), |
119 mode_(NORMAL_MODE), | 149 mode_(NORMAL_MODE), |
120 dragging_(false), | 150 dragging_(false), |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 } | 346 } |
317 } | 347 } |
318 | 348 |
319 gfx::Size DownloadItemViewMd::GetPreferredSize() const { | 349 gfx::Size DownloadItemViewMd::GetPreferredSize() const { |
320 int width, height; | 350 int width, height; |
321 | 351 |
322 // First, we set the height to the height of two rows or text plus margins. | 352 // First, we set the height to the height of two rows or text plus margins. |
323 height = std::max(kDefaultHeight, | 353 height = std::max(kDefaultHeight, |
324 2 * kMinimumVerticalPadding + font_list_.GetBaseline() + | 354 2 * kMinimumVerticalPadding + font_list_.GetBaseline() + |
325 kVerticalTextPadding + status_font_list_.GetHeight()); | 355 kVerticalTextPadding + status_font_list_.GetHeight()); |
326 // Then we increase the size if the progress icon doesn't fit. | |
327 height = std::max<int>(height, DownloadShelf::kProgressIndicatorSize); | |
328 | 356 |
329 if (IsShowingWarningDialog()) { | 357 if (IsShowingWarningDialog()) { |
330 width = kStartPadding + warning_icon_->width() + kLabelPadding + | 358 width = kStartPadding + warning_icon_->width() + kLabelPadding + |
331 dangerous_download_label_->width() + kLabelPadding; | 359 dangerous_download_label_->width() + kLabelPadding; |
332 gfx::Size button_size = GetButtonSize(); | 360 gfx::Size button_size = GetButtonSize(); |
333 // Make sure the button fits. | 361 // Make sure the button fits. |
334 height = std::max<int>(height, | 362 height = std::max<int>(height, |
335 2 * kMinimumVerticalPadding + button_size.height()); | 363 2 * kMinimumVerticalPadding + button_size.height()); |
336 // Then we make sure the warning icon fits. | 364 // Then we make sure the warning icon fits. |
337 height = std::max<int>( | 365 height = std::max<int>( |
338 height, 2 * kMinimumVerticalPadding + warning_icon_->height()); | 366 height, 2 * kMinimumVerticalPadding + warning_icon_->height()); |
339 if (save_button_) | 367 if (save_button_) |
340 width += button_size.width() + kButtonPadding; | 368 width += button_size.width() + kButtonPadding; |
341 width += button_size.width() + kEndPadding; | 369 width += button_size.width() + kEndPadding; |
342 } else { | 370 } else { |
343 width = kStartPadding + DownloadShelf::kProgressIndicatorSize + kTextWidth + | 371 width = kStartPadding + DownloadShelf::kProgressIndicatorSize + |
344 kEndPadding; | 372 kProgressTextPadding + kTextWidth + kEndPadding; |
345 } | 373 } |
346 return gfx::Size(width, height); | 374 return gfx::Size(width, height); |
347 } | 375 } |
348 | 376 |
349 // Handle a mouse click and open the context menu if the mouse is | 377 // Handle a mouse click and open the context menu if the mouse is |
350 // over the drop-down region. | 378 // over the drop-down region. |
351 bool DownloadItemViewMd::OnMousePressed(const ui::MouseEvent& event) { | 379 bool DownloadItemViewMd::OnMousePressed(const ui::MouseEvent& event) { |
352 HandlePressEvent(event, event.IsOnlyLeftMouseButton()); | 380 HandlePressEvent(event, event.IsOnlyLeftMouseButton()); |
353 return true; | 381 return true; |
354 } | 382 } |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 if (!status_text_.empty()) | 575 if (!status_text_.empty()) |
548 text_height += kVerticalTextPadding + status_font_list_.GetBaseline(); | 576 text_height += kVerticalTextPadding + status_font_list_.GetBaseline(); |
549 return (height() - text_height) / 2; | 577 return (height() - text_height) / 2; |
550 } | 578 } |
551 | 579 |
552 void DownloadItemViewMd::DrawStatusText(gfx::Canvas* canvas) { | 580 void DownloadItemViewMd::DrawStatusText(gfx::Canvas* canvas) { |
553 if (status_text_.empty() || IsShowingWarningDialog()) | 581 if (status_text_.empty() || IsShowingWarningDialog()) |
554 return; | 582 return; |
555 | 583 |
556 int mirrored_x = GetMirroredXWithWidthInView( | 584 int mirrored_x = GetMirroredXWithWidthInView( |
557 DownloadShelf::kProgressIndicatorSize, kTextWidth); | 585 kStartPadding + DownloadShelf::kProgressIndicatorSize + |
| 586 kProgressTextPadding, |
| 587 kTextWidth); |
558 int y = | 588 int y = |
559 GetYForFilenameText() + font_list_.GetBaseline() + kVerticalTextPadding; | 589 GetYForFilenameText() + font_list_.GetBaseline() + kVerticalTextPadding; |
560 SkColor file_name_color = SkColorSetA( | 590 SkColor file_name_color = SkColorSetA( |
561 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT), 0xC7); | 591 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT), 0xC7); |
562 canvas->DrawStringRect( | 592 canvas->DrawStringRect( |
563 status_text_, status_font_list_, file_name_color, | 593 status_text_, status_font_list_, file_name_color, |
564 gfx::Rect(mirrored_x, y, kTextWidth, status_font_list_.GetHeight())); | 594 gfx::Rect(mirrored_x, y, kTextWidth, status_font_list_.GetHeight())); |
565 } | 595 } |
566 | 596 |
567 void DownloadItemViewMd::DrawFilename(gfx::Canvas* canvas) { | 597 void DownloadItemViewMd::DrawFilename(gfx::Canvas* canvas) { |
(...skipping 15 matching lines...) Expand all Loading... |
583 // Then, elide the file name. | 613 // Then, elide the file name. |
584 base::string16 filename_string = | 614 base::string16 filename_string = |
585 gfx::ElideFilename(download()->GetFileNameToReportUser(), font_list_, | 615 gfx::ElideFilename(download()->GetFileNameToReportUser(), font_list_, |
586 kTextWidth - status_string_width); | 616 kTextWidth - status_string_width); |
587 // Last, concat the whole string. | 617 // Last, concat the whole string. |
588 filename = l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_OPENING, | 618 filename = l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_OPENING, |
589 filename_string); | 619 filename_string); |
590 } | 620 } |
591 | 621 |
592 int mirrored_x = GetMirroredXWithWidthInView( | 622 int mirrored_x = GetMirroredXWithWidthInView( |
593 DownloadShelf::kProgressIndicatorSize, kTextWidth); | 623 kStartPadding + DownloadShelf::kProgressIndicatorSize + |
| 624 kProgressTextPadding, |
| 625 kTextWidth); |
594 SkColor file_name_color = | 626 SkColor file_name_color = |
595 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT); | 627 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT); |
596 | 628 |
597 canvas->DrawStringRect(filename, font_list_, | 629 canvas->DrawStringRect(filename, font_list_, |
598 enabled() ? file_name_color : kFileNameDisabledColor, | 630 enabled() ? file_name_color : kFileNameDisabledColor, |
599 gfx::Rect(mirrored_x, GetYForFilenameText(), | 631 gfx::Rect(mirrored_x, GetYForFilenameText(), |
600 kTextWidth, font_list_.GetHeight())); | 632 kTextWidth, font_list_.GetHeight())); |
601 } | 633 } |
602 | 634 |
603 void DownloadItemViewMd::DrawIcon(gfx::Canvas* canvas) { | 635 void DownloadItemViewMd::DrawIcon(gfx::Canvas* canvas) { |
604 if (IsShowingWarningDialog()) { | 636 if (IsShowingWarningDialog()) { |
605 int icon_x = kStartPadding; | 637 int icon_x = base::i18n::IsRTL() |
| 638 ? width() - warning_icon_->width() - kStartPadding |
| 639 : kStartPadding; |
606 int icon_y = (height() - warning_icon_->height()) / 2; | 640 int icon_y = (height() - warning_icon_->height()) / 2; |
607 canvas->DrawImageInt(*warning_icon_, icon_x, icon_y); | 641 canvas->DrawImageInt(*warning_icon_, icon_x, icon_y); |
608 return; | 642 return; |
609 } | 643 } |
610 | 644 |
611 // Paint download progress. | 645 // Paint download progress. |
612 DownloadItem::DownloadState state = download()->GetState(); | 646 DownloadItem::DownloadState state = download()->GetState(); |
613 canvas->Save(); | 647 canvas->Save(); |
614 if (base::i18n::IsRTL()) { | 648 int progress_x = |
615 canvas->Translate( | 649 base::i18n::IsRTL() |
616 gfx::Vector2d(width() - DownloadShelf::kProgressIndicatorSize, 0)); | 650 ? width() - kStartPadding - DownloadShelf::kProgressIndicatorSize |
617 } | 651 : kStartPadding; |
| 652 int progress_y = (height() - DownloadShelf::kProgressIndicatorSize) / 2; |
| 653 canvas->Translate(gfx::Vector2d(progress_x, progress_y)); |
618 | 654 |
619 if (state == DownloadItem::IN_PROGRESS) { | 655 if (state == DownloadItem::IN_PROGRESS) { |
620 base::TimeDelta progress_time = previous_progress_elapsed_; | 656 base::TimeDelta progress_time = previous_progress_elapsed_; |
621 if (!download()->IsPaused()) | 657 if (!download()->IsPaused()) |
622 progress_time += base::TimeTicks::Now() - progress_start_time_; | 658 progress_time += base::TimeTicks::Now() - progress_start_time_; |
623 DownloadShelf::PaintDownloadProgress( | 659 DownloadShelf::PaintDownloadProgress( |
624 canvas, *GetThemeProvider(), progress_time, model_.PercentComplete()); | 660 canvas, *GetThemeProvider(), progress_time, model_.PercentComplete()); |
625 } else if (complete_animation_.get() && complete_animation_->is_animating()) { | 661 } else if (complete_animation_.get() && complete_animation_->is_animating()) { |
626 if (state == DownloadItem::INTERRUPTED) { | 662 if (state == DownloadItem::INTERRUPTED) { |
627 DownloadShelf::PaintDownloadInterrupted( | 663 DownloadShelf::PaintDownloadInterrupted( |
628 canvas, *GetThemeProvider(), complete_animation_->GetCurrentValue()); | 664 canvas, *GetThemeProvider(), complete_animation_->GetCurrentValue()); |
629 } else { | 665 } else { |
630 DCHECK_EQ(DownloadItem::COMPLETE, state); | 666 DCHECK_EQ(DownloadItem::COMPLETE, state); |
631 DownloadShelf::PaintDownloadComplete( | 667 DownloadShelf::PaintDownloadComplete( |
632 canvas, *GetThemeProvider(), complete_animation_->GetCurrentValue()); | 668 canvas, *GetThemeProvider(), complete_animation_->GetCurrentValue()); |
633 } | 669 } |
634 } | 670 } |
635 canvas->Restore(); | 671 canvas->Restore(); |
636 | 672 |
637 // Fetch the already-loaded icon. | 673 // Fetch the already-loaded icon. |
638 IconManager* im = g_browser_process->icon_manager(); | 674 IconManager* im = g_browser_process->icon_manager(); |
639 gfx::Image* icon = im->LookupIconFromFilepath(download()->GetTargetFilePath(), | 675 gfx::Image* icon = im->LookupIconFromFilepath(download()->GetTargetFilePath(), |
640 IconLoader::SMALL); | 676 IconLoader::SMALL); |
641 if (!icon) | 677 if (!icon) |
642 return; | 678 return; |
643 | 679 |
644 // Draw the icon image. | 680 // Draw the icon image. |
645 int icon_x = DownloadShelf::kFiletypeIconOffset; | 681 int icon_x = progress_x + DownloadShelf::kFiletypeIconOffset; |
646 icon_x = GetMirroredXWithWidthInView(icon_x, icon->Width()); | 682 int icon_y = progress_y + DownloadShelf::kFiletypeIconOffset; |
647 int icon_y = DownloadShelf::kFiletypeIconOffset; | |
648 | |
649 SkPaint paint; | 683 SkPaint paint; |
650 // Use an alpha to make the image look disabled. | 684 // Use an alpha to make the image look disabled. |
651 if (!enabled()) | 685 if (!enabled()) |
652 paint.setAlpha(120); | 686 paint.setAlpha(120); |
653 canvas->DrawImageInt(*icon->ToImageSkia(), icon_x, icon_y, paint); | 687 canvas->DrawImageInt(*icon->ToImageSkia(), icon_x, icon_y, paint); |
654 } | 688 } |
655 | 689 |
656 void DownloadItemViewMd::OnFocus() { | 690 void DownloadItemViewMd::OnFocus() { |
657 View::OnFocus(); | 691 View::OnFocus(); |
658 // We render differently when focused. | 692 // We render differently when focused. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
722 } | 756 } |
723 | 757 |
724 void DownloadItemViewMd::UpdateColorsFromTheme() { | 758 void DownloadItemViewMd::UpdateColorsFromTheme() { |
725 if (!GetThemeProvider()) | 759 if (!GetThemeProvider()) |
726 return; | 760 return; |
727 | 761 |
728 if (dangerous_download_label_) { | 762 if (dangerous_download_label_) { |
729 dangerous_download_label_->SetEnabledColor( | 763 dangerous_download_label_->SetEnabledColor( |
730 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)); | 764 GetThemeProvider()->GetColor(ThemeProperties::COLOR_BOOKMARK_TEXT)); |
731 } | 765 } |
732 SetBorder(views::Border::CreateSolidSidedBorder( | 766 SetBorder(make_scoped_ptr(new SeparatorBorder( |
733 0, 0, 0, 1, | 767 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR_SEPARATOR)))); |
734 GetThemeProvider()->GetColor(ThemeProperties::COLOR_TOOLBAR_SEPARATOR))); | |
735 } | 768 } |
736 | 769 |
737 void DownloadItemViewMd::ShowContextMenuImpl(const gfx::Rect& rect, | 770 void DownloadItemViewMd::ShowContextMenuImpl(const gfx::Rect& rect, |
738 ui::MenuSourceType source_type) { | 771 ui::MenuSourceType source_type) { |
739 // Similar hack as in MenuButton. | 772 // Similar hack as in MenuButton. |
740 // We're about to show the menu from a mouse press. By showing from the | 773 // We're about to show the menu from a mouse press. By showing from the |
741 // mouse press event we block RootView in mouse dispatching. This also | 774 // mouse press event we block RootView in mouse dispatching. This also |
742 // appears to cause RootView to get a mouse pressed BEFORE the mouse | 775 // appears to cause RootView to get a mouse pressed BEFORE the mouse |
743 // release is seen, which means RootView sends us another mouse press no | 776 // release is seen, which means RootView sends us another mouse press no |
744 // matter where the user pressed. To force RootView to recalculate the | 777 // matter where the user pressed. To force RootView to recalculate the |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 State to, | 1063 State to, |
1031 gfx::SlideAnimation* animation) { | 1064 gfx::SlideAnimation* animation) { |
1032 if (from == NORMAL && to == HOT) { | 1065 if (from == NORMAL && to == HOT) { |
1033 animation->Show(); | 1066 animation->Show(); |
1034 } else if (from == HOT && to == NORMAL) { | 1067 } else if (from == HOT && to == NORMAL) { |
1035 animation->Hide(); | 1068 animation->Hide(); |
1036 } else if (from != to) { | 1069 } else if (from != to) { |
1037 animation->Reset((to == HOT) ? 1.0 : 0.0); | 1070 animation->Reset((to == HOT) ? 1.0 : 0.0); |
1038 } | 1071 } |
1039 } | 1072 } |
OLD | NEW |