//
#import "GrowlITTSWController.h"
-#import "GrowlITTSWWindow.h"
+#import "GrowlITTSWPrefs.h"
-#import <ITKit/ITTSWBackgroundView.h>
#import <ITKit/ITWindowEffect.h>
+#import <ITKit/ITTSWBackgroundView.h>
+
+#import "RegexKitLite.h"
@implementation NSImage (SmoothAdditions)
-- (NSImage *)imageScaledSmoothlyToSize:(NSSize)scaledSize
-{
+- (NSImage *)imageScaledSmoothlyToSize:(NSSize)scaledSize {
NSImage *newImage;
NSImageRep *rep = [self bestRepresentationForDevice:nil];
@end
+@interface GrowlITTSWController (Private)
+- (void)syncWithPrefs;
+@end
+
@implementation GrowlITTSWController
-- (id)init
-{
+- (id)init {
if ( ( self = [super init] ) ) {
- NSArray *screens = [NSScreen screens];
-
_window = [[GrowlITTSWWindow sharedWindow] retain];
-
- [_window setScreen:[screens objectAtIndex:0]];
-
- [_window setExitMode:ITTransientStatusWindowExitAfterDelay];
- [_window setExitDelay:4.0];
-
- [_window setHorizontalPosition:ITWindowPositionRight];
- [_window setVerticalPosition:ITWindowPositionTop];
-
- [_window setSizing:ITTransientStatusWindowMini];
-
- [_window setEntryEffect:[[[NSClassFromString(@"ITSlideVerticallyWindowEffect") alloc] initWithWindow:_window] autorelease]];
- [_window setExitEffect:[[[NSClassFromString(@"ITSlideHorizontallyWindowEffect") alloc] initWithWindow:_window] autorelease]];
-
- [[_window entryEffect] setEffectTime:0.8];
- [[_window exitEffect] setEffectTime:0.8];
-
- [(ITTSWBackgroundView *)[_window contentView]setBackgroundMode:
- ITTSWBackgroundReadable];
+ [_window setExitMode:ITTransientStatusWindowExitAfterDelay];
+ [self syncWithPrefs];
+ [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(syncWithPrefs) name:@"GrowlPreferencesChanged" object:nil];
}
return self;
}
-- (void)dealloc
-{
+- (void)dealloc {
[_window release];
[super dealloc];
}
-- (void)showWindowWithText:(NSString *)text image:(NSImage *)image
-{
- NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:text];
+- (void)syncWithPrefs {
+ _imageSize = [GrowlITTSWPrefs imageSize];
+ _imageNoUpscale = [GrowlITTSWPrefs imageNoUpscale];
+ _wrapNotifications = [GrowlITTSWPrefs wrapNotifications];
+ _wrapColumns = [GrowlITTSWPrefs wrapColumns];
+
+ NSScreen *screen = [GrowlITTSWPrefs screen];
+ ITHorizontalWindowPosition horizontalPosition = [GrowlITTSWPrefs horizontalPosition];
+ ITVerticalWindowPosition verticalPosition = [GrowlITTSWPrefs verticalPosition];
+
+ Class appearanceEffect = [GrowlITTSWPrefs appearanceEffect];
+ float appearanceSpeed = [GrowlITTSWPrefs appearanceSpeed];
+ Class vanishEffect = [GrowlITTSWPrefs vanishEffect];
+ float vanishSpeed = [GrowlITTSWPrefs vanishSpeed];
+ float vanishDelay = [GrowlITTSWPrefs vanishDelay];
+
+ ITTSWBackgroundMode backgroundStyle = [GrowlITTSWPrefs backgroundStyle];
+ NSColor *backgroundColor = [GrowlITTSWPrefs backgroundColor];
+ ITTransientStatusWindowSizing windowSize = [GrowlITTSWPrefs windowSize];
+
+ if ([_window screen] != screen) {
+ [_window setScreen:screen];
+ }
+ if ([_window horizontalPosition] != horizontalPosition) {
+ [_window setHorizontalPosition:horizontalPosition];
+ }
+ if ([_window verticalPosition] != verticalPosition) {
+ [_window setVerticalPosition:verticalPosition];
+ }
+
+ if (![[_window entryEffect] isKindOfClass:appearanceEffect]) {
+ [_window setEntryEffect:[[[appearanceEffect alloc] initWithWindow:_window] autorelease]];
+ }
+ if ([[_window entryEffect] effectTime] != appearanceSpeed) {
+ [[_window entryEffect] setEffectTime:appearanceSpeed];
+ }
+ if (![[_window exitEffect] isKindOfClass:vanishEffect]) {
+ [_window setExitEffect:[[[vanishEffect alloc] initWithWindow:_window] autorelease]];
+ }
+ if ([[_window exitEffect] effectTime] != vanishSpeed) {
+ [[_window exitEffect] setEffectTime:vanishSpeed];
+ }
+ if ([_window exitDelay] != vanishDelay) {
+ [_window setExitDelay:vanishDelay];
+ }
+
+ if ([(ITTSWBackgroundView *)[_window contentView] backgroundMode] != backgroundStyle) {
+ [(ITTSWBackgroundView *)[_window contentView] setBackgroundMode:backgroundStyle];
+ }
+ if (([(ITTSWBackgroundView *)[_window contentView] backgroundMode] == ITTSWBackgroundColored) && ![[(ITTSWBackgroundView *)[_window contentView] backgroundColor] isEqual:backgroundColor]) {
+ [(ITTSWBackgroundView *)[_window contentView] setBackgroundColor:backgroundColor];
+ }
+ if ([_window sizing] != windowSize) {
+ [_window setSizing:windowSize];
+ }
+}
+
+- (void)showWindowWithTitle:(NSString *)title desc:(NSString *)desc image:(NSImage *)image {
+ NSString *text = title;
+
+ if (desc && ![desc isEqualToString:@""] && ![desc isEqualToString:@"\n"]) {
+ text = [text stringByAppendingFormat:@"\n%@", desc];
+ }
+
NSSize newSize;
NSSize oldSize = [image size];
+ BOOL wouldUpscale = ((oldSize.width <= _imageSize) && (oldSize.height <= _imageSize));
- if (oldSize.width > oldSize.height) {
- newSize = NSMakeSize(110.0f, (oldSize.height * (110.0f / oldSize.width)));
- } else {
- newSize = NSMakeSize((oldSize.width * (110.0f / oldSize.height)), 110.0f);
+ if (!(wouldUpscale && _imageNoUpscale)) {
+ if (oldSize.width > oldSize.height) {
+ newSize = NSMakeSize(_imageSize, (oldSize.height * (_imageSize / oldSize.width)));
+ } else {
+ newSize = NSMakeSize((oldSize.width * (_imageSize / oldSize.height)), _imageSize);
+ }
+
+ image = [[[[NSImage alloc] initWithData:[image TIFFRepresentation]] autorelease] imageScaledSmoothlyToSize:newSize];
}
- image = [[[[NSImage alloc] initWithData:[image TIFFRepresentation]] autorelease] imageScaledSmoothlyToSize:newSize];
+ if (_wrapNotifications) {
+ text = [text stringByReplacingOccurrencesOfRegex:[NSString stringWithFormat:@"(\\S\\S{%i,}|.{1,%i})(?:\\s+|$)", _wrapColumns, _wrapColumns] withString:@"$1\n"];
+ }
+
+ //trim trailing whitespace
+ text = [text stringByReplacingOccurrencesOfRegex:@"\\s+$" withString:@""];
+
+ NSArray *gothicChars = [NSArray arrayWithObjects:[NSString stringWithUTF8String:"☆"], [NSString stringWithUTF8String:"★"], nil];
+ NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] initWithString:text];
+
+ if (([gothicChars count] > 0) && ([text length] > 0)) {
+ NSMutableString *gothicRegex = [[NSMutableString alloc] init];
+
+ [gothicRegex appendString:@"[\\n"];
+ for (NSString *gothicChar in gothicChars) {
+ [gothicRegex appendString:gothicChar];
+ }
+ [gothicRegex appendString:@"]+"];
+
+ NSUInteger endOfLastRange = 0;
+ NSRange foundRange;
+ while (endOfLastRange != NSNotFound) {
+ foundRange = [text rangeOfRegex:gothicRegex inRange:NSMakeRange(endOfLastRange, ([text length] - endOfLastRange))];
+ if (foundRange.location != NSNotFound) {
+ [attributedText setAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[NSFont fontWithName:@"AppleGothic" size:(18.0 / MINI_DIVISOR)], NSFontAttributeName, nil, nil] range:foundRange];
+ endOfLastRange = foundRange.location+foundRange.length;
+ if (endOfLastRange >= [text length]) {
+ endOfLastRange = NSNotFound;
+ }
+ } else {
+ endOfLastRange = NSNotFound;
+ }
+ }
+ }
[_window setImage:image];
[_window buildTextWindowWithString:attributedText];