|
zaudragon@3188
|
1 |
//
|
|
zaudragon@3189
|
2 |
// GrowliCalWindowController.m
|
|
zaudragon@3188
|
3 |
// Growl
|
|
zaudragon@3188
|
4 |
//
|
|
zaudragon@3188
|
5 |
// Created by Nelson Elhage on Wed Jun 09 2004.
|
|
zaudragon@3188
|
6 |
// Name changed from KABubbleWindowController.m by Justin Burns on Fri Nov 05 2004.
|
|
zaudragon@3189
|
7 |
// Adapted for iCal by Takumi Murayama on Thu Aug 17 2006.
|
|
zaudragon@3188
|
8 |
// Copyright (c) 2004-2006 The Growl Project. All rights reserved.
|
|
zaudragon@3188
|
9 |
//
|
|
zaudragon@3188
|
10 |
|
|
zaudragon@3189
|
11 |
#import "GrowliCalWindowController.h"
|
|
zaudragon@3189
|
12 |
#import "GrowliCalWindowView.h"
|
|
zaudragon@3189
|
13 |
#import "GrowliCalPrefsController.h"
|
|
zaudragon@3189
|
14 |
#import "GrowliCalDefines.h"
|
|
zaudragon@3188
|
15 |
#import "GrowlApplicationNotification.h"
|
|
zaudragon@3188
|
16 |
#import "NSWindow+Transforms.h"
|
|
zaudragon@3188
|
17 |
#include "CFDictionaryAdditions.h"
|
|
zaudragon@3188
|
18 |
#import "GrowlWindowTransition.h"
|
|
zaudragon@3188
|
19 |
#import "GrowlFadingWindowTransition.h"
|
|
zaudragon@3188
|
20 |
|
|
zaudragon@3189
|
21 |
@implementation GrowliCalWindowController
|
|
zaudragon@3188
|
22 |
|
|
zaudragon@3189
|
23 |
#define GrowliCalPadding 5.0f
|
|
zaudragon@3188
|
24 |
|
|
zaudragon@3188
|
25 |
#pragma mark -
|
|
zaudragon@3188
|
26 |
|
|
zaudragon@3188
|
27 |
- (id) init {
|
|
zaudragon@3188
|
28 |
screenNumber = 0U;
|
|
zaudragon@3189
|
29 |
READ_GROWL_PREF_INT(GrowliCalScreen, GrowliCalPrefDomain, &screenNumber);
|
|
evands@3954
|
30 |
NSArray *screens = [NSScreen screens];
|
|
ingmarstein@3958
|
31 |
unsigned screensCount = [screens count];
|
|
evands@3954
|
32 |
if (screensCount) {
|
|
evands@3954
|
33 |
[self setScreen:((screensCount >= (screenNumber + 1)) ? [screens objectAtIndex:screenNumber] : [screens objectAtIndex:0])];
|
|
evands@3954
|
34 |
}
|
|
zaudragon@3188
|
35 |
|
|
zaudragon@3188
|
36 |
CFNumberRef prefsDuration = NULL;
|
|
evands@3637
|
37 |
READ_GROWL_PREF_VALUE(GrowliCalDuration, GrowliCalPrefDomain, CFNumberRef, &prefsDuration);
|
|
evands@3637
|
38 |
[self setDisplayDuration:(prefsDuration ?
|
|
evands@3637
|
39 |
[(NSNumber *)prefsDuration doubleValue] :
|
|
evands@3637
|
40 |
GrowliCalDurationPrefDefault)];
|
|
boredzo@4135
|
41 |
if (prefsDuration) CFRelease(prefsDuration);
|
|
evands@3637
|
42 |
|
|
zaudragon@3188
|
43 |
// I tried setting the width/height to zero, since the view resizes itself later.
|
|
zaudragon@3188
|
44 |
// This made it ignore the alpha at the edges (using 1.0 instead). Why?
|
|
zaudragon@3188
|
45 |
// A window with a frame of NSZeroRect is off-screen and doesn't respect opacity even
|
|
zaudragon@3188
|
46 |
// if moved on screen later. -Evan
|
|
zaudragon@3188
|
47 |
NSPanel *panel = [[NSPanel alloc] initWithContentRect:NSMakeRect(0.0f, 0.0f, 270.0f, 65.0f)
|
|
zaudragon@3188
|
48 |
styleMask:NSBorderlessWindowMask | NSNonactivatingPanelMask
|
|
zaudragon@3188
|
49 |
backing:NSBackingStoreBuffered
|
|
zaudragon@3188
|
50 |
defer:YES];
|
|
zaudragon@3188
|
51 |
NSRect panelFrame = [panel frame];
|
|
zaudragon@3188
|
52 |
[panel setBecomesKeyOnlyIfNeeded:YES];
|
|
zaudragon@3188
|
53 |
[panel setHidesOnDeactivate:NO];
|
|
zaudragon@3188
|
54 |
[panel setBackgroundColor:[NSColor clearColor]];
|
|
zaudragon@3188
|
55 |
[panel setLevel:NSStatusWindowLevel];
|
|
zaudragon@3188
|
56 |
[panel setSticky:YES];
|
|
zaudragon@3188
|
57 |
[panel setAlphaValue:0.0f];
|
|
zaudragon@3188
|
58 |
[panel setOpaque:NO];
|
|
zaudragon@3188
|
59 |
[panel setHasShadow:YES];
|
|
zaudragon@3188
|
60 |
[panel setCanHide:NO];
|
|
zaudragon@3188
|
61 |
[panel setOneShot:YES];
|
|
zaudragon@3188
|
62 |
[panel useOptimizedDrawing:YES];
|
|
zaudragon@3188
|
63 |
[panel setMovableByWindowBackground:NO];
|
|
zaudragon@3188
|
64 |
|
|
zaudragon@3188
|
65 |
// Create the content view...
|
|
zaudragon@3189
|
66 |
GrowliCalWindowView *view = [[GrowliCalWindowView alloc] initWithFrame:panelFrame];
|
|
zaudragon@3188
|
67 |
[view setTarget:self];
|
|
zaudragon@3188
|
68 |
[view setAction:@selector(notificationClicked:)];
|
|
zaudragon@3188
|
69 |
[panel setContentView:view];
|
|
evands@3534
|
70 |
[view release];
|
|
zaudragon@3188
|
71 |
|
|
zaudragon@3188
|
72 |
// call super so everything else is set up...
|
|
zaudragon@3188
|
73 |
if ((self = [super initWithWindow:panel])) {
|
|
zaudragon@3188
|
74 |
// set up the transitions...
|
|
zaudragon@3188
|
75 |
GrowlFadingWindowTransition *fader = [[GrowlFadingWindowTransition alloc] initWithWindow:panel];
|
|
zaudragon@3188
|
76 |
[self addTransition:fader];
|
|
zaudragon@3188
|
77 |
[self setStartPercentage:0 endPercentage:100 forTransition:fader];
|
|
zaudragon@3188
|
78 |
[fader setAutoReverses:YES];
|
|
zaudragon@3188
|
79 |
[fader release];
|
|
zaudragon@3188
|
80 |
}
|
|
evands@3543
|
81 |
|
|
evands@3543
|
82 |
[panel release];
|
|
zaudragon@3188
|
83 |
|
|
zaudragon@3188
|
84 |
return self;
|
|
zaudragon@3188
|
85 |
}
|
|
zaudragon@3188
|
86 |
|
|
zaudragon@3188
|
87 |
#pragma mark -
|
|
zaudragon@3188
|
88 |
|
|
zaudragon@3188
|
89 |
- (void) setNotification: (GrowlApplicationNotification *) theNotification {
|
|
zaudragon@3188
|
90 |
[super setNotification:theNotification];
|
|
zaudragon@3188
|
91 |
if (!theNotification)
|
|
zaudragon@3188
|
92 |
return;
|
|
zaudragon@3188
|
93 |
|
|
zaudragon@3188
|
94 |
NSDictionary *noteDict = [notification dictionaryRepresentation];
|
|
bgannin@3404
|
95 |
NSString *title = [notification title];
|
|
bgannin@3404
|
96 |
NSString *text = [notification notificationDescription];
|
|
zaudragon@3188
|
97 |
NSImage *icon = getObjectForKey(noteDict, GROWL_NOTIFICATION_ICON);
|
|
zaudragon@3188
|
98 |
int priority = getIntegerForKey(noteDict, GROWL_NOTIFICATION_PRIORITY);
|
|
bgannin@3404
|
99 |
|
|
zaudragon@3189
|
100 |
GrowliCalWindowView *view = [[self window] contentView];
|
|
zaudragon@3188
|
101 |
[view setPriority:priority];
|
|
bgannin@3404
|
102 |
[view setTitle:title];
|
|
bgannin@3404
|
103 |
[view setText:text];
|
|
zaudragon@3188
|
104 |
[view setIcon:icon];
|
|
zaudragon@3188
|
105 |
[view sizeToFit];
|
|
zaudragon@3188
|
106 |
}
|
|
zaudragon@3188
|
107 |
|
|
zaudragon@3188
|
108 |
#pragma mark -
|
|
zaudragon@3188
|
109 |
#pragma mark positioning methods
|
|
zaudragon@3188
|
110 |
|
|
zaudragon@3188
|
111 |
- (NSPoint) idealOriginInRect:(NSRect)rect {
|
|
zaudragon@3188
|
112 |
NSRect viewFrame = [[[self window] contentView] frame];
|
|
bgannin@3317
|
113 |
enum GrowlPosition originatingPosition = [[GrowlPositionController sharedInstance] originPosition];
|
|
bgannin@3272
|
114 |
NSPoint idealOrigin;
|
|
bgannin@3272
|
115 |
|
|
bgannin@3272
|
116 |
switch(originatingPosition){
|
|
bgannin@3272
|
117 |
case GrowlTopRightPosition:
|
|
bgannin@3272
|
118 |
idealOrigin = NSMakePoint(NSMaxX(rect) - NSWidth(viewFrame) - GrowliCalPadding,
|
|
bgannin@3272
|
119 |
NSMaxY(rect) - GrowliCalPadding - NSHeight(viewFrame));
|
|
bgannin@3272
|
120 |
break;
|
|
bgannin@3272
|
121 |
case GrowlTopLeftPosition:
|
|
bgannin@3272
|
122 |
idealOrigin = NSMakePoint(NSMinX(rect) + GrowliCalPadding,
|
|
bgannin@3272
|
123 |
NSMaxY(rect) - GrowliCalPadding - NSHeight(viewFrame));
|
|
bgannin@3272
|
124 |
break;
|
|
bgannin@3272
|
125 |
case GrowlBottomLeftPosition:
|
|
bgannin@3272
|
126 |
idealOrigin = NSMakePoint(NSMinX(rect) + GrowliCalPadding,
|
|
bgannin@3272
|
127 |
NSMinY(rect) + GrowliCalPadding);
|
|
bgannin@3272
|
128 |
break;
|
|
bgannin@3272
|
129 |
case GrowlBottomRightPosition:
|
|
bgannin@3272
|
130 |
idealOrigin = NSMakePoint(NSMaxX(rect) - NSWidth(viewFrame) - GrowliCalPadding,
|
|
bgannin@3272
|
131 |
NSMinY(rect) + GrowliCalPadding);
|
|
bgannin@3272
|
132 |
break;
|
|
bgannin@3272
|
133 |
default:
|
|
bgannin@3272
|
134 |
idealOrigin = NSMakePoint(NSMaxX(rect) - NSWidth(viewFrame) - GrowliCalPadding,
|
|
bgannin@3272
|
135 |
NSMaxY(rect) - GrowliCalPadding - NSHeight(viewFrame));
|
|
bgannin@3272
|
136 |
break;
|
|
bgannin@3272
|
137 |
}
|
|
bgannin@3272
|
138 |
|
|
bgannin@3272
|
139 |
return idealOrigin;
|
|
zaudragon@3188
|
140 |
}
|
|
zaudragon@3188
|
141 |
|
|
zaudragon@3188
|
142 |
- (enum GrowlExpansionDirection) primaryExpansionDirection {
|
|
bgannin@3317
|
143 |
enum GrowlPosition originatingPosition = [[GrowlPositionController sharedInstance] originPosition];
|
|
bgannin@3272
|
144 |
enum GrowlExpansionDirection directionToExpand;
|
|
bgannin@3272
|
145 |
|
|
bgannin@3272
|
146 |
switch(originatingPosition){
|
|
bgannin@3272
|
147 |
case GrowlTopLeftPosition:
|
|
bgannin@3272
|
148 |
directionToExpand = GrowlDownExpansionDirection;
|
|
bgannin@3272
|
149 |
break;
|
|
bgannin@3272
|
150 |
case GrowlTopRightPosition:
|
|
bgannin@3272
|
151 |
directionToExpand = GrowlDownExpansionDirection;
|
|
bgannin@3272
|
152 |
break;
|
|
bgannin@3272
|
153 |
case GrowlBottomLeftPosition:
|
|
bgannin@3272
|
154 |
directionToExpand = GrowlUpExpansionDirection;
|
|
bgannin@3272
|
155 |
break;
|
|
bgannin@3272
|
156 |
case GrowlBottomRightPosition:
|
|
bgannin@3272
|
157 |
directionToExpand = GrowlUpExpansionDirection;
|
|
bgannin@3272
|
158 |
break;
|
|
bgannin@3272
|
159 |
default:
|
|
bgannin@3272
|
160 |
directionToExpand = GrowlDownExpansionDirection;
|
|
bgannin@3272
|
161 |
break;
|
|
bgannin@3272
|
162 |
}
|
|
bgannin@3272
|
163 |
|
|
bgannin@3272
|
164 |
return directionToExpand;
|
|
zaudragon@3188
|
165 |
}
|
|
zaudragon@3188
|
166 |
|
|
zaudragon@3188
|
167 |
- (enum GrowlExpansionDirection) secondaryExpansionDirection {
|
|
bgannin@3317
|
168 |
enum GrowlPosition originatingPosition = [[GrowlPositionController sharedInstance] originPosition];
|
|
bgannin@3272
|
169 |
enum GrowlExpansionDirection directionToExpand;
|
|
bgannin@3272
|
170 |
|
|
bgannin@3272
|
171 |
switch(originatingPosition){
|
|
bgannin@3272
|
172 |
case GrowlTopLeftPosition:
|
|
bgannin@3272
|
173 |
directionToExpand = GrowlRightExpansionDirection;
|
|
bgannin@3272
|
174 |
break;
|
|
bgannin@3272
|
175 |
case GrowlTopRightPosition:
|
|
bgannin@3272
|
176 |
directionToExpand = GrowlLeftExpansionDirection;
|
|
bgannin@3272
|
177 |
break;
|
|
bgannin@3272
|
178 |
case GrowlBottomLeftPosition:
|
|
bgannin@3272
|
179 |
directionToExpand = GrowlRightExpansionDirection;
|
|
bgannin@3272
|
180 |
break;
|
|
bgannin@3272
|
181 |
case GrowlBottomRightPosition:
|
|
bgannin@3272
|
182 |
directionToExpand = GrowlLeftExpansionDirection;
|
|
bgannin@3272
|
183 |
break;
|
|
bgannin@3272
|
184 |
default:
|
|
bgannin@3272
|
185 |
directionToExpand = GrowlRightExpansionDirection;
|
|
bgannin@3272
|
186 |
break;
|
|
bgannin@3272
|
187 |
}
|
|
bgannin@3272
|
188 |
|
|
bgannin@3272
|
189 |
return directionToExpand;
|
|
zaudragon@3188
|
190 |
}
|
|
zaudragon@3188
|
191 |
|
|
zaudragon@3188
|
192 |
- (float) requiredDistanceFromExistingDisplays {
|
|
zaudragon@3189
|
193 |
return GrowliCalPadding;
|
|
zaudragon@3188
|
194 |
}
|
|
zaudragon@3188
|
195 |
|
|
zaudragon@3188
|
196 |
@end
|