1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-01-03 05:25:52 +00:00

refactor: replace NSMutableDictionary with constant attributes (#5221)

This commit is contained in:
Cœur 2023-06-12 18:03:22 +02:00 committed by GitHub
parent c379cd727f
commit 76166d8fa7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 127 additions and 122 deletions

View file

@ -4,6 +4,12 @@
#import <AppKit/AppKit.h>
typedef NS_ENUM(NSInteger, AttributesStyle) {
AttributesStyleNormal,
AttributesStyleEmphasized,
AttributesStyleDisabled,
};
@interface FileNameCell : NSActionCell
- (NSRect)imageRectForBounds:(NSRect)bounds;

View file

@ -20,46 +20,52 @@ static CGFloat const kPaddingBelowStatusFile = 2.0;
static CGFloat const kPaddingBetweenNameAndFolderStatus = 4.0;
static CGFloat const kPaddingExpansionFrame = 2.0;
@interface FileNameCell ()
@property(nonatomic, readonly) NSAttributedString* attributedTitle;
@property(nonatomic, readonly) NSAttributedString* attributedStatus;
@property(nonatomic, readonly) NSMutableDictionary* fTitleAttributes;
@property(nonatomic, readonly) NSMutableDictionary* fStatusAttributes;
@end
@implementation FileNameCell
- (instancetype)init
static NSMutableParagraphStyle* sParagraphStyle()
{
if ((self = [super init]))
{
NSMutableParagraphStyle* paragraphStyle = [NSParagraphStyle.defaultParagraphStyle mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingMiddle;
_fTitleAttributes = [[NSMutableDictionary alloc]
initWithObjectsAndKeys:[NSFont messageFontOfSize:12.0], NSFontAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil];
NSMutableParagraphStyle* statusParagraphStyle = [NSParagraphStyle.defaultParagraphStyle mutableCopy];
statusParagraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
_fStatusAttributes = [[NSMutableDictionary alloc]
initWithObjectsAndKeys:[NSFont messageFontOfSize:9.0], NSFontAttributeName, statusParagraphStyle, NSParagraphStyleAttributeName, nil];
}
return self;
return paragraphStyle;
}
- (id)copyWithZone:(NSZone*)zone
static NSMutableParagraphStyle* sStatusParagraphStyle()
{
FileNameCell* copy = [super copyWithZone:zone];
copy->_fTitleAttributes = _fTitleAttributes;
copy->_fStatusAttributes = _fStatusAttributes;
return copy;
NSMutableParagraphStyle* paragraphStyle = [NSParagraphStyle.defaultParagraphStyle mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail;
return paragraphStyle;
}
static NSDictionary<NSAttributedStringKey, id>* const kTitleAttributes = @{
NSFontAttributeName : [NSFont messageFontOfSize:12.0],
NSParagraphStyleAttributeName : sParagraphStyle(),
NSForegroundColorAttributeName : NSColor.controlTextColor
};
static NSDictionary<NSAttributedStringKey, id>* const kStatusAttributes = @{
NSFontAttributeName : [NSFont messageFontOfSize:9.0],
NSParagraphStyleAttributeName : sStatusParagraphStyle(),
NSForegroundColorAttributeName : NSColor.secondaryLabelColor
};
static NSDictionary<NSAttributedStringKey, id>* const kTitleEmphasizedAttributes = @{
NSFontAttributeName : [NSFont messageFontOfSize:12.0],
NSParagraphStyleAttributeName : sParagraphStyle(),
NSForegroundColorAttributeName : NSColor.whiteColor
};
static NSDictionary<NSAttributedStringKey, id>* const kStatusEmphasizedAttributes = @{
NSFontAttributeName : [NSFont messageFontOfSize:9.0],
NSParagraphStyleAttributeName : sStatusParagraphStyle(),
NSForegroundColorAttributeName : NSColor.whiteColor
};
static NSDictionary<NSAttributedStringKey, id>* const kTitleDisabledAttributes = @{
NSFontAttributeName : [NSFont messageFontOfSize:12.0],
NSParagraphStyleAttributeName : sParagraphStyle(),
NSForegroundColorAttributeName : NSColor.disabledControlTextColor
};
static NSDictionary<NSAttributedStringKey, id>* const kStatusDisabledAttributes = @{
NSFontAttributeName : [NSFont messageFontOfSize:9.0],
NSParagraphStyleAttributeName : sStatusParagraphStyle(),
NSForegroundColorAttributeName : NSColor.disabledControlTextColor
};
@implementation FileNameCell
- (NSImage*)image
{
FileListNode* node = (FileListNode*)self.objectValue;
@ -87,40 +93,36 @@ static CGFloat const kPaddingExpansionFrame = 2.0;
respectFlipped:YES
hints:nil];
NSColor *titleColor, *statusColor;
FileListNode* node = self.objectValue;
AttributesStyle style;
if (self.backgroundStyle == NSBackgroundStyleEmphasized)
{
titleColor = statusColor = NSColor.whiteColor;
style = AttributesStyleEmphasized;
}
else if ([node.torrent checkForFiles:node.indexes] == NSControlStateValueOff)
{
titleColor = statusColor = NSColor.disabledControlTextColor;
style = AttributesStyleDisabled;
}
else
{
titleColor = NSColor.controlTextColor;
statusColor = NSColor.secondaryLabelColor;
style = AttributesStyleNormal;
}
self.fTitleAttributes[NSForegroundColorAttributeName] = titleColor;
self.fStatusAttributes[NSForegroundColorAttributeName] = statusColor;
//title
NSAttributedString* titleString = self.attributedTitle;
NSRect titleRect = [self rectForTitleWithString:titleString inBounds:cellFrame];
NSAttributedString* titleString = [self attributedTitleWithStyle:style];
NSRect titleRect = [self rectForTitleWithStringSize:[titleString size] inBounds:cellFrame];
[titleString drawInRect:titleRect];
//status
NSAttributedString* statusString = self.attributedStatus;
NSAttributedString* statusString = [self attributedStatusWithStyle:style];
NSRect statusRect = [self rectForStatusWithString:statusString withTitleRect:titleRect inBounds:cellFrame];
[statusString drawInRect:statusRect];
}
- (NSRect)expansionFrameWithFrame:(NSRect)cellFrame inView:(NSView*)view
{
NSAttributedString* titleString = self.attributedTitle;
NSRect realRect = [self rectForTitleWithString:titleString inBounds:cellFrame];
NSAttributedString* titleString = [self attributedTitleWithStyle:AttributesStyleNormal];
NSRect realRect = [self rectForTitleWithStringSize:[titleString size] inBounds:cellFrame];
if ([titleString size].width > NSWidth(realRect) &&
NSMouseInRect([view convertPoint:view.window.mouseLocationOutsideOfEventStream fromView:nil], realRect, view.flipped))
@ -137,16 +139,15 @@ static CGFloat const kPaddingExpansionFrame = 2.0;
cellFrame.origin.x += kPaddingExpansionFrame;
cellFrame.origin.y += kPaddingExpansionFrame;
self.fTitleAttributes[NSForegroundColorAttributeName] = NSColor.controlTextColor;
NSAttributedString* titleString = self.attributedTitle;
NSAttributedString* titleString = [self attributedTitleWithStyle:AttributesStyleNormal];
[titleString drawInRect:cellFrame];
}
#pragma mark - Private
- (NSRect)rectForTitleWithString:(NSAttributedString*)string inBounds:(NSRect)bounds
- (NSRect)rectForTitleWithStringSize:(NSSize)stringSize inBounds:(NSRect)bounds
{
NSSize const titleSize = [string size];
NSSize const titleSize = stringSize;
//no right padding, so that there's not too much space between this and the priority image
NSRect result;
@ -189,13 +190,15 @@ static CGFloat const kPaddingExpansionFrame = 2.0;
return result;
}
- (NSAttributedString*)attributedTitle
- (NSAttributedString*)attributedTitleWithStyle:(AttributesStyle)style
{
NSString* title = ((FileListNode*)self.objectValue).name;
return [[NSAttributedString alloc] initWithString:title attributes:self.fTitleAttributes];
return [[NSAttributedString alloc] initWithString:title attributes:style == AttributesStyleEmphasized ? kTitleEmphasizedAttributes :
style == AttributesStyleDisabled ? kTitleDisabledAttributes :
kTitleAttributes];
}
- (NSAttributedString*)attributedStatus
- (NSAttributedString*)attributedStatusWithStyle:(AttributesStyle)style
{
FileListNode* node = (FileListNode*)self.objectValue;
Torrent* torrent = node.torrent;
@ -207,7 +210,9 @@ static CGFloat const kPaddingExpansionFrame = 2.0;
percentString,
[NSString stringForFileSize:node.size]];
return [[NSAttributedString alloc] initWithString:status attributes:self.fStatusAttributes];
return [[NSAttributedString alloc] initWithString:status attributes:style == AttributesStyleEmphasized ? kStatusEmphasizedAttributes :
style == AttributesStyleDisabled ? kStatusDisabledAttributes :
kStatusAttributes];
}
@end

View file

@ -3,6 +3,7 @@
// License text can be found in the licenses/ folder.
#import "TorrentCell.h"
#import "FileNameCell.h"
#import "GroupsController.h"
#import "NSImageAdditions.h"
#import "NSStringAdditions.h"
@ -48,13 +49,35 @@ static CGFloat const kPiecesTotalPercent = 0.6;
static NSInteger const kMaxPieces = 18 * 18;
static NSMutableParagraphStyle* sParagraphStyle()
{
NSMutableParagraphStyle* paragraphStyle = [NSParagraphStyle.defaultParagraphStyle mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingMiddle;
return paragraphStyle;
}
static NSDictionary<NSAttributedStringKey, id>* const kTitleAttributes = @{
NSFontAttributeName : [NSFont messageFontOfSize:12.0],
NSParagraphStyleAttributeName : sParagraphStyle(),
NSForegroundColorAttributeName : NSColor.labelColor
};
static NSDictionary<NSAttributedStringKey, id>* const kStatusAttributes = @{
NSFontAttributeName : [NSFont messageFontOfSize:10.0],
NSParagraphStyleAttributeName : sParagraphStyle(),
NSForegroundColorAttributeName : NSColor.secondaryLabelColor
};
static NSDictionary<NSAttributedStringKey, id>* const kTitleEmphasizedAttributes = @{
NSFontAttributeName : [NSFont messageFontOfSize:12.0],
NSParagraphStyleAttributeName : sParagraphStyle(),
NSForegroundColorAttributeName : NSColor.whiteColor
};
static NSDictionary<NSAttributedStringKey, id>* const kStatusEmphasizedAttributes = @{
NSFontAttributeName : [NSFont messageFontOfSize:10.0],
NSParagraphStyleAttributeName : sParagraphStyle(),
NSForegroundColorAttributeName : NSColor.whiteColor
};
@interface TorrentCell ()
@property(nonatomic, readonly) NSUserDefaults* fDefaults;
@property(nonatomic, readonly) NSMutableDictionary* fTitleAttributes;
@property(nonatomic, readonly) NSMutableDictionary* fStatusAttributes;
@property(nonatomic) BOOL fTracking;
@property(nonatomic) BOOL fMouseDownControlButton;
@property(nonatomic) BOOL fMouseDownRevealButton;
@ -63,13 +86,6 @@ static NSInteger const kMaxPieces = 18 * 18;
@property(nonatomic, readonly) NSColor* fBluePieceColor;
@property(nonatomic, readonly) NSColor* fBarMinimalBorderColor;
@property(nonatomic, readonly) NSAttributedString* attributedTitle;
- (NSAttributedString*)attributedStatusString:(NSString*)string;
@property(nonatomic, readonly) NSString* buttonString;
@property(nonatomic, readonly) NSString* statusString;
@property(nonatomic, readonly) NSString* minimalStatusString;
@end
@implementation TorrentCell
@ -79,17 +95,6 @@ static NSInteger const kMaxPieces = 18 * 18;
{
if ((self = [super init]))
{
NSMutableParagraphStyle* paragraphStyle = [NSParagraphStyle.defaultParagraphStyle mutableCopy];
paragraphStyle.lineBreakMode = NSLineBreakByTruncatingMiddle;
_fTitleAttributes = [[NSMutableDictionary alloc] initWithCapacity:3];
_fTitleAttributes[NSFontAttributeName] = [NSFont messageFontOfSize:12.0];
_fTitleAttributes[NSParagraphStyleAttributeName] = paragraphStyle;
_fStatusAttributes = [[NSMutableDictionary alloc] initWithCapacity:3];
_fStatusAttributes[NSFontAttributeName] = [NSFont messageFontOfSize:10.0];
_fStatusAttributes[NSParagraphStyleAttributeName] = paragraphStyle;
_fBluePieceColor = [NSColor colorWithCalibratedRed:0.0 green:0.4 blue:0.8 alpha:1.0];
_fBarBorderColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0.2];
_fBarMinimalBorderColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0.015];
@ -100,8 +105,6 @@ static NSInteger const kMaxPieces = 18 * 18;
- (id)copyWithZone:(NSZone*)zone
{
TorrentCell* copy = [super copyWithZone:zone];
copy->_fTitleAttributes = [_fTitleAttributes mutableCopyWithZone:zone];
copy->_fStatusAttributes = [_fStatusAttributes mutableCopyWithZone:zone];
copy->_fBluePieceColor = _fBluePieceColor;
copy->_fBarBorderColor = _fBarBorderColor;
copy->_fBarMinimalBorderColor = _fBarMinimalBorderColor;
@ -333,27 +336,14 @@ static NSInteger const kMaxPieces = 18 * 18;
hints:nil];
}
//text color
NSColor *titleColor, *statusColor;
if (self.backgroundStyle == NSBackgroundStyleEmphasized)
{
titleColor = statusColor = NSColor.whiteColor;
}
else
{
titleColor = NSColor.labelColor;
statusColor = NSColor.secondaryLabelColor;
}
self.fTitleAttributes[NSForegroundColorAttributeName] = titleColor;
self.fStatusAttributes[NSForegroundColorAttributeName] = statusColor;
AttributesStyle style = self.backgroundStyle == NSBackgroundStyleEmphasized ? AttributesStyleEmphasized : AttributesStyleNormal;
CGFloat titleRightBound;
//minimal status
if (minimal)
{
NSAttributedString* minimalString = [self attributedStatusString:self.minimalStatusString];
NSRect minimalStatusRect = [self rectForMinimalStatusWithString:minimalString inBounds:cellFrame];
NSAttributedString* minimalString = [self attributedStatusString:self.minimalStatusString style:style];
NSRect minimalStatusRect = [self rectForMinimalStatusWithStringSize:[minimalString size] inBounds:cellFrame];
if (!self.hover)
{
@ -365,7 +355,7 @@ static NSInteger const kMaxPieces = 18 * 18;
//progress
else
{
NSAttributedString* progressString = [self attributedStatusString:torrent.progressString];
NSAttributedString* progressString = [self attributedStatusString:torrent.progressString style:style];
NSRect progressRect = [self rectForProgressWithStringInBounds:cellFrame];
[progressString drawInRect:progressRect];
@ -455,8 +445,9 @@ static NSInteger const kMaxPieces = 18 * 18;
}
//title
NSAttributedString* titleString = self.attributedTitle;
NSRect titleRect = [self rectForTitleWithString:titleString withRightBound:titleRightBound inBounds:cellFrame minimal:minimal];
NSAttributedString* titleString = [self attributedTitleWithStyle:style];
NSRect titleRect = [self rectForTitleWithStringSize:[titleString size] withRightBound:titleRightBound inBounds:cellFrame
minimal:minimal];
[titleString drawInRect:titleRect];
//priority icon
@ -480,7 +471,7 @@ static NSInteger const kMaxPieces = 18 * 18;
//status
if (!minimal)
{
NSAttributedString* statusString = [self attributedStatusString:self.statusString];
NSAttributedString* statusString = [self attributedStatusString:self.statusString style:style];
[statusString drawInRect:[self rectForStatusWithStringInBounds:cellFrame]];
}
}
@ -493,8 +484,8 @@ static NSInteger const kMaxPieces = 18 * 18;
CGFloat titleRightBound;
if (minimal)
{
NSAttributedString* minimalString = [self attributedStatusString:self.minimalStatusString];
NSRect minimalStatusRect = [self rectForMinimalStatusWithString:minimalString inBounds:cellFrame];
NSAttributedString* minimalString = [self attributedStatusString:self.minimalStatusString style:AttributesStyleNormal];
NSRect minimalStatusRect = [self rectForMinimalStatusWithStringSize:[minimalString size] inBounds:cellFrame];
titleRightBound = NSMinX(minimalStatusRect);
@ -509,15 +500,17 @@ static NSInteger const kMaxPieces = 18 * 18;
titleRightBound = NSMaxX(cellFrame);
}
NSAttributedString* titleString = self.attributedTitle;
NSRect realRect = [self rectForTitleWithString:titleString withRightBound:titleRightBound inBounds:cellFrame minimal:minimal];
NSAttributedString* titleString = [self attributedTitleWithStyle:AttributesStyleNormal];
NSSize titleStringSize = [titleString size];
NSRect realRect = [self rectForTitleWithStringSize:titleStringSize withRightBound:titleRightBound inBounds:cellFrame
minimal:minimal];
NSAssert([titleString size].width >= NSWidth(realRect), @"Full rect width should not be less than the used title rect width!");
NSAssert(titleStringSize.width >= NSWidth(realRect), @"Full rect width should not be less than the used title rect width!");
if ([titleString size].width > NSWidth(realRect) &&
if (titleStringSize.width > NSWidth(realRect) &&
NSMouseInRect([view convertPoint:view.window.mouseLocationOutsideOfEventStream fromView:nil], realRect, view.flipped))
{
realRect.size.width = [titleString size].width;
realRect.size.width = titleStringSize.width;
return NSInsetRect(realRect, -kPaddingExpansionFrame, -kPaddingExpansionFrame);
}
@ -529,8 +522,7 @@ static NSInteger const kMaxPieces = 18 * 18;
cellFrame.origin.x += kPaddingExpansionFrame;
cellFrame.origin.y += kPaddingExpansionFrame;
self.fTitleAttributes[NSForegroundColorAttributeName] = NSColor.labelColor;
NSAttributedString* titleString = self.attributedTitle;
NSAttributedString* titleString = [self attributedTitleWithStyle:AttributesStyleNormal];
[titleString drawInRect:cellFrame];
}
@ -711,10 +703,10 @@ static NSInteger const kMaxPieces = 18 * 18;
hints:nil];
}
- (NSRect)rectForMinimalStatusWithString:(NSAttributedString*)string inBounds:(NSRect)bounds
- (NSRect)rectForMinimalStatusWithStringSize:(NSSize)stringSize inBounds:(NSRect)bounds
{
NSRect result;
result.size = [string size];
result.size = stringSize;
result.origin.x = NSMaxX(bounds) - (kPaddingHorizontal + NSWidth(result) + kPaddingEdgeMax);
result.origin.y = ceil(NSMidY(bounds) - NSHeight(result) * 0.5);
@ -722,7 +714,7 @@ static NSInteger const kMaxPieces = 18 * 18;
return result;
}
- (NSRect)rectForTitleWithString:(NSAttributedString*)string
- (NSRect)rectForTitleWithStringSize:(NSSize)stringSize
withRightBound:(CGFloat)rightBound
inBounds:(NSRect)bounds
minimal:(BOOL)minimal
@ -748,7 +740,7 @@ static NSInteger const kMaxPieces = 18 * 18;
{
result.size.width -= kPriorityIconSize + kPaddingBetweenTitleAndPriority;
}
result.size.width = MIN(NSWidth(result), [string size].width);
result.size.width = MIN(NSWidth(result), stringSize.width);
return result;
}
@ -857,15 +849,17 @@ static NSInteger const kMaxPieces = 18 * 18;
return NSMakeRect(NSMinX(bounds) - padding * 0.5, NSMidY(bounds) - imageSize * 0.5, imageSize, imageSize);
}
- (NSAttributedString*)attributedTitle
- (NSAttributedString*)attributedTitleWithStyle:(AttributesStyle)style
{
NSString* title = ((Torrent*)self.representedObject).name;
return [[NSAttributedString alloc] initWithString:title attributes:self.fTitleAttributes];
return [[NSAttributedString alloc] initWithString:title
attributes:style == AttributesStyleEmphasized ? kTitleEmphasizedAttributes : kTitleAttributes];
}
- (NSAttributedString*)attributedStatusString:(NSString*)string
- (NSAttributedString*)attributedStatusString:(NSString*)string style:(AttributesStyle)style
{
return [[NSAttributedString alloc] initWithString:string attributes:self.fStatusAttributes];
return [[NSAttributedString alloc] initWithString:string
attributes:style == AttributesStyleEmphasized ? kStatusEmphasizedAttributes : kStatusAttributes];
}
- (NSString*)buttonString