Source/events.c

/*************************************************************************************
#
#       events.c
#
#       This segment handles the basic event calls.
#
#       Author(s):  Michael Marinkovich & Guillermo Ortiz
#                   marink@apple.com
#
#       Modification History: 
#
#           4/3/96      MWM     Initial coding                   
#
#       Copyright © 1992-96 Apple Computer, Inc., All Rights Reserved
#
#
#       You may incorporate this sample code into your applications without
#       restriction, though the sample code has been provided "AS IS" and the
#       responsibility for its operation is 100% yours.  However, what you are
#       not permitted to do is to redistribute the source as "DSC Sample 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 Code, but that you've made changes.
#
*************************************************************************************/
 
#include <Devices.h>
#include <DiskInit.h>
#include <Events.h>
#include <ToolUtils.h>
#include <Gestalt.h>
#include <OSUtils.h>
#include <Palettes.h>
 
#include "App.h"
#include "Proto.h"
 
extern Boolean      gInBackground;
extern Boolean      gDone;
extern Boolean      gHasAbout;      // have an about box?
 
 
//----------------------------------------------------------------------
//
//  EventLoop - main entry and loop for all event processing
//
//
//----------------------------------------------------------------------
 
void EventLoop(void)
{
    EventRecord     event;
    RgnHandle       cursorRgn;
    Boolean         gotEvent;
        
    gDone = false;
    cursorRgn = NewRgn();
        
    do 
    {
        gotEvent = WaitNextEvent(everyEvent,&event,MyGetSleep(),cursorRgn);
                                    
        if (gotEvent)
            DoEvent(&event);
 
                        
    } while ( !gDone );
        
    DisposeRgn(cursorRgn);
}
 
 
//----------------------------------------------------------------------
//
//  MyGetSleep - return sleep value based upon whether or not the app
//               is in the background.
//
//----------------------------------------------------------------------
 
short MyGetSleep(void)
{
    short       sleep = 30;
    
    if (gInBackground)
        sleep = 1L;
 
    return sleep;
 
}
 
 
//----------------------------------------------------------------------
//
//  CustomWindowEvent - Handles custom procs assigned to a window. 
//                      Different window kinds can easily have unique event
//                      handlers, ie. floaters, dialogs, documentprocs
//----------------------------------------------------------------------
 
void CustomWindowEvent(short eventType,WindowRef window,void *refCon)
{
    CustomProc      theProc;
    DocHnd          doc;
    short           kind;
    
    if (nil == window)
        return;
        
    kind = GetWindKind(window);
    if (kind < kDocKind || kind > kAboutKind)   // not our window
        return;
 
    doc = (DocHnd)GetWRefCon(window);
    
    if (doc != nil) 
    {
        HLockHi((Handle)doc);
        switch(eventType) 
        {
            case kIdleProc:
                theProc = (**doc).idleProc;
                break;
                
            case kMenuProc:
                theProc = (**doc).mMenuProc;
                break;
 
            case kInContentProc:
                theProc = (**doc).inContentProc;
                break;
 
            case kInGoAwayProc:
                theProc = (**doc).inGoAwayProc;
                break;
                
            case kInZoomProc:
                theProc = (**doc).inZoomProc;
                break;
                
            case kInGrowProc:
                theProc = (**doc).inGrowProc;
                break;
                
            case kMUpProc:
                theProc = (**doc).mUpProc;
                break;
                
            case kKeyProc:
                theProc = (**doc).keyProc;
                break;
            
            case kActivateProc:
                theProc = (**doc).activateProc;
                break;
 
            case kUpdateProc:
                theProc = (**doc).updateProc;
                break;
 
            default:
                theProc = nil;
                break;
        }       
    
        if (theProc != nil) 
        {
            (*theProc)(window,refCon);
            HUnlock((Handle)doc);
    
        }
    }   
    
    
}
 
 
//----------------------------------------------------------------------
//
//  DoEvent - event dispatcher, called by eventloop
//              
//
//----------------------------------------------------------------------
 
