[NSApp beginSheet: saveSheet modalForWindow: window modalDelegate: self didEndSelector: @selector(saveSheetDidEnd:returnCode:contextInfo:) contextInfo: NULL];In the controls in the sheet, use something like
[NSApp endSheet: saveSheet returnCode: NSOKButton];To invoke the
didEndSelector
. Inside of that method, you can check the return code and decide what to do:
- (void) saveSheetDidEnd: (NSWindow *) sheet returnCode: (int) returnCode contextInfo: (void *) contextInfo { if (returnCode == NSOKButton) { // ... } else if (returnCode == NSCancelButton) { // ... } else { // ... } [sheet close]; } // saveSheetDidEnd
setFrame:
for a window, you have to account for the height of the title bar. In the Classic days it was 16 pixels. In Aqua-land, it's currently 22 pixels. But that's not safe to use, so try this instead:
- (float) titleBarHeight { NSRect frame = NSMakeRect (0, 0, 100, 100); NSRect contentRect; contentRect = [NSWindow contentRectForFrameRect: frame styleMask: NSTitledWindowMask]; return (frame.size.height - contentRect.size.height); } // titleBarHeightRainer Brockerhoff points out that this might miss any system-suppled window decorations at the bottom of the window. There aren't any now, but Mac OS X 10.37 Sabertooth might, so you may want to take into account the y positions of the original rectangle and the newly calculated content rect.
window
method, that will force the nib file to be loaded. Something like this:
+ (BWInspector *) sharedInspector { static BWInspector *s_inspector; if (s_inspector == nil) { s_inspector = [[BWInspector alloc] initWithWindowNibName: @"BWInspector"]; assert (s_inspector != nil); // force loading of nib (void) [s_inspector window]; } return (s_inspector); } // sharedInspector
[sheet close]
in addition to your [NSApp endSheet: sheet returnCode:23]
[panel setHidesOnDeactivate: NO];
setFrame:display:animate:
to resize a window, and have the window animate between the two sizes. Remember that Cocoa uses a bottom-left origin, which is a pain when dealing with windows. You want the window's top left to be the same between the old and new sizes, so you have to dink with the origin as well as the size:
float delta = ... how much to make the window bigger or smaller ...; NSRect frame = [window frame]; frame.origin.y -= delta; frame.size.height += delta; [window setFrame: frame display: YES animate: YES];
NSViewAnimation
lets you resize a window and cross-fade some views in one operation. (note I've had problems with the window size getting a couple of pixels off using this. Hopefully either I'm doing something dumb, or Apple fixes a bug). This code resizes the window, and changes the view that lives inside of a box. This is like how the Pages inspector works (except Pages doesn't do the gratuitous animation effect)
NSRect newWindowFrame = ... the new window size; NSDictionary *windowResize; windowResize = [NSDictionary dictionaryWithObjectsAndKeys: window, NSViewAnimationTargetKey, [NSValue valueWithRect: newWindowFrame], NSViewAnimationEndFrameKey, nil]; NSDictionary *oldFadeOut = nil; if (oldView != nil) { oldFadeOut = [NSDictionary dictionaryWithObjectsAndKeys: oldView, NSViewAnimationTargetKey, NSViewAnimationFadeOutEffect, NSViewAnimationEffectKey, nil]; } NSDictionary *newFadeIn; newFadeIn = [NSDictionary dictionaryWithObjectsAndKeys: newView, NSViewAnimationTargetKey, NSViewAnimationFadeInEffect, NSViewAnimationEffectKey, nil]; NSArray *animations; animations = [NSArray arrayWithObjects: windowResize, newFadeIn, oldFadeOut, nil]; NSViewAnimation *animation; animation = [[NSViewAnimation alloc] initWithViewAnimations: animations]; [animation setAnimationBlockingMode: NSAnimationBlocking]; [animation setDuration: 0.5]; // or however long you want it for [animation startAnimation]; // because it's blocking, once it returns, we're done [animation release];
// I am the very modal of a modern major general. int blah = [NSApp runModalForWindow:[self window]];and then elsewhere, like in your OK or cancel button
[NSApp stopModalWithCode:NSOKButton];
NSWindowController
:
@interface BWInspector : NSWindowController { // ivars, IBOutlets, etc } // IBActions, etc + (BWInspector *) sharedInspector; @end // BWInspectorThen make a nib file with the window, the controls, and other fun stuff you want. This one lives in
English.lproj/BWInspector.nib
Then in that class method load the window:
+ (BWInspector *) sharedInspector { static BWInspector *g_inspector; if (g_inspector == nil) { g_inspector = [[BWInspector alloc] initWithWindowNibName: @"BWInspector"]; assert (g_inspector != nil); // or other error handling [g_inspector showWindow: self]; } return (g_inspector); } // sharedInspectorThat will load the nib file, set up the connections and then open the window for display
@implementation NSView (BWYellowView) - (void) drawRect: (NSRect) rect { NSColor *transparentYellow; rect = [self bounds]; transparentYellow = [NSColor colorWithCalibratedRed: 1.0 green: 1.0 blue: 0.0 alpha: 0.333]; [transparentYellow set]; [NSBezierPath fillRect: rect]; } // rect @end // BWYellowViewI have no idea how you colorize the titlebar.
NSWindow
and override sendEvent
:- (void) sendEvent: (NSEvent *) anEvent { if ([anEvent type] == NSKeyDown) { [someOtherWindow sendEvent: anEvent]; } else { [super sendEvent: anEvent]; } } // sendEventIt's up to you to figure out what "
someOtherWindow
" is, whether it's a delegate or an instance variable that holds the other window.