source: trunk/macosx/Badger.m @ 7069

Last change on this file since 7069 was 7069, checked in by charles, 13 years ago

more fucking around with the speed measurements.

  • Property svn:keywords set to Date Rev Author Id
File size: 10.0 KB
Line 
1/******************************************************************************
2 * $Id: Badger.m 7069 2008-11-08 02:49:04Z charles $
3 *
4 * Copyright (c) 2006-2008 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#import "Badger.h"
26#import "BadgeView.h"
27#import "NSApplicationAdditions.h"
28#import "NSStringAdditions.h"
29
30#define COMPLETED_BOTTOM_PADDING 5.0
31#define SPEED_BOTTOM_PADDING 2.0
32#define SPEED_BETWEEN_PADDING 2.0
33#define BADGE_HEIGHT 30.0
34
35@interface Badger (Private)
36
37- (void) badgeString: (NSString *) string forRect: (NSRect) rect;
38
39@end
40
41@implementation Badger
42
43- (id) initWithLib: (tr_handle *) lib
44{
45    if ((self = [super init]))
46    {
47        fLib = lib;
48       
49        fCompleted = 0;
50       
51        if ([NSApp isOnLeopardOrBetter])
52        {
53            BadgeView * view = [[BadgeView alloc] initWithFrame: [[[NSApp dockTile] contentView] frame] lib: lib];
54            [[NSApp dockTile] setContentView: view];
55            [view release];
56        }
57        else
58        {
59            fQuittingTiger = NO;
60            fSpeedBadge = NO;
61            fCompletedBadged = 0;
62        }
63       
64        //change that just impacts the dock badge
65        [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateBadge) name: @"DockBadgeChange" object: nil];
66    }
67   
68    return self;
69}
70
71- (void) dealloc
72{
73    [[NSNotificationCenter defaultCenter] removeObserver: self];
74   
75    if (![NSApp isOnLeopardOrBetter])
76        [NSApp setApplicationIconImage: nil]; //needed on 10.4
77   
78    [fDockIcon release];
79    [fAttributes release];
80   
81    [super dealloc];
82}
83
84- (void) updateBadge
85{
86    if ([NSApp isOnLeopardOrBetter])
87    {
88        BOOL badgeDownload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeDownloadRate"],
89            badgeUpload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeUploadRate"];
90        float downloadRate = badgeDownload ? tr_sessionGetPieceSpeed( fLib, TR_DOWN ) : 0.0f;
91        float uploadRate   = badgeUpload   ? tr_sessionGetPieceSpeed( fLib, TR_UP   ) : 0.0f;
92       
93        //only update if the badged values change
94        if ([(BadgeView *)[[NSApp dockTile] contentView] setRatesWithDownload: downloadRate upload: uploadRate])
95            [[NSApp dockTile] display];
96       
97        return;
98    }
99    else if (fQuittingTiger)
100        return;
101    else;
102   
103    //set completed badge to top right
104    BOOL completedChange = fCompleted != fCompletedBadged;
105    if (completedChange)
106    {
107        fCompletedBadged = fCompleted;
108       
109        //force image to reload - copy does not work
110        NSImage * icon = [[NSImage imageNamed: @"NSApplicationIcon"] copy];
111        NSSize iconSize = [icon size];
112       
113        [fDockIcon release];
114        fDockIcon = [[NSImage alloc] initWithSize: iconSize];
115        [fDockIcon addRepresentation: [icon bestRepresentationForDevice: nil]];
116        [icon release];
117       
118        if (fCompleted > 0)
119        {
120            if (!fBadge)
121                fBadge = [NSImage imageNamed: @"Badge"];
122           
123            NSRect badgeRect;
124            badgeRect.size = [fBadge size];
125            badgeRect.origin.x = iconSize.width - badgeRect.size.width;
126            badgeRect.origin.y = iconSize.height - badgeRect.size.height;
127           
128            [fDockIcon lockFocus];
129           
130            //place badge
131            [fBadge compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
132           
133            //ignore shadow of badge when placing string
134            badgeRect.size.height -= COMPLETED_BOTTOM_PADDING;
135            badgeRect.origin.y += COMPLETED_BOTTOM_PADDING;
136           
137            //place badge text
138            [self badgeString: [NSString stringWithFormat: @"%d", fCompleted] forRect: badgeRect];
139                       
140            [fDockIcon unlockFocus];
141        }
142    }
143   
144    NSImage * dockIcon = nil;
145    BOOL speedBadge = NO;
146   
147    BOOL checkDownload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeDownloadRate"],
148        checkUpload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeUploadRate"];
149    if (checkDownload || checkUpload)
150    {
151        //set upload and download rate badges
152        NSString * downloadRateString = nil, * uploadRateString = nil;
153       
154        float downloadRate = tr_sessionGetPieceSpeed( fLib, TR_DOWN );
155        float uploadRate   = tr_sessionGetPieceSpeed( fLib, TR_UP );
156       
157        if (checkDownload && downloadRate >= 0.1)
158            downloadRateString = [NSString stringForSpeedAbbrev: downloadRate];
159        if (checkUpload && uploadRate >= 0.1)
160            uploadRateString = [NSString stringForSpeedAbbrev: uploadRate];
161       
162        speedBadge = uploadRateString || downloadRateString;
163        if (speedBadge)
164        {
165            if (!fDockIcon)
166                fDockIcon = [[NSImage imageNamed: @"NSApplicationIcon"] copy];
167            dockIcon = [fDockIcon copy];
168           
169            NSRect badgeRect;
170            badgeRect.size = [[NSImage imageNamed: @"UploadBadge.png"] size];
171            badgeRect.origin = NSZeroPoint;
172           
173            //ignore shadow of badge when placing string
174            NSRect stringRect = badgeRect;
175            stringRect.size.height -= SPEED_BOTTOM_PADDING;
176            stringRect.origin.y += SPEED_BOTTOM_PADDING;
177           
178            [dockIcon lockFocus];
179           
180            if (uploadRateString)
181            {
182                //place badge and text
183                [[NSImage imageNamed: @"UploadBadge.png"] compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
184                [self badgeString: uploadRateString forRect: stringRect];
185            }
186           
187            if (downloadRateString)
188            {
189                //download rate above upload rate
190                if (uploadRateString)
191                {
192                    float spaceBetween = badgeRect.size.height + SPEED_BETWEEN_PADDING;
193                    badgeRect.origin.y += spaceBetween;
194                    stringRect.origin.y += spaceBetween;
195                }
196               
197                //place badge and text
198                [[NSImage imageNamed: @"DownloadBadge.png"] compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
199                [self badgeString: downloadRateString forRect: stringRect];
200            }
201           
202            [dockIcon unlockFocus];
203        }
204    }
205   
206    //update dock badge
207    if (fSpeedBadge || speedBadge || completedChange)
208    {
209        [NSApp setApplicationIconImage: dockIcon ? dockIcon : fDockIcon];
210        [dockIcon release];
211       
212        fSpeedBadge = speedBadge;
213    }
214}
215
216- (void) incrementCompleted
217{
218    fCompleted++;
219   
220    if ([NSApp isOnLeopardOrBetter])
221        [[NSApp dockTile] setBadgeLabel: [NSString stringWithFormat: @"%d", fCompleted]];
222    else
223        [self updateBadge];
224}
225
226- (void) clearCompleted
227{
228    if (fCompleted != 0)
229    {
230        fCompleted = 0;
231        if ([NSApp isOnLeopardOrBetter])
232            [[NSApp dockTile] setBadgeLabel: @""];
233        else
234            [self updateBadge];
235    }
236}
237
238- (void) setQuitting
239{
240    if ([NSApp isOnLeopardOrBetter])
241    {
242        [self clearCompleted];
243        [(BadgeView *)[[NSApp dockTile] contentView] setQuitting];
244        [[NSApp dockTile] display];
245    }
246    else
247    {
248        fQuittingTiger = YES;
249       
250        fSpeedBadge = NO;
251        fCompleted = 0;
252        fCompletedBadged = 0;
253       
254        NSImage * quitIcon = [[NSImage imageNamed: @"NSApplicationIcon"] copy];
255        NSRect rect = NSZeroRect;
256        rect.size = [quitIcon size];
257       
258        NSRect badgeRect = NSMakeRect(0.0, (rect.size.height - BADGE_HEIGHT) * 0.5, rect.size.width, BADGE_HEIGHT);
259       
260        [quitIcon lockFocus];
261       
262        [[NSImage imageNamed: @"QuitBadge.png"] compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
263        [self badgeString: NSLocalizedString(@"Quitting", "Dock Badger -> quit message") forRect: badgeRect];
264       
265        [quitIcon unlockFocus];
266       
267        [NSApp setApplicationIconImage: quitIcon];
268        [quitIcon release];
269    }
270}
271
272@end
273
274@implementation Badger (Private)
275
276//dock icon must have locked focus
277- (void) badgeString: (NSString *) string forRect: (NSRect) rect
278{
279    if (!fAttributes)
280    {
281        NSShadow * stringShadow = [[NSShadow alloc] init];
282        [stringShadow setShadowOffset: NSMakeSize(2.0, -2.0)];
283        [stringShadow setShadowBlurRadius: 4.0];
284       
285        fAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
286            [NSColor whiteColor], NSForegroundColorAttributeName,
287            [NSFont boldSystemFontOfSize: 26.0], NSFontAttributeName, stringShadow, NSShadowAttributeName, nil];
288       
289        [stringShadow release];
290    }
291   
292    NSSize stringSize = [string sizeWithAttributes: fAttributes];
293   
294    //string is in center of image
295    rect.origin.x += (rect.size.width - stringSize.width) * 0.5;
296    rect.origin.y += (rect.size.height - stringSize.height) * 0.5;
297    rect.size = stringSize;
298                       
299    [string drawInRect: rect withAttributes: fAttributes];
300}
301
302@end
Note: See TracBrowser for help on using the repository browser.