home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / mac / MAC / System Extensions / Macintosh Drag and Drop 1.1.1 / Demo Applications / DragText Sources / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-14  |  10.4 KB  |  490 lines  |  [TEXT/KAHL]

  1. /*
  2.  *
  3.  *        event.c
  4.  *
  5.  *        Event handling routines.
  6.  *        
  7.  *
  8.  *        Author:        Rob Johnston
  9.  *        Date:        Monday, Janurary 20, 1992
  10.  *
  11.  *        Copyright © 1992 Apple Computer, Inc.
  12.  *
  13.  */
  14.  
  15.  
  16. /*
  17.  *    Debugging Aids :
  18.  *
  19.  *    Turn this flag on to see where the current hilite region is.
  20.  *
  21.  *        #define    _FLASH_HILITE_RGN_
  22.  *
  23.  */
  24.  
  25.  
  26. #include <Drag.h>
  27. #include "globals.h"
  28. #include "prototypes.h"
  29. #include "resources.h"
  30. #include "AppleEvents.h"
  31.  
  32.  
  33. #define    SleepDuration        20        /* WaitNextEvent sleep constant        */
  34.  
  35.  
  36. /*
  37.  *    DoContent handles mouseDown events in the content region of a document window.
  38.  *
  39.  *    (1)    If the mouseDown is on a control, handle the click by calling TrackControl.
  40.  *
  41.  *    (2)    If the mouseDown is on a draggable object (the document's hiliteRgn) and a
  42.  *        successful drag occurs, no further processing is necessary.
  43.  *
  44.  *    (3)    If the mouseDown is on a draggable object and the mouse is released without
  45.  *        dragging, set the insertion point to the original mouseDown location by calling
  46.  *        TEClick with the mouseDown information.
  47.  *
  48.  *    (4)    If the mouseDown is not on a draggable object and within the viewRect of the
  49.  *        TextEdit field, call TEClick to handle the mouseDown.
  50.  */
  51.  
  52. void DoContent(Document *theDocument, EventRecord *theEvent)
  53.  
  54. {    short            thePart;
  55.     Point            thePoint;
  56.     ControlHandle    theControl;
  57.  
  58.     SetPort(theDocument->theWindow);
  59.     thePoint = theEvent->where;
  60.     GlobalToLocal(&thePoint);
  61.  
  62.     if (thePart = FindControl(thePoint, theDocument->theWindow, &theControl)) {
  63.         if (theControl == theDocument->vScroll) {
  64.             if (thePart == inThumb) {
  65.                 TrackControl(theControl, thePoint, 0L);
  66.                 AdjustDocumentView(theDocument);
  67.             } else {
  68.                 TrackControl(theControl, thePoint, &ScrollProc);
  69.             }
  70.             AdjustScrollBar(theDocument);
  71.         }
  72.     } else if (PtInRgn(thePoint, theDocument->hiliteRgn)) {
  73.         if (!DragText(theDocument, theEvent, theDocument->hiliteRgn)) {
  74.             TEClick(thePoint, false, theDocument->theTE);
  75.         }
  76.     } else if (PtInRect(thePoint, &(**(theDocument->theTE)).viewRect)) {
  77.             TEClick(thePoint, (theEvent->modifiers & shiftKey) != 0,
  78.                     theDocument->theTE);
  79.     }
  80.  
  81.     TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
  82. }
  83.  
  84.  
  85. /*
  86.  *    DoBackgroundContent handles mouseDown events in the content region of a document window
  87.  *    when the window is not frontmost. The following bullet items describe how this background
  88.  *    mouseDown event is handled:
  89.  *
  90.  *    (1)    If the mouseDown is not in a draggable object (not in the document's hiliteRgn) call
  91.  *        SelectWindow to bring the window to the front as usual.
  92.  *
  93.  *    (2)    If the mouseDown is in a draggable object and the mouse is released without
  94.  *        dragging, call SelectWindow when the mouse is released.
  95.  *
  96.  *    (3)    If the mouseDown is in a draggable object and a successful drag occurs, SelectWindow
  97.  *        should only be called if the drop occurred in the same window (the DragText function
  98.  *        calls SelectWindow in this case).
  99.  */
  100.  
  101. void DoBackgroundContent(Document *theDocument, EventRecord *theEvent)
  102.  
  103. {    short            thePart;
  104.     Point            thePoint;
  105.     ControlHandle    theControl;
  106.  
  107.     SetPort(theDocument->theWindow);
  108.     thePoint = theEvent->where;
  109.     GlobalToLocal(&thePoint);
  110.  
  111.     if (PtInRgn(thePoint, theDocument->hiliteRgn)) {
  112.  
  113.         if (! DragText(theDocument, theEvent, theDocument->hiliteRgn)) {
  114.             SelectWindow(theDocument->theWindow);
  115.         }
  116.  
  117.     } else {
  118.  
  119.         SelectWindow(theDocument->theWindow);
  120.  
  121.     }
  122. }
  123.  
  124.  
  125. /*
  126.  *    DoMouseDown is called to handle mouseDown events.
  127.  */
  128.  
  129. void DoMouseDown(EventRecord *theEvent)
  130.  
  131. {    short        thePart;
  132.     WindowPtr    theWindow;
  133.     Rect        dragRect;
  134.     Document    *theDocument;
  135.  
  136.     thePart = FindWindow(theEvent->where, &theWindow);
  137.     switch(thePart) {
  138.         case inMenuBar:
  139.             PrepareMenus();
  140.             DoMenuCommand(MenuSelect(theEvent->where));
  141.             break;
  142.         case inSysWindow:
  143.             SystemClick(theEvent, theWindow);
  144.             break;
  145.         case inContent:
  146.             theDocument = IsDocumentWindow(theWindow);
  147.             if (theWindow == FrontWindow()) {
  148.                 DoContent(theDocument, theEvent);
  149.             } else {
  150.                 DoBackgroundContent(theDocument, theEvent);
  151.             }
  152.             break;
  153.         case inDrag:
  154.             if (theWindow != FrontWindow())
  155.                 SelectWindow(theWindow);
  156.             dragRect = screenBits.bounds;
  157.             DragWindow(theWindow, theEvent->where, &dragRect);
  158.             break;
  159.         case inGrow:
  160.             if (theDocument = IsDocumentWindow(theWindow)) {
  161.                 GrowDocumentWindow(theWindow, theEvent->where);
  162.                 TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
  163.             }
  164.             break;
  165.         case inGoAway:
  166.             if (theDocument = IsDocumentWindow(theWindow))
  167.                 if (TrackGoAway(theWindow, theEvent->where)) {
  168.                     CloseDocument(theDocument);
  169.                     PrepareMenus();
  170.                     DrawMenuBar();
  171.                 }
  172.             break;
  173.     }
  174. }
  175.  
  176.  
  177. /*
  178.  *    DoKey is called each time a character is typed on the keyboard to
  179.  *    be entered into a document window.
  180.  */
  181.  
  182. void DoKey(char theChar)
  183.  
  184. {    WindowPtr        theWindow;
  185.     Document        *theDocument;
  186.  
  187.     if (theWindow = FrontWindow()) {
  188.         if (theDocument = IsDocumentWindow(theWindow)) {
  189.             SetPort(theDocument->theWindow);
  190.             TEKey(theChar, theDocument->theTE);
  191.             AdjustScrollBar(theDocument);
  192.             theDocument->dirty = true;
  193.             TEGetHiliteRgn(theDocument->hiliteRgn, theDocument->theTE);
  194.  
  195.             if ((theChar < 0x1C) || (theChar > 0x1F)) {
  196.                 DisableUndoDrag();
  197.             }
  198.         }
  199.     }
  200. }
  201.  
  202.  
  203. /*
  204.  *    DoKeyDown is called to handle keyDown or autoKey events.
  205.  */
  206.  
  207. void DoKeyDown(EventRecord *theEvent)
  208.  
  209. {    char        theChar;
  210.  
  211.     theChar = theEvent->message & charCodeMask;
  212.  
  213.     if (theEvent->modifiers & cmdKey) {
  214.         PrepareMenus();
  215.         DoMenuCommand(MenuKey(theChar));
  216.     } else {
  217.         DoKey(theChar);
  218.     }
  219. }
  220.  
  221.  
  222. /*
  223.  *    DoActivate is called in response to activate/deactivate events.
  224.  */
  225.  
  226. void DoActivate(EventRecord *theEvent)
  227.  
  228. {    WindowPtr        theWindow;
  229.     Document        *theDocument;
  230.  
  231.     if (theWindow = (WindowPtr) theEvent->message) {
  232.         if (theDocument = IsDocumentWindow(theWindow)) {
  233.             DoActivateDocument(theDocument, (theEvent->modifiers & activeFlag));
  234.         }
  235.     }
  236. }
  237.  
  238.  
  239. /*
  240.  *    DoUpdate is called in response to update events.
  241.  */
  242.  
  243. void DoUpdate(EventRecord *theEvent)
  244.  
  245. {    Document    *theDocument;
  246.  
  247.     if (theDocument = IsDocumentWindow((WindowPtr) theEvent->message))
  248.         UpdateWindow(theDocument);
  249. }
  250.  
  251.  
  252. /*
  253.  *    DoOSEvent is called in response to Operating System events.
  254.  */
  255.  
  256. void DoOSEvent(EventRecord *theEvent)
  257.  
  258. {    Document        *theDocument;
  259.  
  260.     switch ((theEvent->message >> 24) & 0x0FF) {
  261.         case suspendResumeMessage:
  262.             gInBackground = (theEvent->message & resumeFlag) == 0;
  263.             if (theDocument = IsDocumentWindow(FrontWindow()))
  264.                 DoActivateDocument(theDocument, !gInBackground);
  265.             break;
  266.     }
  267. }
  268.  
  269.  
  270. pascal OSErr MyHandleOAPP(AppleEvent theAppleEvent, AppleEvent reply, long handlerRefCon)
  271.  
  272. {
  273.     DoNewDocument();
  274. }
  275.  
  276.  
  277. pascal OSErr MyHandleODOC(AppleEvent theAppleEvent, AppleEvent reply, long handlerRefCon)
  278.  
  279. {    AEDescList        docList;
  280.     AEKeyword        keyword;
  281.     DescType        returnedType;
  282.     FSSpec            theFSSpec;
  283.     Size            actualSize;
  284.     long            itemsInList;
  285.     short            index;
  286.     OSErr            result;
  287.  
  288.     if (result = AEGetParamDesc(&theAppleEvent, keyDirectObject, typeAEList, &docList))
  289.         return(result);
  290.  
  291.     if (result = AECountItems(&docList, &itemsInList))
  292.         return(result);
  293.  
  294.     for (index = 1; index <= itemsInList; index++) {
  295.         if (result = AEGetNthPtr(&docList, index, typeFSS, &keyword,
  296.                                  &returnedType, (Ptr) &theFSSpec, sizeof(FSSpec), &actualSize))
  297.             return(result);
  298.  
  299.         DoOpenFile(&theFSSpec);
  300.     }
  301.     
  302. }
  303.  
  304.  
  305. pascal OSErr MyHandleQUIT(AppleEvent theAppleEvent, AppleEvent reply, long handlerRefCon)
  306.  
  307. {    Document        *theDocument;
  308.  
  309.     gQuitting = true;
  310.     while ((gQuitting) && (theDocument = IsDocumentWindow(FrontWindow()))) {
  311.         CloseDocument(theDocument);
  312.     }
  313.     if (gQuitting)
  314.         gQuit = true;
  315. }
  316.  
  317.  
  318. /*
  319.  *    InitEvents
  320.  */
  321.  
  322. void InitEvents()
  323.  
  324. {
  325.     AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, MyHandleOAPP, 0, false);
  326.     AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, MyHandleODOC, 0, false);
  327.     AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, MyHandleQUIT, 0, false);
  328. }
  329.  
  330.  
  331. /*
  332.  *    ScrollProc is the function used in a call to TrackControl for
  333.  *    scrolling a document window.
  334.  */
  335.  
  336. pascal void ScrollProc(ControlHandle theControl, short theCode)
  337.  
  338. {    short        delta = 0, pageDelta;
  339.     Document    *theDocument;
  340.     Rect        viewRect;
  341.  
  342.     if (theCode == 0)
  343.         return;
  344.  
  345.     theDocument = (Document *) (**theControl).contrlRfCon;
  346.     viewRect = (**(theDocument->theTE)).viewRect;
  347.     pageDelta = ((viewRect.bottom - viewRect.top) / ScrollResolution) - 1;
  348.  
  349.     switch(theCode) {
  350.         case inUpButton:
  351.             delta = -1;
  352.             break;
  353.         case inDownButton:
  354.             delta = 1;
  355.             break;
  356.         case inPageUp:
  357.             delta = -pageDelta;
  358.             break;
  359.         case inPageDown:
  360.             delta = pageDelta;
  361.             break;
  362.     }
  363.  
  364.     SetCtlValue(theControl, GetCtlValue(theControl) + delta);
  365.     AdjustDocumentView((Document *) (**theControl).contrlRfCon);
  366. }
  367.  
  368.  
  369. /*
  370.  *
  371.  */
  372.  
  373. void DoHighLevelEvent(EventRecord *theEvent)
  374.  
  375. {
  376.     AEProcessAppleEvent(theEvent);
  377. }
  378.  
  379.  
  380. /*
  381.  *    Each time WaitNextEvent returns an event to this application, DoEvent
  382.  *    is called to handle the event.
  383.  */
  384.  
  385. void DoEvent(EventRecord *theEvent)
  386.  
  387. {    WindowPtr        theWindow;
  388.     Document        *theDocument;
  389.  
  390.     if (theWindow = FrontWindow()) {
  391.         if (theDocument = IsDocumentWindow(theWindow)) {
  392.             gFrontDocument = theDocument;
  393.         }
  394.     }
  395.  
  396.     switch(theEvent->what) {
  397.         case mouseDown:
  398.             DoMouseDown(theEvent);
  399.             break;
  400.         case mouseUp:
  401.             break;
  402.         case keyDown:
  403.         case autoKey:
  404.             DoKeyDown(theEvent);
  405.             break;
  406.         case activateEvt:
  407.             DoActivate(theEvent);
  408.             break;
  409.         case updateEvt:
  410.             DoUpdate(theEvent);
  411.             break;
  412.         case osEvt:
  413.             DoOSEvent(theEvent);
  414.             break;
  415.         case kHighLevelEvent:
  416.             DoHighLevelEvent(theEvent);
  417.             break;
  418.     }
  419. }
  420.  
  421.  
  422. /*
  423.  *    DoIdle get called repetitively while the application is not doing
  424.  *    anything.
  425.  */
  426.  
  427. void DoIdle()
  428.  
  429. {    WindowPtr        theWindow;
  430.     Document        *theDocument;
  431.  
  432.     if (theWindow = FrontWindow()) {
  433.         if (theDocument = IsDocumentWindow(theWindow)) {
  434.             SetPort(theDocument->theWindow);
  435.             TEIdle(theDocument->theTE);
  436.  
  437. #ifdef _FLASH_HILITE_RGN_
  438.  
  439.             {    long            dTime;
  440.  
  441.                 InvertRgn(theDocument->hiliteRgn);
  442.                 Delay(10, &dTime);
  443.                 InvertRgn(theDocument->hiliteRgn);
  444.             }
  445. #endif
  446.  
  447.         }
  448.     }
  449. }
  450.  
  451.  
  452. /*
  453.  *    This is the main event loop of the program. It calls WaitNextEvent
  454.  *    and dispatches the returned event until gQuit is true.
  455.  */
  456.  
  457. void EventLoop()
  458.  
  459. {    short            gotEvent;
  460.     EventRecord        theEvent;
  461.     RgnHandle        theMouseRgn;
  462.     Point            theLoc;
  463.  
  464.     theMouseRgn = NewRgn();
  465.  
  466.     do {
  467.  
  468.         //
  469.         //    Removed this AdjustCursor because it would sometimes set cursor to I-Beam
  470.         //    just before receiving a drag event. I don't think its really needed anyway.
  471.         //
  472.  
  473. //        GetGlobalMouse(&theLoc);
  474. //        AdjustCursor(theLoc, theMouseRgn);
  475.  
  476.         gotEvent = WaitNextEvent(everyEvent, &theEvent, SleepDuration, theMouseRgn);
  477.  
  478.         if (gotEvent) {
  479.             AdjustCursor(theEvent.where, theMouseRgn);
  480.             DoEvent(&theEvent);
  481.             AdjustCursor(theEvent.where, theMouseRgn);
  482.         } else {
  483.             DoIdle();
  484.         }
  485.     } while (! gQuit);
  486.  
  487.     DisposeRgn(theMouseRgn);
  488. }
  489.  
  490.