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 |