Source/Viewer_Callbacks.c

/* 
 *  Viewer_Callbacks.c
 *
 *  QuickDraw 3D 1.6 Sample
 *  Robert Dierkes
 *
 *   12/22/98   RDD     Created.
 */
 
/*------------------*/
/*  Include Files   */
/*------------------*/
#include "QD3D.h"
#include "QD3DDrawContext.h"
#include "QD3DView.h"
#include "QD3DViewer.h"
 
#if defined(OS_MACINTOSH) && OS_MACINTOSH
#include <MacWindows.h>
#include <ToolUtils.h>
#endif
 
#include "Viewer_Error.h"
#include "Viewer_Events.h"
#include "Viewer_Callbacks.h"
 
 
//  #define TEST_CustomWindowResizeCallback             /**/
//  #define TEST_CustomPaneResizeCallback               /**/
//  #define RESIZE_WINDOW_IN_CustomPaneResizedCallback  /**/
//--Ã   #define TEST_CustomDrawingCallback
 
 
/*----------------------*/
/*  Global Declarations */
/*----------------------*/
static Rect     gLastBounds1 = { 0, 0, 0, 0 };
static Rect     gLastBounds2 = { 0, 0, 0, 0 };
 
 
/*----------------------*/
/*  Local Prototypes    */
/*----------------------*/
static
TQ3Status   Sample_WindowResizeCallback(
    TQ3ViewerObject     viewer,
    const void          *data);
 
static
TQ3Status   Sample_PaneResizeNotifyCallback(
    TQ3ViewerObject     viewer,
    const void          *data);
 
static
OSErr   Sample_DrawingCallback(
    TQ3ViewerObject     viewer,
    const void          *data);
 
 
 
/*
 * Callbacks_InitWindowResizeCallback
 */
TQ3Status Callbacks_InitWindowResizeCallback(
    TQ3ViewerObject viewer,
    WindowPtr       window)
{
    OSErr           theErr = noErr;
 
    theErr = Q3ViewerSetWindowResizeCallback(
                viewer,
                Sample_WindowResizeCallback,
                window);    /* Test the user parameter */
 
    return (theErr == noErr) ? kQ3Success : kQ3Failure; 
}
 
 
/*
 * Callbacks_InitPaneResizeCallback
 */
TQ3Status Callbacks_InitPaneResizeCallback(
    TQ3ViewerObject viewer,
    WindowPtr       window,
    unsigned long   example)
{
    TQ3ViewObject   view        = NULL;
    TQ3Status       status      = kQ3Failure;
    OSErr           theErr      = noErr;
    Rect            *pRect;
 
    #pragma unused(window)
 
    /* Save Viewer's previous bounds in global */
    if ((view = Q3ViewerGetView(viewer)) == NULL) {
        ERROR_DEBUG_STR("Callbacks_InitPaneResizeCallback: Q3ViewerGetView failed.");
        return kQ3Failure;  
    }
 
    pRect = (example == 0) ? &gLastBounds1 : &gLastBounds2;
 
    /* Pass in global to Viewer's previous bounds */
    if ((theErr = Q3ViewerGetBounds(viewer, pRect)) != noErr) {
        ERROR_DEBUG_STR("Callbacks_InitPaneResizeCallback: Q3ViewerGetBounds failed.");
        return kQ3Failure;  
    }
 
    theErr = Q3ViewerSetPaneResizeNotifyCallback(
                viewer,
                Sample_PaneResizeNotifyCallback,
                pRect); /* Test the user parameter */
 
    return (theErr == noErr) ? kQ3Success : kQ3Failure; 
}
 
 
/*
 * Callbacks_InitDrawingCallback
 */
TQ3Status Callbacks_InitDrawingCallback(
    TQ3ViewerObject viewer,
    WindowPtr       window)
{
    OSErr           theErr  = noErr;
 
    theErr = Q3ViewerSetDrawingCallbackMethod(
                viewer,
                Sample_DrawingCallback,
                window);    /* Test the user parameter */
 
    return (theErr == noErr) ? kQ3Success : kQ3Failure; 
}
 
 
#pragma mark -
 
/*
 * Sample_WindowResizeCallback
 *
 * Called after user clicks in the Viewer's window grow box.
 * This only works if the kQ3ViewerDrawGrowBox flag is enabled
 * and does _not_ work if the kQ3ViewerPaneGrowBox flag is enabled.
 */
