TumblerSource/Tumbler_menus.c

//      Tumbler_menus.c
//
//      Menu handling routines and utilities.
//      
//
//      Author:     Nick Thompson & Pablo Fernicola, with thanks to the QuickDraw 3D team
//
//  Modification History:
//
//  11/25/94    Nick    Started Factoring for AppleEvent senders, cleanup
//
//      Copyright © 1992-95 Apple Computer, Inc., All Rights Reserved
 
#define FINAL
 
#include <Drag.h>
#include <Devices.h>
#include <ColorPicker.h>
 
#include "Tumbler_globals.h"
#include "Tumbler_prototypes.h"
#include "Tumbler_resources.h"
#include "Tumbler_AEVT.h"
 
#include "QD3DStorage.h"
#include "QD3DIO.h"
#include "QD3DView.h"
#include "QD3DTransform.h"
#include "QD3DDrawContext.h"
#include "QD3DGeometry.h"
#include "QD3DGroup.h"
#include "QD3DShader.h"
#include "QD3DLight.h"
#include "QD3DRenderer.h"
#include "QD3DAcceleration.h"
 
#include "Tumbler_menus.h"
#include "Tumbler_document.h"
#include "Tumbler_file.h"
#include "Tumbler_windows.h"
#include "Tumbler_PICTImport.h"
#include "Tumbler_drag.h"
#include "Tumbler_offscreen.h"
#include "Tumbler_menus.h"
#include "Tumbler_utility.h"
#include "Tumbler_camera.h"
 
#define BETA_OR_LATER 1
 
#if !defined(BETA_OR_LATER) || (BETA_OR_LATER == 0)
#include "Catwoman.h"
#endif
 
static void DoCopy(DocumentPtr theDocument, Boolean cut);
static short FindCheckItem(MenuHandle theMenu, short rangeStart, short rangeEnd);
static short Check1Item(MenuHandle theMenu, short theItem, short rangeStart, short rangeEnd);
static short ItemCheck(MenuHandle theMenu, short theItem);
static short ToggleCheck(MenuHandle theMenu, short theItem);
static void SetItemEnable(MenuHandle theMenu, short theItem, short enable);
static short ItemStringToItem(Str255 theItemString, MenuHandle theMenu);
static short FontToItem(short fontFamilyNumber);
static short DoSpecialPaste(DocumentPtr theDocument);
static void DoPaste(DocumentPtr theDocument);
 
 
static void UpdateWindow( WindowPtr theWindow)
{
    GrafPtr savedPort ;
    
    // just tell the toolbox that the window is bogus
    GetPort(&savedPort) ;
    SetPort(theWindow) ;
    InvalRect( &theWindow->portRect ) ;
    SetPort(savedPort) ;
}
 
 
 
 
static void DoCopy(DocumentPtr theDocument, Boolean cut)
{
    TQ3FileObject       fd;
    TQ3StorageObject    st;
    Handle              theData;
    long                anErr;
    unsigned long       size;
    PicHandle           thePicture;
    GrafPtr             restorePort;
    RGBColor            qdBgColor;
    Boolean             didAllocate = false ;
    
    // Write the data to a strage object 
 
    // as of 1.0a3 handle storage objects break when increasing the size
    // of the handle in increments with complex models.  To try to get
    // around this we'll temporarily allocate a 1 meg handle. FIX THIS
    if((theData = NewHandle( 1024 * 1024 )) != nil) {
        MoveHHi( theData ) ;
        HLock( theData ) ;
        didAllocate = true ;
        st = Q3HandleStorage_New( theData, GetHandleSize( theData ) );
    }
    else    
        st = Q3HandleStorage_New(nil, 0);
 
    if (st == nil)
    {
        if( didAllocate )
            DisposeHandle( theData ) ;
        return;
    }
    
    fd = Q3File_New();
    
    if (fd == nil) {
        Q3Object_Dispose(st);
        if( didAllocate )
            DisposeHandle( theData ) ;
        return;
    }
    
    Q3File_SetStorage(fd, st);
    
        
    Tumbler_WriteScene(fd, 
                        false,
                        theDocument) ;
    
    theData = nil; size = 0;
    
    if( Q3HandleStorage_Get(st, &theData, &size) == kQ3Failure ) {
        Q3Object_Dispose(st);
        if( didAllocate )
            DisposeHandle( theData ) ;
        return;
    }
    
    /* Transfer the data to the scrap */
    HLock(theData);
    
    GetPort( &restorePort);
    SetPort( (GrafPtr) theDocument->theWindow);
    
    qdBgColor.red   = (unsigned short)65535;
    qdBgColor.green = (unsigned short)65535;
    qdBgColor.blue  = (unsigned short)65535;
    RGBBackColor(&qdBgColor);
    qdBgColor.red   = 0;
    qdBgColor.green = 0;
    qdBgColor.blue  = 0;
    RGBForeColor(&qdBgColor);
    thePicture = OpenPicture(&theDocument->theWindow->portRect);
    EraseRect( &theDocument->theWindow->portRect ) ;
    
    if( DrawOffscreen(theDocument) == kQ3Failure ) {
        goto memExit;
    }
    
    ClosePicture();
    
    HLock( (Handle) thePicture);
    
    /* Initialize the scrap */
    anErr = LoadScrap();
    if (anErr != noErr) {
        goto errorExit;
    } else {
        anErr = ZeroScrap();
        if (anErr == noErr) {
            anErr = PutScrap(size, '3DMF', (Ptr) *theData);
            if (anErr == noErr) {
                anErr = PutScrap(GetHandleSize((Handle)thePicture), 'PICT', (Ptr) *thePicture);
                if (anErr == noErr) {
                    anErr = UnloadScrap();
                }
            }
        }
    }
    
    HUnlock(theData);
 
    if( cut == true ) {
        Q3Object_Dispose(theDocument->documentGroup);
        theDocument->documentGroup = nil;
        SetPort(theDocument->theWindow) ;
        InvalRect( &theDocument->theWindow->portRect) ;
    }
    
errorExit:  
    SetPort(restorePort);
 
    HUnlock((Handle)thePicture);
    KillPicture(thePicture);
    
memExit:    
    Q3Object_Dispose(st);
    
    if( didAllocate )
        DisposeHandle( theData ) ;
        
    Q3Object_Dispose(fd);
    return;
}
 
