|
boredzo@2402
|
1 |
//
|
|
boredzo@2402
|
2 |
// GrowlBezelWindowController.m
|
|
boredzo@2402
|
3 |
// Display Plugins
|
|
boredzo@2402
|
4 |
//
|
|
boredzo@2402
|
5 |
// Created by Jorge Salvador Caffarena on 09/09/04.
|
|
boredzo@2402
|
6 |
// Copyright 2004 Jorge Salvador Caffarena. All rights reserved.
|
|
boredzo@2402
|
7 |
//
|
|
boredzo@2402
|
8 |
|
|
boredzo@2402
|
9 |
#import "GrowlBezelWindowController.h"
|
|
boredzo@2402
|
10 |
#import "GrowlBezelWindowView.h"
|
|
boredzo@2402
|
11 |
#import "GrowlBezelPrefs.h"
|
|
boredzo@2402
|
12 |
#import "NSWindow+Transforms.h"
|
|
rudy@2807
|
13 |
#include "CFDictionaryAdditions.h"
|
|
jkp@2817
|
14 |
#import "GrowlFadingWindowTransition.h"
|
|
jkp@2818
|
15 |
#import "GrowlFlippingWindowTransition.h"
|
|
rudy@2829
|
16 |
#import "GrowlShrinkingWindowTransition.h"
|
|
rudy@3300
|
17 |
#import "GrowlRipplingWindowTransition.h"
|
|
jkp@2818
|
18 |
#import "GrowlWindowTransition.h"
|
|
ingmarstein@2941
|
19 |
#import "GrowlApplicationNotification.h"
|
|
boredzo@2402
|
20 |
|
|
boredzo@2402
|
21 |
@implementation GrowlBezelWindowController
|
|
boredzo@2402
|
22 |
|
|
boredzo@2402
|
23 |
#define MIN_DISPLAY_TIME 3.0
|
|
boredzo@2402
|
24 |
#define GrowlBezelPadding 10.0f
|
|
boredzo@2402
|
25 |
|
|
rudy@2807
|
26 |
- (id) init {
|
|
rudy@2807
|
27 |
int sizePref = 0;
|
|
rudy@2807
|
28 |
screenNumber = 0U;
|
|
rudy@2807
|
29 |
shrinkEnabled = NO;
|
|
rudy@2807
|
30 |
flipEnabled = NO;
|
|
rudy@2807
|
31 |
|
|
rudy@2807
|
32 |
CFNumberRef prefsDuration = NULL;
|
|
rudy@2807
|
33 |
READ_GROWL_PREF_VALUE(GrowlBezelDuration, GrowlBezelPrefDomain, CFNumberRef, &prefsDuration);
|
|
evands@3637
|
34 |
[self setDisplayDuration:(prefsDuration ?
|
|
evands@3637
|
35 |
[(NSNumber *)prefsDuration doubleValue] :
|
|
evands@3637
|
36 |
MIN_DISPLAY_TIME)];
|
|
boredzo@4135
|
37 |
if (prefsDuration) CFRelease(prefsDuration);
|
|
rudy@2807
|
38 |
|
|
rudy@2807
|
39 |
READ_GROWL_PREF_INT(BEZEL_SCREEN_PREF, GrowlBezelPrefDomain, &screenNumber);
|
|
evands@3954
|
40 |
NSArray *screens = [NSScreen screens];
|
|
ingmarstein@3958
|
41 |
unsigned screensCount = [screens count];
|
|
evands@3954
|
42 |
if (screensCount) {
|
|
evands@3954
|
43 |
[self setScreen:((screensCount >= (screenNumber + 1)) ? [screens objectAtIndex:screenNumber] : [screens objectAtIndex:0])];
|
|
evands@3954
|
44 |
}
|
|
ingmarstein@2943
|
45 |
|
|
rudy@2807
|
46 |
READ_GROWL_PREF_INT(BEZEL_SIZE_PREF, GrowlBezelPrefDomain, &sizePref);
|
|
rudy@2807
|
47 |
READ_GROWL_PREF_BOOL(BEZEL_SHRINK_PREF, GrowlBezelPrefDomain, &shrinkEnabled);
|
|
rudy@2807
|
48 |
READ_GROWL_PREF_BOOL(BEZEL_FLIP_PREF, GrowlBezelPrefDomain, &flipEnabled);
|
|
rudy@2807
|
49 |
|
|
rudy@2807
|
50 |
NSRect sizeRect;
|
|
rudy@2807
|
51 |
sizeRect.origin.x = 0.0f;
|
|
rudy@2807
|
52 |
sizeRect.origin.y = 0.0f;
|
|
rudy@2807
|
53 |
|
|
rudy@2807
|
54 |
if (sizePref == BEZEL_SIZE_NORMAL) {
|
|
rudy@2807
|
55 |
sizeRect.size.width = 211.0f;
|
|
rudy@2807
|
56 |
sizeRect.size.height = 206.0f;
|
|
rudy@2807
|
57 |
} else {
|
|
rudy@2807
|
58 |
sizeRect.size.width = 160.0f;
|
|
rudy@2807
|
59 |
sizeRect.size.height = 160.0f;
|
|
rudy@2807
|
60 |
}
|
|
rudy@2807
|
61 |
NSPanel *panel = [[NSPanel alloc] initWithContentRect:sizeRect
|
|
rudy@2807
|
62 |
styleMask:NSBorderlessWindowMask
|
|
rudy@2807
|
63 |
backing:NSBackingStoreBuffered
|
|
rudy@3005
|
64 |
defer:YES];
|
|
rudy@2807
|
65 |
NSRect panelFrame = [panel frame];
|
|
rudy@2807
|
66 |
[panel setBecomesKeyOnlyIfNeeded:YES];
|
|
rudy@2807
|
67 |
[panel setHidesOnDeactivate:NO];
|
|
rudy@2807
|
68 |
[panel setBackgroundColor:[NSColor clearColor]];
|
|
rudy@2807
|
69 |
[panel setLevel:NSStatusWindowLevel];
|
|
rudy@2807
|
70 |
[panel setIgnoresMouseEvents:YES];
|
|
rudy@2807
|
71 |
[panel setSticky:YES];
|
|
rudy@2807
|
72 |
[panel setOpaque:NO];
|
|
rudy@2807
|
73 |
[panel setHasShadow:NO];
|
|
rudy@2807
|
74 |
[panel setCanHide:NO];
|
|
rudy@2807
|
75 |
[panel setOneShot:YES];
|
|
rudy@2807
|
76 |
[panel useOptimizedDrawing:YES];
|
|
jkp@2817
|
77 |
[panel setAlphaValue:0.0f];
|
|
rudy@2807
|
78 |
[panel setDelegate:self];
|
|
rudy@2807
|
79 |
|
|
rudy@2807
|
80 |
GrowlBezelWindowView *view = [[GrowlBezelWindowView alloc] initWithFrame:panelFrame];
|
|
rudy@2807
|
81 |
[view setTarget:self];
|
|
rudy@2807
|
82 |
[view setAction:@selector(notificationClicked:)];
|
|
rudy@2807
|
83 |
[panel setContentView:view];
|
|
evands@3534
|
84 |
[view release];
|
|
evands@3534
|
85 |
|
|
evands@3534
|
86 |
panelFrame = [[panel contentView] frame];
|
|
rudy@2807
|
87 |
[panel setFrame:panelFrame display:NO];
|
|
rudy@2807
|
88 |
|
|
jkp@2817
|
89 |
// call super so everything else is set up...
|
|
ingmarstein@2943
|
90 |
if ((self = [super initWithWindow:panel])) {
|
|
ingmarstein@2943
|
91 |
// set up the transitions...
|
|
rudy@3300
|
92 |
/*GrowlRipplingWindowTransition *ripple = [[GrowlRipplingWindowTransition alloc] initWithWindow:panel];
|
|
rudy@3300
|
93 |
[self addTransition:ripple];
|
|
rudy@3300
|
94 |
[self setStartPercentage:0 endPercentage:100 forTransition:ripple];
|
|
rudy@3300
|
95 |
[ripple setAutoReverses:NO];
|
|
rudy@3300
|
96 |
[ripple release];
|
|
rudy@3300
|
97 |
[panel setAlphaValue:1.0f];
|
|
rudy@3300
|
98 |
*/
|
|
ingmarstein@2943
|
99 |
GrowlFadingWindowTransition *fader = [[GrowlFadingWindowTransition alloc] initWithWindow:panel];
|
|
ingmarstein@2943
|
100 |
[self addTransition:fader];
|
|
ingmarstein@2943
|
101 |
[self setStartPercentage:0 endPercentage:100 forTransition:fader];
|
|
ingmarstein@2943
|
102 |
[fader setAutoReverses:YES];
|
|
ingmarstein@2943
|
103 |
[fader release];
|
|
ingmarstein@2943
|
104 |
|
|
ingmarstein@2943
|
105 |
if (shrinkEnabled) {
|
|
ingmarstein@2943
|
106 |
GrowlShrinkingWindowTransition *shrinker = [[GrowlShrinkingWindowTransition alloc] initWithWindow:panel];
|
|
ingmarstein@2943
|
107 |
[self addTransition:shrinker];
|
|
ingmarstein@2943
|
108 |
[self setStartPercentage:0 endPercentage:80 forTransition:shrinker];
|
|
ingmarstein@2943
|
109 |
[shrinker setAutoReverses:YES];
|
|
ingmarstein@2943
|
110 |
[shrinker release];
|
|
ingmarstein@2943
|
111 |
}
|
|
ingmarstein@2943
|
112 |
if (flipEnabled) {
|
|
ingmarstein@2943
|
113 |
GrowlFlippingWindowTransition *flipper = [[GrowlFlippingWindowTransition alloc] initWithWindow:panel];
|
|
ingmarstein@2943
|
114 |
[self addTransition:flipper];
|
|
ingmarstein@2943
|
115 |
[self setStartPercentage:0 endPercentage:100 forTransition:flipper];
|
|
ingmarstein@2943
|
116 |
[flipper setFlipsX:YES];
|
|
ingmarstein@2943
|
117 |
[flipper setAutoReverses:YES];
|
|
ingmarstein@2943
|
118 |
[flipper release];
|
|
ingmarstein@2943
|
119 |
}
|
|
rudy@2822
|
120 |
}
|
|
evands@3543
|
121 |
[panel release];
|
|
evands@3543
|
122 |
|
|
jkp@2817
|
123 |
return self;
|
|
rudy@2807
|
124 |
}
|
|
rudy@2807
|
125 |
|
|
jkp@2817
|
126 |
#pragma mark -
|
|
jkp@2817
|
127 |
|
|
rudy@2807
|
128 |
- (void) setNotification: (GrowlApplicationNotification *) theNotification {
|
|
rudy@2807
|
129 |
[super setNotification:theNotification];
|
|
rudy@2807
|
130 |
if (!theNotification)
|
|
rudy@2807
|
131 |
return;
|
|
ingmarstein@2941
|
132 |
|
|
rudy@2807
|
133 |
NSDictionary *noteDict = [notification dictionaryRepresentation];
|
|
rudy@2807
|
134 |
NSString *title = [notification title];
|
|
evands@2922
|
135 |
NSString *text = [notification notificationDescription];
|
|
rudy@2807
|
136 |
NSImage *icon = getObjectForKey(noteDict, GROWL_NOTIFICATION_ICON);
|
|
ingmarstein@2941
|
137 |
int myPriority = getIntegerForKey(noteDict, GROWL_NOTIFICATION_PRIORITY);
|
|
ingmarstein@2943
|
138 |
|
|
rudy@2807
|
139 |
GrowlBezelWindowView *view = [[self window] contentView];
|
|
evands@2910
|
140 |
[view setPriority:myPriority];
|
|
bgannin@3404
|
141 |
[view setTitle:title];
|
|
bgannin@3404
|
142 |
[view setText:text];
|
|
rudy@2807
|
143 |
[view setIcon:icon];
|
|
boredzo@2402
|
144 |
}
|
|
boredzo@2402
|
145 |
|
|
boredzo@2402
|
146 |
#pragma mark -
|
|
jkp@2841
|
147 |
#pragma mark positioning methods
|
|
jkp@2841
|
148 |
|
|
jkp@2841
|
149 |
- (NSPoint) idealOriginInRect:(NSRect)rect {
|
|
jkp@2841
|
150 |
NSRect viewFrame = [[[self window] contentView] frame];
|
|
ingmarstein@2943
|
151 |
|
|
jkp@2841
|
152 |
NSPoint result;
|
|
jkp@2841
|
153 |
int positionPref = BEZEL_POSITION_DEFAULT;
|
|
jkp@2841
|
154 |
READ_GROWL_PREF_INT(BEZEL_POSITION_PREF, GrowlBezelPrefDomain, &positionPref);
|
|
jkp@2841
|
155 |
switch (positionPref) {
|
|
jkp@2841
|
156 |
default:
|
|
jkp@2841
|
157 |
case BEZEL_POSITION_DEFAULT:
|
|
jkp@2841
|
158 |
result.x = rect.origin.x + ceilf((NSWidth(rect) - NSWidth(viewFrame)) * 0.5f);
|
|
jkp@2841
|
159 |
result.y = rect.origin.y + 140.0f;
|
|
jkp@2841
|
160 |
break;
|
|
jkp@2841
|
161 |
case BEZEL_POSITION_TOPRIGHT:
|
|
jkp@2841
|
162 |
result.x = NSMaxX(rect) - NSWidth(viewFrame) - GrowlBezelPadding;
|
|
jkp@2841
|
163 |
result.y = NSMaxY(rect) - GrowlBezelPadding - NSHeight(viewFrame);
|
|
jkp@2841
|
164 |
break;
|
|
jkp@2841
|
165 |
case BEZEL_POSITION_BOTTOMRIGHT:
|
|
jkp@2841
|
166 |
result.x = NSMaxX(rect) - NSWidth(viewFrame) - GrowlBezelPadding;
|
|
jkp@2841
|
167 |
result.y = rect.origin.y + GrowlBezelPadding;
|
|
jkp@2841
|
168 |
break;
|
|
jkp@2841
|
169 |
case BEZEL_POSITION_BOTTOMLEFT:
|
|
jkp@2841
|
170 |
result.x = rect.origin.x + GrowlBezelPadding;
|
|
jkp@2841
|
171 |
result.y = rect.origin.y + GrowlBezelPadding;
|
|
jkp@2841
|
172 |
break;
|
|
jkp@2841
|
173 |
case BEZEL_POSITION_TOPLEFT:
|
|
jkp@2841
|
174 |
result.x = rect.origin.x + GrowlBezelPadding;
|
|
jkp@2841
|
175 |
result.y = NSMaxY(rect) - GrowlBezelPadding - NSHeight(viewFrame);
|
|
jkp@2841
|
176 |
break;
|
|
jkp@2841
|
177 |
}
|
|
jkp@2841
|
178 |
return result;
|
|
jkp@2841
|
179 |
}
|
|
jkp@2841
|
180 |
|
|
boredzo@3095
|
181 |
- (enum GrowlExpansionDirection) primaryExpansionDirection {
|
|
jkp@2841
|
182 |
return GrowlNoExpansionDirection;
|
|
jkp@2841
|
183 |
}
|
|
jkp@2841
|
184 |
|
|
boredzo@3095
|
185 |
- (enum GrowlExpansionDirection) secondaryExpansionDirection {
|
|
jkp@2841
|
186 |
return GrowlNoExpansionDirection;
|
|
jkp@2841
|
187 |
}
|
|
jkp@2841
|
188 |
|
|
jkp@2841
|
189 |
- (float) requiredDistanceFromExistingDisplays {
|
|
jkp@2841
|
190 |
return GrowlBezelPadding;
|
|
jkp@2841
|
191 |
}
|
|
jkp@2841
|
192 |
|
|
bgannin@3280
|
193 |
- (BOOL) requiresPositioning {
|
|
bgannin@3280
|
194 |
return NO;
|
|
bgannin@3280
|
195 |
}
|
|
bgannin@3280
|
196 |
|
|
boredzo@2402
|
197 |
@end
|