static
TQ3Status   Sample_WindowResizeCallback(
    TQ3ViewerObject viewer,
    const void      *data)
{
    #define kMinH   50
    #define kMaxH   1024
    #define kMinW   200
    #define kMaxW   1024
 
    WindowRef   viewerPort;
    GrafPtr     savedPort;
    long        newSize;
    short       newHeight,
                newWidth;
    Rect        growLimitSizes;
    Point       mouse;
 
    #pragma unused(viewer)
 
    /* Get Viewer's port from data parameter */
    viewerPort = (WindowRef) data;
 
    if (viewerPort == NULL) {
        ERROR_DEBUG_STR("Sample_WindowResizeCallback: viewerPort is NULL.");
        return kQ3Failure;
    }
 
    /* Get window port from Viewer */
    GetPort(&savedPort);
 
    /* Set for Viewer's port */
    if (viewerPort != savedPort) {
        SetPort(viewerPort);
    }
 
    growLimitSizes.top    =  kMinH;     /* min height */
    growLimitSizes.bottom =  kMaxH;     /* max height */
    growLimitSizes.left   =  kMinW;     /* min width */
    growLimitSizes.right  =  kMaxW;     /* max width */
 
    GetMouse(&mouse);
    LocalToGlobal(&mouse);
 
    newSize = GrowWindow(viewerPort, mouse, &growLimitSizes);
 
    if (newSize != 0) {
        newHeight = HiWord(newSize);
        newWidth  = LoWord(newSize);
 
        if (newHeight > kMaxH)  newHeight = kMaxH;
        if (newHeight < kMinH)  newHeight = kMinH;
        if (newWidth  > kMaxW)  newWidth  = kMaxW;
        if (newWidth  < kMinW)  newWidth  = kMinW;
 
        SizeWindow(viewerPort, newWidth, newHeight, true);
        InvalRect(&viewerPort->portRect);
    }
 
    /* Restore port */
    if (viewerPort != savedPort) {
        SetPort(savedPort);
    }
 
    return kQ3Success;
}
 
 
/*
 * Sample_PaneResizeNotifyCallback
 *
 * This callback is called if the kQ3ViewerPaneGrowBox flag is set
 * and after the user clicks in the Viewer's pane grow box.
 */
static
TQ3Status   Sample_PaneResizeNotifyCallback(
    TQ3ViewerObject viewer,
    const void      *data)
{
    OSErr                   theErr      = noErr;
    TQ3Status               status      = kQ3Failure;
    Rect                    newBounds,
                            *pPrevBounds = ((Rect *) data);
    RgnHandle               newRegion   = NULL,
                            exposedRegion= NULL;
 
    if ((theErr = Q3ViewerGetBounds(viewer, &newBounds)) != noErr) {
        ERROR_DEBUG_STR("Sample_PaneResizeNotifyCallback: Q3ViewerGetBounds failed.");
        return kQ3Failure;  
    }
 
 
    /* Erase the area exposed between old and new Viewer bounds */
    if ((newRegion = NewRgn()) != NULL) {
        RectRgn(newRegion, &newBounds);
 
        if ((exposedRegion = NewRgn()) != NULL) {
            RectRgn(exposedRegion, pPrevBounds);
 
            DiffRgn(exposedRegion, newRegion, exposedRegion);
            EraseRgn(exposedRegion);
 
            DisposeRgn(exposedRegion);
        }
 
        DisposeRgn(newRegion);
 
        /* Draw the Viewer again with after it's been sized */
        if (Q3ViewerDraw(viewer) == noErr) {
            status = kQ3Success;
        }
    }
 
    /* Save new bounds as last bounds */
    *pPrevBounds = newBounds;
 
    return status;
}
 
 
/*
 * Sample_DrawingCallback
 *
 * This callback is called after the Viewer completes drawing in
 * in Q3ViewerDraw().
 *
 * This example draws several lines across the Viewer.
 */
OSErr Sample_DrawingCallback(
    TQ3ViewerObject viewer,
    const void      *data)
{
    OSErr           osErr = noErr;
    WindowRef       viewerPort;
    GrafPtr         savedPort;
    Rect            bounds;
    short           y, yIncr, yMax;
    unsigned long   width,
                    height;
 
    /* Get Viewer's port from data parameter */
    viewerPort = (WindowRef) data;
 
    if (viewerPort == NULL) {
        ERROR_DEBUG_STR("Sample_DrawingCallback: viewerPort is NULL.");
        return paramErr;
    }
 
    GetPort(&savedPort);
 
    /* Set for Viewer's port */
    if ((GrafPtr) viewerPort != savedPort) {
        SetPort((GrafPtr) viewerPort);
    }
 
 
    /* Compute where to draw lines */
    if ((osErr = Q3ViewerGetBounds(viewer, &bounds)) != noErr) {
        ERROR_DEBUG_STR("Sample_DrawingCallback: Q3ViewerGetBounds failed.");
        return osErr;
    }
 
    if ((osErr = Q3ViewerGetDimension(viewer, &width, &height)) != noErr) {
        ERROR_DEBUG_STR("Sample_DrawingCallback: Q3ViewerGetDimension failed.");
        return osErr;
    }
 
    /* Draw horizontal lines across the model */
    yIncr = height / 5;
    y     = bounds.top + yIncr;
    yMax  = bounds.top + height - yIncr;
 
    while (y <= yMax) {
 
        MoveTo(bounds.left  + 4, y);
        LineTo(bounds.right - 6, y);
 
        y += yIncr;
    }
 
    /* Restore port */
    if ((GrafPtr) viewerPort != savedPort) {
        SetPort(savedPort);
    }
 
    return osErr;
}