Plugins/Displays/Smoke/GrowlSmokeWindowController.m
author boredzo
Sun Jul 06 15:10:15 2008 +0000 (2008-07-06)
changeset 4135 9d0747a53f45
parent 3958 157225f6bfee
child 4246 4f52d1d98978
child 4771 d398be175a6e
permissions -rw-r--r--
CFRelease the duration preference value if we get one. Found by the clang static analyzer.
     1 //
     2 //  GrowlSmokeWindowController.m
     3 //  Display Plugins
     4 //
     5 //  Created by Matthew Walton on 11/09/2004.
     6 //  Copyright 2004-2006 The Growl Project. All rights reserved.
     7 //
     8 //  Most of this is lifted from KABubbleWindowController in the Growl source
     9 
    10 #import "GrowlSmokeWindowController.h"
    11 #import "GrowlSmokeWindowView.h"
    12 #import "GrowlSmokeDefines.h"
    13 #import "GrowlDefinesInternal.h"
    14 #import "NSWindow+Transforms.h"
    15 #import "GrowlApplicationNotification.h"
    16 #import "GrowlWindowTransition.h"
    17 #import "GrowlFadingWindowTransition.h"
    18 #include "CFDictionaryAdditions.h"
    19 
    20 @implementation GrowlSmokeWindowController
    21 
    22 //static const double gAdditionalLinesDisplayTime = 0.5;
    23 //static const double gMaxDisplayTime = 10.0;
    24 
    25 - (id) init {
    26 	screenNumber = 0U;
    27 	READ_GROWL_PREF_INT(GrowlSmokeScreenPref, GrowlSmokePrefDomain, &screenNumber);
    28 	NSArray *screens = [NSScreen screens];
    29 	unsigned screensCount = [screens count];
    30 	if (screensCount) {
    31 		[self setScreen:((screensCount >= (screenNumber + 1)) ? [screens objectAtIndex:screenNumber] : [screens objectAtIndex:0])];
    32 	}
    33 
    34 	CFNumberRef prefsDuration = NULL;
    35 	READ_GROWL_PREF_VALUE(GrowlSmokeDurationPref, GrowlSmokePrefDomain, CFNumberRef, &prefsDuration);
    36 	[self setDisplayDuration:(prefsDuration ?
    37 							  [(NSNumber *)prefsDuration doubleValue] :
    38 							  GrowlSmokeDurationPrefDefault)];
    39 	if (prefsDuration) CFRelease(prefsDuration);
    40 
    41 	NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0.0f, 0.0f, GrowlSmokeNotificationWidth, 65.0f)
    42 												styleMask:NSBorderlessWindowMask | NSNonactivatingPanelMask
    43 												  backing:NSBackingStoreBuffered
    44 													defer:YES];
    45 	NSRect panelFrame = [panel frame];
    46 	[panel setBecomesKeyOnlyIfNeeded:YES];
    47 	[panel setHidesOnDeactivate:NO];
    48 	[panel setBackgroundColor:[NSColor clearColor]];
    49 	[panel setLevel:NSStatusWindowLevel];
    50 	[panel setSticky:YES];
    51 	[panel setAlphaValue:0.0f];
    52 	[panel setOpaque:NO];
    53 	[panel setHasShadow:YES];
    54 	[panel setCanHide:NO];
    55 	[panel setOneShot:YES];
    56 	[panel useOptimizedDrawing:YES];
    57 
    58 	GrowlSmokeWindowView *view = [[GrowlSmokeWindowView alloc] initWithFrame:panelFrame];
    59 	[view setTarget:self];
    60 	[view setAction:@selector(notificationClicked:)];
    61 	[panel setContentView:view];
    62 	[view release];
    63 
    64 	// call super so everything else is set up...
    65 	if ((self = [super initWithWindow:panel])) {
    66 		// set up the transitions...
    67 		GrowlFadingWindowTransition *fader = [[GrowlFadingWindowTransition alloc] initWithWindow:panel];
    68 		[self addTransition:fader];
    69 		[self setStartPercentage:0 endPercentage:100 forTransition:fader];
    70 		[fader setAutoReverses:YES];
    71 		[fader release];
    72 	}
    73 	[panel release];
    74 
    75 	return self;
    76 }
    77 
    78 #pragma mark -
    79 - (void) setNotification:(GrowlApplicationNotification *)theNotification {
    80 	[super setNotification:theNotification];
    81 	if (!theNotification)
    82 		return;
    83 
    84 	NSDictionary *noteDict = [notification dictionaryRepresentation];
    85 	NSString *title = [notification title];
    86 	NSString *text  = [notification notificationDescription];
    87 	NSImage *icon   = getObjectForKey(noteDict, GROWL_NOTIFICATION_ICON);
    88 	int priority    = getIntegerForKey(noteDict, GROWL_NOTIFICATION_PRIORITY);
    89 
    90 	GrowlSmokeWindowView *view = [[self window] contentView];
    91 	[view setPriority:priority];
    92 	[view setTitle:title];
    93 	[view setText:text];
    94 	[view setIcon:icon];
    95 	[view sizeToFit];
    96 }
    97 
    98 #pragma mark -
    99 #pragma mark positioning methods
   100 
   101 - (NSPoint) idealOriginInRect:(NSRect)rect {
   102 	NSRect viewFrame = [[[self window] contentView] frame];
   103 	enum GrowlPosition originatingPosition = [[GrowlPositionController sharedInstance] originPosition];
   104 	NSPoint idealOrigin;
   105 	
   106 	switch(originatingPosition){
   107 		case GrowlTopRightPosition:
   108 			idealOrigin = NSMakePoint(NSMaxX(rect) - NSWidth(viewFrame) - GrowlSmokePadding,
   109 									  NSMaxY(rect) - GrowlSmokePadding - NSHeight(viewFrame));
   110 			break;
   111 		case GrowlTopLeftPosition:
   112 			idealOrigin = NSMakePoint(NSMinX(rect) + GrowlSmokePadding,
   113 									  NSMaxY(rect) - GrowlSmokePadding - NSHeight(viewFrame));
   114 			break;
   115 		case GrowlBottomLeftPosition:
   116 			idealOrigin = NSMakePoint(NSMinX(rect) + GrowlSmokePadding,
   117 									  NSMinY(rect) + GrowlSmokePadding);
   118 			break;
   119 		case GrowlBottomRightPosition:
   120 			idealOrigin = NSMakePoint(NSMaxX(rect) - NSWidth(viewFrame) - GrowlSmokePadding,
   121 									  NSMinY(rect) + GrowlSmokePadding);
   122 			break;
   123 		default:
   124 			idealOrigin = NSMakePoint(NSMaxX(rect) - NSWidth(viewFrame) - GrowlSmokePadding,
   125 									  NSMaxY(rect) - GrowlSmokePadding - NSHeight(viewFrame));
   126 			break;			
   127 	}
   128 	
   129 	return idealOrigin;	
   130 }
   131 
   132 - (enum GrowlExpansionDirection) primaryExpansionDirection {
   133 	enum GrowlPosition originatingPosition = [[GrowlPositionController sharedInstance] originPosition];
   134 	enum GrowlExpansionDirection directionToExpand;
   135 	
   136 	switch(originatingPosition){
   137 		case GrowlTopLeftPosition:
   138 			directionToExpand = GrowlDownExpansionDirection;
   139 			break;
   140 		case GrowlTopRightPosition:
   141 			directionToExpand = GrowlDownExpansionDirection;
   142 			break;
   143 		case GrowlBottomLeftPosition:
   144 			directionToExpand = GrowlUpExpansionDirection;
   145 			break;
   146 		case GrowlBottomRightPosition:
   147 			directionToExpand = GrowlUpExpansionDirection;
   148 			break;
   149 		default:
   150 			directionToExpand = GrowlDownExpansionDirection;
   151 			break;			
   152 	}
   153 	
   154 	return directionToExpand;
   155 }
   156 
   157 - (enum GrowlExpansionDirection) secondaryExpansionDirection {
   158 	enum GrowlPosition originatingPosition = [[GrowlPositionController sharedInstance] originPosition];
   159 	enum GrowlExpansionDirection directionToExpand;
   160 	
   161 	switch(originatingPosition){
   162 		case GrowlTopLeftPosition:
   163 			directionToExpand = GrowlRightExpansionDirection;
   164 			break;
   165 		case GrowlTopRightPosition:
   166 			directionToExpand = GrowlLeftExpansionDirection;
   167 			break;
   168 		case GrowlBottomLeftPosition:
   169 			directionToExpand = GrowlRightExpansionDirection;
   170 			break;
   171 		case GrowlBottomRightPosition:
   172 			directionToExpand = GrowlLeftExpansionDirection;
   173 			break;
   174 		default:
   175 			directionToExpand = GrowlRightExpansionDirection;
   176 			break;
   177 	}
   178 	
   179 	return directionToExpand;
   180 }
   181 
   182 - (float) requiredDistanceFromExistingDisplays {
   183 	return GrowlSmokePadding;
   184 }
   185 
   186 @end