Adding a better cancel job to the Pivot effect. Also redoing the showcase interface...
[ITKit.git] / Showcase / Controller.m
1 #import "Controller.h"
2 #import "ITTransientStatusWindow.h"
3 #import "ITTextField.h"
4 #import "ITPivotWindowEffect.h"
5
6 #define SW_PAD    24.0
7 #define SW_SPACE  24.0
8 #define SW_MINW   211.0
9 #define SW_BORDER 32.0
10 #define SW_IMAGE  @"Library"
11
12 @interface Controller (ITStatusItemSupport)
13 - (void)createStatusItem;
14 - (void)removeStatusItem;
15 @end
16
17
18 @implementation Controller
19
20 - (void)awakeFromNib
21 {
22     [self createStatusItem];
23     [testTextField setCastsShadow:YES];
24     [tabView setAllowsDragging:YES];
25     statusWindow = [ITTransientStatusWindow sharedWindow];
26 //  [tabView setAllowsDragging:YES];
27 }
28
29 /*************************************************************************/
30 #pragma mark -
31 #pragma mark ITStatusItem SUPPORT
32 /*************************************************************************/
33
34 - (void)createStatusItem
35 {
36     statusItem = [[ITStatusItem alloc] initWithStatusBar:[NSStatusBar systemStatusBar]
37                                               withLength:NSVariableStatusItemLength];
38
39     if ( [showImageCheckBox state] == NSOnState ) {
40         [statusItem setImage:[NSImage imageNamed:@"ITStatusItem"]];
41     }
42
43     if ( [useInvertedCheckBox state] == NSOnState ) {
44         [statusItem setAlternateImage:[NSImage imageNamed:@"ITStatusItemInv"]];
45     }
46
47     if ( [showTitleCheckBox state] == NSOnState ) {
48         [statusItem setTitle:@"ITStatusItem"];
49     }
50
51     [statusItem setMenu:statusItemMenu];
52 }
53
54 - (void)removeStatusItem
55 {
56     [[statusItem statusBar] removeStatusItem:statusItem];
57     [statusItem autorelease];
58     statusItem = nil;
59 }
60
61 - (IBAction)toggleStatusItem:(id)sender
62 {
63     if ( [sender state] == NSOnState ) {
64         [self createStatusItem];
65         [showImageCheckBox   setEnabled:YES];
66         [showTitleCheckBox   setEnabled:YES];
67         [useInvertedCheckBox setEnabled:YES];
68     } else {
69         [self removeStatusItem];
70         [showImageCheckBox   setEnabled:NO];
71         [useInvertedCheckBox setEnabled:NO];
72         [showTitleCheckBox   setEnabled:NO];
73     }
74 }
75
76 - (IBAction)toggleImage:(id)sender
77 {
78     if ( [sender state] == NSOnState ) {
79         [statusItem setImage:[NSImage imageNamed:@"ITStatusItem"]];
80         [statusItem setAlternateImage:[NSImage imageNamed:@"ITStatusItemInv"]];
81         [useInvertedCheckBox setEnabled:YES];
82         [useInvertedCheckBox setState:NSOnState];
83     } else {
84         [statusItem setImage:nil];
85         [statusItem setAlternateImage:nil];
86         [useInvertedCheckBox setEnabled:NO];
87         [useInvertedCheckBox setState:NSOffState];
88     }
89 }
90
91 - (IBAction)toggleInvertedImage:(id)sender
92 {
93     if ( [sender state] == NSOnState ) {
94         [statusItem setAlternateImage:[NSImage imageNamed:@"ITStatusItemInv"]];
95     } else {
96         [statusItem setAlternateImage:nil];
97     }
98 }
99
100 - (IBAction)toggleTitle:(id)sender
101 {
102     if ( [sender state] == NSOnState ) {
103         [statusItem setTitle:@"ITStatusItem"];
104     } else {
105         [statusItem setTitle:nil];
106     }
107 }
108
109
110 /*************************************************************************/
111 #pragma mark -
112 #pragma mark ITTextView SUPPORT
113 /*************************************************************************/
114
115 - (IBAction)toggleCastsShadow:(id)sender
116 {
117     [testTextField setCastsShadow:([sender state] == NSOnState)];
118 }
119
120
121 /*************************************************************************/
122 #pragma mark -
123 #pragma mark ITTransientStatusWindow SUPPORT
124 /*************************************************************************/
125
126 - (IBAction)buildStatusWindow:(id)sender
127 {
128     NSImageView *imageView    = nil;
129     ITTextField *textField    = nil;
130     NSImage     *image        = [NSImage imageNamed:SW_IMAGE];
131     NSRect       imageRect;
132     NSRect       textRect;   
133
134     float imageWidth    = 0.0;
135     float imageHeight   = 0.0;
136     float textWidth     = 0.0;
137     float textHeight    = 0.0;
138     float contentHeight = 0.0;
139     float windowWidth   = 0.0;
140     float windowHeight  = 0.0;
141
142     NSString     *text     = [swSampleTextView string];
143     NSArray      *lines    = [text componentsSeparatedByString:@"\n"];
144     id                    oneLine  = nil;
145     NSEnumerator *lineEnum = [lines objectEnumerator];
146
147     NSFont *font           = [NSFont fontWithName:@"Lucida Grande Bold" size:18];
148     NSDictionary *attr     = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
149     
150     // Get image width and height.
151     imageWidth  = [image size].width;
152     imageHeight = [image size].height;
153     
154     // Iterate over each line to get text width and height
155     while ( oneLine = [lineEnum nextObject] ) {
156         // Get the width of one line, adding 8.0 because Apple sucks donkey rectum.
157         float oneLineWidth = ( [oneLine sizeWithAttributes:attr].width + 8.0 );
158         // Add the height of this line to the total text height
159         textHeight += [oneLine sizeWithAttributes:attr].height;
160         // If this line wider than the last one, set it as the text width.
161         textWidth = ( ( textWidth > oneLineWidth ) ? textWidth : oneLineWidth );
162     }
163     
164     // Add 4.0 to the final textHeight to accomodate the shadow.
165     textHeight += 4.0;
166     
167     // Set the content height to the greater of the text and image heights.
168     contentHeight = ( ( imageHeight > textHeight ) ? imageHeight : textHeight );
169     
170     // Setup the Window, and remove all its contentview's subviews.
171     windowWidth  = ( SW_PAD + imageWidth + SW_SPACE + textWidth + SW_PAD );
172     windowHeight = ( SW_PAD + contentHeight + SW_PAD );
173     [statusWindow setFrame:NSMakeRect(SW_BORDER, SW_BORDER, windowWidth, windowHeight) display:YES];
174     [[[statusWindow contentView] subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
175     
176     // Setup, position, fill, and add the image view to the content view.
177     imageRect = NSMakeRect( SW_PAD,
178                             (SW_PAD + ((contentHeight - imageHeight) / 2)),
179                             imageWidth,
180                             imageHeight );
181     imageView = [[[NSImageView alloc] initWithFrame:imageRect] autorelease];
182     [imageView setImage:image];
183     [[statusWindow contentView] addSubview:imageView];
184     
185     // Setup, position, fill, and add the text view to the content view.
186     textRect = NSMakeRect( (SW_PAD + imageWidth + SW_SPACE),
187                            (SW_PAD + ((contentHeight - textHeight) / 2)),
188                            textWidth,
189                            textHeight);
190     textField = [[[ITTextField alloc] initWithFrame:textRect] autorelease];
191     [textField setEditable:NO];
192     [textField setSelectable:NO];
193     [textField setBordered:NO];
194     [textField setDrawsBackground:NO];
195     [textField setFont:[NSFont fontWithName:@"Lucida Grande Bold" size:18]];
196     [textField setTextColor:[NSColor whiteColor]];
197     [textField setCastsShadow:YES];
198     [textField setStringValue:text];
199     [[statusWindow contentView] addSubview:textField];
200
201     [[statusWindow contentView] setNeedsDisplay:YES];
202
203     [statusWindow setEntryEffect:[[ITPivotWindowEffect alloc] initWithWindow:statusWindow]];
204     [statusWindow setExitEffect:[[ITPivotWindowEffect alloc] initWithWindow:statusWindow]];
205 }
206
207 - (IBAction)toggleStatusWindow:(id)sender
208 {
209     if ( ([statusWindow visibilityState] == ITTransientStatusWindowHiddenState) ||
210          ([statusWindow visibilityState] == ITTransientStatusWindowVanishingState) ) {
211         [[statusWindow contentView] setNeedsDisplay:YES];
212         [statusWindow appear:self];
213     } else {
214         [statusWindow vanish:self];
215     }
216 }
217
218 - (IBAction)changeWindowSetting:(id)sender
219 {
220     switch ( [sender tag] )
221     {
222         case 3010:  // Not yet supported.
223             break;
224         case 3020:  // Not yet supported.
225             break;
226         case 3030:  // Change vanish delay
227             [statusWindow setExitDelay:[sender floatValue]];
228             break;
229         case 3040:  // Change vertical position
230             [statusWindow setVerticalPosition:[sender indexOfSelectedItem]];
231             break;
232         case 3050:  // Change horizontal position
233             [statusWindow setHorizontalPosition:[sender indexOfSelectedItem]];
234             break;
235         case 3060:  // Change effect speed
236             [[statusWindow entryEffect] setEffectTime:[sender floatValue]];
237             [[statusWindow exitEffect]  setEffectTime:[sender floatValue]];
238             break;
239         case 3070:  // Change entry effect
240             break;
241         case 3080:  // Change exit effect
242             break;
243     }
244 }
245
246
247 /*************************************************************************/
248 #pragma mark -
249 #pragma mark ITTabView SUPPORT
250 /*************************************************************************/
251
252 - (IBAction)toggleTabDragging:(id)sender
253 {
254     if ([sender state] == NSOnState) {
255         [tabView setAllowsDragging:YES];
256     } else {
257         [tabView setAllowsDragging:NO];
258     }
259 }
260
261 - (IBAction)toggleCommandDragging:(id)sender
262 {
263     if ([sender state] == NSOnState) {
264         [tabView setRequiredModifiers:NSCommandKeyMask];
265     } else {
266         [tabView setRequiredModifiers:0];
267     }
268 }
269
270 - (IBAction)toggleControlDragging:(id)sender
271 {
272 }
273
274 - (IBAction)toggleOptionDragging:(id)sender
275 {
276 }
277
278 - (IBAction)toggleShiftDragging:(id)sender
279 {
280 }
281
282
283 /*************************************************************************/
284 #pragma mark -
285 #pragma mark NSWindow DELEGATE METHODS
286 /*************************************************************************/
287
288 - (void)windowWillMiniaturize:(NSNotification *)note
289 {
290     [[note object] setMiniwindowImage:[NSImage imageNamed:@"ITStatusItem"]];
291 }
292
293
294 @end