MoviePrefs.c

/*
    File:       MoviePrefs.c
 
    Contains:       movie handling routines
 
    Written by: Jason Hodges-Harris & Don Swatman   
 
    Copyright:  Copyright © 1995-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/17/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
#include <Dialogs.h>
#include <TextUtils.h>
 
#include "MoviePrefs.h"
 
#include "MovieStuff.h"
 
 
//==============================================
// Global Stuff, init and tear down             
//==============================================
 
// Prototypes of functions  used in UPPs
pascal void DrawDLOGFrameRect(WindowPtr theDialog, short itemNo);
 
// Global UPPs
UserItemUPP     gDLOGFrameUpp;
 
// Globals
MovieOptionsType gDefaultMoviePrefs;
 
//----------------------------------------------
// InitMoviePrefs
//
// Init's any globals used in MovieStuff
// i.e. the UPPs             
//----------------------------------------------
void InitMoviePrefs(void)
{
    gDLOGFrameUpp = nil;
// Create Dialog Frame Upp for "DrawDLOGFrameRect"
    gDLOGFrameUpp = NewUserItemProc( DrawDLOGFrameRect );
 
// Set up the default movie prefs
    SetUpDefaultMoviePref( &gDefaultMoviePrefs );
}
 
//----------------------------------------------
// KillMoviePrefs
//
// Removes the UPPs             
//----------------------------------------------
void KillMoviePrefs(void)
{
// Clear the Universal Proc Pointers
//    You don't need to do this as quiting the app will do it for you,
//    however, I have this thing about neatness.    
    if (gDLOGFrameUpp)
        DisposeRoutineDescriptor(gDLOGFrameUpp);
        
}
 
//----------------------------------------------
//  SetUpDefaultMoviePref 
//
// Puts the standard options into a MovieOptionsType
// preference record                                  
//----------------------------------------------
void SetUpDefaultMoviePref ( MovieOptionsType *theOptions )
{
    (*theOptions).closeAtEnd      = kUserCloseWind;       // User has to close the window
    (*theOptions).hasController   = kHasMovieController;  // Movie has a controller
    (*theOptions).do20to10Loop    = false;     // Don't do the loop stuff
    (*theOptions).loopFrom        = 20;        // Set loop to start at 20 secs
    (*theOptions).loopTo          = 10;        //    and loop to 10 secs
    (*theOptions).rateChangeDelay = kInSync;   // No rate change stuff
    (*theOptions).slaveAheadBy    = kInSync;   // Slave is in sync with master
    (*theOptions).slaveStartDelay = kInSync;   // Slave starts at the same time as the master
}
 
//==============================================
// Usefull dialog item stuff
//==============================================
 
//----------------------------------------------
//  InstallCustomDlogItem                                   
//----------------------------------------------
 
void InstallCustomDlogItem( DialogPtr theDialog,
                                                        short     itemNum,
                                                        UserItemUPP customProcUpp );
void InstallCustomDlogItem( DialogPtr theDialog,
                                                        short     itemNum,
                                                        UserItemUPP customProcUpp )
{
    short     itemType;
    Handle    itemHandle;
    Rect      itemRect;
 
    GetDialogItem(theDialog, itemNum, &itemType, &itemHandle, &itemRect);
    SetDialogItem(theDialog, itemNum, itemType, (Handle)customProcUpp, &itemRect);
}
 
//----------------------------------------------
//  DrawDLOGFrameRect
//
// Dialog custom draw item. It draws a frame round the 
// items's rect so it can be used to frame areas                              
//----------------------------------------------
 
pascal void DrawDLOGFrameRect(WindowPtr theDialog, short itemNo)
{
    short     itemType;   //returned item type
    Rect      itemRect;   //returned display rectangle
    Handle    itemHandle; //returned item handle
    WindowPtr oldPort;
    PenState  curPen;
 
// Get information about the item ( including it's rect )
    GetDialogItem(theDialog, itemNo, &itemType, &itemHandle, &itemRect);
 
// Save the current port and the pen's state
    GetPort(&oldPort);
    SetPort( theDialog );
    GetPenState(&curPen);
 
// Draw the frame with a normal pen
    PenNormal();
    FrameRect( &itemRect );
 
// Reset the pen state and the port
    SetPenState(&curPen);
    SetPort(oldPort);
}
 
//==============================================
//  Movie Preferences                                   
//==============================================
 
//----------------------------------------------
// Constants used in the dialog box
//----------------------------------------------
 
#define kOneMovieID 9000
 
enum {
        kOkButton = 1,
        kCancelButton,
        kTitleStatic,
        kHelpBox,
        kHelpTitle,
        kHelpText,
        kCloseAtEnd,
        kHasController,
        kDoTheLoop,
        kRateChangePU,
        kSlaveAheadPU,
        kSlaveDelayStartPU,
        kSlaveBox,
        kSlaveTitle
};
 
//----------------------------------------------
// ConvertTimeToMenuItem
//
// Converts one of the time values into the pop up menu's
// selected item.
//----------------------------------------------
 
short ConvertTimeToMenuItem( short time );
short ConvertTimeToMenuItem( short time )
{
    short menuItem = 1; // default the item to 1, normally kInSync
    
    switch (time)
    {
    case (kInSync):
        menuItem = 1;
        break;
    case (kOneThird):
        menuItem = 2;
        break;
    case (10):
        menuItem = 3;
        break;
    }
    return ( menuItem );
}
 
//----------------------------------------------
// ConvertMenuItemToTime
//
// Converts a pop up menu's selected item into
// one of the time values
//----------------------------------------------
 
short ConvertMenuItemToTime( short menuItem );
short ConvertMenuItemToTime( short menuItem )
{
    short time = kInSync;  // default to kInSync (i.e. don't do anything)
    
    switch (menuItem)
    {
    case (1):
        time = kInSync;
        break;
    case (2):
        time = kOneThird;
        break;
    case (3):
        time = 10;
        break;
    }
    return ( time );
}
 
//----------------------------------------------
// SetUpOneMovieDLOG
//
// Sets up the items in the preferences dialog
// depending on "MovieOptionsType *theOptions"
// In general, each chunk get's the control handle from
// a dialog item and set's it up appropriately
//----------------------------------------------
 
void SetUpOneMovieDLOG( DialogPtr oneMovieDialog,
                                                MovieOptionsType *theOptions,
                                                Boolean hasSlaveMovie );
 
void SetUpOneMovieDLOG( DialogPtr oneMovieDialog,
                                                MovieOptionsType *theOptions,
                                                Boolean hasSlaveMovie )
{
    short     itemType;
    Handle    item;
    Rect      box;
    short     newPUValue;
 
// Set up the frame boxes custom items
    InstallCustomDlogItem( oneMovieDialog, kHelpBox, gDLOGFrameUpp );
    InstallCustomDlogItem( oneMovieDialog, kSlaveBox, gDLOGFrameUpp );
 
// kCloseAtEnd from closeAtEnd
    GetDialogItem( oneMovieDialog, kCloseAtEnd, &itemType, &item, &box);
    if ((*theOptions).closeAtEnd)
        SetControlValue ((ControlHandle)item, 1);
    else
        SetControlValue ((ControlHandle)item, 0);
 
// kHasController from hasController
    GetDialogItem( oneMovieDialog, kHasController, &itemType, &item, &box);
    if ((*theOptions).hasController)
        SetControlValue ((ControlHandle)item, 1);
    else
        SetControlValue ((ControlHandle)item, 0);
 
// kDoTheLoop from do20to10Loop
    GetDialogItem( oneMovieDialog, kDoTheLoop, &itemType, &item, &box);
    if ((*theOptions).do20to10Loop)
        SetControlValue ((ControlHandle)item, 1);
    else
        SetControlValue ((ControlHandle)item, 0);
 
// kRateChangePU from rateChangeDelay
    GetDialogItem( oneMovieDialog, kRateChangePU, &itemType, &item, &box);
    newPUValue = ConvertTimeToMenuItem( (*theOptions).rateChangeDelay );
    SetControlValue ((ControlHandle)item, newPUValue);
 
// kSlaveAheadPU from slaveAheadBy
    GetDialogItem( oneMovieDialog, kSlaveAheadPU, &itemType, &item, &box);
    newPUValue = ConvertTimeToMenuItem( (*theOptions).slaveAheadBy );
    SetControlValue ((ControlHandle)item, newPUValue);
// If we're not setting up a master/slave them we don't need
// this , so gray it out
    if (!hasSlaveMovie)
        HiliteControl ((ControlHandle)item, 255);
 
// Set slave start delay PU
    GetDialogItem( oneMovieDialog, kSlaveDelayStartPU, &itemType, &item, &box);
    newPUValue = ConvertTimeToMenuItem( (*theOptions).slaveStartDelay );
    SetControlValue ((ControlHandle)item, newPUValue);
// If we're not setting up a master/slave them we don't need
// this , so gray it out
    if (!hasSlaveMovie)
        HiliteControl ((ControlHandle)item, 255);
 
}
 
//----------------------------------------------
// GetOneMovieDLOG
//
// Gets the information from the items in the preferences
// dialog and puts them back in "MovieOptionsType *theOptions"
// In general, each chunk get's the control handle from
// a dialog item and interprates the result accordingly
//----------------------------------------------
 
void GetOneMovieDLOG( DialogPtr oneMovieDialog,
                                            MovieOptionsType *theOptions );
 
void GetOneMovieDLOG( DialogPtr oneMovieDialog,
                                            MovieOptionsType *theOptions )
{
    short  itemType;
    Handle item;
    Rect   box;
    short  newPUValue;
 
// kCloseAtEnd into closeAtEnd
    GetDialogItem( oneMovieDialog, kCloseAtEnd, &itemType, &item, &box);
    (*theOptions).closeAtEnd = (GetControlValue ((ControlHandle)item) == 1);
 
// kHasController into hasController
    GetDialogItem( oneMovieDialog, kHasController, &itemType, &item, &box);
    (*theOptions).hasController = (GetControlValue ((ControlHandle)item) == 1);
 
// kDoTheLoop into do20to10Loop
    GetDialogItem( oneMovieDialog, kDoTheLoop, &itemType, &item, &box);
    (*theOptions).do20to10Loop = (GetControlValue ((ControlHandle)item) == 1);
 
// kRateChangePU into rateChangeDelay
    GetDialogItem( oneMovieDialog, kRateChangePU, &itemType, &item, &box);
    newPUValue = GetControlValue ((ControlHandle)item);
    (*theOptions).rateChangeDelay = ConvertMenuItemToTime( newPUValue );
 
// kSlaveAheadPU into slaveAheadBy
    GetDialogItem( oneMovieDialog, kSlaveAheadPU, &itemType, &item, &box);
    newPUValue = GetControlValue ((ControlHandle)item);
    (*theOptions).slaveAheadBy = ConvertMenuItemToTime( newPUValue );
 
// kSlaveDelayStartPU into slaveStartDelay
    GetDialogItem( oneMovieDialog, kSlaveDelayStartPU, &itemType, &item, &box);
    newPUValue = GetControlValue ((ControlHandle)item);
    (*theOptions).slaveStartDelay = ConvertMenuItemToTime( newPUValue );
}
 
//----------------------------------------------
// GetItemHelpText
//
// Item hit gives the last item clicked on, interprates
// its current state and returns an appropriate comment
// in "helpString"
//----------------------------------------------
 
void GetItemHelpText( DialogPtr oneMovieDialog,
                                            Str255    helpString,
                                            short     itemHit );
 
void GetItemHelpText( DialogPtr oneMovieDialog,
                                            Str255    helpString,
                                            short     itemHit )
{
    short   itemType;
    Handle  item;
    Rect    box;
    short   strNum = 1; // Resource index of the string we want
    
    
// Get information about the last dialog item clicked on
    GetDialogItem( oneMovieDialog, itemHit, &itemType, &item, &box);
 
// Look at what was last hit and what it's state is
    switch (itemHit)
    {
    case (kCloseAtEnd) :
        if (GetControlValue ((ControlHandle)item))
            strNum = 2;
        else
            strNum = 3;
        break;
    case (kHasController) :
        if (GetControlValue ((ControlHandle)item))
            strNum = 4;
        else
            strNum = 5;
        break;
    case (kDoTheLoop) :
        if (GetControlValue ((ControlHandle)item))
            strNum = 6;
        else
            strNum = 7;
        break;
    case (kRateChangePU) :
        strNum = GetControlValue ((ControlHandle)item) + 7;
        break;
    case (kSlaveAheadPU) :
        strNum = GetControlValue ((ControlHandle)item) + 10;
        break;
    case (kSlaveDelayStartPU) :
        strNum = GetControlValue ((ControlHandle)item) + 13;
        break;
    };
 
// Now get helpString from the resource file
    GetIndString ( helpString, kOneMovieID, strNum);
}
 
//----------------------------------------------
// OneMoviePref
//
// This creates, handles and destroys the movie
// preferences dialog box
//----------------------------------------------
 
OSErr OneMoviePref( MovieOptionsType *theOptions,
                                        Boolean hasSlaveMovie )
{
    OSErr     theErr = noErr;
    GrafPtr   savePort = nil;
    DialogPtr oneMovieDialog;
    ModalFilterUPP theFilter = nil;
    short     itemHit = 0;  // Item clicked by user
    short     lastHit = 0;  // Last item clicked by user
    Str255    helpString;   // help String
    short     itemType;
    Handle    item;
    Rect      box;
    short     checkBox;  //Temporary value of a checkbox control
    
  GetPort(&savePort);
 
// Load the resource from the res file
    oneMovieDialog = GetNewDialog(kOneMovieID, nil, (WindowPtr) -1 );
 
// Setup the dialogs items
    SetUpOneMovieDLOG( oneMovieDialog, theOptions, hasSlaveMovie );
    
// Show the dialog to the user now it's set up
  SetPort( oneMovieDialog );
    ShowWindow( oneMovieDialog );
        
// Get the standard filter proc
  if (GetStdFilterProc(&theFilter) != noErr)
    DebugStr("\pFailed to get standard dialog filter.");
  
// Tell the OS which items the <OK> and <Cancel> buttons are
    SetDialogDefaultItem( oneMovieDialog, kOkButton);
    SetDialogCancelItem ( oneMovieDialog, kCancelButton);
  
// Modal dialog loop
    do
    {
// Use "theFilter" in ModalDialog call
    ModalDialog(theFilter,&itemHit);
 
        switch (itemHit)
        {
// Toggle Check box type items
            case (kCloseAtEnd) :
            case (kHasController) :
            case (kDoTheLoop) :
    // Get the control handle - in item
                GetDialogItem( oneMovieDialog, itemHit, &itemType, &item, &box);
    // Get the current state of the check box
                checkBox = GetControlValue ((ControlHandle)item);
    // Toggle it's state
                checkBox = 1 - checkBox;
    // Put the new item into the control
                SetControlValue ((ControlHandle)item, checkBox);
                break;
        }
 
// Put up the help text
        if ((itemHit != lastHit) && (itemHit > 0))
        {
    // Work out what text we're going to put up
            GetItemHelpText( oneMovieDialog, helpString, itemHit );
    //  and put it into the static text item 
            GetDialogItem ( oneMovieDialog, kHelpText, &itemType, &item, &box);
            SetDialogItemText (item, helpString);
        }
    } while ((itemHit != kOkButton) && (itemHit != kCancelButton));
// Keep going until the <OK> and <Cancel> have been hit
 
// If the <OK> button was pressed then extract the information
// from the dialog items, and return noErr
    if (itemHit == kOkButton)
    {
        GetOneMovieDLOG( oneMovieDialog, theOptions );
        theErr = noErr;
    }
    else
// <Cancel> button was pressed so return userCanceledErr
        theErr = userCanceledErr;
 
// Dispose of the dialog and reset the port
  DisposeDialog(oneMovieDialog);
  SetPort(savePort);
  
  return ( theErr );
}