Implemented preference pane.
authorJoseph Spiros <joseph.spiros@ithinksw.com>
Sun, 1 Mar 2009 21:43:49 +0000 (16:43 -0500)
committerJoseph Spiros <joseph.spiros@ithinksw.com>
Sun, 1 Mar 2009 21:43:49 +0000 (16:43 -0500)
English.lproj/GrowlITTSWPrefs.nib/classes.nib
English.lproj/GrowlITTSWPrefs.nib/info.nib
English.lproj/GrowlITTSWPrefs.nib/keyedobjects.nib
GrowlITTSW.xcodeproj/project.pbxproj
GrowlITTSWController.m
GrowlITTSWDisplay.h
GrowlITTSWDisplay.m
GrowlITTSWPrefs.h
GrowlITTSWPrefs.m

index 1f69d3a..6462c4d 100644 (file)
                        <string>NSResponder</string>
                </dict>
                <dict>
+                       <key>ACTIONS</key>
+                       <dict>
+                               <key>setAppearanceEffect</key>
+                               <string>id</string>
+                               <key>setAppearanceSpeed</key>
+                               <string>id</string>
+                               <key>setBackgroundColor</key>
+                               <string>id</string>
+                               <key>setBackgroundStyle</key>
+                               <string>id</string>
+                               <key>setScreen</key>
+                               <string>id</string>
+                               <key>setVanishDelay</key>
+                               <string>id</string>
+                               <key>setVanishEffect</key>
+                               <string>id</string>
+                               <key>setVanishSpeed</key>
+                               <string>id</string>
+                               <key>setWindowSize</key>
+                               <string>id</string>
+                       </dict>
                        <key>CLASS</key>
                        <string>GrowlITTSWPrefs</string>
                        <key>LANGUAGE</key>
                        <string>ObjC</string>
                        <key>OUTLETS</key>
                        <dict>
+                               <key>appearanceEffectButton</key>
+                               <string>NSPopUpButton</string>
+                               <key>appearanceSpeedSlider</key>
+                               <string>NSSlider</string>
+                               <key>backgroundColorWell</key>
+                               <string>NSColorWell</string>
+                               <key>backgroundStyleButton</key>
+                               <string>NSPopUpButton</string>
+                               <key>screenButton</key>
+                               <string>NSPopUpButton</string>
                                <key>slider_opacity</key>
                                <string>NSSlider</string>
+                               <key>vanishDelaySlider</key>
+                               <string>NSSlider</string>
+                               <key>vanishEffectButton</key>
+                               <string>NSPopUpButton</string>
+                               <key>vanishSpeedSlider</key>
+                               <string>NSSlider</string>
+                               <key>windowSizeButton</key>
+                               <string>NSPopUpButton</string>
                        </dict>
                        <key>SUPERCLASS</key>
                        <string>NSPreferencePane</string>
index 61d25e2..2c41c85 100644 (file)
@@ -10,7 +10,7 @@
        <integer>3</integer>
        <key>IBOpenObjects</key>
        <array>
-               <integer>244</integer>
+               <integer>6</integer>
        </array>
        <key>IBSystem Version</key>
        <string>9G55</string>
index d017b7d..7a1f10a 100644 (file)
Binary files a/English.lproj/GrowlITTSWPrefs.nib/keyedobjects.nib and b/English.lproj/GrowlITTSWPrefs.nib/keyedobjects.nib differ
index d2fc688..fd93ea2 100644 (file)
@@ -9,6 +9,7 @@
 /* Begin PBXBuildFile section */
                8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
                8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+               FA35C10E0F5AABB3002FCE77 /* GrowlITTSWPrefs.m in Sources */ = {isa = PBXBuildFile; fileRef = FA4A47200F5A3C2A00F37A2B /* GrowlITTSWPrefs.m */; };
                FA4A47250F5A3C2A00F37A2B /* GrowlITTSWDisplay.m in Sources */ = {isa = PBXBuildFile; fileRef = FA4A471E0F5A3C2A00F37A2B /* GrowlITTSWDisplay.m */; };
                FA4A47270F5A3C2A00F37A2B /* GrowlITTSWController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA4A47220F5A3C2A00F37A2B /* GrowlITTSWController.m */; };
                FA4A47400F5A3C7100F37A2B /* ITKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA4A473D0F5A3C6900F37A2B /* ITKit.framework */; };
                                FA4A47270F5A3C2A00F37A2B /* GrowlITTSWController.m in Sources */,
                                FA7C86AB0F5A936900213B2E /* RegexKitLite.m in Sources */,
                                FA7C87DA0F5A9C3400213B2E /* GrowlITTSWWindow.m in Sources */,
