TS3Utils.c

/*
 *  File:       TS3Utils.c
 *
 *  Contents:   Some utilities.
 *
 *  Copyright © 1996 Apple Computer, Inc.
 */
 
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
 
#include "TS3Utils.h"
 
 
#ifndef HONOR_RANGE
    #define HONOR_RANGE     0
#endif
 
 
static UserItemUPP          gUtilsOKUserItemProc    = NULL;
 
 
static pascal void Utils_OKUserItem(
    DialogPtr           inDialog,
    short               inItem);
 
 
/* =============================================================================
 *      Utils_Init (external)
 *
 *  Initializes the utilities.
 * ========================================================================== */
void Utils_Init(
    void)
{
}
 
 
/* =============================================================================
 *      Utils_Exit (external)
 *
 *  Prepares for exit.
 * ========================================================================== */
void Utils_Exit(
    void)
{
    if (gUtilsOKUserItemProc != NULL)
    {
        DisposeRoutineDescriptor(gUtilsOKUserItemProc);
        gUtilsOKUserItemProc = NULL;
    }
}
 
 
/* =============================================================================
 *      Utils_Interval (external)
 *
 *  Returns the interval, in seconds, between two results of Microseconds.
 * ========================================================================== */
float Utils_Interval(
    const UnsignedWide* inPrevTime,
    const UnsignedWide* inCurrTime)
{
    //¥ Should actually take high words into consideration too
    return 0.000001*(inCurrTime->lo - inPrevTime->lo);
}
 
 
/* =============================================================================
 *      Utils_OKUserItem (internal)
 *
 *  Draws the user item used for framing the OK button.  The user item should
 *  be four pixels larger than the OK button in each direction.
 * ========================================================================== */
pascal void Utils_OKUserItem(
    DialogPtr           inDialog,
    short               inItem)
{
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    
    GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
    
    PenSize(3, 3);
    FrameRoundRect(&itemBounds, 16, 16);
    PenSize(1, 1);
}
 
 
/* =============================================================================
 *      Utils_GetOKUserItemProc (external)
 *
 *  Returns the UPP for the dialog user item that outlines the default button.
 * ========================================================================== */
UserItemUPP Utils_GetOKUserItemProc(
    void)
{
    if (gUtilsOKUserItemProc == NULL)
    {
        gUtilsOKUserItemProc = NewUserItemProc(Utils_OKUserItem);
        assert(gUtilsOKUserItemProc != NULL);
    }
    
    return gUtilsOKUserItemProc;
}
 
 
/* =============================================================================
 *      Utils_SetStr255Field (external)
 *
 *  Changes the text of the given dialog item to the given string value.  If
 *  inHasValue is false, then the field is emptied instead.  The dialog item must
 *  of course be editable or static text.
 * ========================================================================== */
void Utils_SetStr255Field(
    DialogPtr           inDialog,
    short               inItem,
    ConstStr255Param    inValue,
    Boolean             inHasValue)
{
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    
    GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
    if (inHasValue)
    {
        SetDialogItemText(itemHandle, inValue);
    }
    else
    {
        SetDialogItemText(itemHandle, "\p");
    }
}
 
 
/* =============================================================================
 *      Utils_GetStr255Field (external)
 *
 *  Interprets the value of the given editable or static text field as an
 *  string value.  If outHasValue is NULL then the field must not be blank.
 *  If outHasValue is non-NULL then it is set to false if the field is blank
 *  and true if it has a value.  Returns false if there is a formatting problem.
 * ========================================================================== */
Boolean Utils_GetStr255Field(
    DialogPtr           inDialog,
    short               inItem,
    Str255              outValue,
    Boolean*            outHasValue)
{
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    
    // Grab the string
    GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
    GetDialogItemText(itemHandle, outValue);
    
    if (outHasValue != NULL)
    {
        *outHasValue = outValue[0] > 0;
    }
    
    return true;
}
 
 
/* =============================================================================
 *      Utils_SetUInt32Field (external)
 *
 *  Changes the text of the given dialog item to the given integer value.  If
 *  inHasValue is false, then the field is emptied instead.  The dialog item must
 *  of course be editable or static text.
 * ========================================================================== */
void Utils_SetUInt32Field(
    DialogPtr           inDialog,
    short               inItem,
    UInt32              inValue,
    Boolean             inHasValue)
{
    Str255              str;
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    
    if (inHasValue)
    {
        sprintf((char*) str, "x%lu", inValue);
        str[0] = strlen((char*) str) - 1;
    }
    else
    {
        str[0] = 0;
    }
    
    GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
    SetDialogItemText(itemHandle, str);
}
 
 
/* =============================================================================
 *      Utils_GetUInt32Field (external)
 *
 *  Interprets the value of the given editable or static text field as an
 *  integer value.  If outHasValue is NULL then the field must not be blank.
 *  If outHasValue is non-NULL then it is set to false if the field is blank
 *  and true if it has a value.  Returns false if there is a formatting problem.
 * ========================================================================== */
