home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / scnote / ooptsamp.013 / UTESample.inc1.p < prev    next >
Encoding:
Text File  |  1989-10-01  |  9.8 KB  |  375 lines

  1. {---------------------------------------------------------------------
  2. #
  3. #    Apple Macintosh Developer Technical Support
  4. #
  5. #    MultiFinder-Aware Simple TextEdit Sample Application
  6. #
  7. #    OOPTESample
  8. #
  9. #    UTESample.inc1.p        -    Pascal Source
  10. #
  11. #    Copyright ⌐ 1988, 1989 Apple Computer, Inc.
  12. #    All rights reserved.
  13. #
  14. #    Version:        
  15. #                    1.10                    10/89
  16. #                    1.00                    04/89
  17. #
  18. #    Components:     
  19. #                    BuildOOPTESample        October 1, 1989
  20. #                    MOOPTESample.p            October 1, 1989
  21. #                    OOPTESample.make        October 1, 1989
  22. #                    TECommon.h                October 1, 1989
  23. #                    TESampleGlue.a            October 1, 1989
  24. #                    TESample.r                October 1, 1989
  25. #                    UApplication.p            October 1, 1989
  26. #                    UApplication.inc1.p        October 1, 1989
  27. #                    UDocument.p                October 1, 1989
  28. #                    UDocument.inc1.p        October 1, 1989
  29. #                    UTEDocument.p            October 1, 1989
  30. #                    UTEDocument.inc1.p        October 1, 1989
  31. #                    UTESample.p                October 1, 1989
  32. #                    UTESample.inc1.p        October 1, 1989
  33. #
  34. ---------------------------------------------------------------------}
  35.  
  36. CONST
  37.     rMenuBar    = 128;
  38.     rDocWindow    = 128;                { application's window }
  39.     rAboutAlert    = 128;                { about alert }
  40.  
  41.     { The following constants are used to identify menus and their items. The menu IDs }
  42.     { have an "m" prefix and the item numbers within each menu have an "i" prefix. }
  43.     mApple        = 128;                {Apple menu}
  44.     iAbout        = 1;
  45.  
  46.     mFile        = 129;                { File menu }
  47.     iNew        = 1;
  48.     iClose        = 4;
  49.     iQuit        = 12;
  50.  
  51.     mEdit        = 130;                { Edit menu }
  52.     iUndo        = 1;
  53.     iCut        = 3;
  54.     iCopy        = 4;
  55.     iPaste        = 5;
  56.     iClear        = 6;
  57.  
  58.     kMinSize        = 40;
  59.     kMaxSleepTime    = 60;
  60.     kSleepTime        = $7FFFFFFF;
  61.  
  62.     kExtremePos        = 32767 - 1;    { required for old region bug }
  63.     kExtremeNeg        = -32768;        {kExtremePos and kExtremeNeg are used to set up
  64.                                     wide open rectangles and regions.}
  65.  
  66.     kMaxOpenDocuments        = 1;    {kMaxOpenDocuments is used to determine whether
  67.                                     a new document can be opened or created. We keep
  68.                                     track of the number of open documents, and disable
  69.                                     the menu items that create a new document when the
  70.                                     maximum is reached. If the number of documents falls
  71.                                     below the maximum, the items are enabled again.}
  72.  
  73. (********************************************************************************************)
  74. (*        T T E S a m p l e                                                                    *)
  75. (********************************************************************************************)
  76. {$S Initialize}
  77. {-----------------------------------+
  78. |    ITESample                        |
  79. +-----------------------------------}
  80. PROCEDURE TTESample.ITESample;
  81. VAR
  82.     menuBar: Handle;
  83. BEGIN
  84.     IApplication;
  85.     
  86.     { Read menus into menubar }
  87.     menuBar := GetNewMBar(rMenuBar);
  88.     
  89.     { Install menus }
  90.     SetMenuBar(menuBar);
  91.     DisposHandle(menuBar);
  92.     
  93.     { Add DA names to Apple menu }
  94.     AddResMenu(GetMHandle(mApple),'DRVR');
  95.     DrawMenuBar;
  96.     
  97.     { Create empty mouse region }
  98.     fMouseRgn := NewRgn;
  99.     
  100.     { Create a single empty document }
  101.     DoNew;
  102.     
  103.     {Make sure we have a valid cursor region }
  104.     AdjustCursor;
  105. END;
  106.  
  107. {$S Main}
  108. {-----------------------------------+
  109. |    DoIdle                            |
  110. +-----------------------------------}
  111. { This is called whenever we get a NULL event et al. }
  112. { It takes care of necessary periodic actions. For this program, }
  113. { it calls the DoIdle method of the current document. }
  114. PROCEDURE TTESample.DoIdle; OVERRIDE;
  115. VAR
  116.     fTECurDoc: TTEDocument;
  117. BEGIN
  118.     fTECurdoc := TTEDocument(fCurDoc);
  119.     IF fTECurDoc <> NIL THEN
  120.         fTECurDoc.DoIdle;
  121. END;
  122.  
  123. {$S Main}
  124. {-----------------------------------+
  125. |    AdjustMenus                        |
  126. +-----------------------------------}
  127. { Enable and disable menus based on the current state. The }
  128. { user can only select enabled menu items. We set up all the }
  129. { menu items before calling MenuSelect or MenuKey, since }
  130. { these are the only times that a menu item can be selected. }
  131. { Note that MenuSelect is also the only time the user will }
  132. { see menu items. This approach to deciding what enable/ }
  133. { disable state a menu item has the advantage of }
  134. { concentrating all the decision-making in one routine, as }
  135. { opposed to being spread throughout the application. Other }
  136. { application designs may take a different approach that may }
  137. { or may not be as valid.  }
  138.  
  139. PROCEDURE TTESample.AdjustMenus; OVERRIDE;
  140. VAR
  141.     frontMost:    WindowPtr;
  142.     menu:        MenuHandle;
  143.     offset:        longint;
  144.     undo:        Boolean;
  145.     cutCopyClear:    Boolean;
  146.     paste:        Boolean;
  147.     fTECurDoc:    TTEDocument;
  148. BEGIN
  149.     fTECurdoc := TTEDocument(fCurDoc);
  150.     frontMost := FrontWindow;
  151.     
  152.     menu := GetMHandle(mFile);
  153.     IF (fDocList.NumDocs < kMaxOpenDocuments) THEN
  154.         EnableItem(menu,iNew)
  155.     ELSE
  156.         DisableItem(menu,iNew);
  157.     IF (frontMost <> NIL) THEN
  158.         EnableItem(menu,iClose)
  159.     ELSE
  160.         DisableItem(menu,iClose);
  161.         
  162.     menu := GetMHandle(mEdit);
  163.     undo := FALSE;
  164.     cutCopyClear := FALSE;
  165.     paste := FALSE;
  166.     IF (frontMost <> NIL) THEN 
  167.         IF (fTECurDoc = NIL) THEN BEGIN        { all editing is enabled for DA windows }
  168.             undo := TRUE;
  169.             cutCopyClear := TRUE;
  170.             paste := TRUE;
  171.         END ELSE BEGIN
  172.             { Cut, Copy, and Clear is enabled for app. windows with selections  }
  173.             IF fTECurDoc.HaveSelection THEN
  174.               cutCopyClear := TRUE;
  175.             { If we have any TEXT in the scrap, enable paste }
  176.             IF GetScrap(NIL, 'TEXT', offset) > 0 THEN
  177.                 paste := TRUE; 
  178.         END;
  179.     
  180.     IF undo THEN
  181.         EnableItem(menu,iUndo)
  182.     ELSE
  183.         DisableItem(menu,iUndo);
  184.     IF cutCopyClear THEN BEGIN
  185.         EnableItem(menu,iCut);
  186.         EnableItem(menu,iCopy);
  187.         EnableItem(menu,iClear);
  188.     END ELSE BEGIN
  189.         DisableItem(menu,iCut);
  190.         DisableItem(menu,iCopy);
  191.         DisableItem(menu,iClear);
  192.     END;
  193.     IF paste THEN
  194.         EnableItem(menu,iPaste)
  195.     ELSE
  196.         DisableItem(menu,iPaste);
  197. END;
  198.  
  199. {$S Main}
  200. {-----------------------------------+
  201. |    AdjustCursor                    |
  202. +-----------------------------------}
  203. { Change the cursor's shape, depending on its position. This also calculates a }
  204. { region that includes the cursor for WaitNextEvent. }
  205. PROCEDURE TTESample.AdjustCursor; OVERRIDE;
  206. VAR
  207.     fTECurDoc:    TTEDocument;
  208.     arrowRgn,
  209.     iBeamRgn:    RgnHandle;
  210.     mouse:        Point;
  211. BEGIN
  212.     fTECurdoc := TTEDocument(fCurDoc);
  213.     
  214.     { Notice that we don't change the cursor if front window isn't ours }
  215.     IF (NOT(fInBackGround) AND (fTECurDoc <> NIL)) THEN BEGIN
  216.     
  217.         GetMouse(mouse);
  218.         LocalToGlobal(mouse);
  219.         
  220.         arrowRgn := NewRgn;
  221.         iBeamRgn := NewRgn;
  222.         
  223.         SetRectRgn(arrowRgn,kExtremeNeg, kExtremeNeg, kExtremePos, kExtremePos);
  224.         
  225.         fTECurDoc.GetVisTERgn(iBeamRgn);
  226.         
  227.         DiffRgn(arrowRgn,iBeamRgn,arrowRgn);
  228.         
  229.         IF PtInRgn(mouse,iBeamRgn) THEN BEGIN
  230.             SetCursor(GetCursor(iBeamCursor)^^);
  231.             CopyRgn(iBeamRgn,fMouseRgn);
  232.         END ELSE BEGIN
  233.             SetCursor(arrow);
  234.             CopyRgn(arrowRgn,fMouseRgn);
  235.         END;
  236.         DisposeRgn(arrowRgn);
  237.         DisposeRgn(iBeamRgn);
  238.     END;
  239. END;
  240.  
  241. {$S Main}
  242. {-----------------------------------+
  243. |    DoMenuCommand                    |
  244. +-----------------------------------}
  245. { This is called when an item is chosen from the menu bar (after calling }
  246. { MenuSelect or MenuKey). It does the right thing for each command. }
  247. PROCEDURE TTESample.DoMenuCommand(menuID,menuItem: integer); OVERRIDE;
  248. VAR
  249.     itemHit:    integer;
  250.     daName:        Str255;
  251.     daRefNum:    integer;
  252.     window:        WindowPtr;
  253.     fTECurDoc: TTEDocument;
  254. BEGIN
  255.     fTECurdoc := TTEDocument(fCurDoc);
  256.     window := FrontWindow;
  257.     
  258.     CASE menuID OF
  259.         mApple:
  260.             CASE menuItem OF
  261.                 iAbout:                    { bring up alert for About  }
  262.                     itemHit := Alert(rAboutAlert, NIL);
  263.                 OTHERWISE BEGIN            { all non-About items in this menu are DAs et al  }
  264.                     GetItem(GetMHandle(mApple), menuItem, daName);
  265.                     daRefNum := OpenDeskAcc(daName);
  266.                 END; { OTHERWISE }
  267.             END; { CASE menuItem }
  268.         mFile:
  269.             CASE menuItem OF
  270.                 iNew:
  271.                     DoNew;
  272.                 iClose:
  273.                     BEGIN
  274.                         IF fTECurDoc <> NIL THEN BEGIN
  275.                             fDocList.RemoveDoc(fTECurDoc);
  276.                             fTECurDoc.Free;
  277.                         END ELSE BEGIN
  278.                             CloseDeskAcc(WindowPeek(fWhichWindow)^.windowKind);
  279.                         END;
  280.                         
  281.                         { make sure our current document/window references are valid }
  282.                         window := FrontWindow;
  283.                         IF window <> NIL THEN BEGIN
  284.                             fCurDoc := fDocList.FindDoc(window);
  285.                             SetPort(window);
  286.                         END ELSE BEGIN
  287.                             fCurDoc := NIL;
  288.                         END;
  289.                     END;
  290.  
  291.                 iQuit:
  292.                     Terminate;
  293.             END; { CASE menuItem }
  294.         mEdit:                    { call SystemEdit for DA editing & MultiFinder  }
  295.             IF NOT SystemEdit(menuItem-1) THEN
  296.                  CASE menuItem OF
  297.                     iCut:    fTECurDoc.DoCut;
  298.                     iCopy:    fTECurDoc.DoCopy;
  299.                     iPaste:    fTECurDoc.DoPaste;
  300.                     iClear:    fTECurDoc.DoClear;
  301.                 END; { CASE menuItem }
  302.     END;
  303.     HiliteMenu(0);
  304. END; { doMenuCommand }
  305.  
  306. {$S Main}
  307. {-----------------------------------+
  308. |    HeapNeeded                        |
  309. +-----------------------------------}
  310. FUNCTION TTESample.HeapNeeded: Longint; OVERRIDE;
  311. BEGIN
  312.     HeapNeeded := kMinSize * 1024;
  313. END;
  314.  
  315. {$S Main}
  316. {-----------------------------------+
  317. |    SleepVal                        |
  318. +-----------------------------------}
  319.  
  320. { Calculate a sleep value for WaitNextEvent. This takes into account the things }
  321. { that DoIdle does with Idle Time. The formula used here is: 
  322.     IF we are in the foreground
  323.     AND our document window is in front
  324.     THEN
  325.         SleepVal := whatever the front document says it should be
  326.     ELSE
  327.         SleepVal := aRealLongTime
  328.         
  329.     After that, SleepVal is clipped to kMaxSleepTime which is currently set
  330.     to 60 ticks. This is to account for a Notification Manager bug wherein
  331.     notifications don't occur while the front application is asleep. }
  332.  
  333. FUNCTION TTESample.SleepVal: LongInt; OVERRIDE;
  334. VAR
  335.     sleep: longint;
  336.     fTECurDoc: TTEDocument;
  337. BEGIN
  338.     sleep := kSleepTime;
  339.     fTECurdoc := TTEDocument(fCurDoc);
  340.     IF ((NOT fInBackGround) AND (fTECurdoc <> NIL)) THEN BEGIN
  341.         sleep := fTECurDoc.CalcIdle;
  342.     END;
  343.     IF sleep > kMaxSleepTime THEN
  344.         sleep := kMaxSleepTime;
  345.     SleepVal := sleep;
  346. END;
  347.  
  348. {$S Initialize}
  349. {-----------------------------------+
  350. |    DoNew                            |
  351. +-----------------------------------}
  352. { Create a new document and window.  }
  353. PROCEDURE TTESample.DoNew;
  354. VAR
  355.     tDoc:    TTEDocument;
  356. BEGIN
  357.     New(tdoc);
  358.     tDoc.ITEDocument(rDocWindow);
  359.     
  360.     IF tdoc <> NIL THEN
  361.         fdocList.Adddoc(tdoc);
  362. END;
  363.  
  364. {$S Main}
  365. {-----------------------------------+
  366. |    Terminate                        |
  367. +-----------------------------------}
  368. { Clean up the application and exits. We close all of the windows so that }
  369. { they can update their documents. }
  370. PROCEDURE TTESample.Terminate;
  371. BEGIN
  372.     { FIX: close all docs }
  373.     ExitLoop;
  374. END;
  375.