//
//  Given a range of menu items and a menu, FindCheckItem returns the
//  item number of the first checked item. If no items in the range
//  are checked, FindCheckItem returns 0 (zero).
//
 
 
static short FindCheckItem(MenuHandle theMenu, short rangeStart, short rangeEnd)
 
{   short       theMark;
 
    while (rangeStart <= rangeEnd) {
        GetItemMark(theMenu, rangeStart, &theMark);
        if (theMark == checkMark)
            return(rangeStart);
        rangeStart++;
    }
 
    return(0);
}
 
 
//
//  Check1Item checks a single menu item in a range of menu items. theItem is
//  the item number to check. rangeStart and rangeEnd denote a range of menu
//  items that theItem belongs to. Check1Item checks theItem and removes
//  any checks from the other items in the given range. Check1Item returns
//  the item number of the checked item if a newly checked item is selected.
//  If theItem was already checked or theItem was outside of the given range,
//  Check1Item returns 0 (zero).
//
 
static short Check1Item(MenuHandle theMenu, short theItem, short rangeStart, short rangeEnd)
 
{   short       theMark;
 
    if ((theItem < rangeStart) || (theItem > rangeEnd))
        return(0);
 
    while (rangeStart <= rangeEnd) {
        if (rangeStart != theItem)
            CheckItem(theMenu, rangeStart, false);
        rangeStart++;
    }
 
    GetItemMark(theMenu, theItem, &theMark);
 
    if (theMark != checkMark) {
        CheckItem(theMenu, theItem, true);
        return(theItem);
    } else {
        return(0);
    }
}
 
 
//
//  ItemCheck returns true if the given menu item is checked, false otherwise.
//
 
static short ItemCheck(MenuHandle theMenu, short theItem)
 