void DoEvent(EventRecord *event)
{
    OSErr           err;
    short           kind;
    long            menuChoice;
    Point           thePoint;
    Boolean         active;
    WindowRef       window;
    
    window = FrontWindow();
 
    switch(event->what) 
    {
        case nullEvent:
            CustomWindowEvent(kIdleProc, window, nil);
            break;
            
        case mouseDown:
            HandleMouseDown(event);
            break;
                            
        case mouseUp:
            break;
                            
        case keyDown:
        case autoKey:
            if (event->modifiers & cmdKey)  //  is cmd key down
            { 
                menuChoice = MenuKey(event->message & charCodeMask);
                kind = GetWindKind(window);
                if (kind < kDocKind || kind > kFloatKind)           // not our window
                    HandleMenuChoice(window, (void *)&menuChoice);  // default menu
                else    
                    CustomWindowEvent(kMenuProc, window, (void *)&menuChoice);
            }
            break;
                            
        case activateEvt:
            gInBackground = event->modifiers & activeFlag;
            active = gInBackground;
            CustomWindowEvent(kActivateProc, (WindowRef)event->message, &active);
            break;
                            
        case updateEvt:
            UpdateWindow((WindowRef)event->message);
            break;
                            
        case diskEvt:
            if (HiWord(event->message) != noErr) 
            {
                SetPt(&thePoint, 50, 50);
                err = DIBadMount(thePoint, event->message);
            }
            break;
                            
        case osEvt:
            switch ((event->message >> 24) & 0x0FF) 
            {       
                case suspendResumeMessage:  
                    gInBackground = event->message & resumeFlag;
                    active = gInBackground;
                    CustomWindowEvent(kActivateProc, FrontWindow(), &active);
                    break;
            }
            break;
    
        case kHighLevelEvent:
            AEProcessAppleEvent(event);
            break;
    }
 
}           
 
 
 
//----------------------------------------------------------------------
//
//  DoIdle - handle Idle events
//              
//
//----------------------------------------------------------------------
 
void DoIdle(WindowRef window, void *refCon)
{
    #pragma unused (window, refCon)
}
 
 
//----------------------------------------------------------------------
//
//  HandleMouseDown - 
//              
//
//----------------------------------------------------------------------
 
void HandleMouseDown(EventRecord *event)
{
    long            menuChoice;
    short           thePart;
    short           kind;
    WindowRef       window;
        
 
    thePart = FindWindow(event->where,&window);
        
    switch(thePart) 
    {
        case inMenuBar:
            menuChoice = MenuSelect(event->where);
            window = FrontWindow();
            kind = GetWindKind(window);
            if (kind < kDocKind || kind > kAboutKind)           // not our window
                HandleMenuChoice(window, (void *)&menuChoice);  // default menu
            else    
                CustomWindowEvent(kMenuProc, window, (void *)&menuChoice);
            break;
 
        case inContent:
            if (window != FrontWindow())
                SelectWindow(window);
            else
                CustomWindowEvent(kInContentProc, window, &event->where);
    
            break;
 
        case inSysWindow:
            SystemClick(event,window);
            break;
                                                
        case inDrag:
            if (window != FrontWindow())
                SelectWindow(window);
            DragWindow(window, event->where,&qd.screenBits.bounds);
            break;
                        
        case inGoAway:
            if (TrackGoAway(window, event->where))
                RemoveWindow(window);
            break;
                        
        case inZoomIn:
        case inZoomOut:
            if (TrackBox(window,event->where,thePart)) 
                CustomWindowEvent(kInZoomProc, window,&thePart);
            break;
                        
        case inGrow:
            CustomWindowEvent(kInGrowProc, window, &event->where);
            break;
    }
    
}
 
 
//----------------------------------------------------------------------
//
//  HandleMenuChoice - 
//              
//
//----------------------------------------------------------------------
 
void HandleMenuChoice(WindowRef window, void *refCon)
{
    OSErr       err = noErr;
    long        menuChoice;
    short       item, menu;
    short       daRefNum;
    Rect        bounds;
    Str255      daName;
    WindowRef   newWindow;
    
    
    menuChoice = *(long *)refCon;
    
    item = LoWord(menuChoice);
    menu = HiWord(menuChoice);
 
    switch(menu) {
        case mApple:
            switch(item) {
                case iAbout:
                    if ( !gHasAbout ) {
                        SetRect( &bounds,2, 40 ,352 ,140 );
                        newWindow = CreateWindow(nil, nil, &bounds, "\pAbout", true,
                                                 documentProc, kAboutKind, (WindowPtr)-1,
                                                 true, nil );
                        gHasAbout = true;
                    }                       
                    break;
                    
                default:
                    GetItem(GetMHandle(mApple),item,daName);
                    daRefNum = OpenDeskAcc( daName );
                    break;
            }   
            break;
                    
        case mFile:
            switch(item) {
                case iNew:
                    SetRect(&bounds,100,100,300,300);
                    newWindow = CreateWindow(128, nil, &bounds, nil, false,
                                            documentProc, kDocKind, (WindowPtr)-1,
                                            true, nil );
                    break;
                case iOpen:
                    DoOpenNew();
                    break;
                        
                case iSave:
                    err = SaveJPEG(window);
                    break;
 
                case iClose:
                    RemoveWindow(FrontWindow());
                    break;  
                        
                case iQuit:
                    gDone = true;
                    break;
                    
                default:
                    break;  
            }
            break;
                    
        default:
            break;  
        
    }
    
    HiliteMenu(0);
    
}
 
 
//----------------------------------------------------------------------
//
//  HandleContentClick - 
//              
//
//----------------------------------------------------------------------
 
