Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
GLUTWindow.m
| /* Copyright (c) Dietmar Planitzer, 1998, 2002 - 2003 */ | 
| /* This program is freely distributable without licensing fees | 
| and is provided without guarantee or warrantee expressed or | 
| implied. This program is -not- in the public domain. */ | 
| #import "macx_glut.h" | 
| #import "GLUTWindow.h" | 
| #import "GLUTView.h" | 
| #import "GLUTApplication.h" | 
| NSString *GLUTWindowFrame = @"GLUTWindowFrame"; | 
| @interface GLUTView(GLUTPrivate) | 
| - (void)_commonReshape; | 
| @end | 
| @interface GLUTWindow(GLUTPrivate) | 
| - (id)_initWithContentRect: (NSRect)rect styleMask: (unsigned int)mask contentView: (GLUTView *)aView; | 
| - (id)_initWithWindow: (GLUTWindow *)aWindow operation: (int)op arguments: (NSDictionary *)operands; | 
| - (NSWindow *)_windowWithTIFFInsideRect: (NSRect)rect; | 
| - (NSData *)_dataWithTIFFOfContentView; | 
| - (NSData *)_dataWithRTFDOfContentView; | 
| @end | 
| ///////////////////////////////////////////// | 
| #pragma mark - | 
| @implementation GLUTWindow | 
| static BOOL gInitialized = NO; | 
| static NSArray * gServicesTypes = nil; | 
| + (void)initialize | 
| {    | 
|     if(!gInitialized) { | 
| gInitialized = YES; | 
| gServicesTypes = [[NSArray arrayWithObjects: NSTIFFPboardType, NSRTFDPboardType, nil] retain]; | 
| [NSApp registerServicesMenuSendTypes: gServicesTypes returnTypes: nil]; | 
| } | 
| } | 
| + (id)windowByMorphingWindow: (GLUTWindow *)aWindow operation: (int)op arguments: (NSDictionary *)dict | 
| { | 
| return [[[self alloc] _initWithWindow: aWindow operation: op arguments: dict] autorelease]; | 
| } | 
| /* Designated initializer */ | 
| - (id)_initWithContentRect: (NSRect)rect styleMask: (unsigned int)mask contentView: (GLUTView *)aView | 
| { | 
|    if((self = [super initWithContentRect: rect styleMask: mask backing: NSBackingStoreBuffered defer: NO]) != nil) { | 
| [self setReleasedWhenClosed: NO]; | 
| [self setMinSize: NSMakeSize(80.0, 80.0)]; | 
| [self setShowsResizeIndicator:NO]; // turn off the grow box. | 
| [self setContentView: aView]; | 
| [self makeFirstResponder: aView]; | 
| [self setDelegate: self]; | 
| return self; | 
| } | 
| return nil; | 
| } | 
| - (id)initWithContentRect: (NSRect)rect pixelFormat: (NSOpenGLPixelFormat *)pixelFormat | 
| windowID: (int)winid gameMode: (BOOL)gameMode fullscreenStereo: (BOOL)pfStereo treatAsSingle: (BOOL)treatAsSingle | 
| { | 
| unsigned int mask; | 
| GLUTView * view = nil; | 
|    if(gameMode) { // set to fill screen | 
| float offsetY = 0.0f; | 
| /* XXX NSScreen BUG WORKAROUND | 
| The purpose of the following code is to workaround a bug in the NSScreen class. | 
| The problem is that this class doesn't realize that we switched from the original | 
| screen mode to another mode via the CGDisplaySwitchToMode() function and thus | 
| keeps on reporting now out-dated screen attributes like screen width & height. | 
| This however has the unfortunate consequence that our NSWindow would be positioned | 
| incorrectly if the new mode has a smaller Y resolution than the old one. I.e. | 
| if the old Y res was 870 and the new is 480 the window would be placed by 390 pixels | 
| too far below. | 
| */ | 
| NSScreen * screen = [[NSScreen screens] objectAtIndex: 0]; | 
| NSSize screenSize = [screen frame].size; | 
| if(screenSize.height - rect.size.height > 0.0f) | 
| offsetY = screenSize.height - rect.size.height; | 
| rect.origin.y = offsetY; | 
| mask = NSBorderlessWindowMask; | 
|    } else { | 
| mask = (NSTitledWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask); | 
| } | 
| /* create and configure content view */ | 
| view = [[[GLUTView alloc] initWithFrame: rect | 
| pixelFormat: pixelFormat | 
| windowID: winid | 
| treatAsSingle: treatAsSingle | 
| isSubwindow: NO | 
| fullscreenStereo:pfStereo | 
| isVBLSynced: __glutSyncToVBL] autorelease]; | 
| if(view) | 
| return [self _initWithContentRect: rect styleMask: mask contentView: view]; | 
| else | 
| return nil; | 
| } | 
| - (id)_initWithWindow: (GLUTWindow *)aWindow operation: (int)op arguments: (NSDictionary *)dict | 
| { | 
| GLUTView * contentView = nil; | 
| NSResponder * savedFirstResponder; | 
|    NSRect           rect = {{0.0f, 0.0f}, {0.0f, 0.0f}}; | 
| unsigned int mask = 0; | 
| int level = 0; | 
|    switch(op) { | 
| case kGLUTMorphOperationFullscreen: | 
| /* Make a fullscreen window */ | 
|             if (NO == __glutUseExtendedDesktop) { | 
| rect = [[aWindow screen] frame]; | 
|             } else { // look at all screens | 
| NSEnumerator *enumerator = [[NSScreen screens] objectEnumerator]; | 
| NSScreen * screen = nil; | 
|                 while (nil != (screen = (NSScreen *)[enumerator nextObject])) { | 
| if([screen frame].origin.x < rect.origin.x) | 
| rect.origin.x = [screen frame].origin.x; | 
| if([screen frame].origin.y < rect.origin.y) | 
| rect.origin.y = [screen frame].origin.y; | 
| if(([screen frame].origin.x + [screen frame].size.width - rect.origin.x) > rect.size.width) | 
| rect.size.width = [screen frame].origin.x + [screen frame].size.width - rect.origin.x; | 
| if(([screen frame].origin.y + [screen frame].size.height - rect.origin.y) > rect.size.height) | 
| rect.size.height = [screen frame].origin.y + [screen frame].size.height - rect.origin.y; | 
| } | 
| } | 
| mask = NSBorderlessWindowMask; | 
| level = GLUT_FULLSCREEN_LEVEL; | 
| break; | 
| case kGLUTMorphOperationRegular: | 
| /* Make a standard window */ | 
| rect = [[dict objectForKey: GLUTWindowFrame] rectValue]; | 
| mask = (NSTitledWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask); | 
| level = GLUT_NORMAL_LEVEL; | 
| break; | 
| } | 
| savedFirstResponder = [aWindow firstResponder]; | 
| contentView = (GLUTView *) [[aWindow contentView] retain]; | 
| [contentView recursiveWillBeginMorph: op]; | 
| [aWindow setContentView: nil]; | 
|    if((self = [self _initWithContentRect: rect styleMask: mask contentView: contentView]) != nil) { | 
| [self setLevel: level]; | 
|       switch(op) { | 
| case kGLUTMorphOperationFullscreen: // new window is full screen | 
| _isFullscreen = YES; | 
| /* put window on fullscreen window list */ | 
| _nextFullscreenWindow = __glutFullscreenWindows; | 
| __glutFullscreenWindows = self; | 
| break; | 
| case kGLUTMorphOperationRegular: // new window is not full screen | 
| _isFullscreen = NO; | 
| break; | 
| } | 
| _imagePath = [aWindow->_imagePath copy]; | 
| _enabledMouseMovedEvents = aWindow->_enabledMouseMovedEvents; | 
| if(_enabledMouseMovedEvents > 0) | 
| [self setAcceptsMouseMovedEvents: YES]; | 
| [contentView recursiveDidEndMorph: op]; | 
| [self makeFirstResponder: savedFirstResponder]; | 
| // Call _commonReshape on the window's content view in order | 
| // to simulate a resize event (we don't automatically get one | 
| // because we just moved the content view from one window to | 
| // to another one...) | 
| [contentView _commonReshape]; | 
| [contentView release]; | 
| return self; | 
| } | 
| return nil; | 
| } | 
| - (void)dealloc | 
| { | 
| // remove from full screen window list | 
|    if(_isFullscreen) { | 
| GLUTWindow * prev = nil; | 
| GLUTWindow * cur = __glutFullscreenWindows; | 
|       while(cur != nil && cur != self) { | 
| prev = cur; | 
| cur = cur->_nextFullscreenWindow; | 
| } | 
| if(prev) | 
| prev->_nextFullscreenWindow = _nextFullscreenWindow; | 
| else | 
| __glutFullscreenWindows = _nextFullscreenWindow; | 
| } | 
| [super dealloc]; | 
| } | 
| - (void)finalize | 
| { | 
|    if(_isFullscreen) { | 
| GLUTWindow * prev = nil; | 
| GLUTWindow * cur = __glutFullscreenWindows; | 
|       while(cur != nil && cur != self) { | 
| prev = cur; | 
| cur = cur->_nextFullscreenWindow; | 
| } | 
| if(prev) | 
| prev->_nextFullscreenWindow = _nextFullscreenWindow; | 
| else | 
| __glutFullscreenWindows = _nextFullscreenWindow; | 
| } | 
| [super finalize]; | 
| } | 
| - (BOOL)isFullscreen | 
| { | 
| return _isFullscreen; | 
| } | 
| /* Returns YES if the window 'me' is either above or below the frame rectangle | 
| of any fullscreen window and NO otherwise */ | 
| - (BOOL)isAffectedByFullscreenWindow | 
| { | 
| NSRect frame = [self frame]; | 
| GLUTWindow * cur = __glutFullscreenWindows; | 
|    while(cur != nil) { | 
| NSRect othFrame = [cur frame]; | 
| if(NSContainsRect(othFrame, frame) || | 
| NSEqualRects(othFrame, frame) || | 
| NSIntersectsRect(othFrame, frame)) | 
| return YES; | 
| cur = cur->_nextFullscreenWindow; | 
| } | 
| return NO; | 
| } | 
| ///////////////////////////////////////////// | 
| #pragma mark - | 
| #pragma mark Events | 
| #pragma mark - | 
| - (void)enableMouseMovedEvents | 
| { | 
| _enabledMouseMovedEvents++; | 
| if(_enabledMouseMovedEvents == 1) | 
| [self setAcceptsMouseMovedEvents: YES]; | 
| } | 
| - (void)disableMouseMovedEvents | 
| { | 
| NSAssert(_enabledMouseMovedEvents >= 0, @"bogus -disableMouseMovedEvents"); | 
| _enabledMouseMovedEvents--; | 
| if(_enabledMouseMovedEvents == 0) | 
| [self setAcceptsMouseMovedEvents: NO]; | 
| } | 
| - (BOOL)canBecomeKeyWindow | 
| { | 
| return (!__glutGameModeWindow && !_isFullscreen) ? [super canBecomeKeyWindow] : YES; | 
| } | 
| - (void)sendEvent: (NSEvent *)event | 
| { | 
| [super sendEvent: event]; | 
|    if(__glutMappedMenu) { | 
| /* use mapped menu to determine if menu finishing needs to be done, regardless of button */ | 
| __glutFinishMenu([NSEvent mouseLocation]); /* sets mapped menu to nil */ | 
| __glutMenuWindow = nil; | 
| } | 
| } | 
| - (BOOL)validateMenuItem: (NSMenuItem *)menuItem | 
| { | 
| SEL action = [menuItem action]; | 
| if(action == @selector(save:) || action == @selector(saveAs:)) | 
| return (!__glutDisableGrabbing) ? [self isDocumentEdited] : NO; | 
| if(action == @selector(copy:)) | 
| return (!__glutDisableGrabbing); | 
|    if(__glutDisablePrinting) { | 
| if(action == @selector(runPageLayout:) || action == @selector(print:)) | 
| return NO; | 
| } | 
| return [super validateMenuItem: menuItem]; | 
| } | 
| - (IBAction)save: (id)sender | 
| { | 
|    if(_imagePath) { | 
| NSData * data = [self contentsAsDataOfType: NSTIFFPboardType]; | 
|       if(!data || !__glutWriteDataToFile(data, _imagePath, 'TIFF')) { | 
| NSBundle * bdl = __glutGetFrameworkBundle(); | 
| NSRunCriticalAlertPanel(NSLocalizedStringFromTableInBundle(@"Save Error", @"GLUTUI", | 
| bdl, @"Save Error"), | 
| NSLocalizedStringFromTableInBundle(@"Unable to save current window contents.", @"GLUTUI", | 
| bdl, @"Unable to save current window contents."), | 
| @"OK", nil, nil); | 
| } | 
| [self setDocumentEdited: NO]; | 
|    } else { | 
| [self saveAs: sender]; | 
| } | 
| } | 
| /* Save As */ | 
| - (void)savePanelDidEnd: (NSWindow *)sheet returnCode: (int)returnCode contextInfo: (id)savePanel | 
| { | 
|    if(returnCode == NSOKButton) { | 
| NSData * data = [self contentsAsDataOfType: NSTIFFPboardType]; | 
| [_imagePath release]; | 
| _imagePath = [[savePanel filename] copy]; | 
|       if(!data || !__glutWriteDataToFile(data, _imagePath, 'TIFF')) { | 
| NSBundle * bdl = __glutGetFrameworkBundle(); | 
| NSRunCriticalAlertPanel(NSLocalizedStringFromTableInBundle(@"Save Error", @"GLUTUI", | 
| bdl, @"Save Error"), | 
| NSLocalizedStringFromTableInBundle(@"Unable to save current window contents.", @"GLUTUI", | 
| bdl, @"Unable to save current window contents."), | 
| @"OK", nil, nil); | 
| } | 
| [self setDocumentEdited: NO]; | 
| } | 
| } | 
| - (IBAction)saveAs: (id)sender | 
| { | 
| NSSavePanel * savePanel = [NSSavePanel savePanel]; | 
| NSString * imageDirectory, *imageName; | 
|    if(!_imagePath) { | 
| _imagePath = [[[NSFileManager defaultManager] currentDirectoryPath] copy]; | 
| imageDirectory = _imagePath; | 
| imageName = @""; | 
|    } else { | 
| imageDirectory = _imagePath; | 
| imageName = [[_imagePath lastPathComponent] stringByDeletingPathExtension]; | 
| } | 
| [savePanel setCanSelectHiddenExtension: YES]; | 
| [savePanel setRequiredFileType: @"tiff"]; | 
| [savePanel beginSheetForDirectory: imageDirectory | 
| file: imageName | 
| modalForWindow: self | 
| modalDelegate: self | 
| didEndSelector: @selector(savePanelDidEnd:returnCode:contextInfo:) | 
| contextInfo: savePanel]; | 
| } | 
| - (IBAction)copy: (id)sender | 
| { | 
| NSString * type = NSTIFFPboardType; | 
| NSData * imageData = [self contentsAsDataOfType: type]; | 
|    if(imageData) { | 
| NSPasteboard * generalPboard = [NSPasteboard generalPasteboard]; | 
| [generalPboard declareTypes: [NSArray arrayWithObjects: type, nil] owner: nil]; | 
| [generalPboard setData: imageData forType: type]; | 
| } | 
| } | 
| /* Page Layout */ | 
| - (void)pageLayoutDidEnd: (NSPageLayout *)pageLayout returnCode: (int)returnCode contextInfo: (id)printInfo | 
| { | 
|    if(returnCode == NSOKButton) { | 
| [NSPrintInfo setSharedPrintInfo: printInfo]; | 
| } | 
| } | 
| - (void)runPageLayout: (id)sender | 
| { | 
| NSPageLayout * pageLayout = [NSPageLayout pageLayout]; | 
| NSPrintInfo * printInfo = [NSPrintInfo sharedPrintInfo]; | 
| [pageLayout beginSheetWithPrintInfo: printInfo | 
| modalForWindow: self | 
| delegate: self | 
| didEndSelector: @selector(pageLayoutDidEnd:returnCode:contextInfo:) | 
| contextInfo: printInfo]; | 
| } | 
| /* Print Panel */ | 
| - (void)printOperationDidRun: (NSPrintOperation *)printOperation success: (BOOL)success contextInfo: (id)window | 
| { | 
| [window release]; | 
| } | 
| - (void)print: (id)sender | 
| { | 
| NSWindow * window = [[self _windowWithTIFFInsideRect: NSZeroRect] retain]; | 
|    if(window) { | 
| NSPrintOperation * printOperation = [NSPrintOperation printOperationWithView: [window contentView]]; | 
| [printOperation runOperationModalForWindow: self | 
| delegate: self | 
| didRunSelector: @selector(printOperationDidRun:success:contextInfo:) | 
| contextInfo: window]; | 
|    } else { | 
| NSBundle * bdl = __glutGetFrameworkBundle(); | 
| NSRunCriticalAlertPanel(NSLocalizedStringFromTableInBundle(@"Print Error", @"GLUTUI", | 
| bdl, @"Print Error"), | 
| NSLocalizedStringFromTableInBundle(@"Could not generate PDF data for printing.", @"GLUTUI", | 
| bdl, @"Could not generate PDF data for printing."), | 
| @"OK", nil, nil); | 
| } | 
| } | 
| - (void)zoom:(id)sender | 
| { | 
| NSMutableSet * views = [NSMutableSet set]; | 
| GLUTView * view = (GLUTView *) [self contentView]; | 
| [views unionSet: [view coveredViews]]; | 
| [views addObject: view]; | 
| [super zoom: sender]; | 
| [views unionSet: [view coveredViews]]; | 
| [GLUTView evaluateVisibilityOfViews: views]; | 
| } | 
| ///////////////////////////////////////////// | 
| #pragma mark - | 
| #pragma mark Services | 
| #pragma mark - | 
| - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType | 
| { | 
| if([gServicesTypes containsObject: sendType]) | 
| return self; | 
| return [super validRequestorForSendType: sendType returnType: returnType]; | 
| } | 
| - (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard types:(NSArray *)types | 
| { | 
| unsigned i, count = [types count]; | 
|    for(i = 0; i < count; i++) { | 
| NSString * pboardType = [types objectAtIndex: i]; | 
| NSData * imageData = [self contentsAsDataOfType: pboardType]; | 
|       if(imageData) { | 
| [pboard declareTypes: [NSArray arrayWithObject: pboardType] owner: nil]; | 
| [pboard setData: imageData forType: pboardType]; | 
| return YES; | 
| } | 
| } | 
| return NO; | 
| } | 
| ///////////////////////////////////////////// | 
| #pragma mark - | 
| #pragma mark Image Data Creation | 
| #pragma mark - | 
| - (NSWindow *)_windowWithTIFFInsideRect: (NSRect)rect | 
| { | 
| NSImage * image = nil; | 
| NSImageView * imageView = nil; | 
| NSWindow * window = nil; | 
| GLUTView * view = (GLUTView *) [self contentView]; | 
| if(NSIsEmptyRect(rect)) | 
| rect = [view bounds]; | 
| if((imageView = [[NSImageView alloc] initWithFrame: rect]) == nil) | 
| return nil; | 
| if((window = [[NSWindow alloc] initWithContentRect: rect | 
| styleMask: NSBorderlessWindowMask | 
| backing: NSBackingStoreNonretained | 
|                                                 defer: NO]) == nil) { | 
| [imageView release]; | 
| return nil; | 
| } | 
| [window setContentView: imageView]; | 
| [imageView release]; | 
|    if((image = [view imageWithTIFFInsideRect: rect]) == nil) { | 
| [window release]; | 
| return nil; | 
| } | 
| [imageView setImage: image]; | 
| return [window autorelease]; | 
| } | 
| - (NSData *)_dataWithTIFFOfContentView | 
| { | 
| NSImage * image = [(GLUTView *) [self contentView] imageWithTIFFInsideRect: NSZeroRect]; | 
| NSData * data = nil; | 
|    if(image != nil) { | 
| data = [image TIFFRepresentation]; | 
| } | 
| return data; | 
| } | 
| - (NSData *)_dataWithRTFDOfContentView | 
| { | 
| static int generationCounter = 1; | 
| NSAttributedString * myString = nil; | 
| NSFileWrapper * myFileWrapper = nil; | 
| NSTextAttachment * myTextAttachment = nil; | 
| NSData * tiffData = [self _dataWithTIFFOfContentView]; | 
| // create file wrapper | 
| if((myFileWrapper = [[NSFileWrapper alloc] initRegularFileWithContents: tiffData]) == nil) | 
| return nil; | 
| [myFileWrapper setPreferredFilename: [NSString stringWithFormat: @"GLUT Picture No.%d.tiff", generationCounter++]]; | 
| // create the text attachment | 
|     if((myTextAttachment = [[NSTextAttachment alloc] initWithFileWrapper: myFileWrapper]) == nil) { | 
| [myFileWrapper release]; | 
| return nil; | 
| } | 
| [myFileWrapper release]; | 
| // create the attributed string | 
|     if((myString = [NSAttributedString attributedStringWithAttachment: myTextAttachment]) == nil) { | 
| [myTextAttachment release]; | 
| return nil; | 
| } | 
| [myTextAttachment release]; | 
| // return the flattend data | 
| return [myString RTFDFromRange: NSMakeRange(0, [myString length]) documentAttributes: nil]; | 
| } | 
| /* Returns a data object containing the current contents of the receiving window */ | 
| - (NSData *)contentsAsDataOfType: (NSString *)pboardType | 
| { | 
| NSData * data = nil; | 
|    if([pboardType isEqualToString: NSTIFFPboardType] == YES) { | 
| data = [self _dataWithTIFFOfContentView]; | 
|     } else if([pboardType isEqualToString: NSRTFDPboardType] == YES) { | 
| data = [self _dataWithRTFDOfContentView]; | 
| } | 
| return data; | 
| } | 
| ///////////////////////////////////////////// | 
| #pragma mark - | 
| #pragma mark Delegate | 
| #pragma mark - | 
| - (BOOL)windowShouldClose: (id)sender | 
| { | 
| GLUTView * view = (GLUTView *) [self contentView]; | 
| GLUTwmcloseCB closeFunc = [view wmCloseCallback]; | 
| /* Enable special behavior of glutDestroyWindow() while we're here */ | 
| __glutInsideWindowShouldClose = YES; | 
| __glutShouldWindowClose = NO; | 
| __glutSetWindow(view); | 
| closeFunc(); | 
| __glutInsideWindowShouldClose = NO; | 
| /* Only return with YES, if the application called glutDestroyWindow(). | 
| Return NO otherwise. */ | 
| return __glutShouldWindowClose; | 
| } | 
| /* Update the window status of the receiver and all of it's sub windows. */ | 
| - (void)windowWillMiniaturize:(NSNotification *)notification | 
| { | 
| GLUTView * view = (GLUTView *) [self contentView]; | 
| /* Miniaturizing a window with an OpenGL content view in it is a bit tricky, | 
| because the OpenGL graphics is drawn in its own surface which floats above | 
| the Quartz window and thus is not directly accessible to the latter. | 
| In order to get around this, we tell our GLUTView to copy its OpenGL pixels | 
| from its associated surface into its Quartz context. The copied pixels will | 
| finally end up in the window's backing store where they can be easily | 
| grabbed from by the window minaturization engine. */ | 
| [view prepareForMiniaturization]; | 
| _viewStorage = [[NSMutableSet alloc] init]; | 
| [_viewStorage unionSet: [view coveredViews]]; | 
| [_viewStorage addObject: view]; | 
| } | 
| - (void)windowDidMiniaturize:(NSNotification *)notification | 
| { | 
| [GLUTView evaluateVisibilityOfViews: _viewStorage]; | 
| [_viewStorage release]; | 
| _viewStorage = nil; | 
| [(GLUTView *) [self contentView] setShown: NO]; | 
| } | 
| - (void)windowWillMove:(NSNotification *)notification | 
| { | 
| GLUTView * view = (GLUTView *) [self contentView]; | 
| _viewStorage = [[NSMutableSet alloc] init]; | 
| [_viewStorage unionSet: [view coveredViews]]; | 
| [_viewStorage addObject: view]; | 
| } | 
| - (void)windowDidMove:(NSNotification *)notification | 
| { | 
| [_viewStorage unionSet: [(GLUTView *) [self contentView] coveredViews]]; | 
| [GLUTView evaluateVisibilityOfViews: _viewStorage]; | 
| [_viewStorage release]; | 
| _viewStorage = nil; | 
| } | 
| - (void)orderWindow:(NSWindowOrderingMode)place relativeTo:(int)otherWin | 
| { | 
| GLUTView * view = (GLUTView *) [self contentView]; | 
|    if(view != nil) { | 
| NSMutableSet * views = [NSMutableSet set]; | 
|       if(place == NSWindowOut) { | 
| [views unionSet: [view coveredViews]]; | 
| [views addObject: view]; | 
| } | 
| [view setShown: (place != NSWindowOut)]; | 
| [super orderWindow: place relativeTo: otherWin]; | 
|       if(place != NSWindowOut) { | 
| [views unionSet: [view coveredViews]]; | 
| [view recursiveCollectViewsIntoSet: views]; | 
| } | 
| [GLUTView evaluateVisibilityOfViews: views]; | 
|    } else { | 
| [super orderWindow: place relativeTo: otherWin]; | 
| } | 
| } | 
| @end | 
Copyright © 2008 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2008-02-08