Updated badging

This commit is contained in:
Eric Petit 2006-02-08 17:44:07 +00:00
parent d8bdcea349
commit 65316f1b72
9 changed files with 175 additions and 161 deletions

View File

@ -12,18 +12,18 @@
@interface Badger : NSObject {
NSImage * fBadge, * fDockIcon, * fBadgedDockIcon;
NSDictionary * fBadgeAttributes, * fStringAttributes;
NSColor * fUploadingColor, * fDownloadingColor;
int fCompleted;
NSImage * fDockIcon, * fBadgedDockIcon,
* fBadge, * fUploadBadge, * fDownloadBadge;
NSDictionary * fAttributes;
int fCompleted;
BOOL fSpeedShown;
}
- (void) updateBadgeWithCompleted: (int) completed
uploadRate: (NSString *) uploadRate
downloadRate: (NSString *) downloadRate;
uploadRate: (NSString *) uploadRate
downloadRate: (NSString *) downloadRate;
- (void) clearBadge;
@end

View File

@ -9,7 +9,7 @@
@interface Badger (Private)
- (NSImage *) badgeWithNum: (int) num;
- (void) badgeString: (NSString *) string forRect: (NSRect) rect;
@end
@ -17,174 +17,173 @@
- (id) init
{
if ((self = [super init]))
{
fBadge = [NSImage imageNamed: @"Badge"];
fDockIcon = [[NSApp applicationIconImage] copy];
fBadgedDockIcon = [fDockIcon copy];
fBadgeAttributes = [[NSDictionary dictionaryWithObjectsAndKeys:
[NSColor whiteColor], NSForegroundColorAttributeName,
[NSFont fontWithName: @"Helvetica-Bold" size: 24], NSFontAttributeName,
nil] retain];
fStringAttributes = [[NSDictionary dictionaryWithObjectsAndKeys:
[NSColor whiteColor], NSForegroundColorAttributeName,
[NSFont fontWithName: @"Helvetica-Bold" size: 20], NSFontAttributeName,
nil] retain];
fUploadingColor = [[[NSColor greenColor] colorWithAlphaComponent: 0.65] retain];
fDownloadingColor = [[[NSColor blueColor] colorWithAlphaComponent: 0.65] retain];
fCompleted = 0;
}
return self;
if ((self = [super init]))
{
fBadge = [NSImage imageNamed: @"Badge"];
fDockIcon = [[NSApp applicationIconImage] copy];
fBadgedDockIcon = [fDockIcon copy];
fUploadBadge = [NSImage imageNamed: @"UploadBadge"];
fDownloadBadge = [NSImage imageNamed: @"DownloadBadge"];
NSShadow * stringShadow = [[NSShadow alloc] init];
[stringShadow setShadowOffset: NSMakeSize(2, -2)];
[stringShadow setShadowBlurRadius: 4];
fAttributes = [[NSDictionary dictionaryWithObjectsAndKeys:
[NSColor whiteColor], NSForegroundColorAttributeName,
[NSFont fontWithName: @"Helvetica-Bold" size: 28], NSFontAttributeName,
stringShadow, NSShadowAttributeName,
nil] retain];
[stringShadow release];
fCompleted = 0;
fSpeedShown = NO;
}
return self;
}
- (void) dealloc
{
[fDockIcon release];
[fBadgedDockIcon release];
[fDockIcon release];
[fBadgedDockIcon release];
[fBadgeAttributes release];
[fStringAttributes release];
[fUploadingColor release];
[fDownloadingColor release];
[fAttributes release];
[super dealloc];
[super dealloc];
}
- (void) updateBadgeWithCompleted: (int) completed
uploadRate: (NSString *) uploadRate
downloadRate: (NSString *) downloadRate
uploadRate: (NSString *) uploadRate
downloadRate: (NSString *) downloadRate
{
NSImage * dockIcon;
NSSize iconSize = [fDockIcon size];
//set seeding and downloading badges if there was a change
if (completed != fCompleted)
{
fCompleted = completed;
dockIcon = [fDockIcon copy];
[dockIcon lockFocus];
//set completed badge to top right
if (completed > 0)
{
NSSize badgeSize = [fBadge size];
[[self badgeWithNum: completed]
compositeToPoint: NSMakePoint(iconSize.width - badgeSize.width,
iconSize.height - badgeSize.height)
operation: NSCompositeSourceOver];
}
NSImage * dockIcon = nil;
NSSize iconSize = [fDockIcon size];
[dockIcon unlockFocus];
[fBadgedDockIcon release];
fBadgedDockIcon = [dockIcon copy];
}
else
dockIcon = [fBadgedDockIcon copy];
if (uploadRate || downloadRate)
{
//upload rate at bottom
float mainY = 5,
mainHeight = 25;
NSRect shapeRect = NSMakeRect(12.5, mainY, iconSize.width - 25, mainHeight);
NSRect leftRect, rightRect;
leftRect.origin.x = 0;
leftRect.origin.y = mainY;
leftRect.size.width = shapeRect.origin.x * 2.0;
leftRect.size.height = mainHeight;
rightRect = leftRect;
rightRect.origin.x = iconSize.width - rightRect.size.width;
NSRect textRect;
textRect.origin.y = mainY;
textRect.size.height = mainHeight;
[dockIcon lockFocus];
if (uploadRate)
{
float width = [uploadRate sizeWithAttributes: fStringAttributes].width;
textRect.origin.x = (iconSize.width - width) * 0.5;
textRect.size.width = width;
NSBezierPath * uploadOval = [NSBezierPath bezierPathWithRect: shapeRect];
[uploadOval appendBezierPathWithOvalInRect: leftRect];
[uploadOval appendBezierPathWithOvalInRect: rightRect];
[fUploadingColor set];
[uploadOval fill];
[uploadRate drawInRect: textRect withAttributes: fStringAttributes];
//shift up for download rate if there is an upload rate
float heightDiff = 27;
shapeRect.origin.y += heightDiff;
leftRect.origin.y += heightDiff;
rightRect.origin.y += heightDiff;
textRect.origin.y += heightDiff;
}
//download rate above upload rate
if (downloadRate)
{
float width = [downloadRate sizeWithAttributes: fStringAttributes].width;
textRect.origin.x = (iconSize.width - width) * 0.5;
textRect.size.width = width;
NSBezierPath * downloadOval = [NSBezierPath bezierPathWithRect: shapeRect];
[downloadOval appendBezierPathWithOvalInRect: leftRect];
[downloadOval appendBezierPathWithOvalInRect: rightRect];
[fDownloadingColor set];
[downloadOval fill];
[downloadRate drawInRect: textRect withAttributes: fStringAttributes];
}
[dockIcon unlockFocus];
}
[NSApp setApplicationIconImage: dockIcon];
[dockIcon release];
//set seeding and downloading badges if there was a change
if (completed != fCompleted)
{
fCompleted = completed;
dockIcon = [fDockIcon copy];
//set completed badge to top right
if (completed > 0)
{
NSRect badgeRect;
badgeRect.size = [fBadge size];
badgeRect.origin.x = iconSize.width - badgeRect.size.width;
badgeRect.origin.y = iconSize.height - badgeRect.size.height;
[dockIcon lockFocus];
//place badge
[fBadge compositeToPoint: badgeRect.origin
operation: NSCompositeSourceOver];
//ignore shadow of badge when placing string
float badgeBottomExtra = 5.0;
badgeRect.size.height -= badgeBottomExtra;
badgeRect.origin.y += badgeBottomExtra;
//place badge text
[self badgeString: [NSString stringWithFormat: @"%d", completed]
forRect: badgeRect];
[dockIcon unlockFocus];
}
[fBadgedDockIcon release];
fBadgedDockIcon = [dockIcon copy];
}
//display upload and download rates
BOOL speedShown = NO;
if (uploadRate || downloadRate)
{
speedShown = YES;
NSRect badgeRect, stringRect;
badgeRect.size = [fUploadBadge size];
badgeRect.origin = NSZeroPoint;
//ignore shadow of badge when placing string
float badgeBottomExtra = 2.0;
stringRect = badgeRect;
stringRect.size.height -= badgeBottomExtra;
stringRect.origin.y += badgeBottomExtra;
if (!dockIcon)
dockIcon = [fBadgedDockIcon copy];
[dockIcon lockFocus];
if (uploadRate)
{
//place badge
[fUploadBadge compositeToPoint: badgeRect.origin
operation: NSCompositeSourceOver];
//place badge text
[self badgeString: uploadRate forRect: stringRect];
}
if (downloadRate)
{
//download rate above upload rate
if (uploadRate)
{
float spaceBetween = badgeRect.size.height + 2.0;
badgeRect.origin.y += spaceBetween;
stringRect.origin.y += spaceBetween;
}
//place badge
[fDownloadBadge compositeToPoint: badgeRect.origin
operation: NSCompositeSourceOver];
//place badge text
[self badgeString: downloadRate forRect: stringRect];
}
[dockIcon unlockFocus];
}
if (dockIcon || fSpeedShown)
{
if (!dockIcon)
dockIcon = [fBadgedDockIcon copy];
[NSApp setApplicationIconImage: dockIcon];
[dockIcon release];
}
fSpeedShown = speedShown;
}
- (void) clearBadge
{
[fBadgedDockIcon release];
fBadgedDockIcon = [fDockIcon copy];
[fBadgedDockIcon release];
fBadgedDockIcon = [fDockIcon copy];
[NSApp setApplicationIconImage: fDockIcon];
[NSApp setApplicationIconImage: fDockIcon];
}
@end
@implementation Badger (Private)
- (NSImage *) badgeWithNum: (int) num
{
NSImage * badge = [[fBadge copy] autorelease];
NSString * numString = [NSString stringWithFormat: @"%d", num];
//number is in center of image
NSRect badgeRect;
NSSize numSize = [numString sizeWithAttributes: fBadgeAttributes];
badgeRect.size = [badge size];
badgeRect.origin.x = (badgeRect.size.width - numSize.width) * 0.5;
badgeRect.origin.y = badgeRect.size.height * 0.5 - numSize.height * 1.2;
[badge lockFocus];
[numString drawInRect: badgeRect withAttributes: fBadgeAttributes];
[badge unlockFocus];
return badge;
//dock icon must have locked focus
- (void) badgeString: (NSString *) string forRect: (NSRect) rect
{
NSSize stringSize = [string sizeWithAttributes: fAttributes];
//string is in center of image
rect.origin.x += (rect.size.width - stringSize.width) * 0.5;
rect.origin.y += (rect.size.height - stringSize.height) * 0.5;
[string drawAtPoint: rect.origin withAttributes: fAttributes];
}
@end

View File

@ -612,8 +612,8 @@ static void sleepCallBack( void * controller, io_service_t y,
//badge dock
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
[fBadger updateBadgeWithCompleted: [defaults boolForKey: @"BadgeCompleted"] ? fCompleted : 0
uploadRate: ul >= 0.1 && [defaults boolForKey: @"BadgeUploadRate"] ? uploadRate : nil
downloadRate: dl >= 0.1 && [defaults boolForKey: @"BadgeDownloadRate"] ? downloadRate : nil];
uploadRate: ul >= 0.1 && [defaults boolForKey: @"BadgeUploadRate"] ? [NSString stringForSpeedAbbrev: ul] : nil
downloadRate: dl >= 0.1 && [defaults boolForKey: @"BadgeDownloadRate"] ? [NSString stringForSpeedAbbrev: dl] : nil];
}
- (int) numberOfRowsInTableView: (NSTableView *) t

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 768 B

