This adds badging

This commit is contained in:
Eric Petit 2006-01-20 01:51:07 +00:00
parent 16a8e74cdc
commit 80b7627b5c
6 changed files with 256 additions and 4 deletions

31
macosx/Badger.h Normal file
View File

@ -0,0 +1,31 @@
//
// Badger.h
// Transmission
//
// Created by Mitchell Livingston on 12/21/05.
//
#ifndef BADGER_H
#define BADGER_H
#import <Cocoa/Cocoa.h>
@interface Badger : NSObject {
NSImage * fBadge, * fDockIcon, * fBadgedDockIcon;
NSDictionary * fBadgeAttributes, * fStringAttributes;
NSColor * fUploadingColor, * fDownloadingColor;
int fCompleted;
}
- (void) updateBadgeWithCompleted: (int) completed
uploadRate: (NSString *) uploadRate
downloadRate: (NSString *) downloadRate;
- (void) clearBadge;
@end
#endif

190
macosx/Badger.m Normal file
View File

@ -0,0 +1,190 @@
//
// Badger.m
// Transmission
//
// Created by Mitchell Livingston on 12/21/05.
//
#import "Badger.h"
@interface Badger (Private)
- (NSImage *) badgeWithNum: (int) num;
@end
@implementation Badger
- (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;
}
- (void) dealloc
{
[fDockIcon release];
[fBadgedDockIcon release];
[fBadgeAttributes release];
[fStringAttributes release];
[fUploadingColor release];
[fDownloadingColor release];
[super dealloc];
}
- (void) updateBadgeWithCompleted: (int) completed
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];
}
[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];
}
- (void) clearBadge
{
[fBadgedDockIcon release];
fBadgedDockIcon = [fDockIcon copy];
[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;
}
@end

View File

@ -26,13 +26,14 @@
#import <Cocoa/Cocoa.h>
#import <transmission.h>
#import "PrefsController.h"
#import "Badger.h"
@class TorrentTableView;
@interface Controller : NSObject
{
tr_handle_t * fHandle;
int fCount;
int fCount, fCompleted;
tr_stat_t * fStat;
int fResumeOnWake[TR_MAX_TORRENT_COUNT];
@ -74,6 +75,7 @@
NSUserDefaults * fDefaults;
BOOL fHasGrowl;
Badger * fBadger;
}
- (void) advancedChanged: (id) sender;

View File

@ -133,6 +133,10 @@ static void sleepCallBack( void * controller, io_service_t y,
|| [manager fileExistsAtPath: [[NSString stringWithFormat: @"~%@",
GROWL_PATH] stringByExpandingTildeInPath]];
[self growlRegister: self];
//initialize badging
fBadger = [[Badger alloc] init];
fCompleted = 0;
//update the interface every 500 ms
fCount = 0;
@ -143,6 +147,12 @@ static void sleepCallBack( void * controller, io_service_t y,
forMode: NSEventTrackingRunLoopMode];
}
- (void) windowDidBecomeKey: (NSNotification *) n
{
/* Reset the number of recently completed downloads */
fCompleted = 0;
}
- (void) windowDidResize: (NSNotification *) n
{
[fTableView sizeToFit];
@ -557,8 +567,10 @@ static void sleepCallBack( void * controller, io_service_t y,
//Update the global DL/UL rates
tr_torrentRates( fHandle, &dl, &ul );
[fTotalDLField setStringValue: [NSString stringForSpeed: dl]];
[fTotalULField setStringValue: [NSString stringForSpeed: ul]];
NSString * downloadRate = [NSString stringForSpeed: dl];
NSString * uploadRate = [NSString stringForSpeed: ul];
[fTotalDLField setStringValue: downloadRate];
[fTotalULField setStringValue: uploadRate];
//Update DL/UL totals in the Info panel
row = [fTableView selectedRow];
@ -575,11 +587,18 @@ static void sleepCallBack( void * controller, io_service_t y,
{
if( !tr_getFinished( fHandle, i ) )
continue;
fCompleted++;
[self notifyGrowl: [NSString stringWithUTF8String:
fStat[i].info.name]];
tr_setFinished( fHandle, i, 0 );
}
//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];
}
- (int) numberOfRowsInTableView: (NSTableView *) t

BIN
macosx/Images/Badge.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -24,6 +24,8 @@
4DA6FDC5091141AD00450CB1 /* ResumeOff.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DA6FDC3091141AD00450CB1 /* ResumeOff.png */; };
4DA6FDC6091141AD00450CB1 /* ResumeOn.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DA6FDC4091141AD00450CB1 /* ResumeOn.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 */; };
4DF0C5AB0899190500DD8943 /* Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = 4DF0C5A90899190500DD8943 /* Controller.m */; };
4DF0C5AE08991C1600DD8943 /* libtransmission.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DF0C5AD08991C1600DD8943 /* libtransmission.a */; };
4DF7500C08A103AD007B0D70 /* Open.png in Resources */ = {isa = PBXBuildFile; fileRef = 4DF7500708A103AD007B0D70 /* Open.png */; };
@ -93,6 +95,9 @@
4DA6FDC4091141AD00450CB1 /* ResumeOn.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ResumeOn.png; path = Images/ResumeOn.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>"; };
4DE5CCA60980735700BE280E /* Badger.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = Badger.m; sourceTree = "<group>"; };
4DE5CCA80980739100BE280E /* Badge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Badge.png; path = Images/Badge.png; sourceTree = "<group>"; };
4DF0C5A90899190500DD8943 /* Controller.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = Controller.m; sourceTree = "<group>"; };
4DF0C5AA0899190500DD8943 /* Controller.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = "<group>"; };
4DF0C5AD08991C1600DD8943 /* libtransmission.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtransmission.a; path = ../libtransmission/libtransmission.a; sourceTree = SOURCE_ROOT; };
@ -132,6 +137,8 @@
4D364D9F091FBB2C00377D12 /* TorrentTableView.m */,
4DE5CC9B0980656F00BE280E /* StringAdditions.h */,
4DE5CC9C0980656F00BE280E /* StringAdditions.m */,
4DE5CCA50980735700BE280E /* Badger.h */,
4DE5CCA60980735700BE280E /* Badger.m */,
);
name = Classes;
sourceTree = "<group>";
@ -202,6 +209,7 @@
4DA6FDC4091141AD00450CB1 /* ResumeOn.png */,
4D752E920913C949008EAAD4 /* Preferences.png */,
4D8CEF90095870E00063BAEA /* Network.png */,
4DE5CCA80980739100BE280E /* Badge.png */,
8D1107310486CEB800E47090 /* Info.plist */,
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
29B97318FDCFA39411CA2CEA /* MainMenu.nib */,
@ -292,6 +300,7 @@
4DA6FDC6091141AD00450CB1 /* ResumeOn.png in Resources */,
4D752E930913C949008EAAD4 /* Preferences.png in Resources */,
4D8CEF91095870E00063BAEA /* Network.png in Resources */,
4DE5CCA90980739100BE280E /* Badge.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -309,6 +318,7 @@
4D118E1A08CB46B20033958F /* PrefsController.m in Sources */,
4D364DA0091FBB2C00377D12 /* TorrentTableView.m in Sources */,
4DE5CC9D0980656F00BE280E /* StringAdditions.m in Sources */,
4DE5CCA70980735700BE280E /* Badger.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};