+                               FA35C10E0F5AABB3002FCE77 /* GrowlITTSWPrefs.m in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 3cf14a3..172453a 100644 (file)
@@ -7,22 +7,16 @@
 //
 
 #import "GrowlITTSWController.h"
+#import "GrowlITTSWPrefs.h"
 
-#import <ITKit/ITTSWBackgroundView.h>
 #import <ITKit/ITWindowEffect.h>
+#import <ITKit/ITTSWBackgroundView.h>
 
 #import "RegexKitLite.h"
 
-#import "GrowlPositioningDefines.h"
-
-@interface GrowlPositionController
-+ (enum GrowlPosition)selectedOriginPosition;
-@end
-
 @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 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
-{
+- (void)syncWithPrefs {
+       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)showWindowWithText:(NSString *)text image:(NSImage *)image {
        NSSize newSize;
        NSSize oldSize = [image size];
        
                }
        }
        
-       switch ([GrowlPositionController selectedOriginPosition]) {
-               case GrowlMiddleColumnPosition:
-                       [_window setVerticalPosition:ITWindowPositionMiddle];
-                       [_window setHorizontalPosition:ITWindowPositionCenter];
-                       break;
-               case GrowlTopLeftPosition:
-                       [_window setVerticalPosition:ITWindowPositionTop];
-                       [_window setHorizontalPosition:ITWindowPositionLeft];
-                       break;
-               case GrowlBottomRightPosition:
-                       [_window setVerticalPosition:ITWindowPositionBottom];
-                       [_window setHorizontalPosition:ITWindowPositionRight];
-                       break;
-               case GrowlTopRightPosition:
-                       [_window setVerticalPosition:ITWindowPositionTop];
-                       [_window setHorizontalPosition:ITWindowPositionRight];
-                       break;
-               case GrowlBottomLeftPosition:
-                       [_window setVerticalPosition:ITWindowPositionBottom];
-                       [_window setHorizontalPosition:ITWindowPositionLeft];
-                       break;
-       }
-       
        [_window setImage:image];
     [_window buildTextWindowWithString:attributedText];
     [_window appear:self];
index 1330358..dad8209 100644 (file)
@@ -1,5 +1,6 @@
 #import <Cocoa/Cocoa.h>
 #import "GrowlDisplayPlugin.h"
+#import "GrowlITTSWPrefs.h"
 
 @class GrowlApplicationNotification;
 
index bbd7515..b6727e8 100644 (file)
        [super dealloc];
 }
 
-/* - (NSPreferencePane *) preferencePane {
-       if (!preferencePane)
-               preferencePane = [[GrowlITTSWPrefs alloc] initWithBundle:[NSBundle bundleWithIdentifier:@"com.ithinksw.growl.ittsw"]];
+- (NSPreferencePane *) preferencePane {
+       if (!preferencePane) {
+               preferencePane = [[GrowlITTSWPrefs alloc] initWithBundle:[NSBundle bundleWithIdentifier:@"com.ithinksw.growl-ittsw"]];
+       }
        return preferencePane;
-}*/
+}
 
 //we implement requiresPositioning entirely because it was added as a requirement for doing 1.1 plugins, however
 //we don't really care if positioning is required or not, because we are only ever in the menubar.
index e2c287d..a83d30f 100644 (file)
@@ -1,6 +1,44 @@
 #import <PreferencePanes/PreferencePanes.h>
