| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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/views/download_item_view.h" | 5 #include "chrome/browser/views/download_item_view.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "app/gfx/canvas.h" | 9 #include "app/gfx/canvas.h" |
| 10 #include "app/gfx/text_elider.h" | 10 #include "app/gfx/text_elider.h" |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 dragging_(false), | 145 dragging_(false), |
| 146 starting_drag_(false), | 146 starting_drag_(false), |
| 147 model_(model), | 147 model_(model), |
| 148 save_button_(NULL), | 148 save_button_(NULL), |
| 149 discard_button_(NULL), | 149 discard_button_(NULL), |
| 150 dangerous_download_label_(NULL), | 150 dangerous_download_label_(NULL), |
| 151 dangerous_download_label_sized_(false), | 151 dangerous_download_label_sized_(false), |
| 152 disabled_while_opening_(false), | 152 disabled_while_opening_(false), |
| 153 creation_time_(base::Time::Now()), | 153 creation_time_(base::Time::Now()), |
| 154 ALLOW_THIS_IN_INITIALIZER_LIST(reenable_method_factory_(this)) { | 154 ALLOW_THIS_IN_INITIALIZER_LIST(reenable_method_factory_(this)) { |
| 155 // TODO(idana) Bug# 1163334 | |
| 156 // | |
| 157 // We currently do not mirror each download item on the download shelf (even | |
| 158 // though the download shelf itself is mirrored and the items appear from | |
| 159 // right to left on RTL UIs). | |
| 160 // | |
| 161 // We explicitly disable mirroring for the item because the code that draws | |
| 162 // the download progress animation relies on the View's UI layout setting | |
| 163 // when positioning the animation so we should make sure that code doesn't | |
| 164 // treat our View as a mirrored View. | |
| 165 EnableUIMirroringForRTLLanguages(false); | |
| 166 DCHECK(download_); | 155 DCHECK(download_); |
| 167 download_->AddObserver(this); | 156 download_->AddObserver(this); |
| 168 | 157 |
| 169 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); | 158 ResourceBundle &rb = ResourceBundle::GetSharedInstance(); |
| 170 | 159 |
| 171 BodyImageSet normal_body_image_set = { | 160 BodyImageSet normal_body_image_set = { |
| 172 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP), | 161 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_TOP), |
| 173 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE), | 162 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_MIDDLE), |
| 174 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM), | 163 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_LEFT_BOTTOM), |
| 175 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP), | 164 rb.GetBitmapNamed(IDR_DOWNLOAD_BUTTON_CENTER_TOP), |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 (drop_down_image_set ? | 467 (drop_down_image_set ? |
| 479 normal_drop_down_image_set_.center->width() : | 468 normal_drop_down_image_set_.center->width() : |
| 480 0); | 469 0); |
| 481 | 470 |
| 482 // May be caused by animation. | 471 // May be caused by animation. |
| 483 if (center_width <= 0) | 472 if (center_width <= 0) |
| 484 return; | 473 return; |
| 485 | 474 |
| 486 // Paint the background images. | 475 // Paint the background images. |
| 487 int x = kLeftPadding; | 476 int x = kLeftPadding; |
| 477 bool rtl_ui = UILayoutIsRightToLeft(); |
| 478 if (rtl_ui) { |
| 479 // Since we do not have the mirrored images for |
| 480 // (hot_)body_image_set->top_left, (hot_)body_image_set->left, |
| 481 // (hot_)body_image_set->bottom_left, and drop_down_image_set, |
| 482 // for RTL UI, we flip the canvas to draw those images mirrored. |
| 483 // Consequently, we do not need to mirror the x-axis of those images. |
| 484 canvas->save(); |
| 485 canvas->TranslateInt(width(), 0); |
| 486 canvas->ScaleInt(-1, 1); |
| 487 } |
| 488 PaintBitmaps(canvas, | 488 PaintBitmaps(canvas, |
| 489 body_image_set->top_left, body_image_set->left, | 489 body_image_set->top_left, body_image_set->left, |
| 490 body_image_set->bottom_left, | 490 body_image_set->bottom_left, |
| 491 x, box_y_, box_height_, body_image_set->top_left->width()); | 491 x, box_y_, box_height_, body_image_set->top_left->width()); |
| 492 x += body_image_set->top_left->width(); | 492 x += body_image_set->top_left->width(); |
| 493 PaintBitmaps(canvas, | 493 PaintBitmaps(canvas, |
| 494 body_image_set->top, body_image_set->center, | 494 body_image_set->top, body_image_set->center, |
| 495 body_image_set->bottom, | 495 body_image_set->bottom, |
| 496 x, box_y_, box_height_, center_width); | 496 x, box_y_, box_height_, center_width); |
| 497 x += center_width; | 497 x += center_width; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 517 hot_body_image_set_.top, hot_body_image_set_.center, | 517 hot_body_image_set_.top, hot_body_image_set_.center, |
| 518 hot_body_image_set_.bottom, | 518 hot_body_image_set_.bottom, |
| 519 x, box_y_, box_height_, center_width); | 519 x, box_y_, box_height_, center_width); |
| 520 x += center_width; | 520 x += center_width; |
| 521 PaintBitmaps(canvas, | 521 PaintBitmaps(canvas, |
| 522 hot_body_image_set_.top_right, hot_body_image_set_.right, | 522 hot_body_image_set_.top_right, hot_body_image_set_.right, |
| 523 hot_body_image_set_.bottom_right, | 523 hot_body_image_set_.bottom_right, |
| 524 x, box_y_, box_height_, | 524 x, box_y_, box_height_, |
| 525 hot_body_image_set_.top_right->width()); | 525 hot_body_image_set_.top_right->width()); |
| 526 canvas->restore(); | 526 canvas->restore(); |
| 527 if (rtl_ui) { |
| 528 canvas->restore(); |
| 529 canvas->save(); |
| 530 // Flip it for drawing drop-down images for RTL locales. |
| 531 canvas->TranslateInt(width(), 0); |
| 532 canvas->ScaleInt(-1, 1); |
| 533 } |
| 527 } | 534 } |
| 528 | 535 |
| 529 x += body_image_set->top_right->width(); | 536 x += body_image_set->top_right->width(); |
| 530 | 537 |
| 531 // Paint the drop-down. | 538 // Paint the drop-down. |
| 532 if (drop_down_image_set) { | 539 if (drop_down_image_set) { |
| 533 PaintBitmaps(canvas, | 540 PaintBitmaps(canvas, |
| 534 drop_down_image_set->top, drop_down_image_set->center, | 541 drop_down_image_set->top, drop_down_image_set->center, |
| 535 drop_down_image_set->bottom, | 542 drop_down_image_set->bottom, |
| 536 x, box_y_, box_height_, drop_down_image_set->top->width()); | 543 x, box_y_, box_height_, drop_down_image_set->top->width()); |
| 537 | 544 |
| 538 // Overlay our drop-down hot state. | 545 // Overlay our drop-down hot state. |
| 539 if (drop_hover_animation_->GetCurrentValue() > 0) { | 546 if (drop_hover_animation_->GetCurrentValue() > 0) { |
| 540 canvas->saveLayerAlpha(NULL, | 547 canvas->saveLayerAlpha(NULL, |
| 541 static_cast<int>(drop_hover_animation_->GetCurrentValue() * 255), | 548 static_cast<int>(drop_hover_animation_->GetCurrentValue() * 255), |
| 542 SkCanvas::kARGB_NoClipLayer_SaveFlag); | 549 SkCanvas::kARGB_NoClipLayer_SaveFlag); |
| 543 canvas->drawARGB(0, 255, 255, 255, SkPorterDuff::kClear_Mode); | 550 canvas->drawARGB(0, 255, 255, 255, SkPorterDuff::kClear_Mode); |
| 544 | 551 |
| 545 PaintBitmaps(canvas, | 552 PaintBitmaps(canvas, |
| 546 drop_down_image_set->top, drop_down_image_set->center, | 553 drop_down_image_set->top, drop_down_image_set->center, |
| 547 drop_down_image_set->bottom, | 554 drop_down_image_set->bottom, |
| 548 x, box_y_, box_height_, drop_down_image_set->top->width()); | 555 x, box_y_, box_height_, drop_down_image_set->top->width()); |
| 549 | 556 |
| 550 canvas->restore(); | 557 canvas->restore(); |
| 551 } | 558 } |
| 552 } | 559 } |
| 553 | 560 |
| 561 if (rtl_ui) { |
| 562 // Restore the canvas to avoid file name etc. text are drawn flipped. |
| 563 // Consequently, the x-axis of following canvas->DrawXXX() method should be |
| 564 // mirrored so the text and images are down in the right positions. |
| 565 canvas->restore(); |
| 566 } |
| 567 |
| 554 // Print the text, left aligned and always print the file extension. | 568 // Print the text, left aligned and always print the file extension. |
| 555 // Last value of x was the end of the right image, just before the button. | 569 // Last value of x was the end of the right image, just before the button. |
| 556 // Note that in dangerous mode we use a label (as the text is multi-line). | 570 // Note that in dangerous mode we use a label (as the text is multi-line). |
| 557 if (!IsDangerousMode()) { | 571 if (!IsDangerousMode()) { |
| 558 std::wstring filename; | 572 std::wstring filename; |
| 559 if (!disabled_while_opening_) { | 573 if (!disabled_while_opening_) { |
| 560 filename = gfx::ElideFilename(download_->GetFileName(), | 574 filename = gfx::ElideFilename(download_->GetFileName(), |
| 561 font_, kTextWidth); | 575 font_, kTextWidth); |
| 562 } else { | 576 } else { |
| 563 std::wstring tmp_name = | 577 std::wstring tmp_name = |
| 564 l10n_util::GetStringF(IDS_DOWNLOAD_STATUS_OPENING, | 578 l10n_util::GetStringF(IDS_DOWNLOAD_STATUS_OPENING, |
| 565 download_->GetFileName().ToWStringHack()); | 579 download_->GetFileName().ToWStringHack()); |
| 566 #if defined(OS_WIN) | 580 #if defined(OS_WIN) |
| 567 FilePath filepath(tmp_name); | 581 FilePath filepath(tmp_name); |
| 568 #else | 582 #else |
| 569 FilePath filepath(base::SysWideToNativeMB(tmp_name)); | 583 FilePath filepath(base::SysWideToNativeMB(tmp_name)); |
| 570 #endif | 584 #endif |
| 571 filename = gfx::ElideFilename(filepath, font_, kTextWidth); | 585 filename = gfx::ElideFilename(filepath, font_, kTextWidth); |
| 572 } | 586 } |
| 573 | 587 |
| 588 int mirrored_x = MirroredXWithWidthInsideView( |
| 589 download_util::kSmallProgressIconSize, kTextWidth); |
| 574 if (show_status_text_) { | 590 if (show_status_text_) { |
| 575 int y = box_y_ + kVerticalPadding; | 591 int y = box_y_ + kVerticalPadding; |
| 576 | 592 |
| 577 // Draw the file's name. | 593 // Draw the file's name. |
| 578 canvas->DrawStringInt(filename, font_, | 594 canvas->DrawStringInt(filename, font_, |
| 579 IsEnabled() ? kFileNameColor : | 595 IsEnabled() ? kFileNameColor : |
| 580 kFileNameDisabledColor, | 596 kFileNameDisabledColor, |
| 581 download_util::kSmallProgressIconSize, y, | 597 mirrored_x, y, kTextWidth, font_.height()); |
| 582 kTextWidth, font_.height()); | |
| 583 | 598 |
| 584 y += font_.height() + kVerticalTextPadding; | 599 y += font_.height() + kVerticalTextPadding; |
| 585 | 600 |
| 586 canvas->DrawStringInt(status_text_, font_, kStatusColor, | 601 canvas->DrawStringInt(status_text_, font_, kStatusColor, mirrored_x, y, |
| 587 download_util::kSmallProgressIconSize, y, | |
| 588 kTextWidth, font_.height()); | 602 kTextWidth, font_.height()); |
| 589 } else { | 603 } else { |
| 590 int y = box_y_ + (box_height_ - font_.height()) / 2; | 604 int y = box_y_ + (box_height_ - font_.height()) / 2; |
| 591 | 605 |
| 592 // Draw the file's name. | 606 // Draw the file's name. |
| 593 canvas->DrawStringInt(filename, font_, | 607 canvas->DrawStringInt(filename, font_, |
| 594 IsEnabled() ? kFileNameColor : | 608 IsEnabled() ? kFileNameColor : |
| 595 kFileNameDisabledColor, | 609 kFileNameDisabledColor, |
| 596 download_util::kSmallProgressIconSize, y, | 610 mirrored_x, y, kTextWidth, font_.height()); |
| 597 kTextWidth, font_.height()); | |
| 598 } | 611 } |
| 599 } | 612 } |
| 600 | 613 |
| 601 // Paint the icon. | 614 // Paint the icon. |
| 602 IconManager* im = g_browser_process->icon_manager(); | 615 IconManager* im = g_browser_process->icon_manager(); |
| 603 SkBitmap* icon = IsDangerousMode() ? warning_icon_ : | 616 SkBitmap* icon = IsDangerousMode() ? warning_icon_ : |
| 604 im->LookupIcon(download_->full_path(), IconLoader::SMALL); | 617 im->LookupIcon(download_->full_path(), IconLoader::SMALL); |
| 605 | 618 |
| 606 // We count on the fact that the icon manager will cache the icons and if one | 619 // We count on the fact that the icon manager will cache the icons and if one |
| 607 // is available, it will be cached here. We *don't* want to request the icon | 620 // is available, it will be cached here. We *don't* want to request the icon |
| (...skipping 10 matching lines...) Expand all Loading... |
| 618 } else if (download_->state() == DownloadItem::COMPLETE && | 631 } else if (download_->state() == DownloadItem::COMPLETE && |
| 619 complete_animation_.get() && | 632 complete_animation_.get() && |
| 620 complete_animation_->IsAnimating()) { | 633 complete_animation_->IsAnimating()) { |
| 621 download_util::PaintDownloadComplete(canvas, this, 0, 0, | 634 download_util::PaintDownloadComplete(canvas, this, 0, 0, |
| 622 complete_animation_->GetCurrentValue(), | 635 complete_animation_->GetCurrentValue(), |
| 623 download_util::SMALL); | 636 download_util::SMALL); |
| 624 } | 637 } |
| 625 } | 638 } |
| 626 | 639 |
| 627 // Draw the icon image. | 640 // Draw the icon image. |
| 641 int mirrored_x = MirroredXWithWidthInsideView( |
| 642 download_util::kSmallProgressIconOffset, icon->width()); |
| 628 if (IsEnabled()) { | 643 if (IsEnabled()) { |
| 629 canvas->DrawBitmapInt(*icon, | 644 canvas->DrawBitmapInt(*icon, mirrored_x, |
| 630 download_util::kSmallProgressIconOffset, | |
| 631 download_util::kSmallProgressIconOffset); | 645 download_util::kSmallProgressIconOffset); |
| 632 } else { | 646 } else { |
| 633 // Use an alpha to make the image look disabled. | 647 // Use an alpha to make the image look disabled. |
| 634 SkPaint paint; | 648 SkPaint paint; |
| 635 paint.setAlpha(120); | 649 paint.setAlpha(120); |
| 636 canvas->DrawBitmapInt(*icon, | 650 canvas->DrawBitmapInt(*icon, mirrored_x, |
| 637 download_util::kSmallProgressIconOffset, | 651 download_util::kSmallProgressIconOffset, paint); |
| 638 download_util::kSmallProgressIconOffset, | |
| 639 paint); | |
| 640 } | 652 } |
| 641 } | 653 } |
| 642 } | 654 } |
| 643 | 655 |
| 644 void DownloadItemView::PaintBitmaps(gfx::Canvas* canvas, | 656 void DownloadItemView::PaintBitmaps(gfx::Canvas* canvas, |
| 645 const SkBitmap* top_bitmap, | 657 const SkBitmap* top_bitmap, |
| 646 const SkBitmap* center_bitmap, | 658 const SkBitmap* center_bitmap, |
| 647 const SkBitmap* bottom_bitmap, | 659 const SkBitmap* bottom_bitmap, |
| 648 int x, int y, int height, int width) { | 660 int x, int y, int height, int width) { |
| 649 int middle_height = height - top_bitmap->height() - bottom_bitmap->height(); | 661 int middle_height = height - top_bitmap->height() - bottom_bitmap->height(); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 764 // appears to cause RootView to get a mouse pressed BEFORE the mouse | 776 // appears to cause RootView to get a mouse pressed BEFORE the mouse |
| 765 // release is seen, which means RootView sends us another mouse press no | 777 // release is seen, which means RootView sends us another mouse press no |
| 766 // matter where the user pressed. To force RootView to recalculate the | 778 // matter where the user pressed. To force RootView to recalculate the |
| 767 // mouse target during the mouse press we explicitly set the mouse handler | 779 // mouse target during the mouse press we explicitly set the mouse handler |
| 768 // to NULL. | 780 // to NULL. |
| 769 GetRootView()->SetMouseHandler(NULL); | 781 GetRootView()->SetMouseHandler(NULL); |
| 770 | 782 |
| 771 // The menu's position is different depending on the UI layout. | 783 // The menu's position is different depending on the UI layout. |
| 772 // DownloadShelfContextMenu will take care of setting the right anchor for | 784 // DownloadShelfContextMenu will take care of setting the right anchor for |
| 773 // the menu depending on the locale. | 785 // the menu depending on the locale. |
| 774 // | |
| 775 // TODO(idana): when bug# 1163334 is fixed the following check should be | |
| 776 // replaced with UILayoutIsRightToLeft(). | |
| 777 point.set_y(height()); | 786 point.set_y(height()); |
| 778 if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) { | 787 if (UILayoutIsRightToLeft()) { |
| 779 point.set_x(width()); | 788 point.set_x(width()); |
| 780 } else { | 789 } else { |
| 781 point.set_x(drop_down_x_); | 790 point.set_x(drop_down_x_); |
| 782 } | 791 } |
| 783 | 792 |
| 784 views::View::ConvertPointToScreen(this, &point); | 793 views::View::ConvertPointToScreen(this, &point); |
| 785 DownloadShelfContextMenuWin menu(model_.get(), | 794 DownloadShelfContextMenuWin menu(model_.get(), |
| 786 GetWidget()->GetNativeView(), | 795 GetWidget()->GetNativeView(), |
| 787 point); | 796 point); |
| 788 drop_down_pressed_ = false; | 797 drop_down_pressed_ = false; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 size = dangerous_download_label_->GetPreferredSize(); | 957 size = dangerous_download_label_->GetPreferredSize(); |
| 949 | 958 |
| 950 dangerous_download_label_->SetBounds(0, 0, size.width(), size.height()); | 959 dangerous_download_label_->SetBounds(0, 0, size.width(), size.height()); |
| 951 dangerous_download_label_sized_ = true; | 960 dangerous_download_label_sized_ = true; |
| 952 } | 961 } |
| 953 | 962 |
| 954 void DownloadItemView::Reenable() { | 963 void DownloadItemView::Reenable() { |
| 955 disabled_while_opening_ = false; | 964 disabled_while_opening_ = false; |
| 956 SetEnabled(true); // Triggers a repaint. | 965 SetEnabled(true); // Triggers a repaint. |
| 957 } | 966 } |
| OLD | NEW |