Boolean Utils_GetUInt32Field(
    DialogPtr           inDialog,
    short               inItem,
    UInt32*             outValue,
    Boolean*            outHasValue,
    UInt32              inMin,
    UInt32              inMax)
{
    #pragma unused (inMin, inMax)
    Str255              str;
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    
    // Grab the string
    GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
    GetDialogItemText(itemHandle, str);
    str[str[0]+1] = 0;
    
    // Parse it
    if (sscanf((char*) str, "%*c%lu", outValue) > 0)
    {
        // Got a number
        if (outHasValue != NULL)
        {
            *outHasValue = true;
        }
        
        // Check the range
        #if HONOR_RANGE
            if (*outValue < inMin || *outValue > inMax)
            {
                return false;
            }
        #endif
    }
    else
    {
        if (outHasValue != NULL)
        {
            *outHasValue = false;
        }
        else
        {
            return false;
        }
    }
    
    return true;
}
 
 
/* =============================================================================
 *      Utils_SetFloatField (external)
 *
 *  Changes the text of the given dialog item to the given float value.  If
 *  inHasValue is false, then the field is emptied instead.  The dialog item must
 *  of course be editable or static text.
 * ========================================================================== */
void Utils_SetFloatField(
    DialogPtr           inDialog,
    short               inItem,
    float               inValue,
    Boolean             inHasValue)
{
    Str255              str;
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    float               abs;
    float               fract;
    
    if (inHasValue)
    {
        abs = fabsf(inValue);
        fract = abs-floorf(abs);
        if (fract < 0.0001 || fract > 0.9999)
        {
            // Value is close enough to integer to show it that way
            sprintf((char*) str, "x%.0f", inValue);
        }
        else
        {
            // Has a fractional part
            sprintf((char*) str, "x%.2f", inValue);
        }
        str[0] = strlen((char*) str) - 1;
    }
    else
    {
        str[0] = 0;
    }
    
    GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
    SetDialogItemText(itemHandle, str);
}
 
 
/* =============================================================================
 *      Utils_GetFloatField (external)
 *
 *  Interprets the value of the given editable or static text field as an
 *  float value.  If outHasValue is NULL then the field must not be blank.
 *  If outHasValue is non-NULL then it is set to false if the field is blank
 *  and true if it has a value.  Returns false if there is a formatting problem.
 * ========================================================================== */
Boolean Utils_GetFloatField(
    DialogPtr           inDialog,
    short               inItem,
    float*              outValue,
    Boolean*            outHasValue,
    float               inMin,
    float               inMax)
{
    #pragma unused (inMin, inMax)
    Str255              str;
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    
    // Grab the string
    GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
    GetDialogItemText(itemHandle, str);
    str[str[0]+1] = 0;
    
    // Parse it
    if (sscanf((char*) str, "%*c%f", outValue) > 0)
    {
        // Got a number
        if (outHasValue != NULL)
        {
            *outHasValue = true;
        }
        
        // Check the range
        #if HONOR_RANGE
            if (*outValue < inMin || *outValue > inMax)
            {
                return false;
            }
        #endif
    }
    else
    {
        if (outHasValue != NULL)
        {
            *outHasValue = false;
        }
        else
        {
            return false;
        }
    }
    
    return true;
}
 
 
/* =============================================================================
 *      Utils_SetVector3DField (external)
 *
 *  Changes the text of the given dialog item to the given TQ3ector3D value.  If
 *  inHasValue is false, then the field is emptied instead.  The dialog item must
 *  of course be editable or static text.
 * ========================================================================== */
void Utils_SetVector3DField(
    DialogPtr           inDialog,
    short               inItem,
    const TQ3Vector3D*  inValue,
    Boolean             inHasValue)
{
    Str255              str;
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    float               abs;
    float               fract;
    UInt32              xPrecision;
    UInt32              yPrecision;
    UInt32              zPrecision;
    
    if (inHasValue)
    {
        abs = fabsf(inValue->x);
        fract = abs-floorf(abs);
        xPrecision = (fract < 0.0001 || fract > 0.9999) ? 0 : 2;
        
        abs = fabsf(inValue->y);
        fract = abs-floorf(abs);
        yPrecision = (fract < 0.0001 || fract > 0.9999) ? 0 : 2;
        
        abs = fabsf(inValue->z);
        fract = abs-floorf(abs);
        zPrecision = (fract < 0.0001 || fract > 0.9999) ? 0 : 2;
        
        sprintf((char*) str, "x%.*f %.*f %.*f", xPrecision, inValue->x, yPrecision, inValue->y, zPrecision, inValue->z);
        str[0] = strlen((char*) str) - 1;
    }
    else
    {
        str[0] = 0;
    }
    
    GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
    SetDialogItemText(itemHandle, str);
}
 
 
/* =============================================================================
 *      Utils_GetVector3DField (external)
 *
 *  Interprets the value of the given editable or static text field as an
 *  TQ3Vector3D value.  If outHasValue is NULL then the field must not be blank.
 *  If outHasValue is non-NULL then it is set to false if the field is blank
 *  and true if it has a value.  Returns false if there is a formatting problem.
 * ========================================================================== */
Boolean Utils_GetVector3DField(
    DialogPtr           inDialog,
    short               inItem,
    TQ3Vector3D*        outValue,
    Boolean*            outHasValue)
{
    Str255              str;
    short               itemType;
    Handle              itemHandle;
    Rect                itemBounds;
    
    // Grab the string
    GetDialogItem(inDialog, inItem, &itemType, &itemHandle, &itemBounds);
    GetDialogItemText(itemHandle, str);
    str[str[0]+1] = 0;
    
    // Parse it
    if (sscanf((char*) str, "%*c%f%f%f", &outValue->x, &outValue->y, &outValue->z) == 3)
    {
        // Got a number
        if (outHasValue != NULL)
        {
            *outHasValue = true;
        }
    }
    else
    {
        if (outHasValue != NULL)
        {
            *outHasValue = false;
        }
        else
        {
            return false;
        }
    }
    
    return true;
}