home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-01 | 15.3 KB | 574 lines | [TEXT/MMCC] |
- //
- // CModalProgress.cp
- //
- // This file contains the definition information for the CModalProgress class.
- // This class provides an interface for displaying to the user, a visual
- // indication to the progress of a time intensive task.
- //
- // History
- // -------
- //
- // 01/9/94 G. Heathcote Created version 1.0
- //
- // Version 1.0
- //
- // Copyright 1994 Alysoft Solutions. All rights reserved.
- //
-
- #ifndef __QUICKDRAW__
- #include <Quickdraw.h>
- #endif
-
- #include "CModalProgress.h"
-
- // ---------------------------------------------------------------------------
- // • Local Prototypes
- // ---------------------------------------------------------------------------
-
- pascal void DrawBar(WindowPtr theWindow, short itemNumber) ;
- pascal void DrawButtonRect(WindowPtr theWindow, short itemNumber) ;
-
-
- // ---------------------------------------------------------------------------
- // • CModalProgress
- // ---------------------------------------------------------------------------
-
- CModalProgress::CModalProgress()
- {
- fDialog = NULL ;
- fCurrentPercent = 0.0 ;
- fStartStatePercent = 0.0 ;
- fCurrentStateSpacePercent = 0.0 ;
- fInfiniteDrawDelay = kDefaultInfiniteDrawDelay ;
- fPercentText = fProgressBar = fInfiniteBar = false ;
- fPercentTextItem = fProgressBarItem = fInfiniteBarItem = 0 ;
- fPercentTextDeltaLimit = 1 ;
- }
-
- // ---------------------------------------------------------------------------
- // • ~CModalProgress
- // ---------------------------------------------------------------------------
- // Destructor. Delete the dialog structure if it is still around
-
- CModalProgress::~CModalProgress()
- {
- if (fDialog)
- DisposeDialog(fDialog) ;
- }
-
- // ---------------------------------------------------------------------------
- // • SetupDialog
- // ---------------------------------------------------------------------------
- // Set the dialog parameters
-
- short CModalProgress::SetupDialog(short dlgResId)
- {
- short itemType ;
- Handle theItem ;
- Rect box ;
- short err = noErr ;
-
- fDialog = GetNewDialog(dlgResId, NULL, (WindowPtr)-1L) ;
- if (fDialog)
- {
- SetWRefCon((WindowPtr)fDialog, (long)this) ;
-
- GetDialogItem(fDialog, kDefaultButtonOutlineIndex, &itemType, &theItem, &box) ;
- if (itemType == userItem)
- {
- SetDialogItem(fDialog, kDefaultButtonOutlineIndex, itemType, (Handle)&DrawButtonRect, &box) ;
- }
- }
- else
- err = ResError() ;
-
- return err ;
- }
-
- // ---------------------------------------------------------------------------
- // • SetProgressBar
- // ---------------------------------------------------------------------------
- // Set parameters for using the standard progress bar
-
- void CModalProgress::SetProgressBar(short dlgItem)
- {
- short itemType ;
- Handle theItem ;
- Rect box ;
-
- GetDialogItem(fDialog, dlgItem, &itemType, &theItem, &box) ;
- if (itemType == userItem)
- {
- fProgressBar = true ;
- fProgressBarItem = dlgItem ;
- SetDialogItem(fDialog, fProgressBarItem, itemType, (Handle)&DrawBar, &box) ;
- }
- else
- {
- fProgressBar = false ;
- fProgressBarItem = 0 ;
- }
- }
-
- // ---------------------------------------------------------------------------
- // • SetInfiniteBar
- // ---------------------------------------------------------------------------
- // Set parameters for using the infinite progress bar
-
- void CModalProgress::SetInfiniteBar(short dlgItem)
- {
- short itemType ;
- Handle theItem ;
- Rect box ;
-
- GetDialogItem(fDialog, dlgItem, &itemType, &theItem, &box) ;
- if (itemType == userItem)
- {
- fInfiniteBar = true ;
- fInfiniteBarItem = dlgItem ;
- SetDialogItem(fDialog, fInfiniteBarItem, itemType, (Handle)&DrawBar, &box) ;
- }
- else
- {
- fInfiniteBar = false ;
- fInfiniteBarItem = 0 ;
- }
- }
-
- // ---------------------------------------------------------------------------
- // • SetPercentText
- // ---------------------------------------------------------------------------
- // Set parameters for using the textual percent indicator
-
- void CModalProgress::SetPercentText(short dlgItem, short deltaLimit)
- {
- short itemType ;
- Handle theItem ;
- Rect box ;
-
- GetDialogItem(fDialog, dlgItem, &itemType, &theItem, &box) ;
- if ((theItem != NULL) && (itemType == statText))
- {
- fPercentText = true ;
- fPercentTextItem = dlgItem ;
- fPercentTextDeltaLimit = deltaLimit ;
- }
- else
- {
- fPercentText = false ;
- fPercentTextItem = 0 ;
- fPercentTextDeltaLimit = 0 ;
- }
- }
-
- // ---------------------------------------------------------------------------
- // • UpdateProgressIndicator
- // ---------------------------------------------------------------------------
- // Force a redraw of the progress indicator(s)
-
- void CModalProgress::UpdateProgressIndicator(float newPercent)
- {
- GrafPtr oldPort ;
-
- GetPort(&oldPort) ;
- SetPort((GrafPtr)fDialog) ;
- DrawProgressIndicator(newPercent, kIndicatorContent) ;
- SetPort(oldPort) ;
- }
-
- // ---------------------------------------------------------------------------
- // • SetCurrentState
- // ---------------------------------------------------------------------------
- // Set the current progress state
-
- void CModalProgress::SetCurrentState(float statePercent)
- {
-
- fCurrentPercent = fStartStatePercent + fCurrentStateSpacePercent ;
- UpdateProgressIndicator(fCurrentPercent) ;
- fStartStatePercent = fCurrentPercent ;
-
- fCurrentStateSpacePercent = statePercent - fStartStatePercent ;
- fCurrentStateSpace = 0 ;
- fCurrentStateValue = 0 ;
- }
-
- // ---------------------------------------------------------------------------
- // • SetStateSpace
- // ---------------------------------------------------------------------------
- // Set the resolution of the current state
-
- void CModalProgress::SetStateSpace(float space)
- {
- fCurrentStateSpace = space ;
- }
-
- // ---------------------------------------------------------------------------
- // • SetCurrentStateValue
- // ---------------------------------------------------------------------------
- // Set the current position in this state
-
- short CModalProgress::SetCurrentStateValue(float value)
- {
- float currentPercent ;
-
- fCurrentStateValue = value ;
- currentPercent = (fCurrentStateSpacePercent / fCurrentStateSpace) * fCurrentStateValue ;
-
- fCurrentPercent = currentPercent + fStartStatePercent ;
- UpdateProgressIndicator(fCurrentPercent) ;
-
- if (fCurrentStateValue < fCurrentStateSpace)
- return kStateSpaceWithinLimit ;
- else
- return kStateSpaceExceedingLimit ;
- }
-
- // ---------------------------------------------------------------------------
- // • BeginModal
- // ---------------------------------------------------------------------------
- // Set the Modal Dialog process
-
- void CModalProgress::BeginModal()
- {
- fInfiniteDrawTime = TickCount() + fInfiniteDrawDelay ;
- ShowWindow((WindowPtr)fDialog) ;
- DrawDialog(fDialog) ;
- }
-
- // ---------------------------------------------------------------------------
- // • FlashButton
- // ---------------------------------------------------------------------------
- // Flash the indicated button
-
- Boolean CModalProgress::FlashButton(DialogPtr theDialog, short buttonIndex)
- {
- Rect aRect ;
- ControlHandle theItem ;
- short itemType ;
- long delayTime ;
- Boolean retVal = false ;
-
- GetDialogItem(theDialog, buttonIndex, &itemType, (Handle*)&theItem, &aRect) ;
- if (itemType == (btnCtrl + ctrlItem))
- {
- if ((**theItem).contrlHilite != 255) /* is it enabled ? */
- {
- HiliteControl(theItem, 1) ;
- Delay(6, &delayTime) ;
- HiliteControl(theItem, 0) ;
-
- retVal = true ;
- }
- }
-
- return retVal ;
- }
-
- // ---------------------------------------------------------------------------
- // • ProcessEvent
- // ---------------------------------------------------------------------------
- // Process the event from ProcessModal()
-
- short CModalProgress::ProcessEvent(EventRecord *theEvent)
- {
- short retVal = kDialogContinues ;
-
- switch(theEvent->what)
- {
- case updateEvt:
- BeginUpdate((WindowPtr)fDialog) ;
- DrawDialog(fDialog) ;
- EndUpdate((WindowPtr)fDialog) ;
- break ;
-
- case mouseDown:
- WindowPtr theWindow ;
- Rect aRect ;
-
- if (FindWindow(theEvent->where, &theWindow) == inDrag)
- {
- if (theWindow == (WindowPtr)fDialog)
- {
- aRect = qd.screenBits.bounds ;
- InsetRect(&aRect, -4, -4) ;
- DragWindow(theWindow, theEvent->where, &aRect) ;
- }
- }
- else
- if (FindWindow(theEvent->where, &theWindow) == inContent)
- {
- if (theWindow == (WindowPtr)fDialog)
- {
- ControlHandle control ;
- GrafPtr oldPort ;
- short itemType ;
- Rect box ;
- ControlHandle theItem ;
-
- GetPort(&oldPort) ;
- SetPort((GrafPtr)fDialog) ;
- GlobalToLocal(&theEvent->where) ;
- SetPort(oldPort) ;
- if (FindControl(theEvent->where, (WindowPtr)fDialog, &control))
- {
- if (TrackControl(control, theEvent->where, NULL))
- {
- GetDialogItem(fDialog, ok, &itemType, (Handle*)&theItem, &box) ;
- if (control == theItem)
- retVal = kDialogOKHit ;
- else
- retVal = kDialogCancelHit ;
- }
- }
- }
- }
- break ;
-
- case keyDown:
- short keyCode ;
-
- keyCode = BitAnd(theEvent->message, charCodeMask) ;
- switch (keyCode)
- {
- case 46: /* . */
- if ((theEvent->modifiers & cmdKey) != cmdKey)
- break ;
-
- case 27: /* Escape */
- if (FlashButton(fDialog, cancel))
- retVal = kDialogCancelHit ;
- break ;
-
- case 13: /* CR */
- case 3: /* ENTER */
- if (FlashButton(fDialog, ok))
- retVal = kDialogOKHit ;
- break ;
- }
- break ;
- }
-
- return retVal ;
- }
-
-
- // ---------------------------------------------------------------------------
- // • ProcessModal
- // ---------------------------------------------------------------------------
- // Do the general dialog processing
-
- short CModalProgress::ProcessModal()
- {
- EventRecord theEvent ;
- Boolean ok ;
- short retVal = kDialogContinues ;
-
- if (fInfiniteBar)
- {
- if (TickCount() > fInfiniteDrawTime)
- UpdateProgressIndicator(fCurrentPercent) ;
- }
-
- ok = GetNextEvent(everyEvent, &theEvent) ;
- if (ok)
- {
- retVal = ProcessEvent(&theEvent) ;
- }
-
- if ((fCurrentPercent >= 100) && (retVal == kDialogContinues))
- retVal = kDialogExceeding100pc ;
-
- return retVal ;
- }
-
- // ---------------------------------------------------------------------------
- // • EndModal
- // ---------------------------------------------------------------------------
- // Finished with the modal dialog
-
- void CModalProgress::EndModal()
- {
- FlushEvents(everyEvent, everyEvent) ;
- HideWindow((WindowPtr)fDialog) ;
- }
-
- // ---------------------------------------------------------------------------
- // • DrawProgressIndicator
- // ---------------------------------------------------------------------------
- // Draw the appropriate dialog items
-
- void CModalProgress::DrawProgressIndicator(float percent, short part)
- {
- if (fPercentText)
- DrawPercentIndicator(percent, fPercentTextDeltaLimit, fPercentTextItem, part) ;
-
- if (fProgressBar)
- DrawStdBarIndicator(percent, fProgressBarItem, part) ;
-
- if (fInfiniteBar)
- {
- if ((part & kIndicatorOutline) == kIndicatorOutline)
- DrawInfiniteBarIndicator(percent, fInfiniteBarItem, part) ;
- else
- if (TickCount() > fInfiniteDrawTime)
- {
- fInfiniteDrawTime = TickCount() + fInfiniteDrawDelay ;
- DrawInfiniteBarIndicator(percent, fInfiniteBarItem, part) ;
- }
- }
- }
-
- // ---------------------------------------------------------------------------
- // • DrawPercentIndicator
- // ---------------------------------------------------------------------------
-
- void CModalProgress::DrawPercentIndicator(float percent, short deltaLimit, short itemIndex, short part)
- {
- short itemType ;
- Handle item ;
- Rect box ;
- Str255 theText ;
- long theNum ;
- long percentLong ;
-
- GetDialogItem(fDialog, itemIndex, &itemType, &item, &box) ;
-
- GetIText(item, theText) ;
- StringToNum(theText, &theNum) ;
- percentLong = percent ;
-
- if (((percentLong - theNum) >= deltaLimit) &&
- (percentLong > 0) )
- {
- NumToString(percentLong, theText) ;
- SetIText(item, theText) ;
- }
- }
-
- // ---------------------------------------------------------------------------
- // • DrawStdBarIndicator
- // ---------------------------------------------------------------------------
-
- void CModalProgress::DrawStdBarIndicator(float percent, short itemIndex, short part)
- {
- short itemType ;
- Handle item ;
- Rect box ;
- static short previousRight = 0 ;
- RGBColor barColor = {0x4444, 0x4444, 0x4444} ;
- RGBColor emptyBarColor = {0xCCCC, 0xCCCC, 0xFFFF} ;
- RGBColor currentForeColor ;
-
- GetDialogItem(fDialog, itemIndex, &itemType, &item, &box) ;
-
- // Draw the frame of the progress indicator
-
- if ((part & kIndicatorOutline) == kIndicatorOutline)
- {
- // Colour in the purple interior of the progress indicatorbar
-
- GetForeColor(¤tForeColor) ;
- RGBForeColor(&emptyBarColor) ;
- PaintRect(&box) ;
- RGBForeColor(¤tForeColor) ;
-
- // Draw the black frame around the outside
-
- FrameRect(&box) ;
- previousRight = box.left + 1 ; // Ensure the entire body is drawn
- }
-
- // Draw the body of the progress indicator
-
- if ((part & kIndicatorContent) == kIndicatorContent)
- {
- InsetRect(&box, 1, 1) ;
- box.right = box.left + ((float)(box.right - box.left) * (percent / 100.0)) ;
- if (box.right > previousRight)
- {
- if (previousRight > 0)
- box.left = previousRight ;
- previousRight = box.right ;
-
- GetForeColor(¤tForeColor) ;
- RGBForeColor(&barColor) ;
- PaintRect(&box) ;
- RGBForeColor(¤tForeColor) ;
- }
- }
- }
-
- // ---------------------------------------------------------------------------
- // • DrawInfiniteBarIndicator
- // ---------------------------------------------------------------------------
-
- void CModalProgress::DrawInfiniteBarIndicator(float percent, short itemIndex, short part)
- {
- short itemType ;
- Handle item ;
- Rect box ;
- static short originOffset = 0 ;
- PixPatHandle thePattern ;
-
- GetDialogItem(fDialog, itemIndex, &itemType, &item, &box) ;
-
- // Draw the outline of the progress indicator
-
- if ((part & kIndicatorOutline) == kIndicatorOutline)
- {
- FrameRect(&box) ;
- }
-
- // Draw the body of the indicator
-
- InsetRect(&box, 1, 1) ;
- OffsetRect(&box, 0, originOffset) ;
- thePattern = GetPixPat(kInfinitePaternResID) ;
- PenPixPat(thePattern) ;
- SetOrigin(0, originOffset) ;
- PaintRect(&box) ;
-
- SetOrigin(0, 0) ;
- PenNormal() ;
-
- // Increment the origin offset if we have just been asked to draw the Content ONLY
-
- if (part == kIndicatorContent)
- originOffset = (originOffset + 1) % ((((**(**thePattern).patMap).rowBytes) & 0xEFFF) * 8) ;
-
- DisposePixPat(thePattern) ;
- }
-
-
- // ---------------------------------------------------------------------------
- // • Non-Class routines
- // ---------------------------------------------------------------------------
-
- // ---------------------------------------------------------------------------
- // • DawBar
- // ---------------------------------------------------------------------------
-
- pascal void DrawBar(WindowPtr theWindow, short itemNumber)
- {
- CModalProgress *theDialog ;
-
- theDialog = (CModalProgress*)GetWRefCon(theWindow) ;
- theDialog->DrawProgressIndicator(theDialog->fCurrentPercent, kIndicatorOutline | kIndicatorContent) ;
- }
-
- // ---------------------------------------------------------------------------
- // • DrawButtonRect
- // ---------------------------------------------------------------------------
-
- pascal void DrawButtonRect(WindowPtr theWindow, short itemNumber)
- {
- Rect theRect ;
- short itemType ;
- Handle theItem ;
-
- GetDialogItem((DialogPtr)theWindow, itemNumber, &itemType, &theItem, &theRect) ;
- PenSize(3, 3) ;
- FrameRoundRect(&theRect, 16, 16) ;
- PenNormal() ;
- }