void HandleContentClick(WindowRef window, void *refCon)
{
    ControlRef          control;
    ControlActionUPP    scrollUPP;
    Point               mouse;
    short               value;
    short               thePart;
    short               oldSetting;
    short               horzScroll,vertScroll;
    DocHnd              doc;
 
    doc = (DocHnd)GetWRefCon(window);
    if (doc != nil) {
        SetPort(window);
        mouse = *(Point *)refCon;
        GlobalToLocal(&mouse);
        horzScroll = vertScroll = 0;
 
        if ((thePart = FindControl(mouse, window, &control)) != 0) {
            switch(thePart) {
                case inThumb:
                    oldSetting = GetCtlValue(control);
                    thePart = TrackControl(control, mouse, 0L);
                    if (thePart != 0) {
                        value = oldSetting - GetCtlValue(control);
                        if (value != 0){
                            if (control == (**doc).hScroll)
                                horzScroll = value ;
                            if (control == (**doc).vScroll)
                                vertScroll = value;
                            MyScrollPicture(window, horzScroll, vertScroll);
                        }
                    }
                    break;
                case inUpButton:
                case inDownButton:
                case inPageUp:
                case inPageDown:
                    scrollUPP = NewControlActionProc(ScrollActionProc);
                    value = TrackControl(control, mouse, scrollUPP);
                    break;
    
            }
        }
    }
 
}
 
 
//----------------------------------------------------------------------
//
//  HandleZoomClick - 
//              
//
//----------------------------------------------------------------------
 
void HandleZoomClick(WindowRef window, void *refCon)
{
    short           part;
    DocHnd          doc;
    
    doc = (DocHnd)GetWRefCon(window);
    if (doc != nil) {
        part = *(short *)refCon;
        SetPort(window);
        
        EraseRect(&window->portRect);
        ZoomWindow(window,part,true);
        ClipRect(&window->portRect);
        InvalRect(&window->portRect);
        
        HideControl((**doc).hScroll);
        HideControl((**doc).vScroll);
        
        AdjustScrollbars(window, true);
        
        ShowControl((**doc).hScroll);
        ShowControl((**doc).vScroll);
        
    }
}
 
 
//----------------------------------------------------------------------
//
//  HandleGrow - 
//              
//
//----------------------------------------------------------------------
 
void HandleGrow(WindowRef window, void *refCon)
{
    Rect            gIRect;
    Rect            limitRect;
    long            growSize;
        
    limitRect = (**GetGrayRgn()).rgnBBox;
    limitRect.left += 125;
    limitRect.top += 125;
 
    growSize = GrowWindow(window, *(Point *)refCon, &limitRect);
    if (growSize) {
        SetPort(window);    
        gIRect = window->portRect;
        gIRect.top = gIRect.bottom - kScrollWidth;
        gIRect.left = gIRect.right - kScrollWidth;  
        EraseRect(&gIRect);
        SizeWindow(window,LoWord(growSize),HiWord(growSize),true);
        
        ClipRect(&window->portRect);
        AdjustScrollbars(window, true);
        InvalRect(&window->portRect);
    }
 
}
 
 
//----------------------------------------------------------------------
//
//  UpdateWindow - update dispatcher for document windows.
//               
//
//----------------------------------------------------------------------
 
void UpdateWindow(WindowRef window) 
{
    GrafPtr     oldPort;
    
    
    GetPort(&oldPort);
    
    SetPort(window);
    BeginUpdate(window);
    CustomWindowEvent(kUpdateProc, window, nil);
    EndUpdate(window);
    
    SetPort(oldPort);
 
}
 
 
//----------------------------------------------------------------------
//
//  DoActivate - 
//               
//
//----------------------------------------------------------------------
 
void DoActivate(WindowRef window, void *refCon)
{
    Boolean     becomingActive;
    DocHnd      doc;
    
    SetPort(window);
        
    doc = (DocHnd)GetWRefCon(window);
 
    if(doc != nil && GetIsAppWindow(window)) {
        becomingActive = *(Boolean *)refCon;
        if (becomingActive) {
            DrawGrowIcon(window);
            ShowControl((**doc).hScroll);
            ShowControl((**doc).vScroll);
        }
        else {
            HideControl((**doc).hScroll);
            HideControl((**doc).vScroll);
            DrawGrowIcon(window);
        }
    }
    
}