source: trunk/macosx/Badger.m @ 3714

Last change on this file since 3714 was 3714, checked in by livings124, 15 years ago

move dock badging preference change notification into the Badger

  • Property svn:keywords set to Date Rev Author Id
File size: 8.5 KB
Line 
1/******************************************************************************
2 * $Id: Badger.m 3714 2007-11-05 12:47:20Z livings124 $
3 *
4 * Copyright (c) 2006-2007 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
34@interface Badger (Private)
35
36- (void) badgeString: (NSString *) string forRect: (NSRect) rect;
37
38@end
39
40@implementation Badger
41
42- (id) initWithLib: (tr_handle *) lib
43{
44    if ((self = [super init]))
45    {
46        fLib = lib;
47       
48        fCompleted = 0;
49        fCompletedBadged = 0;
50        fSpeedBadge = NO;
51       
52        if ([NSApp isOnLeopardOrBetter])
53        {
54            BadgeView * view = [[BadgeView alloc] initWithFrame: [[[NSApp dockTile] contentView] frame] lib: lib];
55            [[NSApp dockTile] setContentView: view];
56            [view release];
57        }
58       
59        //change that just impacts the dock badge
60        [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateBadge)
61                                                name: @"DockBadgeChange" object: nil];
62    }
63   
64    return self;
65}
66
67- (void) dealloc
68{
69    [[NSNotificationCenter defaultCenter] removeObserver: self];
70   
71    [fDockIcon release];
72    [fAttributes release];
73   
74    [super dealloc];
75}
76
77- (void) updateBadge
78{
79    if ([NSApp isOnLeopardOrBetter])
80    {
81        [[NSApp dockTile] display];
82        return;
83    }
84   
85    //set completed badge to top right
86    BOOL completedChange = fCompleted != fCompletedBadged;
87    if (completedChange)
88    {
89        fCompletedBadged = fCompleted;
90       
91        //force image to reload - copy does not work
92        NSImage * icon = [[NSImage imageNamed: @"NSApplicationIcon"] copy];
93        NSSize iconSize = [icon size];
94       
95        [fDockIcon release];
96        fDockIcon = [[NSImage alloc] initWithSize: iconSize];
97        [fDockIcon addRepresentation: [icon bestRepresentationForDevice: nil]];
98        [icon release];
99       
100        if (fCompleted > 0)
101        {
102            if (!fBadge)
103                fBadge = [NSImage imageNamed: @"Badge"];
104           
105            NSRect badgeRect;
106            badgeRect.size = [fBadge size];
107            badgeRect.origin.x = iconSize.width - badgeRect.size.width;
108            badgeRect.origin.y = iconSize.height - badgeRect.size.height;
109           
110            [fDockIcon lockFocus];
111           
112            //place badge
113            [fBadge compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
114           
115            //ignore shadow of badge when placing string
116            badgeRect.size.height -= COMPLETED_BOTTOM_PADDING;
117            badgeRect.origin.y += COMPLETED_BOTTOM_PADDING;
118           
119            //place badge text
120            [self badgeString: [NSString stringWithFormat: @"%d", fCompleted] forRect: badgeRect];
121                       
122            [fDockIcon unlockFocus];
123        }
124    }
125   
126    NSImage * dockIcon = nil;
127    BOOL speedBadge = NO;
128   
129    BOOL checkDownload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeDownloadRate"],
130        checkUpload = [[NSUserDefaults standardUserDefaults] boolForKey: @"BadgeUploadRate"];
131    if (checkDownload || checkUpload)
132    {
133        //set upload and download rate badges
134        NSString * downloadRateString = nil, * uploadRateString = nil;
135       
136        float downloadRate, uploadRate;
137        tr_torrentRates(fLib, &downloadRate, &uploadRate);
138       
139        if (checkDownload && downloadRate >= 0.1)
140            downloadRateString = [NSString stringForSpeedAbbrev: downloadRate];
141        if (checkUpload && uploadRate >= 0.1)
142            uploadRateString = [NSString stringForSpeedAbbrev: uploadRate];
143       
144        speedBadge = uploadRateString || downloadRateString;
145        if (speedBadge)
146        {
147            if (!fDockIcon)
148                fDockIcon = [[NSImage imageNamed: @"NSApplicationIcon"] copy];
149            dockIcon = [fDockIcon copy];
150           
151            if (!fUploadBadge)
152                fUploadBadge = [NSImage imageNamed: @"UploadBadge"];
153           
154            NSRect badgeRect;
155            badgeRect.size = [fUploadBadge size];
156            badgeRect.origin = NSZeroPoint;
157           
158            //ignore shadow of badge when placing string
159            NSRect stringRect = badgeRect;
160            stringRect.size.height -= SPEED_BOTTOM_PADDING;
161            stringRect.origin.y += SPEED_BOTTOM_PADDING;
162           
163            [dockIcon lockFocus];
164           
165            if (uploadRateString)
166            {
167                //place badge and text
168                [fUploadBadge compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
169                [self badgeString: uploadRateString forRect: stringRect];
170            }
171           
172            if (downloadRateString)
173            {
174                //download rate above upload rate
175                if (uploadRateString)
176                {
177                    float spaceBetween = badgeRect.size.height + SPEED_BETWEEN_PADDING;
178                    badgeRect.origin.y += spaceBetween;
179                    stringRect.origin.y += spaceBetween;
180                }
181               
182                //place badge and text
183                [[NSImage imageNamed: @"DownloadBadge"] compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
184                [self badgeString: downloadRateString forRect: stringRect];
185            }
186           
187            [dockIcon unlockFocus];
188        }
189    }
190   
191    //update dock badge
192    if (fSpeedBadge || speedBadge || completedChange)
193    {
194        [NSApp setApplicationIconImage: dockIcon ? dockIcon : fDockIcon];
195        [dockIcon release];
196       
197        fSpeedBadge = speedBadge;
198    }
199}
200
201- (void) incrementCompleted
202{
203    fCompleted++;
204   
205    if ([NSApp isOnLeopardOrBetter])
206        [[NSApp dockTile] setBadgeLabel: [NSString stringWithFormat: @"%d", fCompleted]];
207    else
208        [self updateBadge];
209}
210
211- (void) clearCompleted
212{
213    if (fCompleted != 0)
214    {
215        fCompleted = 0;
216        if ([NSApp isOnLeopardOrBetter])
217            [[NSApp dockTile] setBadgeLabel: @""];
218        else
219            [self updateBadge];
220    }
221}
222
223//for quitting -- only needed by Tiger
224- (void) clearBadge
225{
226    if (![NSApp isOnLeopardOrBetter])
227    {
228        fSpeedBadge = NO;
229        fCompleted = 0;
230        fCompletedBadged = 0;
231        [NSApp setApplicationIconImage: nil];
232    }
233}
234
235@end
236
237@implementation Badger (Private)
238
239//dock icon must have locked focus
240- (void) badgeString: (NSString *) string forRect: (NSRect) rect
241{
242    if (!fAttributes)
243    {
244        NSShadow * stringShadow = [[NSShadow alloc] init];
245        [stringShadow setShadowOffset: NSMakeSize(2.0, -2.0)];
246        [stringShadow setShadowBlurRadius: 4.0];
247       
248        fAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
249            [NSColor whiteColor], NSForegroundColorAttributeName,
250            [NSFont boldSystemFontOfSize: 26.0], NSFontAttributeName, stringShadow, NSShadowAttributeName, nil];
251       
252        [stringShadow release];
253    }
254   
255    NSSize stringSize = [string sizeWithAttributes: fAttributes];
256   
257    //string is in center of image
258    rect.origin.x += (rect.size.width - stringSize.width) * 0.5;
259    rect.origin.y += (rect.size.height - stringSize.height) * 0.5;
260                       
261    [string drawAtPoint: rect.origin withAttributes: fAttributes];
262}
263
264@end
Note: See TracBrowser for help on using the repository browser.