source: trunk/macosx/Badger.m @ 6995

Last change on this file since 6995 was 6995, checked in by livings124, 10 years ago

CTGradientAdditions is now ProgressGradients?

  • Property svn:keywords set to Date Rev Author Id
File size: 10.0 KB
Line 
1/******************************************************************************
2 * $Id: Badger.m 6995 2008-10-31 00:13:50Z livings124 $
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        float downloadRate = 0.0, uploadRate = 0.0;
89        BOOL badgeDownload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeDownloadRate"],
90            badgeUpload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeUploadRate"];
91        if (badgeDownload || badgeUpload)
92            tr_sessionGetSpeed(fLib, badgeDownload ? &downloadRate : NULL, badgeUpload ? &uploadRate : NULL);
93       
94        //only update if the badged values change
95        if ([(BadgeView *)[[NSApp dockTile] contentView] setRatesWithDownload: downloadRate upload: uploadRate])
96            [[NSApp dockTile] display];
97       
98        return;
99    }
100    else if (fQuittingTiger)
101        return;
102    else;
103   
104    //set completed badge to top right
105    BOOL completedChange = fCompleted != fCompletedBadged;
106    if (completedChange)
107    {
108        fCompletedBadged = fCompleted;
109       
110        //force image to reload - copy does not work
111        NSImage * icon = [[NSImage imageNamed: @"NSApplicationIcon"] copy];
112        NSSize iconSize = [icon size];
113       
114        [fDockIcon release];
115        fDockIcon = [[NSImage alloc] initWithSize: iconSize];
116        [fDockIcon addRepresentation: [icon bestRepresentationForDevice: nil]];
117        [icon release];
118       
119        if (fCompleted > 0)
120        {
121            if (!fBadge)
122                fBadge = [NSImage imageNamed: @"Badge"];
123           
124            NSRect badgeRect;
125            badgeRect.size = [fBadge size];
126            badgeRect.origin.x = iconSize.width - badgeRect.size.width;
127            badgeRect.origin.y = iconSize.height - badgeRect.size.height;
128           
129            [fDockIcon lockFocus];
130           
131            //place badge
132            [fBadge compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
133           
134            //ignore shadow of badge when placing string
135            badgeRect.size.height -= COMPLETED_BOTTOM_PADDING;
136            badgeRect.origin.y += COMPLETED_BOTTOM_PADDING;
137           
138            //place badge text
139            [self badgeString: [NSString stringWithFormat: @"%d", fCompleted] forRect: badgeRect];
140                       
141            [fDockIcon unlockFocus];
142        }
143    }
144   
145    NSImage * dockIcon = nil;
146    BOOL speedBadge = NO;
147   
148    BOOL checkDownload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeDownloadRate"],
149        checkUpload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeUploadRate"];
150    if (checkDownload || checkUpload)
151    {
152        //set upload and download rate badges
153        NSString * downloadRateString = nil, * uploadRateString = nil;
154       
155        float downloadRate, uploadRate;
156        tr_sessionGetSpeed(fLib, &downloadRate, &uploadRate);
157       
158        if (checkDownload && downloadRate >= 0.1)
159            downloadRateString = [NSString stringForSpeedAbbrev: downloadRate];
160        if (checkUpload && uploadRate >= 0.1)
161            uploadRateString = [NSString stringForSpeedAbbrev: uploadRate];
162       
163        speedBadge = uploadRateString || downloadRateString;
164        if (speedBadge)
165        {
166            if (!fDockIcon)
167                fDockIcon = [[NSImage imageNamed: @"NSApplicationIcon"] copy];
168            dockIcon = [fDockIcon copy];
169           
170            NSRect badgeRect;
171            badgeRect.size = [[NSImage imageNamed: @"UploadBadge.png"] size];
172            badgeRect.origin = NSZeroPoint;
173           
174            //ignore shadow of badge when placing string
175            NSRect stringRect = badgeRect;
176            stringRect.size.height -= SPEED_BOTTOM_PADDING;
177            stringRect.origin.y += SPEED_BOTTOM_PADDING;
178           
179            [dockIcon lockFocus];
180           
181            if (uploadRateString)
182            {
183                //place badge and text
184                [[NSImage imageNamed: @"UploadBadge.png"] compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
185                [self badgeString: uploadRateString forRect: stringRect];
186            }
187           
188            if (downloadRateString)
189            {
190                //download rate above upload rate
191                if (uploadRateString)
192                {
193                    float spaceBetween = badgeRect.size.height + SPEED_BETWEEN_PADDING;
194                    badgeRect.origin.y += spaceBetween;
195                    stringRect.origin.y += spaceBetween;
196                }
197               
198                //place badge and text
199                [[NSImage imageNamed: @"DownloadBadge.png"] compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
200                [self badgeString: downloadRateString forRect: stringRect];
201            }
202           
203            [dockIcon unlockFocus];
204        }
205    }
206   
207    //update dock badge
208    if (fSpeedBadge || speedBadge || completedChange)
209    {
210        [NSApp setApplicationIconImage: dockIcon ? dockIcon : fDockIcon];
211        [dockIcon release];
212       
213        fSpeedBadge = speedBadge;
214    }
215}
216
217- (void) incrementCompleted
218{
219    fCompleted++;
220   
221    if ([NSApp isOnLeopardOrBetter])
222        [[NSApp dockTile] setBadgeLabel: [NSString stringWithFormat: @"%d", fCompleted]];
223    else
224        [self updateBadge];
225}
226
227- (void) clearCompleted
228{
229    if (fCompleted != 0)
230    {
231        fCompleted = 0;
232        if ([NSApp isOnLeopardOrBetter])
233            [[NSApp dockTile] setBadgeLabel: @""];
234        else
235            [self updateBadge];
236    }
237}
238
239- (void) setQuitting
240{
241    if ([NSApp isOnLeopardOrBetter])
242    {
243        [self clearCompleted];
244        [(BadgeView *)[[NSApp dockTile] contentView] setQuitting];
245        [[NSApp dockTile] display];
246    }
247    else
248    {
249        fQuittingTiger = YES;
250       
251        fSpeedBadge = NO;
252        fCompleted = 0;
253        fCompletedBadged = 0;
254       
255        NSImage * quitIcon = [[NSImage imageNamed: @"NSApplicationIcon"] copy];
256        NSRect rect = NSZeroRect;
257        rect.size = [quitIcon size];
258       
259        NSRect badgeRect = NSMakeRect(0.0, (rect.size.height - BADGE_HEIGHT) * 0.5, rect.size.width, BADGE_HEIGHT);
260       
261        [quitIcon lockFocus];
262       
263        [[NSImage imageNamed: @"QuitBadge.png"] compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
264        [self badgeString: NSLocalizedString(@"Quitting", "Dock Badger -> quit message") forRect: badgeRect];
265       
266        [quitIcon unlockFocus];
267       
268        [NSApp setApplicationIconImage: quitIcon];
269        [quitIcon release];
270    }
271}
272
273@end
274
275@implementation Badger (Private)
276
277//dock icon must have locked focus
278- (void) badgeString: (NSString *) string forRect: (NSRect) rect
279{
280    if (!fAttributes)
281    {
282        NSShadow * stringShadow = [[NSShadow alloc] init];
283        [stringShadow setShadowOffset: NSMakeSize(2.0, -2.0)];
284        [stringShadow setShadowBlurRadius: 4.0];
285       
286        fAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
287            [NSColor whiteColor], NSForegroundColorAttributeName,
288            [NSFont boldSystemFontOfSize: 26.0], NSFontAttributeName, stringShadow, NSShadowAttributeName, nil];
289       
290        [stringShadow release];
291    }
292   
293    NSSize stringSize = [string sizeWithAttributes: fAttributes];
294   
295    //string is in center of image
296    rect.origin.x += (rect.size.width - stringSize.width) * 0.5;
297    rect.origin.y += (rect.size.height - stringSize.height) * 0.5;
298    rect.size = stringSize;
299                       
300    [string drawInRect: rect withAttributes: fAttributes];
301}
302
303@end
Note: See TracBrowser for help on using the repository browser.