Source/Viewer_Main.c

/* 
 *  Viewer_Main.c
 *
 *  QuickDraw 3D 1.6 Sample
 *  Robert Dierkes
 *
 *   12/22/98   RDD     Created.
 */
 
/*------------------*/
/*  Include Files   */
/*------------------*/
#include "QD3D.h"
#include "QD3DViewer.h"
 
#if defined(OS_MACINTOSH) && OS_MACINTOSH
#include <Fonts.h>
#include <MacWindows.h>
#include <StandardFile.h>   /* SFTypeList */
#endif
 
#include "Viewer_Error.h"
#include "Viewer_Callbacks.h"
#include "Viewer_Events.h"
#include "Viewer_Message.h"
#include "Viewer_Main.h"
#include "Viewer_Menu.h"
#include "Viewer_Window.h"
#include "Viewer_System.h"
 
 
 
/*----------------------*/
/*  Global Declarations */
/*----------------------*/
TQ3Boolean      gTimeToQuit;
WindowRef       gAppResizeWindow = NULL; /* For example 2 */
 
 
/*----------------------*/
/*  Local Prototypes    */
/*----------------------*/
static
TQ3Boolean Main_Initialize(
            void);
static
TQ3Boolean Main_Exit(
            void);
static
void    Main_Initialize_Toolbox (
            void);
static
TQ3Boolean  Main_CreateViewerInWindow(
            unsigned long   viewerFlags,
            Rect            *pWindowRect,
            short           viewerInset,
            Str255          title,
            WindowPtr       *pWindow,
            TQ3ViewerObject *pViewer);
static
TQ3Status Main_CreateViewer(
            unsigned long   example,
            short           fileRefNum,
            WindowPtr       *hWindow);
static
TQ3Status Main_GetModelFileRef(
            short           *pRefNum);
 
 
/*
 *  main
 */
void main(
        void)
{
    if (Main_Initialize()) {
        Events_Process();
        Main_Exit();
    }
}
 
 
/*
 *  Main_Initialize
 */
static
TQ3Boolean Main_Initialize(
            void)
{
    short       fileRefNum = 0;
    long        i;
 
    gTimeToQuit = kQ3False;
 
    Main_Initialize_Toolbox();
 
    if (Events_Initialize() == false)
        return kQ3False;
 
    if (QuickDraw3D_Initialize() == kQ3False)
        return kQ3False;
 
    Message_Register();
 
    if (Menu_Initialize() == kQ3False)
        return kQ3False;
 
 
    /* Select a model */
    if (Main_GetModelFileRef(&fileRefNum) == kQ3Failure) {
        return kQ3False;
    }
 
    if (Window_Initialize() == kQ3Failure) {
        return kQ3False;
    }
 
    i = kMaxWindowCount;
    while (--i >= 0) {
        if (Main_CreateViewer(i, fileRefNum, &gWindows[i]) == kQ3Failure)
            return kQ3False;
    }
 
    return kQ3True;
}
 
 
/*
 *  Main_Initialize_Toolbox
 *
 */
static
void Main_Initialize_Toolbox(
            void)
{
    MaxApplZone();
    MoreMasters();
    MoreMasters();
    MoreMasters(); 
 
    InitGraf(&qd.thePort);
    InitFonts();
    InitWindows();
    InitCursor();
    
    /*
     * Must call this to expand heap is expanded to maximum
     * size before calling any Viewer routines
     */
    MaxApplZone();
}
 
 
/*
 *  Main_Exit
 */
static
TQ3Boolean Main_Exit(
            void)
{
    if (gTimeToQuit) {
        (void) Window_Exit();
 
        (void) QuickDraw3D_Exit();
        gTimeToQuit = kQ3False;
    }
 
    return kQ3True;
}
 
 
#pragma mark -
 
/*
 * Main_CreateViewer
 */