{   short       theMark;
 
    GetItemMark(theMenu, theItem, &theMark);
    return(theMark == checkMark);
 
}
 
 
//
//  ToggleCheck toggles the check mark on the given menu item. ToggleCheck
//  returns true if the item becomes checked and false if the item becomes
//  unchecked.
//
 
static short ToggleCheck(MenuHandle theMenu, short theItem)
 
{   short       theMark;
 
    GetItemMark(theMenu, theItem, &theMark);
    CheckItem(theMenu, theItem, theMark = (theMark != checkMark));
    return(theMark);
}
 
 
//
//  SetItemEnable enables or disables a menu item depending on the value
//  of the enable parameter.
//
 
static void SetItemEnable(MenuHandle theMenu, short theItem, short enable)
 
{
    if (enable) {
        EnableItem(theMenu, theItem);
    } else {
        DisableItem(theMenu, theItem);
    }
}
 
 
//
//  Given a string and a menu, ItemStringToItem will return the item number
//  of the last item that matches the string.
//
 
static short ItemStringToItem(Str255 theItemString, MenuHandle theMenu)
 
{   short       index;
    Str255      theString;
 
    index = CountMItems(theMenu);
    while (index) {
        GetMenuItemText(theMenu, index, theString);
        if (PStrCmp( (char *) theString, (char *) theItemString))
            return(index);
        index--;
    }
    return(0);
}
 
 
static short FontToItem(short fontFamilyNumber)
 
{   Str255      fontName;
 
    GetFontName(fontFamilyNumber, fontName);
    return(ItemStringToItem(fontName, GetMenuHandle(idDisplayMenu)));
}
 
 
//
//  PrepareMenus is called before the user pulls down a menu from the menu
//  bar or types a command key equivalent. PrepareMenus enables and disables
//  menu items within the current program context. Any other menu related
//  setup may be performed here.
//
 
