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 { @interface Badger : NSObject {
NSImage * fBadge, * fDockIcon, * fBadgedDockIcon; NSImage * fDockIcon, * fBadgedDockIcon,
* fBadge, * fUploadBadge, * fDownloadBadge;
NSDictionary * fBadgeAttributes, * fStringAttributes;
NSDictionary * fAttributes;
NSColor * fUploadingColor, * fDownloadingColor;
int fCompleted;
int fCompleted; BOOL fSpeedShown;
} }
- (void) updateBadgeWithCompleted: (int) completed - (void) updateBadgeWithCompleted: (int) completed
uploadRate: (NSString *) uploadRate uploadRate: (NSString *) uploadRate
downloadRate: (NSString *) downloadRate; downloadRate: (NSString *) downloadRate;
- (void) clearBadge; - (void) clearBadge;
@end @end

View File

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

View File

@ -612,8 +612,8 @@ static void sleepCallBack( void * controller, io_service_t y,
//badge dock //badge dock
NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
[fBadger updateBadgeWithCompleted: [defaults boolForKey: @"BadgeCompleted"] ? fCompleted : 0 [fBadger updateBadgeWithCompleted: [defaults boolForKey: @"BadgeCompleted"] ? fCompleted : 0
uploadRate: ul >= 0.1 && [defaults boolForKey: @"BadgeUploadRate"] ? uploadRate : nil uploadRate: ul >= 0.1 && [defaults boolForKey: @"BadgeUploadRate"] ? [NSString stringForSpeedAbbrev: ul] : nil
downloadRate: dl >= 0.1 && [defaults boolForKey: @"BadgeDownloadRate"] ? downloadRate : nil]; downloadRate: dl >= 0.1 && [defaults boolForKey: @"BadgeDownloadRate"] ? [NSString stringForSpeedAbbrev: dl] : nil];
} }
- (int) numberOfRowsInTableView: (NSTableView *) t - (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 *) stringForFileSize: (uint64_t) size;
+ (NSString *) stringForSpeed: (float) speed; + (NSString *) stringForSpeed: (float) speed;
+ (NSString *) stringForSpeedAbbrev: (float) speed;
+ (NSString *) stringForRatio: (uint64_t) down upload: (uint64_t) up; + (NSString *) stringForRatio: (uint64_t) down upload: (uint64_t) up;
- (NSString *) stringFittingInWidth: (float) width - (NSString *) stringFittingInWidth: (float) width
withAttributes: (NSDictionary *) attributes; withAttributes: (NSDictionary *) attributes;

View File

@ -27,13 +27,19 @@
} }
+ (NSString *) stringForSpeed: (float) speed + (NSString *) stringForSpeed: (float) speed
{
return [[self stringForSpeedAbbrev: speed]
stringByAppendingString: @"B/s"];
}
+ (NSString *) stringForSpeedAbbrev: (float) speed
{ {
if (speed < 1024) if (speed < 1024)
return [NSString stringWithFormat: @"%.1f KB/s", speed]; return [NSString stringWithFormat: @"%.1f K", speed];
else if (speed < 1048576) else if (speed < 1048576)
return [NSString stringWithFormat: @"%.2f MB/s", speed / 1024]; return [NSString stringWithFormat: @"%.2f M", speed / 1024];
else 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 + (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 */; }; 4DA6FDBB0911233800450CB1 /* PauseOff.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DA6FDB90911233800450CB1 /* PauseOff.png */; };
4DA6FDC5091141AD00450CB1 /* ResumeOff.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DA6FDC3091141AD00450CB1 /* ResumeOff.png */; }; 4DA6FDC5091141AD00450CB1 /* ResumeOff.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DA6FDC3091141AD00450CB1 /* ResumeOff.png */; };
4DA6FDC6091141AD00450CB1 /* ResumeOn.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DA6FDC4091141AD00450CB1 /* ResumeOn.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 */; }; 4DE5CC9D0980656F00BE280E /* StringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DE5CC9C0980656F00BE280E /* StringAdditions.m */; };
4DE5CCA70980735700BE280E /* Badger.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DE5CCA60980735700BE280E /* Badger.m */; }; 4DE5CCA70980735700BE280E /* Badger.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DE5CCA60980735700BE280E /* Badger.m */; };
4DE5CCA90980739100BE280E /* Badge.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DE5CCA80980739100BE280E /* Badge.png */; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 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>"; }; 4DE5CCA50980735700BE280E /* Badger.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Badger.h; sourceTree = "<group>"; };
@ -216,6 +220,8 @@
4D752E920913C949008EAAD4 /* Preferences.png */, 4D752E920913C949008EAAD4 /* Preferences.png */,
4D8CEF90095870E00063BAEA /* Network.png */, 4D8CEF90095870E00063BAEA /* Network.png */,
4DE5CCA80980739100BE280E /* Badge.png */, 4DE5CCA80980739100BE280E /* Badge.png */,
4DDFDD20099A5D8E00189D81 /* DownloadBadge.png */,
4DDFDD21099A5D8E00189D81 /* UploadBadge.png */,
4DE5CCB80981D27700BE280E /* ResumeAll.png */, 4DE5CCB80981D27700BE280E /* ResumeAll.png */,
4DE5CCB90981D27700BE280E /* PauseAll.png */, 4DE5CCB90981D27700BE280E /* PauseAll.png */,
4DE5CCCA0981D9BE00BE280E /* Defaults.plist */, 4DE5CCCA0981D9BE00BE280E /* Defaults.plist */,
@ -313,6 +319,8 @@
4DE5CCBA0981D27700BE280E /* ResumeAll.png in Resources */, 4DE5CCBA0981D27700BE280E /* ResumeAll.png in Resources */,
4DE5CCBB0981D27700BE280E /* PauseAll.png in Resources */, 4DE5CCBB0981D27700BE280E /* PauseAll.png in Resources */,
4DE5CCCB0981D9BE00BE280E /* Defaults.plist in Resources */, 4DE5CCCB0981D9BE00BE280E /* Defaults.plist in Resources */,
4DDFDD22099A5D8E00189D81 /* DownloadBadge.png in Resources */,
4DDFDD23099A5D8E00189D81 /* UploadBadge.png in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };