Feature: Add fractional track length tooltips
Add fractional track length tooltips, for extra verbose info goodness. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
d5ca037943
commit
b05f428cde
6 changed files with 107 additions and 2 deletions
|
@ -1,8 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="22154" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="macosx"/>
|
<deployment identifier="macosx"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22154"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
|
@ -167,6 +167,7 @@
|
||||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||||
</textFieldCell>
|
</textFieldCell>
|
||||||
<connections>
|
<connections>
|
||||||
|
<binding destination="-2" name="toolTip" keyPath="valueToDisplay.lengthInfo" id="26q-iJ-ecn"/>
|
||||||
<binding destination="-2" name="value" keyPath="valueToDisplay.lengthText" id="ji7-tL-8rb"/>
|
<binding destination="-2" name="value" keyPath="valueToDisplay.lengthText" id="ji7-tL-8rb"/>
|
||||||
</connections>
|
</connections>
|
||||||
</textField>
|
</textField>
|
||||||
|
|
|
@ -24,3 +24,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface SecondsFractionFormatter : NSFormatter {
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
|
@ -99,3 +99,83 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@implementation SecondsFractionFormatter
|
||||||
|
|
||||||
|
- (NSString *)stringForObjectValue:(id)object {
|
||||||
|
NSString *result = nil;
|
||||||
|
double value;
|
||||||
|
unsigned days = 0;
|
||||||
|
unsigned hours = 0;
|
||||||
|
unsigned minutes = 0;
|
||||||
|
float seconds = 0.0;
|
||||||
|
|
||||||
|
if(nil == object || NO == [object isKindOfClass:[NSNumber class]] || isnan([object doubleValue])) {
|
||||||
|
return @"";
|
||||||
|
}
|
||||||
|
|
||||||
|
value = [object doubleValue];
|
||||||
|
|
||||||
|
seconds = fmod(value, 60.0);
|
||||||
|
minutes = (unsigned)floor(value / 60.0);
|
||||||
|
|
||||||
|
while(60 <= minutes) {
|
||||||
|
minutes -= 60;
|
||||||
|
++hours;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(24 <= hours) {
|
||||||
|
hours -= 24;
|
||||||
|
++days;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(0 < days) {
|
||||||
|
result = [NSString stringWithFormat:@"%u:%.2u:%.2u:%06.3f", days, hours, minutes, seconds];
|
||||||
|
} else if(0 < hours) {
|
||||||
|
result = [NSString stringWithFormat:@"%u:%.2u:%06.3f", hours, minutes, seconds];
|
||||||
|
} else if(0 < minutes) {
|
||||||
|
result = [NSString stringWithFormat:@"%u:%06.3f", minutes, seconds];
|
||||||
|
} else {
|
||||||
|
result = [NSString stringWithFormat:@"0:%06.3f", seconds];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)getObjectValue:(id *)object forString:(NSString *)string errorDescription:(NSString **)error {
|
||||||
|
NSScanner *scanner = nil;
|
||||||
|
BOOL result = NO;
|
||||||
|
double value = 0.0;
|
||||||
|
double seconds = 0.0;
|
||||||
|
|
||||||
|
scanner = [NSScanner scannerWithString:string];
|
||||||
|
|
||||||
|
while(NO == [scanner isAtEnd]) {
|
||||||
|
// Grab a value
|
||||||
|
if([scanner scanDouble:&value]) {
|
||||||
|
seconds *= 60.0;
|
||||||
|
seconds += value;
|
||||||
|
result = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab the separator, if present
|
||||||
|
[scanner scanString:@":" intoString:NULL];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result && NULL != object) {
|
||||||
|
*object = @(seconds);
|
||||||
|
} else if(NULL != error) {
|
||||||
|
*error = @"Couldn't convert value to seconds";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSAttributedString *)attributedStringForObjectValue:(id)object withDefaultAttributes:(NSDictionary *)attributes {
|
||||||
|
NSAttributedString *result = nil;
|
||||||
|
|
||||||
|
result = [[NSAttributedString alloc] initWithString:[self stringForObjectValue:object] attributes:attributes];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
|
@ -445,6 +445,7 @@ static void *playlistControllerContext = &playlistControllerContext;
|
||||||
NSImage *cellImage = nil;
|
NSImage *cellImage = nil;
|
||||||
NSString *cellText = @"";
|
NSString *cellText = @"";
|
||||||
NSString *cellIdentifier = @"";
|
NSString *cellIdentifier = @"";
|
||||||
|
NSString *cellToolTip = nil;
|
||||||
NSTextAlignment cellTextAlignment = NSTextAlignmentLeft;
|
NSTextAlignment cellTextAlignment = NSTextAlignmentLeft;
|
||||||
|
|
||||||
PlaylistEntry *pe = [[self arrangedObjects] objectAtIndex:row];
|
PlaylistEntry *pe = [[self arrangedObjects] objectAtIndex:row];
|
||||||
|
@ -486,6 +487,7 @@ static void *playlistControllerContext = &playlistControllerContext;
|
||||||
case 6:
|
case 6:
|
||||||
cellText = pe.lengthText;
|
cellText = pe.lengthText;
|
||||||
cellTextAlignment = NSTextAlignmentRight;
|
cellTextAlignment = NSTextAlignmentRight;
|
||||||
|
cellToolTip = pe.lengthInfo;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
|
@ -583,6 +585,10 @@ static void *playlistControllerContext = &playlistControllerContext;
|
||||||
else
|
else
|
||||||
cellView.textField.toolTip = [pe statusMessage];
|
cellView.textField.toolTip = [pe statusMessage];
|
||||||
|
|
||||||
|
if(cellToolTip) {
|
||||||
|
cellView.textField.toolTip = cellToolTip;
|
||||||
|
}
|
||||||
|
|
||||||
NSRect cellFrameRect = cellView.textField.frame;
|
NSRect cellFrameRect = cellView.textField.frame;
|
||||||
cellFrameRect.origin.y = 1;
|
cellFrameRect.origin.y = 1;
|
||||||
cellFrameRect.size.height = frameRect.size.height;
|
cellFrameRect.size.height = frameRect.size.height;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
+ (NSSet *_Nonnull)keyPathsForValuesAffectingAlbumArt;
|
+ (NSSet *_Nonnull)keyPathsForValuesAffectingAlbumArt;
|
||||||
+ (NSSet *_Nonnull)keyPathsForValuesAffectingTrackText;
|
+ (NSSet *_Nonnull)keyPathsForValuesAffectingTrackText;
|
||||||
+ (NSSet *_Nonnull)keyPathsForValuesAffectingLengthText;
|
+ (NSSet *_Nonnull)keyPathsForValuesAffectingLengthText;
|
||||||
|
+ (NSSet *_Nonnull)keyPathsForValuesAffectingLengthInfo;
|
||||||
+ (NSSet *_Nonnull)keyPathsForValuesAffectingYearText;
|
+ (NSSet *_Nonnull)keyPathsForValuesAffectingYearText;
|
||||||
+ (NSSet *_Nonnull)keyPathsForValuesAffectingCuesheetPresent;
|
+ (NSSet *_Nonnull)keyPathsForValuesAffectingCuesheetPresent;
|
||||||
+ (NSSet *_Nonnull)keyPathsForValuesAffectingGainCorrection;
|
+ (NSSet *_Nonnull)keyPathsForValuesAffectingGainCorrection;
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
@property(nonatomic, readonly) NSString *_Nonnull positionText;
|
@property(nonatomic, readonly) NSString *_Nonnull positionText;
|
||||||
|
|
||||||
@property(nonatomic, readonly) NSString *_Nonnull lengthText;
|
@property(nonatomic, readonly) NSString *_Nonnull lengthText;
|
||||||
|
@property(nonatomic, readonly) NSString *_Nonnull lengthInfo;
|
||||||
|
|
||||||
@property(nonatomic, readonly) NSString *_Nonnull yearText;
|
@property(nonatomic, readonly) NSString *_Nonnull yearText;
|
||||||
|
|
||||||
|
|
|
@ -91,6 +91,10 @@ extern NSMutableDictionary<NSString *, AlbumArtwork *> *kArtworkDictionary;
|
||||||
return [NSSet setWithObject:@"length"];
|
return [NSSet setWithObject:@"length"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (NSSet *)keyPathsForValuesAffectingLengthInfo {
|
||||||
|
return [NSSet setWithObject:@"length"];
|
||||||
|
}
|
||||||
|
|
||||||
+ (NSSet *)keyPathsForValuesAffectingAlbumArt {
|
+ (NSSet *)keyPathsForValuesAffectingAlbumArt {
|
||||||
return [NSSet setWithObjects:@"albumArtInternal", @"artId", nil];
|
return [NSSet setWithObjects:@"albumArtInternal", @"artId", nil];
|
||||||
}
|
}
|
||||||
|
@ -316,6 +320,13 @@ extern NSMutableDictionary<NSString *, AlbumArtwork *> *kArtworkDictionary;
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@dynamic lengthInfo;
|
||||||
|
- (NSString *)lengthInfo {
|
||||||
|
SecondsFractionFormatter * secondsFormatter = [[SecondsFractionFormatter alloc] init];
|
||||||
|
NSString *time = [secondsFormatter stringForObjectValue:self.length];
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
@dynamic albumArt;
|
@dynamic albumArt;
|
||||||
- (NSImage *)albumArt {
|
- (NSImage *)albumArt {
|
||||||
if(!self.albumArtInternal || ![self.albumArtInternal length]) return nil;
|
if(!self.albumArtInternal || ![self.albumArtInternal length]) return nil;
|
||||||
|
|
Loading…
Reference in a new issue