View File

@ -12,6 +12,7 @@
+ (NSString *) stringForFileSize: (uint64_t) size;
+ (NSString *) stringForSpeed: (float) speed;
+ (NSString *) stringForSpeedAbbrev: (float) speed;
+ (NSString *) stringForRatio: (uint64_t) down upload: (uint64_t) up;
- (NSString *) stringFittingInWidth: (float) width
withAttributes: (NSDictionary *) attributes;

View File

@ -27,13 +27,19 @@
}
+ (NSString *) stringForSpeed: (float) speed
{
return [[self stringForSpeedAbbrev: speed]
stringByAppendingString: @"B/s"];
}
+ (NSString *) stringForSpeedAbbrev: (float) speed
{
if (speed < 1024)
return [NSString stringWithFormat: @"%.1f KB/s", speed];
return [NSString stringWithFormat: @"%.1f K", speed];
else if (speed < 1048576)
return [NSString stringWithFormat: @"%.2f MB/s", speed / 1024];
return [NSString stringWithFormat: @"%.2f M", speed / 1024];
else
return [NSString stringWithFormat: @"%.2f GB/s", speed / 1048576];
return [NSString stringWithFormat: @"%.2f G", speed / 1048576];
}
+ (NSString *) stringForRatio: (uint64_t) down upload: (uint64_t) up

