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:
Christopher Snowhill 2025-02-27 00:58:18 -08:00
parent d5ca037943
commit b05f428cde
6 changed files with 107 additions and 2 deletions

View file

@ -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>

View file

@ -24,3 +24,8 @@
} }
@end @end
@interface SecondsFractionFormatter : NSFormatter {
}
@end

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;