source: trunk/macosx/Badger.m @ 794

Last change on this file since 794 was 794, checked in by livings124, 16 years ago

Acquire lock before setting completed badge to help get rid of problem of the completed badge not clearing when the main window is given focus

  • Property svn:keywords set to Date Rev Author Id
File size: 6.9 KB
Line 
1/******************************************************************************
2 * $Id: Badger.m 794 2006-08-19 22:18:39Z livings124 $
3 *
4 * Copyright (c) 2006 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 "StringAdditions.h"
27
28@interface Badger (Private)
29
30- (void) badgeString: (NSString *) string forRect: (NSRect) rect;
31
32@end
33
34@implementation Badger
35
36- (id) init
37{
38    if ((self = [super init]))
39    {
40        fBadge = [NSImage imageNamed: @"Badge"];
41        fDockIcon = [[NSApp applicationIconImage] copy];
42        fBadgedDockIcon = [fDockIcon copy];
43        fUploadBadge = [NSImage imageNamed: @"UploadBadge"];
44        fDownloadBadge = [NSImage imageNamed: @"DownloadBadge"];
45       
46        NSShadow * stringShadow = [[NSShadow alloc] init];
47        [stringShadow setShadowOffset: NSMakeSize(2.0, -2.0)];
48        [stringShadow setShadowBlurRadius: 4.0];
49       
50        NSFont * boldFont = [[NSFontManager sharedFontManager] convertFont:
51                                [NSFont fontWithName: @"Helvetica" size: 28.0] toHaveTrait: NSBoldFontMask];
52       
53        fAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
54            [NSColor whiteColor], NSForegroundColorAttributeName,
55            boldFont, NSFontAttributeName, stringShadow, NSShadowAttributeName, nil];
56       
57        [stringShadow release];
58       
59        fLock = [[NSLock alloc] init];
60       
61        fCompleted = 0;
62        fSpeedShown = NO;
63    }
64   
65    return self;
66}
67
68- (void) dealloc
69{
70    [fDockIcon release];
71    [fBadgedDockIcon release];
72    [fAttributes release];
73    [fLock release];
74
75    [super dealloc];
76}
77
78- (void) updateBadgeWithCompleted: (int) completed uploadRate: (float) uploadRate downloadRate: (float) downloadRate
79{
80    NSImage * dockIcon = nil;
81    NSSize iconSize = [fDockIcon size];
82
83    [fLock lock]; //acquire lock to ensure completed badge is accurate
84
85    //set completed badge
86    if (fCompleted != completed)
87    {
88        dockIcon = [fDockIcon copy];
89       
90        //set completed badge to top right
91        if (completed > 0)
92        {
93            NSRect badgeRect;
94            badgeRect.size = [fBadge size];
95            badgeRect.origin.x = iconSize.width - badgeRect.size.width;
96            badgeRect.origin.y = iconSize.height - badgeRect.size.height;
97                                       
98            [dockIcon lockFocus];
99           
100            //place badge
101            [fBadge compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
102           
103            //ignore shadow of badge when placing string
104            float badgeBottomExtra = 5.0;
105            badgeRect.size.height -= badgeBottomExtra;
106            badgeRect.origin.y += badgeBottomExtra;
107           
108            //place badge text
109            [self badgeString: [NSString stringWithInt: completed] forRect: badgeRect];
110                       
111            [dockIcon unlockFocus];
112        }
113       
114        [fBadgedDockIcon release];
115        fBadgedDockIcon = [dockIcon copy];
116       
117        fCompleted = completed;
118    }
119   
120    [fLock unlock];
121
122    //set upload and download rate badges
123    NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];
124    NSString * uploadRateString = uploadRate >= 0.1 && [defaults boolForKey: @"BadgeUploadRate"]
125                                    ? [NSString stringForSpeedAbbrev: uploadRate] : nil,
126            * downloadRateString = downloadRate >= 0.1 && [defaults boolForKey: @"BadgeDownloadRate"]
127                                    ? [NSString stringForSpeedAbbrev: downloadRate] : nil;
128   
129    BOOL speedShown = uploadRateString || downloadRateString;
130    if (speedShown)
131    {
132        NSRect badgeRect;
133        badgeRect.size = [fUploadBadge size];
134        badgeRect.origin = NSZeroPoint;
135       
136        //ignore shadow of badge when placing string
137        NSRect stringRect = badgeRect;
138        float badgeBottomExtra = 2.0;
139        stringRect.size.height -= badgeBottomExtra;
140        stringRect.origin.y += badgeBottomExtra;
141
142        if (!dockIcon)
143            dockIcon = [fBadgedDockIcon copy];
144       
145        [dockIcon lockFocus];
146       
147        if (uploadRateString)
148        {
149            //place badge
150            [fUploadBadge compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
151           
152            //place badge text
153            [self badgeString: uploadRateString forRect: stringRect];
154        }
155       
156        if (downloadRateString)
157        {
158            //download rate above upload rate
159            if (uploadRateString)
160            {
161                float spaceBetween = badgeRect.size.height + 2.0;
162                badgeRect.origin.y += spaceBetween;
163                stringRect.origin.y += spaceBetween;
164            }
165       
166            //place badge
167            [fDownloadBadge compositeToPoint: badgeRect.origin operation: NSCompositeSourceOver];
168           
169            //place badge text
170            [self badgeString: downloadRateString forRect: stringRect];
171        }
172       
173        [dockIcon unlockFocus];
174    }
175
176    if (dockIcon || fSpeedShown)
177    {
178        if (!dockIcon)
179            dockIcon = [fBadgedDockIcon copy];
180           
181        [NSApp setApplicationIconImage: dockIcon];
182        [dockIcon release];
183    }
184   
185    fSpeedShown = speedShown;
186}
187
188- (void) clearBadge
189{
190    [fBadgedDockIcon release];
191    fBadgedDockIcon = [fDockIcon copy];
192
193    [NSApp setApplicationIconImage: fDockIcon];
194   
195    fCompleted = 0;
196    fSpeedShown = NO;
197}
198
199@end
200
201@implementation Badger (Private)
202
203//dock icon must have locked focus
204- (void) badgeString: (NSString *) string forRect: (NSRect) rect
205{
206    NSSize stringSize = [string sizeWithAttributes: fAttributes];
207   
208    //string is in center of image
209    rect.origin.x += (rect.size.width - stringSize.width) * 0.5;
210    rect.origin.y += (rect.size.height - stringSize.height) * 0.5;
211                       
212    [string drawAtPoint: rect.origin withAttributes: fAttributes];
213}
214
215@end
Note: See TracBrowser for help on using the repository browser.