home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * event.c
- *
- * Event handling routines.
- *
- *
- * Author: Rob Johnston
- * Date: Monday, Janurary 20, 1992
- *
- * Copyright © 1992 Apple Computer, Inc.
- *
- */
-
-
- /*
- * Debugging Aids :
- *
- * Turn this flag on to see where the current hilite region is.
- *
- * #define _FLASH_HILITE_RGN_
- *
- */
-
-
- #include <Drag.h>
- #include "globals.h"
- #include "prototypes.h"
- #include "resources.h"
- #include "AppleEvents.h"
-
-
- #define SleepDuration 20 /* WaitNextEvent sleep constant */
-
-
- /*
- * DoContent handles mouseDown events in the content region of a document window.
- *
- * (1) If the mouseDown is on a control, handle the click by calling TrackControl.
- *
- * (2) If the mouseDown is on a draggable object (the document's hiliteRgn) and a
- * successful drag occurs, no further processing is necessary.
- *
- * (3) If the mouseDown is on a draggable object and the mouse is released without
- * dragging, set the insertion point to the original mouseDown location by calling
- * TEClick with the mouseDown information.
- *
- * (4) If the mouseDown is not on a draggable object and within the viewRect of the
- * TextEdit field, call TEClick to handle the mouseDown.
- */
-
- void DoContent(Document *theDocument, EventRecord *theEvent)
-
- { short thePart;
- Point thePoint;
- ControlHandle theControl;
-
- SetPort(theDocument->theWindow);
- thePoint = theEvent->where;
- GlobalToLocal(&thePoint);
-
- if (thePart = FindControl(thePoint, theDocument->theWindow, &theControl)) {
- if (theControl == theDocument->vScroll) {
- if (thePart == inThumb) {
- TrackControl(theControl, thePoint, 0L);
- AdjustDocumentView(theDocument);
- } else {
- TrackControl(theControl, thePoint, &ScrollProc);
- }
- AdjustScrollBar(theDocument);
- }
- } else if (PtInRgn(thePoint, theDocument->hiliteRgn)) {
- if (!DragText(theDocument, theEvent, theDocument->hiliteRgn)) {
- TEClick(thePoint, false, theDocument->theTE);
- }
- } else if (PtInRect(thePoint, &(**(theDocument->theTE)).viewRect)) {
- TEClick(thePoint, (theEvent->modifiers & shiftKey) != 0,
- theDocument->theTE);
- }
-
- TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
- }
-
-
- /*
- * DoBackgroundContent handles mouseDown events in the content region of a document window
- * when the window is not frontmost. The following bullet items describe how this background
- * mouseDown event is handled:
- *
- * (1) If the mouseDown is not in a draggable object (not in the document's hiliteRgn) call
- * SelectWindow to bring the window to the front as usual.
- *
- * (2) If the mouseDown is in a draggable object and the mouse is released without
- * dragging, call SelectWindow when the mouse is released.
- *
- * (3) If the mouseDown is in a draggable object and a successful drag occurs, SelectWindow
- * should only be called if the drop occurred in the same window (the DragText function
- * calls SelectWindow in this case).
- */
-
- void DoBackgroundContent(Document *theDocument, EventRecord *theEvent)
-
- { short thePart;
- Point thePoint;
- ControlHandle theControl;
-
- SetPort(theDocument->theWindow);
- thePoint = theEvent->where;
- GlobalToLocal(&thePoint);
-
- if (PtInRgn(thePoint, theDocument->hiliteRgn)) {
-
- if (! DragText(theDocument, theEvent, theDocument->hiliteRgn)) {
- SelectWindow(theDocument->theWindow);
- }
-
- } else {
-
- SelectWindow(theDocument->theWindow);
-
- }
- }
-
-
- /*
- * DoMouseDown is called to handle mouseDown events.
- */
-
- void DoMouseDown(EventRecord *theEvent)
-
- { short thePart;
- WindowPtr theWindow;
- Rect dragRect;
- Document *theDocument;
-
- thePart = FindWindow(theEvent->where, &theWindow);
- switch(thePart) {
- case inMenuBar:
- PrepareMenus();
- DoMenuCommand(MenuSelect(theEvent->where));
- break;
- case inSysWindow:
- SystemClick(theEvent, theWindow);
- break;
- case inContent:
- theDocument = IsDocumentWindow(theWindow);
- if (theWindow == FrontWindow()) {
- DoContent(theDocument, theEvent);
- } else {
- DoBackgroundContent(theDocument, theEvent);
- }
- break;
- case inDrag:
- if (theWindow != FrontWindow())
- SelectWindow(theWindow);
- dragRect = screenBits.bounds;
- DragWindow(theWindow, theEvent->where, &dragRect);
- break;
- case inGrow:
- if (theDocument = IsDocumentWindow(theWindow)) {
- GrowDocumentWindow(theWindow, theEvent->where);
- TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
- }
- break;
- case inGoAway:
- if (theDocument = IsDocumentWindow(theWindow))
- if (TrackGoAway(theWindow, theEvent->where)) {
- CloseDocument(theDocument);
- PrepareMenus();
- DrawMenuBar();
- }
- break;
- }
- }
-
-
- /*
- * DoKey is called each time a character is typed on the keyboard to
- * be entered into a document window.
- */
-
- void DoKey(char theChar)
-
- { WindowPtr theWindow;
- Document *theDocument;
-
- if (theWindow = FrontWindow()) {
- if (theDocument = IsDocumentWindow(theWindow)) {
- SetPort(theDocument->theWindow);
- TEKey(theChar, theDocument->theTE);
- AdjustScrollBar(theDocument);
- theDocument->dirty = true;
- TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
-
- if ((theChar < 0x1C) || (theChar > 0x1F)) {
- DisableUndoDrag();
- }
- }
- }
- }
-
-
- /*
- * DoKeyDown is called to handle keyDown or autoKey events.
- */
-
- void DoKeyDown(EventRecord *theEvent)
-
- { char theChar;
-
- theChar = theEvent->message & charCodeMask;
-
- if (theEvent->modifiers & cmdKey) {
- PrepareMenus();
- DoMenuCommand(MenuKey(theChar));
- } else {
- DoKey(theChar);
- }
- }
-
-
- /*
- * DoActivate is called in response to activate/deactivate events.
- */
-
- void DoActivate(EventRecord *theEvent)
-
- { WindowPtr theWindow;
- Document *theDocument;
-
- if (theWindow = (WindowPtr) theEvent->message) {
- if (theDocument = IsDocumentWindow(theWindow)) {
- DoActivateDocument(theDocument, (theEvent->modifiers & activeFlag));
- }
- }
- }
-
-
- /*
- * DoUpdate is called in response to update events.
- */
-
- void DoUpdate(EventRecord *theEvent)
-
- { Document *theDocument;
-
- if (theDocument = IsDocumentWindow((WindowPtr) theEvent->message))
- UpdateWindow(theDocument);
- }
-
-
- /*
- * DoOSEvent is called in response to Operating System events.
- */
-
- void DoOSEvent(EventRecord *theEvent)
-
- { Document *theDocument;
-
- switch ((theEvent->message >> 24) & 0x0FF) {
- case suspendResumeMessage:
- gInBackground = (theEvent->message & resumeFlag) == 0;
- if (theDocument = IsDocumentWindow(FrontWindow()))
- DoActivateDocument(theDocument, !gInBackground);
- break;
- }
- }
-
-
- pascal OSErr MyHandleOAPP(AppleEvent theAppleEvent, AppleEvent reply, long handlerRefCon)
-
- {
- DoNewDocument();
- }
-
-
- pascal OSErr MyHandleODOC(AppleEvent theAppleEvent, AppleEvent reply, long handlerRefCon)
-
- { AEDescList docList;
- AEKeyword keyword;
- DescType returnedType;
- FSSpec theFSSpec;
- Size actualSize;
- long itemsInList;
- short index;
- OSErr result;
-
- if (result = AEGetParamDesc(&theAppleEvent, keyDirectObject, typeAEList, &docList))
- return(result);
-
- if (result = AECountItems(&docList, &itemsInList))
- return(result);
-
- for (index = 1; index <= itemsInList; index++) {
- if (result = AEGetNthPtr(&docList, index, typeFSS, &keyword,
- &returnedType, (Ptr) &theFSSpec, sizeof(FSSpec), &actualSize))
- return(result);
-
- DoOpenFile(&theFSSpec);
- }
-
- }
-
-
- pascal OSErr MyHandleQUIT(AppleEvent theAppleEvent, AppleEvent reply, long handlerRefCon)
-
- { Document *theDocument;
-
- gQuitting = true;
- while ((gQuitting) && (theDocument = IsDocumentWindow(FrontWindow()))) {
- CloseDocument(theDocument);
- }
- if (gQuitting)
- gQuit = true;
- }
-
-
- /*
- * InitEvents
- */
-
- void InitEvents()
-
- {
- AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, MyHandleOAPP, 0, false);
- AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, MyHandleODOC, 0, false);
- AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, MyHandleQUIT, 0, false);
- }
-
-
- /*
- * ScrollProc is the function used in a call to TrackControl for
- * scrolling a document window.
- */
-
- pascal void ScrollProc(ControlHandle theControl, short theCode)
-
- { short delta = 0, pageDelta;
- Document *theDocument;
- Rect viewRect;
-
- if (theCode == 0)
- return;
-
- theDocument = (Document *) (**theControl).contrlRfCon;
- viewRect = (**(theDocument->theTE)).viewRect;
- pageDelta = ((viewRect.bottom - viewRect.top) / ScrollResolution) - 1;
-
- switch(theCode) {
- case inUpButton:
- delta = -1;
- break;
- case inDownButton:
- delta = 1;
- break;
- case inPageUp:
- delta = -pageDelta;
- break;
- case inPageDown:
- delta = pageDelta;
- break;
- }
-
- SetCtlValue(theControl, GetCtlValue(theControl) + delta);
- AdjustDocumentView((Document *) (**theControl).contrlRfCon);
- }
-
-
- /*
- *
- */
-
- void DoHighLevelEvent(EventRecord *theEvent)
-
- {
- AEProcessAppleEvent(theEvent);
- }
-
-
- /*
- * Each time WaitNextEvent returns an event to this application, DoEvent
- * is called to handle the event.
- */
-
- void DoEvent(EventRecord *theEvent)
-
- { WindowPtr theWindow;
- Document *theDocument;
-
- if (theWindow = FrontWindow()) {
- if (theDocument = IsDocumentWindow(theWindow)) {
- gFrontDocument = theDocument;
- }
- }
-
- switch(theEvent->what) {
- case mouseDown:
- DoMouseDown(theEvent);
- break;
- case mouseUp:
- break;
- case keyDown:
- case autoKey:
- DoKeyDown(theEvent);
- break;
- case activateEvt:
- DoActivate(theEvent);
- break;
- case updateEvt:
- DoUpdate(theEvent);
- break;
- case osEvt:
- DoOSEvent(theEvent);
- break;
- case kHighLevelEvent:
- DoHighLevelEvent(theEvent);
- break;
- }
- }
-
-
- /*
- * DoIdle get called repetitively while the application is not doing
- * anything.
- */
-
- void DoIdle()
-
- { WindowPtr theWindow;
- Document *theDocument;
-
- if (theWindow = FrontWindow()) {
- if (theDocument = IsDocumentWindow(theWindow)) {
- SetPort(theDocument->theWindow);
- TEIdle(theDocument->theTE);
-
- #ifdef _FLASH_HILITE_RGN_
-
- { long dTime;
-
- InvertRgn(theDocument->hiliteRgn);
- Delay(10, &dTime);
- InvertRgn(theDocument->hiliteRgn);
- }
- #endif
-
- }
- }
- }
-
-
- /*
- * This is the main event loop of the program. It calls WaitNextEvent
- * and dispatches the returned event until gQuit is true.
- */
-
- void EventLoop()
-
- { short gotEvent;
- EventRecord theEvent;
- RgnHandle theMouseRgn;
- Point theLoc;
-
- theMouseRgn = NewRgn();
-
- do {
-
- //
- // Removed this AdjustCursor because it would sometimes set cursor to I-Beam
- // just before receiving a drag event. I don't think its really needed anyway.
- //
-
- // GetGlobalMouse(&theLoc);
- // AdjustCursor(theLoc, theMouseRgn);
-
- gotEvent = WaitNextEvent(everyEvent, &theEvent, SleepDuration, theMouseRgn);
-
- if (gotEvent) {
- AdjustCursor(theEvent.where, theMouseRgn);
- DoEvent(&theEvent);
- AdjustCursor(theEvent.where, theMouseRgn);
- } else {
- DoIdle();
- }
- } while (! gQuit);
-
- DisposeRgn(theMouseRgn);
- }
-
-