void PrepareMenus(void)
{
    MenuHandle      theMenu;
    DocumentPtr     theDocument;
    WindowPtr       theWindow = FrontWindow() ;
    short           teSelection, theMode;
    Str255          theStr;
 
    theDocument = GetDocumentFromWindow(theWindow);
    teSelection = (short) theDocument->documentGroup;
 
    theMenu = GetMenuHandle(idFileMenu);
 
    SetItemEnable(theMenu, NewItem,   gDocumentCount < MaxDocumentCount);
    SetItemEnable(theMenu, OpenItem,  gDocumentCount < MaxDocumentCount);
 
    SetItemEnable(theMenu, CloseItem, theDocument != 0L);
    SetItemEnable(theMenu, SaveItem, (theDocument) && (theDocument->dirty));
    SetItemEnable(theMenu, SaveAsItem, theDocument != 0L);
    SetItemEnable(theMenu, RevertItem, (theDocument) &&
                                       (theDocument->theFileSpec.parID != 0 ) &&
                                       (theDocument->theFileSpec.vRefNum != 0 ));
#ifdef PODIUM_APP
    SetItemEnable(theMenu, ImportItem, theWindow != nil ) ;
#endif
 
    SetItemEnable(theMenu, PageSetupItem, false);
    SetItemEnable(theMenu, PrintItem, false);
 
    theMenu = GetMenuHandle(idEditMenu);
 
    GetIndString(theStr, MenuStringsID, gCanUndoDrag);
    SetMenuItemText(theMenu, iUndo, theStr);
    SetItemEnable(theMenu, iUndo, gCanUndoDrag != slCantUndo);
 
    SetItemEnable(theMenu, iCut, teSelection);
    SetItemEnable(theMenu, iCopy, teSelection);
    SetItemEnable(theMenu, iPaste, theDocument != 0L);
    SetItemEnable(theMenu, iClear, teSelection);
    SetItemEnable(theMenu, iSelectAll, theDocument != 0L);
    SetItemEnable(theMenu, iShowClipboard, false);
 
#ifdef PODIUM_APP
    theMenu = GetMenuHandle(idSlides);
    SetItemEnable(theMenu, 0, theWindow != nil);
    
    if(theWindow != nil ) {
    
        SetItemEnable(theMenu, iNext, false);       // dummy item, never used
        SetItemEnable(theMenu, iPrevious, false);       // dummy item, never used
        SetItemEnable(theMenu, iIndex, false);      // dummy item, never used
    
        SetItemEnable(theMenu, iRotateModel, true);     
        SetItemEnable(theMenu, iHideShowMenu, true);        
        CheckItem(theMenu, iRotateModel, theDocument->animateModel);
    }
 
#else
    theMenu = GetMenuHandle(idDisplayMenu);
 
    SetItemEnable(theMenu, iShaded, false);
    SetItemEnable(theMenu, iLighted, false);
    SetItemEnable(theMenu, iAnimated, false);
    SetItemEnable(theMenu, iRenderer, false);
    SetItemEnable(theMenu, iBackFacing, false);
    
    if (theDocument) {
        theMode = 0;
 
        if( theDocument->documentGroup) {
            MenuHandle      subMenu;
 
            SetItemEnable(theMenu, iShaded, true);
 
            subMenu = GetMenu(idStyleMenu);
 
            CheckItem(subMenu, iGouraud, false);
            CheckItem(subMenu, iPhong, false);
            CheckItem(subMenu, iFlat, false);
 
            if( theDocument->currentInterpolation == kQ3InterpolationStyleNone) {
                CheckItem(subMenu, iFlat, true);
            } else if( theDocument->currentInterpolation == kQ3InterpolationStylePixel) {
                CheckItem(subMenu, iPhong, true);
            } else {
                CheckItem(subMenu, iGouraud, true);
            }
 
            SetItemEnable(theMenu, iRenderer, true);
            subMenu = GetMenu(idRendererMenu);
 
            CheckItem(subMenu, iWF, false);
            CheckItem(subMenu, iCTSW, false);
            CheckItem(subMenu, iCTHW, false);
 
            {
                TQ3Object   renderer;
                
                Q3View_GetRenderer(theDocument->theView, &renderer);
                
                switch(Q3Object_GetLeafType(renderer)) {
                    case kQ3RendererTypeWireFrame:
                        CheckItem(subMenu, iWF, true);
                        break;
 
                    case kQ3RendererTypeInteractive:
                        if(!gUsingHardware) {
                            CheckItem(subMenu, iCTSW, true);
                        }
                        else {
                            CheckItem(subMenu, iCTHW, true);
                        }
                        break;
                    default:
                        break;
                }
                Q3Object_Dispose(renderer);
            } 
            
            SetItemEnable(theMenu, iLighted, true);
            if( theDocument->light == kQ3True) {
                CheckItem(theMenu, iLighted, true);
            } else {
                CheckItem(theMenu, iLighted, false);
            }
 
            SetItemEnable(theMenu, iAnimated, true);
            subMenu = GetMenu(idAnimateMenu);
 
            if( theDocument->animateLights == kQ3True) {
                CheckItem(subMenu, iLights, true);
            } else {
                CheckItem(subMenu, iLights, false);
            }
 
            if( theDocument->animateModel == kQ3True) {
                CheckItem(subMenu, iModel, true);
            } else {
                CheckItem(subMenu, iModel, false);
            }
            
            SetItemEnable(theMenu, iBackFacing, true);
        }
    }
#endif
    DrawMenuBar() ;
}
 
 
static short DoSpecialPaste(DocumentPtr theDocument)
 
{   long        size, offset;
    Handle      theData;
 
    size = GetScrap(0L, 'UPRC', &offset);
 
    if (size <= 0)
        return(0);
 
    theData = NewHandle(size);
    GetScrap(theData, 'UPRC', &offset);
 
    HLock(theData);
    PutScrap(size, 'test', *theData);
 
    HUnlock(theData);
    DisposeHandle(theData);
 
    return(0);
}
 
static void DoPaste(DocumentPtr theDocument)
 