+#import <ITKit/ITKit.h>
+#import <ITKit/ITTSWBackgroundView.h>
 
 @interface GrowlITTSWPrefs : NSPreferencePane {
+       IBOutlet NSPopUpButton *appearanceEffectButton;
+       IBOutlet NSSlider *appearanceSpeedSlider;
+       IBOutlet NSPopUpButton *vanishEffectButton;
+       IBOutlet NSSlider *vanishSpeedSlider;
+       IBOutlet NSSlider *vanishDelaySlider;
+       
+       IBOutlet NSPopUpButton *backgroundStyleButton;
+       IBOutlet NSColorWell *backgroundColorWell;
+       IBOutlet NSPopUpButton *windowSizeButton;
+       
+       IBOutlet NSPopUpButton *screenButton;
 }
 
++ (Class)appearanceEffect;
++ (float)appearanceSpeed;
++ (Class)vanishEffect;
++ (float)vanishSpeed;
++ (float)vanishDelay;
++ (ITTSWBackgroundMode)backgroundStyle;
++ (NSColor *)backgroundColor;
++ (ITTransientStatusWindowSizing)windowSize;
++ (int)screenIndex;
++ (NSScreen *)screen;
++ (ITHorizontalWindowPosition)horizontalPosition;
++ (ITVerticalWindowPosition)verticalPosition;
+
+- (IBAction)setAppearanceEffect:(id)sender;
+- (IBAction)setAppearanceSpeed:(id)sender;
+- (IBAction)setVanishEffect:(id)sender;
+- (IBAction)setVanishSpeed:(id)sender;
+- (IBAction)setVanishDelay:(id)sender;
+
+- (IBAction)setBackgroundStyle:(id)sender;
+- (IBAction)setBackgroundColor:(id)sender;
+- (IBAction)setWindowSize:(id)sender;
+
+- (IBAction)setScreen:(id)sender;
+
 @end
index 395b2ff..df4f7bf 100644 (file)
@@ -1,6 +1,278 @@
 #import "GrowlITTSWPrefs.h"
+#import "GrowlPositioningDefines.h"
 #import "GrowlDefinesInternal.h"
+#define GrowlITTSWPrefsDomain @"com.ithinksw.growl-ittsw"
+
+@interface GrowlPositionController
++ (enum GrowlPosition)selectedOriginPosition;
+@end
 
 @implementation GrowlITTSWPrefs
 