TQ3Status Main_CreateViewer(
        unsigned long   example,
        short           fileRefNum,
        WindowPtr       *hWindow)
{
    const   short   kWindowHeight   = 240;
    const   short   kWindowWidth    = 360;
 
    const   short   kWindowLeft     = 12;
    const   short   kWindowTop      = 48;
    const   short   kWindowRight    = (kWindowLeft + kWindowWidth);
    const   short   kWindowBottom   = (kWindowTop  + kWindowHeight);
 
    const   short   kWindowOffset   = 24;
    const   short   kViewerInset    = 20;
 
    TQ3Status       status          = kQ3Failure;
    OSErr           theErr          = paramErr;
    TQ3ViewerObject viewer          = NULL;
    unsigned long   viewerFlags;
    short           windowOffset;
    short           viewerInset;
    Rect            windowRect  = { kWindowTop, kWindowLeft, kWindowBottom, kWindowRight };
    Str255          winTitles[] = { "\pDefault Viewer",
                                    "\pViewer with Window Grow Box",
                        /* TODO */  "\pViewer with Application Window Grow Box",
                                    "\pViewer with Pane Grow Box and Callback",
                                    "\pViewer with Pane & Window Grow Boxes",
                                    "\pViewer with Drawing Callback"
                                    };
 
    /* Customize Viewer's appearance and functions */
    viewerFlags =   kQ3ViewerButtonCamera       |
                    kQ3ViewerButtonTruck        |
                    kQ3ViewerButtonOrbit        |
                    kQ3ViewerButtonDolly        |
                    kQ3ViewerButtonReset        |
                    kQ3ViewerButtonOptions      |
                    kQ3ViewerDrawDragBorder     |
                    kQ3ViewerControllerVisible  |
                    kQ3ViewerActive;
 
    switch (example) {
 
    default:
    case 0: /* Use default Viewer flags and behavior */
        viewerFlags  = kQ3ViewerDefault;
        viewerInset  = 0;
        break;
 
    case 1: /* Viewer draws window grow box and handles window resizing */
        viewerFlags |= kQ3ViewerDrawGrowBox;
        viewerInset  = 0;
        break;
 
    case 2: /* Viewer draws window grow box and notifies app after it's been resized */
        viewerFlags  = kQ3ViewerDefault;
//TODO      viewerFlags |= kQ3ViewerDrawGrowBox;
        viewerInset  = 0;
        break;
 
    case 3: /* Viewer draws pane grow box and notifies app when it's been resized */
        viewerFlags |= kQ3ViewerPaneGrowBox;
        viewerInset  = kViewerInset;
        break;
 
    case 4: /* Viewer draws window & pane grow box and notifies app after pane grow box has been resized */
        viewerFlags |= (kQ3ViewerPaneGrowBox | kQ3ViewerDrawGrowBox);
        viewerInset  = kViewerInset;
        break;
 
    case 5: /* Viewer notifies app after it's completed drawing */
        viewerFlags  = kQ3ViewerDefault;
        viewerInset  = kViewerInset;
        break;
    }
 
    windowOffset = example * kWindowOffset;
    MacOffsetRect(&windowRect, windowOffset, windowOffset);
 
    /*
     * Create a Viewer with these flags
     */
    if (Main_CreateViewerInWindow(
            viewerFlags,
            &windowRect,
            viewerInset,
            winTitles[example],
            hWindow,
            &viewer) == kQ3False) {
        return kQ3Failure;
    }
 
    /*
     * Add Viewer model from user selected file
     */
    if (Q3ViewerUseFile(viewer, fileRefNum) != noErr) {
        ERROR_DEBUG_STR("Main_CreateViewer: Q3ViewerUseFile failed.");
        return kQ3Failure;
    }
 
    /*
     * Set callback
     */
    switch (example) {
 
    /* Use default Viewer flags and behavior */
    default:
    case 0: status = kQ3Success;    break;
 
    /* Viewer draws window grow box and handles window resizing */
    case 1: status = kQ3Success;    break;
 
    /* Viewer draws window grow box and calls app to resize window */
    case 2: status = Callbacks_InitWindowResizeCallback(viewer, *hWindow);
        gAppResizeWindow = *hWindow;
        break;
 
    /* Viewer draws pane grow box and notifies app when it's been resized */
    case 3: status = Callbacks_InitPaneResizeCallback(viewer, *hWindow, 0); break;
 
    /* Viewer draws window & pane grow box and notifies app after pane grow box has been resized */
    case 4: status = Callbacks_InitPaneResizeCallback(viewer, *hWindow, 1); break;
 
    /* Viewer notifies app after it's completed drawing */
    case 5: status = Callbacks_InitDrawingCallback(viewer, *hWindow);       break;
    }
 
    return status;
}
 
 
/*
 *  Main_CreateViewerInWindow
 */
static
TQ3Boolean Main_CreateViewerInWindow(
    unsigned long   viewerFlags,
    Rect            *pWindowRect,
    short           viewerInset,
    Str255          title,
    WindowPtr       *pWindow,
    TQ3ViewerObject *pViewer)
{
    WindowPtr       window = NULL;
    Rect            viewerRect;
 
    /*
     * Create a window
     */
    if ((*pWindow = GetNewCWindow(kWindowRsrcID, NULL, kWindowOnTop)) == NULL) {
        ERROR_DEBUG_STR("Main_CreateViewerInWindow: NewCWindow failed.");
        return kQ3False;
    }
    window = *pWindow;
 
    SetPort((GrafPtr) window);
 
    MacMoveWindow(
            window,
            pWindowRect->left,
            pWindowRect->top,
            true);
    SizeWindow(
            window,
            (pWindowRect->right  - pWindowRect->left),
            (pWindowRect->bottom - pWindowRect->left),
            true);
    SetWTitle(window, title);
    ShowWindow(window);
 
    /*
     * Add a Viewer to this window
     */
    viewerRect = window->portRect;
    MacInsetRect(&viewerRect, viewerInset, viewerInset);
 
    if ((*pViewer = Q3ViewerNew(
                        (CGrafPtr) window,
                        &viewerRect,
                        viewerFlags)) == NULL) {
        ERROR_DEBUG_STR("Main_CreateViewerInWindow: Q3ViewerNew failed.");
        return kQ3False;
    }
 
    /* Save reference to Viewer in window's refcon */
    SetWRefCon(window, (long) *pViewer);
 
    return kQ3True;
}
 
 
/*
 *  Main_GetModelFileRef
 */
static
TQ3Status Main_GetModelFileRef(
    short               *pRefNum)
{
    TQ3Status           status   = kQ3Failure;
    short               numTypes = 1; 
    SFTypeList          typeList = { '3DMF' };
    StandardFileReply   sfReply;
 
    StandardGetFile(nil, numTypes, typeList, &sfReply);
 
    if (sfReply.sfGood) {
        /* Open the file */
        if (FSpOpenDF(&sfReply.sfFile, fsRdPerm, pRefNum) == noErr) {
            status = kQ3Success;
        }
        else {
            ERROR_DEBUG_STR("Main_GetModelFileRef: FSpOpenDF failed.");
        }
    }
 
    return status;
}