{   long            size, offset;
    Handle          theData;
    long            anErr= noErr;
    TQ3SharedObject viewHints ;
    
    anErr = LoadScrap();
    if (anErr == noErr) {
        size = GetScrap(0L, '3DMF', &offset);
    
        if (size > 0) {
            TQ3FileObject       fd;
            TQ3StorageObject        storage;
            TQ3Object           objects = nil;
    
            theData = NewHandle(size);
            if( theData ) {
                GetScrap(theData, '3DMF', &offset);
            
                HLock(theData);
        
                /* Read from clipboard */
                storage = Q3MemoryStorage_New((unsigned char *) *theData, (unsigned long) size);
                
                if (storage == nil)
                    goto bail;
                
                fd = Q3File_New();
                Q3File_SetStorage(fd, storage);
                Q3Object_Dispose(storage);
                
                if (fd == nil)
                    goto bail;
                
                Tumbler_ReadScene(  fd,
                                    false,
                                    &viewHints,
                                    &theDocument->documentGroup) ;
                
                TumblerDocument_UpdateView( theDocument, viewHints ) ;
                
                AdjustLightsPositions(theDocument);
            
                if (viewHints != NULL )
                    Q3Object_Dispose(viewHints);
 
                DrawOffscreen(theDocument);
                // DrawControls(theDocument->theWindow);
                DoDrawGrowIcon(theDocument->theWindow);
            bail:
                Q3Object_Dispose(fd);
        
                HUnlock(theData);
                DisposeHandle(theData);
            }
        } else {
            size = GetScrap(0L,'PICT', &offset);
            
            if( size > 0 && theDocument->documentGroup) {
                TQ3StoragePixmap        textureImage;       
                theData = NewHandle(size);
                
                if( theData ) {
                    GetScrap(theData, 'PICT', &offset);
                
                    HLock(theData);
            
                    if( TextureFromPICT( (PicHandle) theData, &textureImage) == kQ3True ) {
    
                        if( AddTextureToDocument( theDocument, &textureImage) == kQ3Success ) {
    
                            DrawOffscreen(theDocument);
                            
                            // DrawControls(theDocument->theWindow);
                            DoDrawGrowIcon(theDocument->theWindow);
                        } else {
                            Alert(130, 0L);
                        }
                    } else {
                        Alert(130, 0L);
                    }
                    HUnlock(theData);
                    DisposeHandle(theData);
                } else {
                    Alert(130, 0L);
                }
            }
        }
    }
}
 
 
//
//  DoMenuCommand dispatches menu command routines from a menu select parameter.
//  This function is called when the user selects a menu item with the mouse
//  or types a command key equivalent.
//
 
void DoMenuCommand(long select)
 