View File

@ -23,6 +23,8 @@
4DA6FDBB0911233800450CB1 /* PauseOff.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DA6FDB90911233800450CB1 /* PauseOff.png */; };
4DA6FDC5091141AD00450CB1 /* ResumeOff.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DA6FDC3091141AD00450CB1 /* ResumeOff.png */; };
4DA6FDC6091141AD00450CB1 /* ResumeOn.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DA6FDC4091141AD00450CB1 /* ResumeOn.png */; };
4DDFDD22099A5D8E00189D81 /* DownloadBadge.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DDFDD20099A5D8E00189D81 /* DownloadBadge.png */; };
4DDFDD23099A5D8E00189D81 /* UploadBadge.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DDFDD21099A5D8E00189D81 /* UploadBadge.png */; };
4DE5CC9D0980656F00BE280E /* StringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DE5CC9C0980656F00BE280E /* StringAdditions.m */; };
4DE5CCA70980735700BE280E /* Badger.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DE5CCA60980735700BE280E /* Badger.m */; };
4DE5CCA90980739100BE280E /* Badge.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DE5CCA80980739100BE280E /* Badge.png */; };
@ -96,6 +98,8 @@
4DA6FDB90911233800450CB1 /* PauseOff.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = PauseOff.png; path = Images/PauseOff.png; sourceTree = "<group>"; };
4DA6FDC3091141AD00450CB1 /* ResumeOff.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ResumeOff.png; path = Images/ResumeOff.png; sourceTree = "<group>"; };
4DA6FDC4091141AD00450CB1 /* ResumeOn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ResumeOn.png; path = Images/ResumeOn.png; sourceTree = "<group>"; };
4DDFDD20099A5D8E00189D81 /* DownloadBadge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = DownloadBadge.png; path = Images/DownloadBadge.png; sourceTree = "<group>"; };
4DDFDD21099A5D8E00189D81 /* UploadBadge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = UploadBadge.png; path = Images/UploadBadge.png; sourceTree = "<group>"; };
4DE5CC9B0980656F00BE280E /* StringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = StringAdditions.h; sourceTree = "<group>"; };
4DE5CC9C0980656F00BE280E /* StringAdditions.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = StringAdditions.m; sourceTree = "<group>"; };
4DE5CCA50980735700BE280E /* Badger.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Badger.h; sourceTree = "<group>"; };
@ -216,6 +220,8 @@
4D752E920913C949008EAAD4 /* Preferences.png */,
4D8CEF90095870E00063BAEA /* Network.png */,
4DE5CCA80980739100BE280E /* Badge.png */,
4DDFDD20099A5D8E00189D81 /* DownloadBadge.png */,
4DDFDD21099A5D8E00189D81 /* UploadBadge.png */,
4DE5CCB80981D27700BE280E /* ResumeAll.png */,
4DE5CCB90981D27700BE280E /* PauseAll.png */,
4DE5CCCA0981D9BE00BE280E /* Defaults.plist */,
@ -313,6 +319,8 @@
4DE5CCBA0981D27700BE280E /* ResumeAll.png in Resources */,
4DE5CCBB0981D27700BE280E /* PauseAll.png in Resources */,
4DE5CCCB0981D9BE00BE280E /* Defaults.plist in Resources */,
4DDFDD22099A5D8E00189D81 /* DownloadBadge.png in Resources */,
4DDFDD23099A5D8E00189D81 /* UploadBadge.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};