NonThreadedProgress.c

/*
    File:       NonThreadedProgress.c
 
    Contains:   Progress bar implementation without using the Threads Manager
 
    Written by: Chris White 
 
    Copyright:  Copyright © 1996-1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                8/10/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
 
#pragma segment Core
 
 
// System Includes
 
#ifndef __DIALOGS__
    #include <Dialogs.h>
#endif
 
 
 
// Application Includes
 
#ifndef __BAREBONES__
    #include "BareBones.h"
#endif
 
#ifndef __PROTOTYPES__
    #include "ProtoTypes.h"
#endif
 
 
 
 
 
 
// static prototypes
static void     DrawProgressBar ( DialogRef theDialog, int doneAmount, int maxAmount );
 
 
 
 
 
 
OSErr ProgressOperation ( tOperation theOperation, void* refCon, StringPtr theText )
{
    Boolean         bCancelled = false;
    OSErr           theErr = noErr;
    SInt16          theType;
    GrafPtr         savePort;
    DialogRef       theDialog = nil;
    Handle          theHan;
    Rect            theRect;
    
    
    theDialog = GetNewDialog ( kProgressDialogID, nil, (WindowPtr) -1 );
    
    GetPort ( &savePort );
    SetPort ( theDialog );
    
    GetDialogItem ( theDialog, kStaticTextItemID, &theType, &theHan, &theRect );
    SetDialogItemText ( theHan, theText );
    
    ShowWindow ( theDialog );
    DrawDialog ( theDialog );
    
    bCancelled = (*theOperation) ( refCon, theDialog );
    
    DisposeDialog ( theDialog );
    SetPort ( savePort );
    
    return theErr;
    
} // ProgressOperation
 
 
 
Boolean UpdateProgressBar ( DialogRef theDialog, int doneAmount, int maxAmount )
{
    Boolean         bCancelled = false;
    OSErr           theErr = noErr;
    EventRecord     theEvent;
    
    
    
    if ( WaitNextEvent ( everyEvent - diskMask, &theEvent, kSleepTime, nil ) )
    {
        if ( IsDialogEvent ( &theEvent ) )
        {
            SInt16      itemHit;
            DialogRef   whichDialog;
            
            if ( DialogSelect ( &theEvent, &whichDialog, &itemHit ) )
            {
                if ( whichDialog == theDialog && itemHit == kCancelItemID )
                    bCancelled = true;
            }
        }
        else if ( theEvent.what == mouseDown )
        {
            WindowRef   theWindow;
            
            if ( FindWindow ( theEvent.where, &theWindow ) == inDrag )
                DoDragWindow ( theWindow, &theEvent );
        }
    }
    
    DrawProgressBar ( theDialog, doneAmount, maxAmount );
    
    return bCancelled;
    
} // UpdateProgressBar
 
 
 
static void DrawProgressBar ( DialogRef theDialog, int doneAmount, int maxAmount )
{
    SInt16          theType;
    int             theLength;
    float           floatDone, floatMax, thePercent;
    Handle          theHan;
    Rect            theRect;
    
    
    
    GetDialogItem ( theDialog, kUserItemID, &theType, &theHan, &theRect );
    if ( maxAmount )        // Standard Progress Bar
    {
        SetDialogItem ( theDialog, kUserItemID, theType, (Handle) gOutlineUserItemUPP, &theRect );
        // call it now, so that after an update event the boarder
        // is drawn before FillRect is called
        CallUserItemProc ( gOutlineUserItemUPP, theDialog, kUserItemID );
        
        
        theLength = theRect.right - theRect.left;
        
        floatDone = doneAmount;
        floatMax = maxAmount;
        thePercent = (floatDone / floatMax) * 100;
        theRect.right = theRect.left + ((thePercent / 100) * theLength);
        FillRect ( &theRect, &qd.black );
    }
    else                    // Barber Pole Progress Bar
    {
        static SInt16   theID = 1000;
        PicHandle       thePic;
        
        
        thePic = GetPicture ( theID++ );
        DrawPicture ( thePic, &theRect );
        if ( theID > 1003 )
            theID = 1000;
    }
    
    return;
    
} // DrawProgressBar
 
 
 
//
// This routine is one of the operations carried out
// which the progress bar is representing.
//
Boolean StandardDemoOperation ( void* refCon, DialogRef theDialog )
{
    #pragma unused(refCon)
    Boolean     bWasCancelled = false;
    int         i;
    const int   max = 100;
    
    
    for ( i = 1; i <= max && bWasCancelled == false; i++ )
    {
        UInt32  theDelay = 10L;
        Delay ( theDelay, &theDelay );
        bWasCancelled = UpdateProgressBar ( theDialog, i, max );
    }
    
    return bWasCancelled;
}
 
 
 
//
// This routine is one of the operations carried out
// which the progress bar is representing.
//
Boolean BarberPoleDemoOperation ( void* refCon, DialogRef theDialog )
{
    #pragma unused(refCon)
    Boolean     bWasCancelled = false;
    int         i;
    const int   max = 100;
    
    
    for ( i = 1; i <= max && bWasCancelled == false; i++ )
    {
        UInt32  theDelay = 10L;
        Delay ( theDelay, &theDelay );
        bWasCancelled = UpdateProgressBar ( theDialog, 0, 0 );
    }
    
    return bWasCancelled;
}