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.
TumblerSource/Tumbler_document.c
// Tumbler_document.c |
// |
// Document handling routines. |
// |
// Author: Nick Thompson & Pablo Fernicola, with thanks to the QuickDraw 3D team |
// |
// Copyright © 1992-95 Apple Computer, Inc., All Rights Reserved |
// |
// Modification History: |
// |
// 11/26/94 nick clean up, remove old TE references from dragtext, remove |
// all other dead code. |
// Modify CloseDocument & CloseAllDocuments to return a Boolean. |
// 01/26/95 nick parameterized NewDocument to take a (possibly null) group |
// and viewhints. Factored this routine as it was way too long |
// |
// to do: store the document reference as a handle in the window's refcon |
// |
#include <Drag.h> |
#include <QuickDraw.h> |
#include "Tumbler_globals.h" |
#include "Tumbler_prototypes.h" |
#include "Tumbler_resources.h" |
#include "QD3DDrawContext.h" |
#include "QD3DCamera.h" |
#include "QD3DView.h" |
#include "QD3DLight.h" |
#include "QD3DGeometry.h" |
#include "QD3DSet.h" |
#include "QD3DTransform.h" |
#include "QD3DShader.h" |
#include "QD3DShader.h" |
#include "QD3DMath.h" |
#include "QD3DIO.h" |
#include "Tumbler_camera.h" |
#include "Tumbler_document.h" |
#include "Tumbler_file.h" |
#include "Tumbler_utility.h" |
extern pascal OSErr MyTrackingHandler(short message, WindowPtr theWindow, |
void *handlerRefCon, DragReference theDrag); |
extern pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, void *handlerRefCon, |
DragReference theDrag); |
//---------------------------------------------------------------------- |
TQ3Status TumblerDocument_NewLights( DocumentPtr theDocument ) |
{ |
TQ3GroupObject lightGroup; |
TQ3LightObject light; |
TQ3PointLightData pointData; |
TQ3LightData ambientData; |
lightGroup = Q3LightGroup_New(); |
pointData.lightData.isOn = kQ3True; |
pointData.lightData.brightness = 0.950; |
pointData.lightData.color.r = 1.0; |
pointData.lightData.color.g = 1.0; |
pointData.lightData.color.b = 1.0; |
pointData.location.x = -10.0; |
pointData.location.y = 10.0; |
pointData.location.z = 30.0; |
pointData.castsShadows = kQ3False; |
pointData.attenuation = kQ3AttenuationTypeNone; |
light = Q3PointLight_New(&pointData); |
Q3Group_AddObject(lightGroup, light); |
Q3Object_Dispose(light); |
ambientData.isOn = kQ3True; |
ambientData.brightness = 0.70; |
ambientData.color.r = 0.4; |
ambientData.color.g = 0.4; |
ambientData.color.b = 0.4; |
light = Q3AmbientLight_New(&ambientData); |
Q3Group_AddObject(lightGroup, light); |
Q3Object_Dispose(light); |
pointData.lightData.isOn = kQ3False; |
pointData.lightData.brightness = 0.80; |
pointData.lightData.color.r = 1.0; |
pointData.lightData.color.g = 0.0; |
pointData.lightData.color.b = 0.0; |
pointData.location.x = -10.0; |
pointData.location.y = 0.0; |
pointData.location.z = 5.0; |
pointData.castsShadows = kQ3False; |
pointData.attenuation = kQ3AttenuationTypeInverseDistance; |
light = Q3PointLight_New(&pointData); |
Q3Group_AddObject(lightGroup, light); |
Q3Object_Dispose(light); |
pointData.lightData.isOn = kQ3False; |
pointData.lightData.brightness = 0.80; |
pointData.lightData.color.r = 0.0; |
pointData.lightData.color.g = 1.0; |
pointData.lightData.color.b = 0.0; |
pointData.location.x = 10.0; |
pointData.location.y = 0.0; |
pointData.location.z = 5.0; |
pointData.castsShadows = kQ3False; |
pointData.attenuation = kQ3AttenuationTypeInverseDistance; |
light = Q3PointLight_New(&pointData); |
Q3Group_AddObject(lightGroup, light); |
Q3Object_Dispose(light); |
pointData.lightData.isOn = kQ3False; |
pointData.lightData.brightness = 0.80; |
pointData.lightData.color.r = 0.0; |
pointData.lightData.color.g = 0.0; |
pointData.lightData.color.b = 1.0; |
pointData.location.x = 10.0; |
pointData.location.y = 0.0; |
pointData.location.z = 5.0; |
pointData.castsShadows = kQ3False; |
pointData.attenuation = kQ3AttenuationTypeInverseDistance; |
light = Q3PointLight_New(&pointData); |
Q3Group_AddObject(lightGroup, light); |
Q3Object_Dispose(light); |
Q3View_SetLightGroup(theDocument->theView, lightGroup); |
Q3Object_Dispose(lightGroup); |
// |
{ |
#if defined(ESCHER_VER_15) && ESCHER_VER_15 |
TQ3ColorRGB ellipsoidColor; |
TQ3EllipsoidData ellipsoidData; |
TQ3GeometryObject ellipsoid; |
TQ3RotateTransformData rotateData; |
theDocument->dynamicLights = Q3DisplayGroup_New(); |
ellipsoidData.origin.x = -10.0; |
ellipsoidData.origin.y = 0.0; |
ellipsoidData.origin.z = 5.0; |
ellipsoidData.orientation.x = 0.0; |
ellipsoidData.orientation.y = 1.0; |
ellipsoidData.orientation.z = 0.0; |
ellipsoidData.majorRadius.x = 0.0; |
ellipsoidData.majorRadius.y = 0.0; |
ellipsoidData.majorRadius.z = 1.0; |
ellipsoidData.minorRadius.x = 1.0; |
ellipsoidData.minorRadius.y = 0.0; |
ellipsoidData.minorRadius.z = 0.0; |
ellipsoidData.ellipsoidAttributeSet = Q3AttributeSet_New(); |
/* Red light ball */ |
ellipsoidColor.r = 1.0; |
ellipsoidColor.g = 0.0; |
ellipsoidColor.b = 0.0; |
Q3AttributeSet_Add( ellipsoidData.ellipsoidAttributeSet, |
kQ3AttributeTypeDiffuseColor, &ellipsoidColor); |
Q3AttributeSet_Add(ellipsoidData.ellipsoidAttributeSet, |
kQ3AttributeTypeSpecularColor, &ellipsoidColor); |
ellipsoid = Q3Ellipsoid_New(&ellipsoidData); |
Q3Object_Dispose(ellipsoidData.ellipsoidAttributeSet); |
theDocument->light1 = Q3OrderedDisplayGroup_New(); |
Q3Group_AddObject(theDocument->light1, ellipsoid); |
Q3Object_Dispose(ellipsoid); |
rotateData.axis = kQ3AxisY; |
rotateData.radians = 0.0; |
theDocument->lightXform1 = Q3RotateTransform_New(&rotateData); |
Q3Group_AddObject(theDocument->light1, theDocument->lightXform1); |
Q3Group_AddObject(theDocument->dynamicLights, theDocument->light1); |
/* Green light ball */ |
ellipsoidData.origin.x = 10.0; |
ellipsoidData.origin.y = 0.0; |
ellipsoidData.origin.z = 5.0; |
ellipsoidData.ellipsoidAttributeSet = Q3AttributeSet_New(); |
ellipsoidColor.r = 0.0; |
ellipsoidColor.g = 1.0; |
ellipsoidColor.b = 0.0; |
Q3AttributeSet_Add( ellipsoidData.ellipsoidAttributeSet, |
kQ3AttributeTypeDiffuseColor, (const void *) &ellipsoidColor); |
Q3AttributeSet_Add(ellipsoidData.ellipsoidAttributeSet, |
kQ3AttributeTypeSpecularColor, &ellipsoidColor); |
ellipsoid = Q3Ellipsoid_New(&ellipsoidData); |
Q3Object_Dispose(ellipsoidData.ellipsoidAttributeSet); |
theDocument->light2 = Q3OrderedDisplayGroup_New(); |
Q3Group_AddObject(theDocument->light2, ellipsoid); |
Q3Object_Dispose(ellipsoid); |
theDocument->lightXform2 = Q3RotateTransform_New(&rotateData); |
Q3Group_AddObject(theDocument->light2, theDocument->lightXform2); |
Q3Group_AddObject(theDocument->dynamicLights, theDocument->light2); |
/* Blue light ball */ |
ellipsoidData.origin.x = 5.0; |
ellipsoidData.origin.y = 0.0; |
ellipsoidData.origin.z = 10.0; |
ellipsoidData.ellipsoidAttributeSet = Q3AttributeSet_New(); |
ellipsoidColor.r = 0.0; |
ellipsoidColor.g = 0.0; |
ellipsoidColor.b = 1.0; |
Q3AttributeSet_Add( ellipsoidData.ellipsoidAttributeSet, |
kQ3AttributeTypeDiffuseColor, (const void *) &ellipsoidColor); |
Q3AttributeSet_Add(ellipsoidData.ellipsoidAttributeSet, |
kQ3AttributeTypeSpecularColor, &ellipsoidColor); |
ellipsoid = Q3Ellipsoid_New(&ellipsoidData); |
Q3Object_Dispose(ellipsoidData.ellipsoidAttributeSet); |
theDocument->light3 = Q3OrderedDisplayGroup_New(); |
Q3Group_AddObject(theDocument->light3, ellipsoid); |
Q3Object_Dispose(ellipsoid); |
rotateData.axis = kQ3AxisX; |
theDocument->lightXform3 = Q3RotateTransform_New(&rotateData); |
Q3Group_AddObject(theDocument->light3, theDocument->lightXform3); |
Q3Group_AddObject(theDocument->dynamicLights, theDocument->light3); |
#endif |
} |
theDocument->animateLights = kQ3False; |
return(kQ3Success); |
} |
//----------------------------------------------------------------------------------- |
TQ3CameraObject TumblerDocument_NewCamera(WindowPtr theWindow) |
{ |
TQ3ViewAngleAspectCameraData perspectiveData; |
TQ3CameraObject camera; |
TQ3Point3D from = { 0.0, 0.0, 30.0 }; |
TQ3Point3D to = { 0.0, 0.0, 0.0 }; |
TQ3Vector3D up = { 0.0, 1.0, 0.0 }; |
float fieldOfView = .52359333333; |
float hither = 0.001; |
float yon = 1000; |
TQ3Status returnVal = kQ3Failure ; |
perspectiveData.cameraData.placement.cameraLocation = from; |
perspectiveData.cameraData.placement.pointOfInterest = to; |
perspectiveData.cameraData.placement.upVector = up; |
perspectiveData.cameraData.range.hither = hither; |
perspectiveData.cameraData.range.yon = yon; |
perspectiveData.cameraData.viewPort.origin.x = -1.0; |
perspectiveData.cameraData.viewPort.origin.y = 1.0; |
perspectiveData.cameraData.viewPort.width = 2.0; |
perspectiveData.cameraData.viewPort.height = 2.0; |
perspectiveData.fov = fieldOfView; |
perspectiveData.aspectRatioXToY = |
(float) (theWindow->portRect.right - theWindow->portRect.left) / |
(float) (theWindow->portRect.bottom - theWindow->portRect.top); |
camera = Q3ViewAngleAspectCamera_New(&perspectiveData); |
return camera ; |
} |
//-------------------------------------------------------------------------------- |
#ifdef PODIUM_APP |
TQ3DrawContextObject TumblerDocument_NewPixmapDrawContext( DocumentPtr theDocument ) |
{ |
TQ3PixmapDrawContextData myDrawContextData; |
TQ3ColorARGB clearColor = {1.0, 1.0, 1.0, 1.0} ; |
TQ3DrawContextObject myDrawContext ; |
GWorldPtr theGWorld ; |
PixMapHandle hPixMap ; |
Rect srcRect ; |
theGWorld = theDocument->geometriesOffscreen ; |
// Fill in draw context data. |
myDrawContextData.drawContextData.clearImageMethod = kQ3ClearMethodWithColor; |
myDrawContextData.drawContextData.clearImageColor = clearColor; |
myDrawContextData.drawContextData.paneState = kQ3False; |
myDrawContextData.drawContextData.maskState = kQ3False; |
myDrawContextData.drawContextData.doubleBufferState = kQ3False; |
hPixMap = GetGWorldPixMap(theGWorld); |
LockPixels(hPixMap); |
srcRect = theGWorld->portRect; |
myDrawContextData.pixmap.width = srcRect.right - srcRect.left; |
myDrawContextData.pixmap.height= srcRect.bottom - srcRect.top; |
myDrawContextData.pixmap.rowBytes = (**hPixMap).rowBytes & 0x7FFF; |
myDrawContextData.pixmap.pixelType = kQ3PixelTypeRGB32; |
myDrawContextData.pixmap.pixelSize = 32; |
myDrawContextData.pixmap.bitOrder = kQ3EndianBig; |
myDrawContextData.pixmap.byteOrder = kQ3EndianBig; |
myDrawContextData.pixmap.image = (**hPixMap).baseAddr; |
return Q3PixmapDrawContext_New(&myDrawContextData); |
} |
#endif |
//-------------------------------------------------------------------------------- |
TQ3DrawContextObject TumblerDocument_NewDrawContext( WindowPtr theWindow ) |
{ |
TQ3DrawContextData myDrawContextData; |
TQ3MacDrawContextData myMacDrawContextData; |
TQ3DrawContextObject myDrawContext ; |
TQ3ColorARGB clearColor = {1.0, kTumblerDefaultClearColor, kTumblerDefaultClearColor, kTumblerDefaultClearColor}; // lt gray |
// Fill in draw context data. |
myDrawContextData.clearImageMethod = kQ3ClearMethodWithColor; |
myDrawContextData.clearImageColor = clearColor; |
myDrawContextData.pane.min.x = (theWindow->portRect).left; |
myDrawContextData.pane.max.x = (theWindow->portRect).right; |
myDrawContextData.pane.min.y = (theWindow->portRect).top; |
myDrawContextData.pane.max.y = (theWindow->portRect).bottom; |
myDrawContextData.paneState = kQ3False; |
myDrawContextData.maskState = kQ3False; |
myDrawContextData.doubleBufferState = kQ3True; |
myMacDrawContextData.drawContextData = myDrawContextData; |
myMacDrawContextData.library = kQ3Mac2DLibraryNone; |
myMacDrawContextData.window = (CWindowPtr) theWindow; |
myMacDrawContextData.grafPort = nil; |
myMacDrawContextData.viewPort = nil; |
// Create draw context and return it, if itÕs nil the caller must handle |
myDrawContext = Q3MacDrawContext_New(&myMacDrawContextData) ; |
return myDrawContext ; |
} |
//-------------------------------------------------------------------------------- |
TQ3Status TumblerDocument_UpdateView( DocumentPtr theDocument, TQ3SharedObject viewHints ) |
{ |
TQ3Object tempObject; |
TQ3CameraObject camera ; |
if( theDocument->theView == NULL) |
return kQ3Failure ; |
TumblerDocument_NewLights( theDocument ) ; |
if( viewHints == NULL ) { |
// if we were called with null viewhints, then just set up |
// sensible defaults for the current document |
camera = TumblerDocument_NewCamera( theDocument->theWindow ) ; |
if( camera != NULL ) { |
Q3View_SetCamera(theDocument->theView, camera ); |
Q3Object_Dispose(camera); |
} |
else |
return kQ3Failure ; |
Q3View_SetRendererByType(theDocument->theView, kQ3RendererTypeInteractive); |
} |
else { |
// we think we have valid viewhints, so attempt to |
// get the information we need from the viewhints |
// passed in, where we dont have an item, then make |
// a sensible default. |
// renderer information |
Q3ViewHints_GetRenderer(viewHints, &tempObject); |
#ifndef PODIUM_APP |
if (tempObject != NULL) |
{ |
Q3View_SetRenderer(theDocument->theView, tempObject); |
Q3Object_Dispose(tempObject); |
} |
else |
Q3View_SetRendererByType(theDocument->theView, kQ3RendererTypeWireFrame); |
#else |
Q3View_SetRendererByType(theDocument->theView, kQ3RendererTypeInteractive); |
#endif |
// camera information |
tempObject = NULL ; |
// Q3ViewHints_GetCamera(viewHints, &tempObject); |
if (tempObject != NULL) { |
Q3View_SetCamera(theDocument->theView, tempObject); |
Q3Object_Dispose(tempObject); |
} |
else { |
camera = TumblerDocument_NewCamera( theDocument->theWindow ) ; |
if( camera != NULL ) { |
Q3View_SetCamera(theDocument->theView, camera ); |
Q3Object_Dispose(camera); |
} |
else |
return kQ3Failure ; |
#ifndef PODIUM_APP |
AdjustCamera(theDocument, |
theDocument->theWindow->portRect.right - theDocument->theWindow->portRect.left, |
theDocument->theWindow->portRect.bottom - theDocument->theWindow->portRect.top); |
#else |
AdjustCamera(theDocument, |
theDocument->geometriesOffscreen->portRect.right - theDocument->geometriesOffscreen->portRect.left, |
theDocument->geometriesOffscreen->portRect.bottom - theDocument->geometriesOffscreen->portRect.top); |
#endif |
} |
// light information |
Q3ViewHints_GetLightGroup(viewHints, &tempObject); |
if (tempObject != NULL) { |
Q3View_SetLightGroup(theDocument->theView, tempObject); |
Q3Object_Dispose(tempObject); |
} |
else { |
TumblerDocument_NewLights( theDocument ) ; |
} |
} |
// replace the existing view hints |
if( theDocument->viewHints ) { |
Q3Object_Dispose(theDocument->viewHints); |
} |
theDocument->viewHints = Q3ViewHints_New(theDocument->theView); |
SetPort( (GrafPtr)theDocument->theWindow) ; |
InvalRect( &theDocument->theWindow->portRect ) ; |
return kQ3Success ; |
} |
//-------------------------------------------------------------------------------- |
// NewDocument is called when a new document window is needed. Creation of |
// document data structures is handled here. |
// |
DocumentPtr NewDocument( TQ3SharedObject viewHints, TQ3GroupObject group ) |
{ |
DocumentPtr theDocument; |
WindowPtr theWindow; |
Rect theRect = { 0, 0, 16, 16 }; |
Point thePoint; |
TQ3Param2D uvValues = {-1.0, -1.0}; |
TQ3DrawContextObject theDrawContext ; |
TQ3CameraObject camera ; |
TQ3AttributeSet viewSet; |
if (gDocumentCount == MaxDocumentCount) |
return( (DocumentPtr )nil ); |
// make sure the pointer is initialised to nil, because we rely on |
// the fields being non nil in order to dispose of the correctly. |
theDocument = gDocumentList[gDocumentCount++] = |
(DocumentPtr )NewPtrClear(sizeof(DocumentRecord)); |
#ifdef PODIUM_APP |
{ |
// for podium set up two GWorlds, on for the bg picture, one for the |
// pixmap draw context that we'll draw the geomentries into |
Rect defaultGeometryRect = { 0, 0, 200, 200 } ; |
GWorldPtr savedGWorld ; |
GDHandle savedGDH ; |
GetGWorld( &savedGWorld, &savedGDH ) ; |
if( NewGWorld(&theDocument->bgOffscreen, 16, &defaultGeometryRect, nil, nil, 0L ) != noErr ) { |
CloseDocument( theDocument ) ; |
return NULL ; |
} |
SetGWorld( theDocument->bgOffscreen, nil ) ; |
EraseRect( &theDocument->bgOffscreen->portRect ) ; |
if( NewGWorld(&theDocument->screenBuffer, 16, &defaultGeometryRect, nil, nil, 0L ) != noErr ) { |
CloseDocument( theDocument ) ; |
return NULL ; |
} |
SetGWorld( theDocument->screenBuffer, nil ) ; |
EraseRect( &theDocument->screenBuffer->portRect ) ; |
if( NewGWorld(&theDocument->geometriesOffscreen, 32, &defaultGeometryRect, nil, nil, 0L ) != noErr ) { |
CloseDocument( theDocument ) ; |
return NULL ; |
} |
SetGWorld( theDocument->geometriesOffscreen, nil ) ; |
EraseRect( &theDocument->geometriesOffscreen->portRect ) ; |
theDocument->dropArea = defaultGeometryRect ; |
// create a 1-bit GW for the mask |
// if( NewGWorld( &theDocument->maskOffscreen, 1, &theDocument->geometriesOffscreen->portRect, nil, nil, 0L) != noErr ) { |
// CloseDocument( theDocument ) ; |
// return NULL ; |
// } |
// SetGWorld( theDocument->maskOffscreen, nil ) ; |
// EraseRect( &theDocument->maskOffscreen->portRect ) ; |
SetGWorld( savedGWorld, savedGDH ) ; |
theDocument->currentInterpolation = kQ3InterpolationStyleVertex; |
} |
#endif |
theWindow = GetNewCWindow(WindowTemplateID, 0L, (WindowPtr) -1L); |
if (theWindow == nil) |
return( (DocumentPtr )nil ); |
theDocument->theWindow = theWindow ; |
SetWRefCon(theWindow, (long)theDocument ) ; |
SetPort(theWindow); |
#ifndef PODIUM_APP |
// only want to set the bg color up for Tumbler |
{ |
RGBColor color = { 0xFFFF, 0xFFFF, 0xFFFF}; |
theDocument->clearColor.r = kTumblerDefaultClearColor ; |
theDocument->clearColor.g = kTumblerDefaultClearColor ; |
theDocument->clearColor.b = kTumblerDefaultClearColor ; |
color.red *= theDocument->clearColor.r; |
color.green *= theDocument->clearColor.r; |
color.blue *= theDocument->clearColor.r; |
RGBBackColor(&color); |
EraseRect(&theWindow->portRect); |
color.blue = color.green = color.red = 0xFFFF; |
RGBBackColor(&color); |
} |
#endif |
thePoint = *((Point *) (&theWindow->portRect.top)); |
LocalToGlobal(&thePoint); |
if (thePoint.h < 10) { |
MoveWindow(theWindow, InitialH, InitialV, false); |
} |
theDocument->fRefNum = 0; |
// zero out the file spec |
theDocument->theFileSpec.vRefNum = 0 ; |
theDocument->theFileSpec.parID = 0 ; |
theDocument->theFileSpec.name[0] = '\0' ; |
theDocument->dirty = false; |
// set up the draw context, camera and lights |
#ifndef PODIUM_APP |
theDrawContext = TumblerDocument_NewDrawContext( theWindow ) ; |
#else |
theDrawContext = TumblerDocument_NewPixmapDrawContext( theDocument ) ; |
#endif |
if( theDrawContext != NULL ) { |
TQ3ColorRGB clearColor = {1.0, 1.0, 1.0}; |
theDocument->theView = Q3View_New(); |
Q3View_GetDefaultAttributeSet(theDocument->theView, &viewSet); |
Q3AttributeSet_Add(viewSet, |
kQ3AttributeTypeSpecularColor, &clearColor); |
Q3AttributeSet_Add(viewSet, |
kQ3AttributeTypeSurfaceUV, &clearColor); |
Q3AttributeSet_Add(viewSet, |
kQ3AttributeTypeShadingUV, &clearColor); |
Q3Object_Dispose(viewSet); |
Q3View_SetDrawContext(theDocument->theView, theDrawContext); |
Q3Object_Dispose(theDrawContext); |
} |
else |
return NULL ; |
InstallTrackingHandler(NewDragTrackingHandlerProc(MyTrackingHandler), theWindow, (void *) theDocument); |
InstallReceiveHandler(NewDragReceiveHandlerProc(MyReceiveDropHandler), theWindow, (void *) theDocument); |
Q3Matrix4x4_SetIdentity(&theDocument->modelRotation); |
theDocument->animateModel = kQ3False; |
theDocument->light = kQ3False; |
theDocument->shaded = kQ3False; |
theDocument->documentGroup = nil; |
#ifndef PODIUM_APP |
theDocument->currentInterpolation = kQ3InterpolationStyleNone; |
#endif |
theDocument->backfacingStyle = Q3BackfacingStyle_New(kQ3BackfacingStyleRemove ) ; |
theDocument->viewHints = Q3ViewHints_New(theDocument->theView);\ |
theDocument->illuminationShader = Q3PhongIllumination_New(); |
return(theDocument); |
} |
//---------------------------------------------------------------------------------- |
// CloseDocument is called when a document window is being closed. Storage |
// of the document file and disposal of document data structures is handled |
// here. |
Boolean CloseDocument( DocumentPtr theDocument ) |
{ short index, response; |
Str255 theName, theVerb; |
Boolean couldCloseIt = false ; |
index = 0; |
while ((gDocumentList[index] != theDocument) && (index < MaxDocumentCount)) |
index++; |
if (gDocumentList[index] == theDocument) { |
if (theDocument->dirty) { |
GetWTitle(theDocument->theWindow, theName); |
GetIndString(theVerb, FileStringsID, (gQuitting) ? slQuittingIndex : slClosingIndex); |
ParamText( (ConstStr255Param)&theName, (ConstStr255Param) &theVerb, (ConstStr255Param) "", (ConstStr255Param) ""); |
SetCursor(&qd.arrow); |
// check with the user - do they want to save this thing |
response = Alert(idSaveChangesALRT, 0L); |
if (response == 1) { // Save |
// check to see that we were able to save the |
// document as requested to by the user |
if (!DidSaveDocument(theDocument)) { |
// signal that we are not quitting (if we were actually trying) |
gQuitting = false; |
// signal that we couldn't save this document |
couldCloseIt = false ; |
return couldCloseIt; |
} |
} else if (response == 3) { /* Don't Save */ |
; |
} else { /* Cancel */ |
gQuitting = false ; |
// signal that we didn't actually want to close this document |
couldCloseIt = false ; |
return couldCloseIt; |
} |
} |
// if we are here we can assume the document has been saved (if required) and |
// that we can junk all of the data structures associated with the document |
// if it has a file associated, close it |
if (theDocument->fRefNum) { |
FSClose(theDocument->fRefNum); |
} |
// remove our drag manager handlers |
RemoveTrackingHandler(NewDragTrackingHandlerProc(MyTrackingHandler), theDocument->theWindow); |
RemoveReceiveHandler(NewDragReceiveHandlerProc(MyReceiveDropHandler), theDocument->theWindow); |
// and we can dispose of the window |
if(theDocument->theWindow) |
DisposeWindow(theDocument->theWindow); |
// close any holes left in the array we |
// have for storing our document objects |
while (index < MaxDocumentCount) { |
gDocumentList[index] = gDocumentList[index + 1]; |
index++; |
} |
// dispose of our QuickDraw 3d view object |
if(theDocument->theView) |
Q3Object_Dispose(theDocument->theView); |
if(theDocument->viewHints) |
Q3Object_Dispose(theDocument->viewHints); |
// if we have a group associated with the document, then delete that |
if(theDocument->documentGroup) |
Q3Object_Dispose(theDocument->documentGroup); |
// dispose of the lights we set up for this document |
if(theDocument->dynamicLights) |
Q3Object_Dispose(theDocument->dynamicLights); |
if(theDocument->light1) { |
Q3Object_Dispose(theDocument->light1); |
Q3Object_Dispose(theDocument->lightXform1); |
} |
if(theDocument->light2) { |
Q3Object_Dispose(theDocument->light2); |
Q3Object_Dispose(theDocument->lightXform2); |
} |
if(theDocument->light3) { |
Q3Object_Dispose(theDocument->light3); |
Q3Object_Dispose(theDocument->lightXform3); |
} |
if(theDocument->backfacingStyle) { |
Q3Object_Dispose(theDocument->backfacingStyle); |
} |
if(theDocument->illuminationShader) { |
Q3Object_Dispose(theDocument->illuminationShader); |
} |
#ifdef PODIUM_APP |
if(theDocument->bgOffscreen != nil ) { |
DisposeGWorld(theDocument->bgOffscreen) ; |
} |
if(theDocument->screenBuffer != nil ) { |
DisposeGWorld(theDocument->screenBuffer) ; |
} |
if(theDocument->geometriesOffscreen != nil ) { |
DisposeGWorld(theDocument->geometriesOffscreen) ; |
} |
// if(theDocument->maskOffscreen != nil ) { |
// DisposeGWorld(theDocument->maskOffscreen) ; |
// } |
#endif |
// finally dispose of the storage used for the document and |
// decrement the document count |
if( theDocument != nil ) |
DisposePtr((Ptr) theDocument); |
gDocumentCount--; |
// signal that we closed this document |
couldCloseIt = true ; |
return couldCloseIt; |
} |
// signal that we could't actually close this document |
couldCloseIt = false ; |
return couldCloseIt; |
} |
//---------------------------------------------------------------------------------- |
// Closes all document windows. |
// |
Boolean CloseAllDocuments( void ) |
{ |
short index ; |
for( index = gDocumentCount - 1; index >= 0; index-- ) { |
if(CloseDocument(gDocumentList[ index ]) == false) |
return false; |
} |
return true ; |
} |
//---------------------------------------------------------------------------------- |
// DoActivateDocument is called when an event is received that reports that |
// a document window is being either activated or deactivated. |
void DoActivateDocument(DocumentPtr theDocument, short activate) |
{ |
if (theDocument) { |
if (activate) { |
// do whatever you'd like to do for a activate event |
#ifdef PODIUM_APP |
void FixGrayRgnAfterContextSwitch( void ) ; |
FixGrayRgnAfterContextSwitch(); |
#endif |
LoadScrap() ; |
} else { |
// do whatever you'd like to do for a deactivate event |
UnloadScrap() ; |
} |
} |
} |
//---------------------------------------------------------------------------------- |
// If the given WindowPtr is a pointer to a document window, this function |
// returns a pointer to a document data structure. If the window is not |
// a document window, the function returns nil. |
DocumentPtr GetDocumentFromWindow(WindowPtr theWindow) |
{ |
short index = 0; |
DocumentPtr theDocument; |
if( theWindow == nil ) |
return((DocumentPtr ) 0L); |
theDocument = (DocumentPtr ) (((WindowPeek) theWindow)->refCon); |
while ((gDocumentList[index] != theDocument) && (index < gDocumentCount)) |
index++; |
if (gDocumentList[index] == theDocument) |
return(theDocument); |
else |
return((DocumentPtr ) 0L); |
} |
TQ3Status InitializeGroup(TQ3GroupObject group) |
{ |
TQ3ShaderObject illuminationShader = Q3PhongIllumination_New(); |
Q3Group_AddObject(group, illuminationShader); |
Q3Object_Dispose(illuminationShader); |
return(kQ3Success); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14