| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #import "chrome/browser/ui/cocoa/download/download_item_cell.h" | 5 #import "chrome/browser/ui/cocoa/download/download_item_cell.h" |
| 6 | 6 |
| 7 #include "base/sys_string_conversions.h" | 7 #include "base/sys_string_conversions.h" |
| 8 #include "chrome/browser/download/download_item.h" | 8 #include "chrome/browser/download/download_item.h" |
| 9 #include "chrome/browser/download/download_item_model.h" | 9 #include "chrome/browser/download/download_item_model.h" |
| 10 #include "chrome/browser/download/download_manager.h" | 10 #include "chrome/browser/download/download_manager.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 // Width of dropdown arrow. | 61 // Width of dropdown arrow. |
| 62 const CGFloat kDropdownArrowWidth = 5; | 62 const CGFloat kDropdownArrowWidth = 5; |
| 63 | 63 |
| 64 // Height of dropdown arrow. | 64 // Height of dropdown arrow. |
| 65 const CGFloat kDropdownArrowHeight = 3; | 65 const CGFloat kDropdownArrowHeight = 3; |
| 66 | 66 |
| 67 // Vertical displacement of dropdown area, relative to the "centered" position. | 67 // Vertical displacement of dropdown area, relative to the "centered" position. |
| 68 const CGFloat kDropdownAreaY = -2; | 68 const CGFloat kDropdownAreaY = -2; |
| 69 | 69 |
| 70 // Duration of the two-lines-to-one-line animation, in seconds. | 70 // Duration of the two-lines-to-one-line animation, in seconds. |
| 71 NSTimeInterval kShowStatusDuration = 0.3; |
| 71 NSTimeInterval kHideStatusDuration = 0.3; | 72 NSTimeInterval kHideStatusDuration = 0.3; |
| 72 | 73 |
| 73 // Duration of the 'download complete' animation, in seconds. | 74 // Duration of the 'download complete' animation, in seconds. |
| 74 const int kCompleteAnimationDuration = 2.5; | 75 const int kCompleteAnimationDuration = 2.5; |
| 75 | 76 |
| 76 // Duration of the 'download interrupted' animation, in seconds. | 77 // Duration of the 'download interrupted' animation, in seconds. |
| 77 const int kInterruptedAnimationDuration = 2.5; | 78 const int kInterruptedAnimationDuration = 2.5; |
| 78 | 79 |
| 79 // This is a helper class to animate the fading out of the status text. | 80 // This is a helper class to animate the fading out of the status text. |
| 80 @interface DownloadItemCellAnimation : NSAnimation { | 81 @interface DownloadItemCellAnimation : NSAnimation { |
| 81 DownloadItemCell* cell_; | 82 DownloadItemCell* cell_; |
| 82 } | 83 } |
| 83 - (id)initWithDownloadItemCell:(DownloadItemCell*)cell | 84 - (id)initWithDownloadItemCell:(DownloadItemCell*)cell |
| 84 duration:(NSTimeInterval)duration | 85 duration:(NSTimeInterval)duration |
| 85 animationCurve:(NSAnimationCurve)animationCurve; | 86 animationCurve:(NSAnimationCurve)animationCurve; |
| 86 @end | 87 @end |
| 87 | 88 |
| 88 @interface DownloadItemCell(Private) | 89 @interface DownloadItemCell(Private) |
| 89 - (void)updateTrackingAreas:(id)sender; | 90 - (void)updateTrackingAreas:(id)sender; |
| 91 - (void)showSecondaryTitle; |
| 90 - (void)hideSecondaryTitle; | 92 - (void)hideSecondaryTitle; |
| 91 - (void)animation:(NSAnimation*)animation | 93 - (void)animation:(NSAnimation*)animation |
| 92 progressed:(NSAnimationProgress)progress; | 94 progressed:(NSAnimationProgress)progress; |
| 93 - (NSString*)elideTitle:(int)availableWidth; | 95 - (NSString*)elideTitle:(int)availableWidth; |
| 94 - (NSString*)elideStatus:(int)availableWidth; | 96 - (NSString*)elideStatus:(int)availableWidth; |
| 95 - (ui::ThemeProvider*)backgroundThemeWrappingProvider: | 97 - (ui::ThemeProvider*)backgroundThemeWrappingProvider: |
| 96 (ui::ThemeProvider*)provider; | 98 (ui::ThemeProvider*)provider; |
| 97 - (BOOL)pressedWithDefaultThemeOnPart:(DownloadItemMousePosition)part; | 99 - (BOOL)pressedWithDefaultThemeOnPart:(DownloadItemMousePosition)part; |
| 98 - (NSColor*)titleColorForPart:(DownloadItemMousePosition)part; | 100 - (NSColor*)titleColorForPart:(DownloadItemMousePosition)part; |
| 99 - (void)drawSecondaryTitleInRect:(NSRect)innerFrame; | 101 - (void)drawSecondaryTitleInRect:(NSRect)innerFrame; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 if ((self = [super initTextCell:string])) { | 137 if ((self = [super initTextCell:string])) { |
| 136 [self setInitialState]; | 138 [self setInitialState]; |
| 137 } | 139 } |
| 138 return self; | 140 return self; |
| 139 } | 141 } |
| 140 | 142 |
| 141 - (void)dealloc { | 143 - (void)dealloc { |
| 142 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 144 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 143 if ([completionAnimation_ isAnimating]) | 145 if ([completionAnimation_ isAnimating]) |
| 144 [completionAnimation_ stopAnimation]; | 146 [completionAnimation_ stopAnimation]; |
| 147 if ([showStatusAnimation_ isAnimating]) |
| 148 [showStatusAnimation_ stopAnimation]; |
| 145 if ([hideStatusAnimation_ isAnimating]) | 149 if ([hideStatusAnimation_ isAnimating]) |
| 146 [hideStatusAnimation_ stopAnimation]; | 150 [hideStatusAnimation_ stopAnimation]; |
| 147 if (trackingAreaButton_) { | 151 if (trackingAreaButton_) { |
| 148 [[self controlView] removeTrackingArea:trackingAreaButton_]; | 152 [[self controlView] removeTrackingArea:trackingAreaButton_]; |
| 149 trackingAreaButton_.reset(); | 153 trackingAreaButton_.reset(); |
| 150 } | 154 } |
| 151 if (trackingAreaDropdown_) { | 155 if (trackingAreaDropdown_) { |
| 152 [[self controlView] removeTrackingArea:trackingAreaDropdown_]; | 156 [[self controlView] removeTrackingArea:trackingAreaDropdown_]; |
| 153 trackingAreaDropdown_.reset(); | 157 trackingAreaDropdown_.reset(); |
| 154 } | 158 } |
| 155 [secondaryTitle_ release]; | 159 [secondaryTitle_ release]; |
| 156 [secondaryFont_ release]; | 160 [secondaryFont_ release]; |
| 157 [super dealloc]; | 161 [super dealloc]; |
| 158 } | 162 } |
| 159 | 163 |
| 160 - (void)setStateFromDownload:(BaseDownloadItemModel*)downloadModel { | 164 - (void)setStateFromDownload:(BaseDownloadItemModel*)downloadModel { |
| 161 // Set the name of the download. | 165 // Set the name of the download. |
| 162 downloadPath_ = downloadModel->download()->GetFileNameToReportUser(); | 166 downloadPath_ = downloadModel->download()->GetFileNameToReportUser(); |
| 163 | 167 |
| 164 string16 statusText = downloadModel->GetStatusText(); | 168 string16 statusText = downloadModel->GetStatusText(); |
| 165 if (statusText.empty()) { | 169 if (statusText.empty()) { |
| 166 // Remove the status text label. | 170 // Remove the status text label. |
| 167 [self hideSecondaryTitle]; | 171 [self hideSecondaryTitle]; |
| 168 isStatusTextVisible_ = NO; | 172 isStatusTextVisible_ = NO; |
| 169 } else { | 173 } else { |
| 170 // Set status text. | 174 // Set status text. |
| 171 NSString* statusString = base::SysUTF16ToNSString(statusText); | 175 NSString* statusString = base::SysUTF16ToNSString(statusText); |
| 172 [self setSecondaryTitle:statusString]; | 176 [self setSecondaryTitle:statusString]; |
| 177 [self showSecondaryTitle]; |
| 173 isStatusTextVisible_ = YES; | 178 isStatusTextVisible_ = YES; |
| 174 } | 179 } |
| 175 | 180 |
| 176 switch (downloadModel->download()->state()) { | 181 switch (downloadModel->download()->state()) { |
| 177 case DownloadItem::COMPLETE: | 182 case DownloadItem::COMPLETE: |
| 178 // Small downloads may start in a complete state due to asynchronous | 183 // Small downloads may start in a complete state due to asynchronous |
| 179 // notifications. In this case, we'll get a second complete notification | 184 // notifications. In this case, we'll get a second complete notification |
| 180 // via the observers, so we ignore it and avoid creating a second complete | 185 // via the observers, so we ignore it and avoid creating a second complete |
| 181 // animation. | 186 // animation. |
| 182 if (completionAnimation_.get()) | 187 if (completionAnimation_.get()) |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 [triangle fill]; | 591 [triangle fill]; |
| 587 } | 592 } |
| 588 | 593 |
| 589 - (NSRect)imageRectForBounds:(NSRect)cellFrame { | 594 - (NSRect)imageRectForBounds:(NSRect)cellFrame { |
| 590 return NSMakeRect(cellFrame.origin.x + kImagePaddingLeft, | 595 return NSMakeRect(cellFrame.origin.x + kImagePaddingLeft, |
| 591 cellFrame.origin.y + kImagePaddingTop, | 596 cellFrame.origin.y + kImagePaddingTop, |
| 592 kImageWidth, | 597 kImageWidth, |
| 593 kImageHeight); | 598 kImageHeight); |
| 594 } | 599 } |
| 595 | 600 |
| 601 - (void)showSecondaryTitle { |
| 602 if (!isStatusTextVisible_) { |
| 603 // No core animation -- text in CA layers is not subpixel antialiased :-/ |
| 604 showStatusAnimation_.reset([[DownloadItemCellAnimation alloc] |
| 605 initWithDownloadItemCell:self |
| 606 duration:kShowStatusDuration |
| 607 animationCurve:NSAnimationEaseIn]); |
| 608 [showStatusAnimation_.get() setDelegate:self]; |
| 609 [showStatusAnimation_.get() startAnimation]; |
| 610 } else { |
| 611 // If the status line continues to be visible, don't show an animation |
| 612 [self animation:nil progressed:0.0]; |
| 613 } |
| 614 } |
| 615 |
| 596 - (void)hideSecondaryTitle { | 616 - (void)hideSecondaryTitle { |
| 597 if (isStatusTextVisible_) { | 617 if (isStatusTextVisible_) { |
| 598 // No core animation -- text in CA layers is not subpixel antialiased :-/ | 618 // No core animation -- text in CA layers is not subpixel antialiased :-/ |
| 599 hideStatusAnimation_.reset([[DownloadItemCellAnimation alloc] | 619 hideStatusAnimation_.reset([[DownloadItemCellAnimation alloc] |
| 600 initWithDownloadItemCell:self | 620 initWithDownloadItemCell:self |
| 601 duration:kHideStatusDuration | 621 duration:kHideStatusDuration |
| 602 animationCurve:NSAnimationEaseIn]); | 622 animationCurve:NSAnimationEaseIn]); |
| 603 [hideStatusAnimation_.get() setDelegate:self]; | 623 [hideStatusAnimation_.get() setDelegate:self]; |
| 604 [hideStatusAnimation_.get() startAnimation]; | 624 [hideStatusAnimation_.get() startAnimation]; |
| 605 } else { | 625 } else { |
| 606 // If the download is done so quickly that the status line is never visible, | 626 // If the download is done so quickly that the status line is never visible, |
| 607 // don't show an animation | 627 // don't show an animation |
| 608 [self animation:nil progressed:1.0]; | 628 [self animation:nil progressed:1.0]; |
| 609 } | 629 } |
| 610 } | 630 } |
| 611 | 631 |
| 612 - (void)animation:(NSAnimation*)animation | 632 - (void)animation:(NSAnimation*)animation |
| 613 progressed:(NSAnimationProgress)progress { | 633 progressed:(NSAnimationProgress)progress { |
| 614 if (animation == hideStatusAnimation_ || animation == nil) { | 634 if (animation == showStatusAnimation_) { |
| 635 titleY_ = (1 - progress)*kPrimaryTextOnlyPosTop + |
| 636 kPrimaryTextPosTop; |
| 637 statusAlpha_ = progress; |
| 638 [[self controlView] setNeedsDisplay:YES]; |
| 639 } else if (animation == hideStatusAnimation_ || animation == nil) { |
| 615 titleY_ = progress*kPrimaryTextOnlyPosTop + | 640 titleY_ = progress*kPrimaryTextOnlyPosTop + |
| 616 (1 - progress)*kPrimaryTextPosTop; | 641 (1 - progress)*kPrimaryTextPosTop; |
| 617 statusAlpha_ = 1 - progress; | 642 statusAlpha_ = 1 - progress; |
| 618 [[self controlView] setNeedsDisplay:YES]; | 643 [[self controlView] setNeedsDisplay:YES]; |
| 619 } else if (animation == completionAnimation_) { | 644 } else if (animation == completionAnimation_) { |
| 620 [[self controlView] setNeedsDisplay:YES]; | 645 [[self controlView] setNeedsDisplay:YES]; |
| 621 } | 646 } |
| 622 } | 647 } |
| 623 | 648 |
| 624 - (void)animationDidEnd:(NSAnimation *)animation { | 649 - (void)animationDidEnd:(NSAnimation *)animation { |
| 625 if (animation == hideStatusAnimation_) | 650 if (animation == showStatusAnimation_) |
| 651 showStatusAnimation_.reset(); |
| 652 else if (animation == hideStatusAnimation_) |
| 626 hideStatusAnimation_.reset(); | 653 hideStatusAnimation_.reset(); |
| 627 else if (animation == completionAnimation_) | 654 else if (animation == completionAnimation_) |
| 628 completionAnimation_.reset(); | 655 completionAnimation_.reset(); |
| 629 } | 656 } |
| 630 | 657 |
| 631 @end | 658 @end |
| 632 | 659 |
| 633 @implementation DownloadItemCellAnimation | 660 @implementation DownloadItemCellAnimation |
| 634 | 661 |
| 635 - (id)initWithDownloadItemCell:(DownloadItemCell*)cell | 662 - (id)initWithDownloadItemCell:(DownloadItemCell*)cell |
| 636 duration:(NSTimeInterval)duration | 663 duration:(NSTimeInterval)duration |
| 637 animationCurve:(NSAnimationCurve)animationCurve { | 664 animationCurve:(NSAnimationCurve)animationCurve { |
| 638 if ((self = [super gtm_initWithDuration:duration | 665 if ((self = [super gtm_initWithDuration:duration |
| 639 eventMask:NSLeftMouseDownMask | 666 eventMask:NSLeftMouseDownMask |
| 640 animationCurve:animationCurve])) { | 667 animationCurve:animationCurve])) { |
| 641 cell_ = cell; | 668 cell_ = cell; |
| 642 [self setAnimationBlockingMode:NSAnimationNonblocking]; | 669 [self setAnimationBlockingMode:NSAnimationNonblocking]; |
| 643 } | 670 } |
| 644 return self; | 671 return self; |
| 645 } | 672 } |
| 646 | 673 |
| 647 - (void)setCurrentProgress:(NSAnimationProgress)progress { | 674 - (void)setCurrentProgress:(NSAnimationProgress)progress { |
| 648 [super setCurrentProgress:progress]; | 675 [super setCurrentProgress:progress]; |
| 649 [cell_ animation:self progressed:progress]; | 676 [cell_ animation:self progressed:progress]; |
| 650 } | 677 } |
| 651 | 678 |
| 652 @end | 679 @end |
| OLD | NEW |