home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / nethack-3.1 / sys / mac / mmodal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-25  |  3.8 KB  |  167 lines

  1. /*    SCCS Id: @(#)mmodal.c    3.1    93/01/24          */
  2. /* Copyright (c) Jon W{tte, Hao-Yang Wang, Jonathan Handler 1992. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include <OSUtils.h>
  7.  
  8. void FlashButton ( DialogPtr , short ) ;
  9. void trans_num_keys ( EventRecord * ) ;
  10.  
  11. #define MAX_MV_DIALOGS 20
  12. static int old_dialog_count = 0;
  13. static struct {
  14.     short      id;
  15.     Boolean   init_visible;
  16.     DialogPtr dialog;
  17. } old_dialog[MAX_MV_DIALOGS];
  18.  
  19. /* Instead of calling GetNewDialog everytime, just call
  20.    SelectWindow/ShowWindow for the old dialog to remember its location.
  21. */
  22. /*
  23.  *    Unfortunately, this does not work, as it doesn't handle old text
  24.  *    in edit text boxes, and not ParamText parameters either.
  25.  *
  26.  */
  27. DialogPtr
  28. mv_get_new_dialog(short dialogID)
  29. {
  30.     DialogPtr dialog;
  31.     int d_idx = old_dialog_count;
  32.     Rect oldRect ;
  33.     Boolean hadOld = 0 ;
  34.  
  35.     old_dialog[0].id = dialogID;
  36.     while (old_dialog[d_idx].id != dialogID)
  37.         --d_idx;
  38.  
  39. /*
  40.  *    This routine modified so that the old dialog is
  41.  *    disposed, and the new one read in after we remember
  42.  *    the old dialog's position.
  43.  *
  44.  *    This takes care of strange default strings and ParamTexts
  45.  *
  46.  */
  47.  
  48.     if ( d_idx ) {
  49.  
  50.         dialog = old_dialog [ d_idx ] . dialog ;
  51.         oldRect = dialog -> portBits . bounds ;
  52.         DisposeDialog ( dialog ) ;
  53.         old_dialog [ d_idx ] . dialog = ( DialogPtr ) NULL ;
  54.         hadOld = 1 ;
  55.  
  56.     } else {
  57.  
  58.         d_idx = ++ old_dialog_count ;
  59.     }
  60.  
  61.     dialog = GetNewDialog(dialogID, nil, (WindowPtr)-1);
  62.     if (dialog) {
  63.  
  64.         if ( hadOld ) {
  65.  
  66.             MoveWindow ( dialog , - oldRect . left , - oldRect . top , FALSE ) ;
  67.         }
  68.         old_dialog[d_idx].id = dialogID;
  69.         old_dialog[d_idx].init_visible
  70.             = ((WindowPeek)dialog)->visible;
  71.         old_dialog[d_idx].dialog = dialog;
  72.     }
  73.     return dialog;
  74. }
  75.  
  76. /* Instead of actually closing the dialog, just hide it so its location
  77.    is remembered. */
  78. void mv_close_dialog(DialogPtr dialog) {
  79.     HideWindow(dialog);
  80. }
  81.  
  82. /* This routine is stolen/borrowed from HandleClick (macwin.c).  See the
  83.    comments in mv_modal_dialog for more information. */
  84. void
  85. mv_handle_click ( EventRecord * theEvent )
  86. {
  87.     int code ;
  88.     WindowPtr theWindow ;
  89.     Rect r = ( * GetGrayRgn ( ) ) -> rgnBBox ;
  90.  
  91.     InsetRect ( & r , 4 , 4 ) ;
  92.     InitCursor ( ) ;
  93.  
  94.     code = FindWindow ( theEvent -> where , & theWindow ) ;
  95.  
  96.     switch ( code ) {
  97.  
  98.     case inContent :
  99.         if ( theWindow != FrontWindow ( ) ) {
  100.             nhbell ( ) ;
  101.         }
  102.         break ;
  103.  
  104.     case inDrag :
  105.         InitCursor ( ) ;
  106.         DragWindow ( theWindow , theEvent -> where , & r ) ;
  107.         SaveWindowPos ( theWindow ) ;
  108.         break ;
  109.  
  110.     default :
  111.         HandleEvent ( theEvent ) ;
  112.     }
  113. }
  114.  
  115. void
  116. mv_modal_dialog(ModalFilterProcPtr filterProc, short *itemHit)
  117. {
  118.     GrafPtr org_port;
  119.     GetPort(&org_port);
  120.  
  121.     for (;;) {
  122.         DialogPtr dialog = FrontWindow();
  123.         EventRecord evt;
  124.  
  125.         WaitNextEvent(everyEvent, &evt, GetCaretTime(), nil);
  126.  
  127.         if (evt.what == keyDown)
  128.             if (evt.modifiers & cmdKey) {
  129.                 if ((evt.message & charCodeMask) == '.') {
  130.                     /* 0x351b is the key code and character code of the esc key. */
  131.                     evt.message = 0x351b;
  132.                     evt.modifiers &= ~cmdKey;
  133.                 }
  134.             } else
  135.                 trans_num_keys(&evt);
  136.  
  137.         if (filterProc) {
  138.             if ((*filterProc)(dialog, &evt, itemHit))
  139.                 break;
  140.         } else if (evt.what == keyDown) {
  141.             char ch = evt.message & charCodeMask;
  142.             if (ch == CHAR_CR || ch == CHAR_ENTER) {
  143.                 *itemHit = ok;
  144.                 FlashButton(dialog, ok);
  145.                 break;
  146.             }
  147.         }
  148.  
  149.         if (IsDialogEvent(&evt)) {
  150.             DialogPtr dont_care;
  151.             if (DialogSelect(&evt, &dont_care, itemHit))
  152.                 break;
  153.  
  154.         /* The following part is problemmatic: (1) Calling HandleEvent
  155.            here may cause some re-entrance problem (seems ok, but I am
  156.            not sure). (2) It is ugly to treat mouseDown events as a
  157.            special case.  If we can just say "else HandleEvent(&evt);"
  158.            here it will be better. */
  159.         } else if (evt.what == mouseDown)
  160.                 mv_handle_click(&evt);
  161.             else
  162.                 HandleEvent(&evt);
  163.  
  164.         SetPort(org_port);
  165.     }
  166. }
  167.