Implemented preference pane.
[GrowlITTSW.git] / GrowlITTSWController.m
1 //
2 //  GrowlITTSWController.m
3 //  Growl
4 //
5 //  Created by Joseph Spiros on 2/28/09.
6 //  Copyright 2009 iThink Software. All rights reserved.
7 //
8
9 #import "GrowlITTSWController.h"
10 #import "GrowlITTSWPrefs.h"
11
12 #import <ITKit/ITWindowEffect.h>
13 #import <ITKit/ITTSWBackgroundView.h>
14
15 #import "RegexKitLite.h"
16
17 @implementation NSImage (SmoothAdditions)
18
19 - (NSImage *)imageScaledSmoothlyToSize:(NSSize)scaledSize {
20     NSImage *newImage;
21     NSImageRep *rep = [self bestRepresentationForDevice:nil];
22     
23     newImage = [[NSImage alloc] initWithSize:scaledSize];
24     [newImage lockFocus];
25     {
26         [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
27         [[NSGraphicsContext currentContext] setShouldAntialias:YES];
28         [rep drawInRect:NSMakeRect(3, 3, scaledSize.width - 6, scaledSize.height - 6)];
29     }
30     [newImage unlockFocus];
31     return [newImage autorelease];
32 }
33
34 @end
35
36 @interface GrowlITTSWController (Private)
37 - (void)syncWithPrefs;
38 @end
39
40 @implementation GrowlITTSWController
41
42 - (id)init {
43     if ( ( self = [super init] ) ) {
44                 _window = [[GrowlITTSWWindow sharedWindow] retain];
45                 [_window setExitMode:ITTransientStatusWindowExitAfterDelay];
46                 [self syncWithPrefs];
47                 [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(syncWithPrefs) name:@"GrowlPreferencesChanged" object:nil];
48     }
49     
50     return self;
51 }
52
53 - (void)dealloc {
54     [_window release];
55     [super dealloc];
56 }
57
58 - (void)syncWithPrefs {
59         NSScreen *screen = [GrowlITTSWPrefs screen];
60         ITHorizontalWindowPosition horizontalPosition = [GrowlITTSWPrefs horizontalPosition];
61         ITVerticalWindowPosition verticalPosition = [GrowlITTSWPrefs verticalPosition];
62         
63         Class appearanceEffect = [GrowlITTSWPrefs appearanceEffect];
64         float appearanceSpeed = [GrowlITTSWPrefs appearanceSpeed];
65         Class vanishEffect = [GrowlITTSWPrefs vanishEffect];
66         float vanishSpeed = [GrowlITTSWPrefs vanishSpeed];
67         float vanishDelay = [GrowlITTSWPrefs vanishDelay];
68         
69         ITTSWBackgroundMode backgroundStyle = [GrowlITTSWPrefs backgroundStyle];
70         NSColor *backgroundColor = [GrowlITTSWPrefs backgroundColor];
71         ITTransientStatusWindowSizing windowSize = [GrowlITTSWPrefs windowSize];
72         
73         if ([_window screen] != screen) {
74                 [_window setScreen:screen];
75         }
76         if ([_window horizontalPosition] != horizontalPosition) {
77                 [_window setHorizontalPosition:horizontalPosition];
78         }
79         if ([_window verticalPosition] != verticalPosition) {
80                 [_window setVerticalPosition:verticalPosition];
81         }
82         
83         if (![[_window entryEffect] isKindOfClass:appearanceEffect]) {
84                 [_window setEntryEffect:[[[appearanceEffect alloc] initWithWindow:_window] autorelease]];
85         }
86         if ([[_window entryEffect] effectTime] != appearanceSpeed) {
87                 [[_window entryEffect] setEffectTime:appearanceSpeed];
88         }
89         if (![[_window exitEffect] isKindOfClass:vanishEffect]) {
90                 [_window setExitEffect:[[[vanishEffect alloc] initWithWindow:_window] autorelease]];
91         }
92         if ([[_window exitEffect] effectTime] != vanishSpeed) {
93                 [[_window exitEffect]  setEffectTime:vanishSpeed];
94         }
95         if ([_window exitDelay] != vanishDelay) {
96                 [_window setExitDelay:vanishDelay];
97         }
98         
99         if ([(ITTSWBackgroundView *)[_window contentView] backgroundMode] != backgroundStyle) {
100                 [(ITTSWBackgroundView *)[_window contentView] setBackgroundMode:backgroundStyle];
101         }
102         if (([(ITTSWBackgroundView *)[_window contentView] backgroundMode] == ITTSWBackgroundColored) && ![[(ITTSWBackgroundView *)[_window contentView] backgroundColor] isEqual:backgroundColor]) {
103                 [(ITTSWBackgroundView *)[_window contentView] setBackgroundColor:backgroundColor];
104         }
105         if ([_window sizing] != windowSize) {
106                 [_window setSizing:windowSize];
107         }
108 }
109
110 - (void)showWindowWithText:(NSString *)text image:(NSImage *)image {
111         NSSize newSize;
112         NSSize oldSize = [image size];
113         
114         if (oldSize.width > oldSize.height) {
115                 newSize = NSMakeSize(110.0f, (oldSize.height * (110.0f / oldSize.width)));
116         } else {
117                 newSize = NSMakeSize((oldSize.width * (110.0f / oldSize.height)), 110.0f);
118         }
119         
120         image = [[[[NSImage alloc] initWithData:[image TIFFRepresentation]] autorelease] imageScaledSmoothlyToSize:newSize];
121         
122         NSArray *gothicChars = [NSArray arrayWithObjects:[NSString stringWithUTF8String:"☆"], [NSString stringWithUTF8String:"★"], nil];
123         NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:text];
124         
125         if (([gothicChars count] > 0) && ([text length] > 0)) {
126                 NSMutableString *gothicRegex = [[NSMutableString alloc] init];
127                 
128                 [gothicRegex appendString:@"["];
129                 for (NSString *gothicChar in gothicChars) {
130                         [gothicRegex appendString:gothicChar];
131                 }
132                 [gothicRegex appendString:@"]+"];
133                 
134                 NSUInteger endOfLastRange = 0;
135                 NSRange foundRange;
136                 while (endOfLastRange != NSNotFound) {
137                         foundRange = [text rangeOfRegex:gothicRegex inRange:NSMakeRange(endOfLastRange, ([text length] - endOfLastRange))];
138                         if (foundRange.location != NSNotFound) {
139                                 [attributedText setAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSFont fontWithName:@"AppleGothic" size:(18.0 / MINI_DIVISOR)], NSFontAttributeName, nil, nil] range:foundRange];
140                                 endOfLastRange = foundRange.location+foundRange.length;
141                                 if (endOfLastRange >= [text length]) {
142                                         endOfLastRange = NSNotFound;
143                                 }
144                         } else {
145                                 endOfLastRange = NSNotFound;
146                         }
147                 }
148         }
149         
150         [_window setImage:image];
151     [_window buildTextWindowWithString:attributedText];
152     [_window appear:self];
153         [attributedText release];
154 }
155
156 @end