++ (Class)appearanceEffect {
+       SYNCHRONIZE_GROWL_PREFS();
+       NSString *className = nil;
+       READ_GROWL_PREF_VALUE(@"appearanceEffect", GrowlITTSWPrefsDomain, NSString *, &className);
+       if (className) {
+               Class effectClass = NSClassFromString(className);
+               if (effectClass && [effectClass isSubclassOfClass:[ITWindowEffect class]]) {
+                       return effectClass;
+               }
+       }
+       return NSClassFromString(@"ITCutWindowEffect");
+}
+
++ (float)appearanceSpeed {
+       SYNCHRONIZE_GROWL_PREFS();
+       float appearanceSpeed = 0.8f;
+       READ_GROWL_PREF_FLOAT(@"appearanceSpeed", GrowlITTSWPrefsDomain, &appearanceSpeed);
+       return appearanceSpeed;
+}
+
++ (Class)vanishEffect {
+       SYNCHRONIZE_GROWL_PREFS();
+       NSString *className = nil;
+       READ_GROWL_PREF_VALUE(@"vanishEffect", GrowlITTSWPrefsDomain, NSString *, &className);
+       if (className) {
+               Class effectClass = NSClassFromString(className);
+               if (effectClass && [effectClass isSubclassOfClass:[ITWindowEffect class]]) {
+                       return effectClass;
+               }
+       }
+       return NSClassFromString(@"ITCutWindowEffect");
+}
+
++ (float)vanishSpeed {
+       SYNCHRONIZE_GROWL_PREFS();
+       float vanishSpeed = 0.8f;
+       READ_GROWL_PREF_FLOAT(@"vanishSpeed", GrowlITTSWPrefsDomain, &vanishSpeed);
+       return vanishSpeed;
+}
+
++ (float)vanishDelay {
+       SYNCHRONIZE_GROWL_PREFS();
+       float vanishDelay = 4.0f;
+       READ_GROWL_PREF_FLOAT(@"vanishDelay", GrowlITTSWPrefsDomain, &vanishDelay);
+       return vanishDelay;
+}
+
++ (ITTSWBackgroundMode)backgroundStyle {
+       SYNCHRONIZE_GROWL_PREFS();
+       int backgroundStyle = ITTSWBackgroundReadable;
+       READ_GROWL_PREF_INT(@"backgroundStyle", GrowlITTSWPrefsDomain, &backgroundStyle);
+       return backgroundStyle;
+}
+
++ (NSColor *)backgroundColor {
+       SYNCHRONIZE_GROWL_PREFS();
+       NSData *backgroundColorData = nil;
+       READ_GROWL_PREF_VALUE(@"backgroundColor", GrowlITTSWPrefsDomain, NSData *, &backgroundColorData);
+       if (backgroundColorData && [backgroundColorData isKindOfClass:[NSData class]]) {
+               NSColor *backgroundColor = [NSUnarchiver unarchiveObjectWithData:backgroundColorData];
+               if (backgroundColor && [backgroundColor isKindOfClass:[NSColor class]]) {
+                       return backgroundColor;
+               }
+       }
+       return [NSColor blueColor];
+}
+
++ (ITTransientStatusWindowSizing)windowSize {
+       SYNCHRONIZE_GROWL_PREFS();
+       ITTransientStatusWindowSizing windowSize = ITTransientStatusWindowMini;
+       READ_GROWL_PREF_INT(@"windowSize", GrowlITTSWPrefsDomain, &windowSize);
+       return windowSize;
+}
+
++ (int)screenIndex {
+       SYNCHRONIZE_GROWL_PREFS();
+       int screenIndex = 0;
+       READ_GROWL_PREF_INT(@"screenIndex", GrowlITTSWPrefsDomain, &screenIndex);
+       return screenIndex;
+}
+
++ (NSScreen *)screen {
+       NSArray *screens = [NSScreen screens];
+       int screenIndex = [GrowlITTSWPrefs screenIndex];
+       if ([screens count] >= (screenIndex+1)) {
+               return [screens objectAtIndex:screenIndex];
+       }
+       return [screens objectAtIndex:0];
+}
+
++ (ITHorizontalWindowPosition)horizontalPosition {
+       switch ([GrowlPositionController selectedOriginPosition]) {
+               case GrowlBottomLeftPosition:
+               case GrowlTopLeftPosition:
+                       return ITWindowPositionLeft;
+                       break;
+               default:
+               case GrowlBottomRightPosition:
+               case GrowlTopRightPosition:
+                       return ITWindowPositionRight;
+                       break;
+       }
+}
+
++ (ITVerticalWindowPosition)verticalPosition {
+       switch ([GrowlPositionController selectedOriginPosition]) {
+               case GrowlBottomLeftPosition:
+               case GrowlBottomRightPosition:
+                       return ITWindowPositionBottom;
+                       break;
+               default:
+               case GrowlTopLeftPosition:
+               case GrowlTopRightPosition:
+                       return ITWindowPositionTop;
+                       break;
+       }
+}
+
+- (NSString *)mainNibName {
+       return @"GrowlITTSWPrefs";
+}
+
+- (void)didSelect {
+       [appearanceEffectButton selectItemAtIndex:[appearanceEffectButton indexOfItemWithRepresentedObject:[GrowlITTSWPrefs appearanceEffect]]];
+       [appearanceSpeedSlider setFloatValue:-([GrowlITTSWPrefs appearanceSpeed])];
+       [vanishEffectButton selectItemAtIndex:[vanishEffectButton indexOfItemWithRepresentedObject:[GrowlITTSWPrefs vanishEffect]]];
+       [vanishSpeedSlider setFloatValue:-([GrowlITTSWPrefs vanishSpeed])];
+       [vanishDelaySlider setFloatValue:[GrowlITTSWPrefs vanishDelay]];
+       
+       ITTSWBackgroundMode backgroundStyle = [GrowlITTSWPrefs backgroundStyle];
+       [backgroundStyleButton selectItemWithTag:backgroundStyle];
+       if (backgroundStyle == ITTSWBackgroundColored) {
+               [backgroundColorWell setEnabled:YES];
+       } else {
+               [backgroundColorWell setEnabled:NO];
+       }
+       [[NSColorPanel sharedColorPanel] setShowsAlpha:YES];
+       [backgroundColorWell setColor:[GrowlITTSWPrefs backgroundColor]];
+       [windowSizeButton selectItemWithTag:[GrowlITTSWPrefs windowSize]];
+       
+       [screenButton removeAllItems];
+       NSArray *screens = [NSScreen screens];
+       int screenCount = 0;
+       for (NSScreen *screen in screens) {
+               NSSize screenSize = [screen frame].size;
+               NSMenuItem *screenItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:@"Screen %i (%1.0fx%1.0f)", screenCount+1, screenSize.width, screenSize.height] action:NULL keyEquivalent:@""];
+               [screenItem setRepresentedObject:screen];
+               [[screenButton menu] addItem:screenItem];
+               screenCount++;
+       }
+       if (screenCount > 1) {
+               [screenButton setEnabled:YES];
+       } else {
+               [screenButton setEnabled:NO];
+       }
+       [screenButton selectItemAtIndex:[screenButton indexOfItemWithRepresentedObject:[GrowlITTSWPrefs screen]]];
+}
+
+- (void)awakeFromNib {
+       NSArray *effectClasses = [ITWindowEffect effectClasses];
+       for (Class effectClass in effectClasses) {
+               NSMenuItem *appearanceEffectItem = [[NSMenuItem alloc] initWithTitle:[effectClass effectName] action:NULL keyEquivalent:@""];
+               NSMenuItem *vanishEffectItem = [[NSMenuItem alloc] initWithTitle:[effectClass effectName] action:NULL keyEquivalent:@""];
+               [appearanceEffectItem setRepresentedObject:effectClass];
+               [vanishEffectItem setRepresentedObject:effectClass];
+               
+               [[appearanceEffectButton menu] addItem:[appearanceEffectItem autorelease]];
+               [[vanishEffectButton menu] addItem:[vanishEffectItem autorelease]];
+       }
+       
+       NSArray *backgroundStyles = [NSArray arrayWithObjects:
+                                                                       [NSDictionary dictionaryWithObjectsAndKeys:@"Mac OS X", @"name", [NSNumber numberWithInt:ITTSWBackgroundApple], @"index", nil],
+                                                                       [NSDictionary dictionaryWithObjectsAndKeys:@"Very Readable", @"name", [NSNumber numberWithInt:ITTSWBackgroundReadable], @"index", nil],
+                                                                       [NSDictionary dictionaryWithObjectsAndKeys:@"Custom Color...", @"name", [NSNumber numberWithInt:ITTSWBackgroundColored], @"index", nil],
+                                                                nil];
+       for (NSDictionary *backgroundStyleDict in backgroundStyles) {
+               NSString *backgroundStyleName = [backgroundStyleDict objectForKey:@"name"];
+               ITTSWBackgroundMode backgroundStyle = [[backgroundStyleDict objectForKey:@"index"] intValue];
+               NSMenuItem *backgroundStyleItem = [[NSMenuItem alloc] initWithTitle:backgroundStyleName action:NULL keyEquivalent:@""];
+               [backgroundStyleItem setTag:backgroundStyle];
+               
+               [[backgroundStyleButton menu] addItem:[backgroundStyleItem autorelease]];
+       }
+       
+       NSArray *windowSizes = [NSArray arrayWithObjects:
+                                                               [NSDictionary dictionaryWithObjectsAndKeys:@"Regular", @"name", [NSNumber numberWithInt:ITTransientStatusWindowRegular], @"index", nil],
+                                                               [NSDictionary dictionaryWithObjectsAndKeys:@"Small", @"name", [NSNumber numberWithInt:ITTransientStatusWindowSmall], @"index", nil],
+                                                               [NSDictionary dictionaryWithObjectsAndKeys:@"Mini", @"name", [NSNumber numberWithInt:ITTransientStatusWindowMini], @"index", nil],
+                                                       nil];
+       for (NSDictionary *windowSizeDict in windowSizes) {
+               NSString *windowSizeName = [windowSizeDict objectForKey:@"name"];
+               ITTransientStatusWindowSizing windowSize = [[windowSizeDict objectForKey:@"index"] intValue];
+               NSMenuItem *windowSizeItem = [[NSMenuItem alloc] initWithTitle:windowSizeName action:NULL keyEquivalent:@""];
+               [windowSizeItem setTag:windowSize];
+               
+               [[windowSizeButton menu] addItem:[windowSizeItem autorelease]];
+       }
+       
+       [self didSelect];
+}
+
+- (IBAction)setAppearanceEffect:(id)sender {
+       SYNCHRONIZE_GROWL_PREFS();
+       WRITE_GROWL_PREF_VALUE(@"appearanceEffect", NSStringFromClass([[appearanceEffectButton selectedItem] representedObject]), GrowlITTSWPrefsDomain);
+       UPDATE_GROWL_PREFS();
+}
+
+- (IBAction)setAppearanceSpeed:(id)sender {
+       SYNCHRONIZE_GROWL_PREFS();
+       float appearanceSpeed = -([appearanceSpeedSlider floatValue]);
+       WRITE_GROWL_PREF_FLOAT(@"appearanceSpeed", appearanceSpeed, GrowlITTSWPrefsDomain);
+       UPDATE_GROWL_PREFS();
+}
+
+- (IBAction)setVanishEffect:(id)sender {
+       SYNCHRONIZE_GROWL_PREFS();
+       WRITE_GROWL_PREF_VALUE(@"vanishEffect", NSStringFromClass([[vanishEffectButton selectedItem] representedObject]), GrowlITTSWPrefsDomain);
+       UPDATE_GROWL_PREFS();
+}
+
+- (IBAction)setVanishSpeed:(id)sender {
+       SYNCHRONIZE_GROWL_PREFS();
+       float vanishSpeed = -([vanishSpeedSlider floatValue]);
+       WRITE_GROWL_PREF_FLOAT(@"vanishSpeed", vanishSpeed, GrowlITTSWPrefsDomain);
+       UPDATE_GROWL_PREFS();
+}
+
+- (IBAction)setVanishDelay:(id)sender {
+       SYNCHRONIZE_GROWL_PREFS();
+       float vanishDelay = [vanishDelaySlider floatValue];
+       WRITE_GROWL_PREF_FLOAT(@"vanishDelay", vanishDelay, GrowlITTSWPrefsDomain);
+       UPDATE_GROWL_PREFS();
+}
+
+- (IBAction)setBackgroundStyle:(id)sender {
+       SYNCHRONIZE_GROWL_PREFS();
+       int style = [[backgroundStyleButton selectedItem] tag];
+       if (style == 2) { // colored
+               [backgroundColorWell setEnabled:YES];
+       } else {
+               [backgroundColorWell setEnabled:NO];
+       }
+       WRITE_GROWL_PREF_INT(@"backgroundStyle", style, GrowlITTSWPrefsDomain);
+       UPDATE_GROWL_PREFS();
+}
+
+- (IBAction)setBackgroundColor:(id)sender {
+       SYNCHRONIZE_GROWL_PREFS();
+       WRITE_GROWL_PREF_VALUE(@"backgroundColor", [NSArchiver archivedDataWithRootObject:[backgroundColorWell color]], GrowlITTSWPrefsDomain);
+       UPDATE_GROWL_PREFS();
+}
+
+- (IBAction)setWindowSize:(id)sender {
+       SYNCHRONIZE_GROWL_PREFS();
+       int size = [[windowSizeButton selectedItem] tag];
+       WRITE_GROWL_PREF_INT(@"windowSize", size, GrowlITTSWPrefsDomain);
+       UPDATE_GROWL_PREFS();
+}
+
+- (IBAction)setScreen:(id)sender {
+       SYNCHRONIZE_GROWL_PREFS();
+       int screenIndex = [screenButton indexOfSelectedItem];
+       WRITE_GROWL_PREF_INT(@"screenIndex", screenIndex, GrowlITTSWPrefsDomain);
+       UPDATE_GROWL_PREFS();
+}
+
 @end