{   short       theMenuID, theItem, result;
    MenuHandle  theMenu;
    Str255      theName;
    WindowPtr   theWindow;
    DocumentPtr theDocument;
 
    theDocument = GetDocumentFromWindow(theWindow = FrontWindow());
 
    theItem   = LoWord(select);
    theMenuID = HiWord(select);
    theMenu   = GetMenuHandle(theMenuID);
    switch(theMenuID) {
        case idAppleMenu:
            switch(theItem) {
                case AboutItem:
                    result = Alert(256, 0L);
                    break;
                default:
                    GetMenuItemText(GetMenuHandle(idAppleMenu), theItem, theName);
                    OpenDeskAcc(theName);
            }
            break;
        case idFileMenu:
            switch(theItem) {
            
                case NewItem:
                    DoNewDocument();
                    break;
                    
                case OpenItem:
                    DoOpenDocument(theDocument);
                    break;
#ifdef PODIUM_APP
                case ImportItem:
                    DoImport3DMFDocument(theDocument);
                    break;
#endif                  
                case CloseItem:
                    if (theDocument) {
                        (void)CloseDocument(theDocument);       // it's not important what the result is here
                    }
                    break;
                    
                case SaveItem:
                    if (theDocument)
                        DidSaveDocument(theDocument);
                    break;
                    
                case SaveAsItem:
                    if (theDocument)
                        DoSaveAsDocument(theDocument);
                    break;
                    
                case RevertItem:
                    if (theDocument)
                        DoRevertDocument(theDocument);
                    break;
                    
                case QuitItem:
                    // to quit we just send ourselves an appleEvent
                    SendQuitApp() ;
                    break;
            }
            break;
        case idEditMenu:
            switch(theItem) {
                case iUndo:
                    break;
                    
                case iCut:
                    if (theDocument) {
                        DoCopy(theDocument, true);
                    }
                    break;
                    
                case iCopy:
                    if (theDocument) {
                        DoCopy(theDocument, false);
                    }
                    break;
                    
                case iPaste:
                    if (theDocument) {
                        DoPaste(theDocument);
                    }
                    UpdateWindow( theDocument->theWindow ) ;
                    break;
                    
                case iClear:
                    break;
                    
                case iSelectAll:
                    break;
                    
            }
            break;
#ifndef PODIUM_APP
        case idDisplayMenu:
 
            switch(theItem) {
                case iBGColor:
                    {
                        TQ3DrawContextObject        drawCtx ;
                        RGBColor                    currentRGBClearColor = { 0xffff, 0xffff, 0xffff } ;
                        RGBColor                    newRGBClearColor ;
                        
                        Point                       wherePt = { 0, 0 } ;
                        float                       factor = 0xffff ;
                        GrafPtr                     savedPort ;
 
                        
                        Q3View_GetDrawContext( theDocument->theView, &drawCtx ) ;
                        
                        currentRGBClearColor.red *= theDocument->clearColor.r ;
                        currentRGBClearColor.green *= theDocument->clearColor.g ;
                        currentRGBClearColor.blue *= theDocument->clearColor.b ;
                        
                        // query the user for a color
                        if(GetColor(wherePt,"\pChoose a new background color",&currentRGBClearColor,&newRGBClearColor)) {
                        
                            theDocument->clearColor.r = newRGBClearColor.red / factor ;
                            theDocument->clearColor.g = newRGBClearColor.green / factor ;
                            theDocument->clearColor.b = newRGBClearColor.blue / factor ;
                            
                            Q3DrawContext_SetClearImageColor( drawCtx, &theDocument->clearColor ) ;
                            
                        }
                        
                        Q3Object_Dispose( drawCtx ) ;
                        
                        GetPort( &savedPort ) ;
                        SetPort( (GrafPtr)theDocument->theWindow) ;
                        InvalRect( &theDocument->theWindow->portRect ) ;
                        SetPort( savedPort ) ;
                                            
                    }
                    break ;
                case iLighted:
                    if( theDocument->light == kQ3True) {
                        TQ3GroupPosition        lightPosition;
                        TQ3LightObject      theLight;
                        TQ3GroupObject      lightGroup;
                                
                        theDocument->light = kQ3False;
                        
                        Q3View_GetLightGroup(theDocument->theView, &lightGroup);
                        Q3Group_GetFirstPosition(lightGroup, &lightPosition);
                        
                        /* First one is always on, skip */
                        Q3Group_GetNextPosition(lightGroup, &lightPosition);
                        Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
                        Q3Light_SetState(theLight,kQ3False);
                        Q3Object_Dispose(theLight);                     
                        
                        Q3Group_GetNextPosition(lightGroup, &lightPosition);
                        Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
                        Q3Light_SetState(theLight,kQ3False);                        
                        Q3Object_Dispose(theLight);                     
                        
                        Q3Group_GetNextPosition(lightGroup, &lightPosition);
                        Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
                        Q3Light_SetState(theLight,kQ3False);                        
                        Q3Object_Dispose(theLight);                     
 
                        Q3Object_Dispose(lightGroup);
                        CheckItem(theMenu, theItem, false);
                    }else { 
                        TQ3GroupPosition        lightPosition;
                        TQ3LightObject      theLight;
                        TQ3GroupObject  lightGroup;
                                
                        theDocument->light = kQ3True;
                        
                        Q3View_GetLightGroup(theDocument->theView, &lightGroup);
                        Q3Group_GetFirstPosition(lightGroup, &lightPosition);
                        
                        /* First one is always on, skip */
                        Q3Group_GetNextPosition(lightGroup, &lightPosition);
                        Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
                        Q3Light_SetState(theLight,kQ3True);
                        Q3Object_Dispose(theLight);                     
                        
                        Q3Group_GetNextPosition(lightGroup, &lightPosition);
                        Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
                        Q3Light_SetState(theLight,kQ3True);                     
                        Q3Object_Dispose(theLight);                     
                        
                        Q3Group_GetNextPosition(lightGroup, &lightPosition);
                        Q3Group_GetPositionObject(lightGroup, lightPosition, &theLight);
                        Q3Light_SetState(theLight,kQ3True);                     
                        Q3Object_Dispose(theLight);                     
 
                        Q3Object_Dispose(lightGroup);
                        
                        CheckItem(theMenu, theItem, true);
                    }
                        
                    DrawOffscreen(theDocument);
                    UpdateWindow( theDocument->theWindow ) ;
                    if( theDocument->viewHints ) {
                        Q3Object_Dispose(theDocument->viewHints);
                    }
                    theDocument->viewHints = Q3ViewHints_New(theDocument->theView);
                    DoDrawGrowIcon(theDocument->theWindow);
                    break;
                    
                default:
                    break;
            }
            break;
            
#endif 
 
        case idAnimateMenu:
            if( theItem == iModel ) {
                if( theDocument->animateModel == kQ3True) {
                    theDocument->animateModel = kQ3False;
                    CheckItem(theMenu, theItem, false);
                }else {
                    theDocument->animateModel = kQ3True;
                    CheckItem(theMenu, theItem, true);
                }
            } else if( theItem == iLights) {
                if( theDocument->animateLights == kQ3True) {
                    theDocument->animateLights = kQ3False;
                    CheckItem(theMenu, theItem, false);
                }else {
                    theDocument->animateLights = kQ3True;
                    CheckItem(theMenu, theItem, true);
                }
            }   
            break;
        
        case idRendererMenu:
            {
                TQ3DrawContextObject        myDrawContext;
                // set the doupble buffer state to false, make the active buffer
                // to be the front buffer
                gUsingHardware = false ;
                Q3View_GetDrawContext(theDocument->theView, &myDrawContext) ;
                Q3DrawContext_SetDoubleBufferState(  myDrawContext, kQ3True ) ;
                Q3Object_Dispose( myDrawContext ) ;
            }
            switch(theItem) {
                case iWF:
                    Q3View_SetRendererByType(theDocument->theView,kQ3RendererTypeWireFrame);
                    CheckItem(theMenu, iCTHW, false);
                    CheckItem(theMenu, iCTSW, false);
                    CheckItem(theMenu, iWF, true);
                    theDocument->shaded = kQ3False;
                    break;
                case iCTSW:
                    {
                        {
                            TQ3RendererObject rendererObject;
                            
                            rendererObject = Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
                            Q3View_SetRenderer(theDocument->theView,rendererObject);
                            
#ifdef FINAL
                            Q3InteractiveRenderer_SetPreferences(rendererObject, kQAVendor_Apple, kQAVendor_BestChoice);
#else
                            Q3InteractiveRenderer_SetPreferences(rendererObject, ZcVendor_Apple, ZcVendor_BestChoice);
#endif
                            Q3Object_Dispose(rendererObject);
                        }
                        CheckItem(theMenu, iWF, false);
                        CheckItem(theMenu, iCTHW, false);
                        CheckItem(theMenu, iCTSW, true);
                        theDocument->shaded = kQ3True;
                    }
                    break;
                case iCTHW:
                    {
                        TQ3DrawContextObject        myDrawContext;
                        // set the doupble buffer state to false, make the active buffer
                        // to be the front buffer
                        gUsingHardware = true ;
 
                        Q3View_GetDrawContext(theDocument->theView, &myDrawContext) ;
                        Q3DrawContext_SetDoubleBufferState(  myDrawContext, kQ3False ) ;
                        Q3Object_Dispose( myDrawContext ) ;
                        
                        {
                            TQ3RendererObject rendererObject;
                            
                            rendererObject = Q3Renderer_NewFromType(kQ3RendererTypeInteractive);
                            Q3View_SetRenderer(theDocument->theView,rendererObject);
                            
#ifdef FINAL
                            Q3InteractiveRenderer_SetPreferences(rendererObject, kQAVendor_BestChoice, 0);
#else
                            Q3InteractiveRenderer_SetPreferences(rendererObject, ZcVendor_BestChoice, 0);
#endif
                            Q3Object_Dispose(rendererObject);
                        }
                        CheckItem(theMenu, iWF, false);
                        CheckItem(theMenu, iCTSW, false);
                        CheckItem(theMenu, iCTHW, true);
                        theDocument->shaded = kQ3True;
                    }
                    break;
            }
            DrawOffscreen(theDocument) ;
            UpdateWindow( theDocument->theWindow ) ;
            if( theDocument->viewHints ) {
                Q3Object_Dispose(theDocument->viewHints);
            }
            theDocument->viewHints = Q3ViewHints_New(theDocument->theView);
            DoDrawGrowIcon(theDocument->theWindow) ;
            break ;
            
        // menu to allow modification of the backfacing style
        case idBackfacingMenu:
            switch(theItem) {
            
                case iDrawBoth:
 
                    Q3BackfacingStyle_Set(theDocument->backfacingStyle, kQ3BackfacingStyleBoth);
                    CheckItem(theMenu, iDrawBoth, true);
                    CheckItem(theMenu, iRemoveBackfacing, false);
                    CheckItem(theMenu, iFlipNormals, false);
                    break;
                    
                case iRemoveBackfacing:
                
                    Q3BackfacingStyle_Set(theDocument->backfacingStyle, kQ3BackfacingStyleRemove);
                    CheckItem(theMenu, iDrawBoth, false);
                    CheckItem(theMenu, iRemoveBackfacing, true);
                    CheckItem(theMenu, iFlipNormals, false);
                    break;
                    
                case iFlipNormals:
 
                    Q3BackfacingStyle_Set(theDocument->backfacingStyle, kQ3BackfacingStyleFlip);
                    CheckItem(theMenu, iDrawBoth, false);
                    CheckItem(theMenu, iRemoveBackfacing, false);
                    CheckItem(theMenu, iFlipNormals, true);
                    break;
                    
            }
 
            DrawOffscreen(theDocument);
            UpdateWindow( theDocument->theWindow ) ;
            
            // DrawControls(theDocument->theWindow);
            DoDrawGrowIcon(theDocument->theWindow);
            break;
        case idStyleMenu:
//          DisableUndoDrag();
            switch(theItem){
                case iFlat:
                    theDocument->currentInterpolation = kQ3InterpolationStyleNone;
                    CheckItem(theMenu, iGouraud, false);
                    CheckItem(theMenu, iPhong, false);
                    CheckItem(theMenu, iFlat, true);
                    break;
                case iGouraud:
                    theDocument->currentInterpolation = kQ3InterpolationStyleVertex;
                    CheckItem(theMenu, iPhong, false);
                    CheckItem(theMenu, iFlat, false);
                    CheckItem(theMenu, iGouraud, true);
                    break;
                case iPhong:
                    theDocument->currentInterpolation = kQ3InterpolationStylePixel;
                    CheckItem(theMenu, iGouraud, false);
                    CheckItem(theMenu, iFlat, false);
                    CheckItem(theMenu, iPhong, true);
                    break;
            }
            
            DrawOffscreen(theDocument);
            UpdateWindow( theDocument->theWindow ) ;
            DoDrawGrowIcon(theDocument->theWindow);
            break;
#ifdef PODIUM_APP
        case idSlides:
            switch(theItem){
                case iRotateModel:
                    if( theDocument->animateModel == kQ3True )
                        theDocument->animateModel = kQ3False ;
                    else
                        theDocument->animateModel = kQ3True ;
                    break ;
                case iHideShowMenu:
                    {
                        void ToggleMenuBar(void) ;
                        ToggleMenuBar() ;
                    }
                default:
                    break ;
            }
            break ;
#endif          
        
        default:
            break;
    }
 
//  if ((theDocument = GetDocumentFromWindow(FrontWindow())) != nil)
//      TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
 
    HiliteMenu(0);
}