home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Snippets / DialogUtils / DialogUtils.c next >
Encoding:
C/C++ Source or Header  |  1994-05-11  |  13.3 KB  |  534 lines  |  [TEXT/KAHL]

  1. /*****************************************************************************************************
  2.  
  3.     DialogUtils.c - A plethora of useful routines for dealing with dialogs.  This include some
  4.                     routines for easier access to dialog stuff, as well as a couple of
  5.                     generic dialogs that can be used in apps.
  6.                     
  7.                     - Remember to include a file called DialogUtils.rsrc in compiling this.
  8.                     
  9.             ©1994 Paul Rademacher
  10.                   Dept. Of Computer Science
  11.                   West Virginia University
  12.                   paulr@cs.wvu.edu
  13.             
  14.             1/5/94
  15.  
  16. *****************************************************************************************************/
  17.  
  18. #include    "DialogUtils.h"
  19.  
  20. /********************************************** highlightDefault() **********************************/
  21. /**** Found in public domain - credit anyways to Paul DuBois and Brian Bechtel                      */
  22. /**** I made a few changes to the code I found - namely, making the item a variable                    */
  23. /**** instead of always the first button, and making it "port-friendly"                                */
  24.  
  25. void        highlightDefault( DialogPtr dPtr, short itemNum )
  26. {
  27.     short         unusedItemType;
  28.     Handle         unusedItemHandle;
  29.     Rect         box;
  30.     PenState     p;
  31.     GrafPtr        oldPort;
  32.  
  33.     /*  This next little piece of code puts the default heavy rounded
  34.         box around the <itemNumber> button, so the user knows that pressing
  35.         return is the same as hitting <itemNumber>
  36.     */
  37.     
  38.     GetPort( &oldPort ); // So we can return to it later
  39.     
  40.     SetPort(dPtr);      /* without this, can't highlite <itemNumber> */
  41.     GetDItem( dPtr, itemNum, &unusedItemType, &unusedItemHandle, &box);
  42.     GetPenState( &p );
  43.     PenSize( 3, 3 );
  44.     InsetRect( &box, -4, -4 );
  45.     FrameRoundRect( &box, 16, 16 );
  46.     PenSize( p.pnSize.h, p.pnSize.v );
  47.     
  48.     SetPort( oldPort );
  49. }
  50.  
  51.  
  52. /************************************************************ fakeMouseClick() **********************/
  53. /* Highlights and dehighlights a button to simulate a mouse click within it.                        */
  54.  
  55. void        fakeMouseClick( DialogPtr dPtr, short itemNum )
  56. {
  57.     ControlHandle    controlHandle;
  58.     short            itemType;
  59.     Rect            itemRect;
  60.     long            time;
  61.  
  62.     GetDItem( dPtr, itemNum, &itemType, ( Handle * ) &controlHandle, &itemRect );
  63.     
  64.     if ( controlHandle == nil )
  65.         return;
  66.  
  67.     HiliteControl( controlHandle, kButtonPress );
  68.     
  69.     Delay( 8, &time );
  70.     
  71.     HiliteControl( controlHandle, kEnableControl ); // We must assume it was enabled before
  72. }
  73.  
  74.  
  75. /************************************************************ getDItemHandle() ************************/
  76. /* Gets the ControlHandle for the item you want in the dialog box dlog.                              */
  77. /* Handy for setting checkboxes and radio buttons                                                     */
  78.  
  79. Handle            getDItemHandle(DialogPtr dlog, short item)
  80. {
  81.     short     itemType;
  82.     Rect     itemRect;
  83.     Handle     itemHandle;
  84.     
  85.     GetDItem( dlog, item, &itemType, &itemHandle, &itemRect);
  86.     
  87.     return( itemHandle );
  88. }
  89.  
  90.  
  91. /************************************************************* setDItemText() ***********************/
  92.  
  93. void            setDItemText( DialogPtr dlog, short item, Str255 text )
  94. {
  95.     Handle    handle;
  96.     
  97.     handle = getDItemHandle( dlog, item );
  98.     
  99.     if ( handle != nil )
  100.         SetIText( handle, text );
  101. }
  102.  
  103.  
  104. /************************************************************* getDItemText() ***********************/
  105.  
  106. void            getDItemText( DialogPtr dlog, short item, StringPtr text )
  107. {
  108.     Handle    handle;
  109.     
  110.     handle = getDItemHandle( dlog, item );
  111.     
  112.     if ( handle != nil )
  113.         GetIText( handle, text );
  114. }
  115.  
  116.  
  117. /************************************************************* getDItemType() ***********************/
  118.  
  119. short            getDItemType( DialogPtr dlog, short item )
  120. {
  121.     short     itemType;
  122.     Rect     itemRect;
  123.     Handle     itemHandle;
  124.     
  125.     GetDItem( dlog, item, &itemType, &itemHandle, &itemRect);
  126.     
  127.     return( itemType );
  128. }
  129.  
  130.  
  131. /**************************************************************** getDItemValue() *******************/
  132.  
  133. short        getDItemValue( DialogPtr dlog, short item )
  134. {
  135.     ControlHandle    handle;
  136.     
  137.     handle = ( ControlHandle ) getDItemHandle( dlog, item );    
  138.     
  139.     if ( handle == nil )
  140.         return( -1 );
  141.     
  142.     return( GetCtlValue( handle ) );
  143. }
  144.  
  145.  
  146. /**************************************************************** setDItemValue() *******************/
  147.  
  148. void        setDItemValue( DialogPtr dlog, short item, short value )
  149. {
  150.     ControlHandle    handle;
  151.     
  152.     handle = ( ControlHandle ) getDItemHandle( dlog, item );    
  153.     
  154.     if ( handle == nil )
  155.         return;
  156.     
  157.     SetCtlValue( handle, value );
  158. }
  159.  
  160.  
  161. /**************************************************************** enableDItem() *********************/
  162.  
  163. void        enableDItem( DialogPtr dlog, short item )
  164. {
  165.     short     itemType;
  166.     Rect     itemRect;
  167.     Handle     controlHandle;
  168.     
  169.     GetDItem( dlog, item, &itemType, &controlHandle, &itemRect);
  170.     
  171.     if ( controlHandle != nil )    
  172.         HiliteControl( ( ControlHandle ) controlHandle, kEnableControl );
  173. }
  174.  
  175.  
  176. /**************************************************************** getDItemRect() ********************/
  177.  
  178. Rect        getDItemRect( DialogPtr dlog, short item )
  179. {
  180.     short     itemType;
  181.     Rect     itemRect;
  182.     Handle     controlHandle;
  183.     
  184.     GetDItem( dlog, item, &itemType, &controlHandle, &itemRect);
  185.         
  186.     return( itemRect );
  187. }
  188.  
  189.  
  190. /**************************************************************** disableDItem() *********************/
  191.  
  192. void        disableDItem( DialogPtr dlog, short item )
  193. {
  194.     short     itemType;
  195.     Rect     itemRect;
  196.     Handle     controlHandle;
  197.     
  198.     GetDItem( dlog, item, &itemType, &controlHandle, &itemRect);
  199.     
  200.     if ( controlHandle != nil )    
  201.         HiliteControl( ( ControlHandle ) controlHandle, kDisableControl );
  202. }
  203.  
  204.  
  205. /********************************************************* drawTextInUserItem() *********************/
  206.  
  207. void            drawTextInUserItem( DialogPtr dlog, short item, StringPtr text )
  208. {
  209.     short     itemType;
  210.     Rect     itemRect;
  211.     Handle     controlHandle;
  212.     FontInfo    fontInfo;
  213.     
  214.     GetDItem( dlog, item, &itemType, &controlHandle, &itemRect);
  215.     
  216.     GetFontInfo( &fontInfo );
  217.     
  218.     EraseRect( &itemRect );
  219.     
  220.     MoveTo( itemRect.left + 4, itemRect.top + fontInfo.ascent );
  221.     DrawString( text );
  222. }
  223.  
  224.  
  225. /********************************************************** drawDottedBoxText() *********************/
  226.  
  227. void            drawDottedBoxText( Rect *rect, StringPtr text )
  228. {
  229.     FontInfo    fontInfo;
  230.     Rect        eraseRect;
  231.     short        width;
  232.    
  233.     PenPat( gray );
  234.     FrameRect( rect );
  235.     PenNormal();
  236.     
  237.     GetFontInfo( &fontInfo );
  238.     
  239.     width = StringWidth( text );
  240.     
  241.     TextMode( srcCopy );
  242.     
  243.     MoveTo( rect->left + 8, rect->top + fontInfo.descent );
  244.     DrawString( text );
  245. }
  246.  
  247.  
  248. /***************************************************** drawDItemDottedBoxText() *********************/
  249.  
  250. void            drawDItemDottedBoxText( DialogPtr dlog, short item, StringPtr text )
  251. {
  252.     FontInfo    fontInfo;
  253.     Rect        eraseRect;
  254.     short        width;
  255.     short         itemType;
  256.     Rect         itemRect;
  257.     Handle         controlHandle;
  258.     
  259.     GetDItem( dlog, item, &itemType, &controlHandle, &itemRect);
  260.  
  261.     drawDottedBoxText( &itemRect, text );    
  262. }
  263.  
  264.  
  265. /*********************************************************** setAlternatingDefaultItems() ***********/
  266. /* This routine, if passed ok as item, will make the OK button the default ( draw a heavy border     */
  267. /* around it ).  If passed cancel, it will make that the default and gray out the ok button.        */
  268. /* Does nothing if item is not 'ok' or 'cancel' ( 1 or 2 ).                                            */
  269.  
  270. void        setAlternatingDefaultItems( DialogPtr dlog, short item )
  271. {
  272.     GrafPtr            oldPort;
  273.     short            other;
  274.  
  275.     GetPort( &oldPort ); /* So we can return to it later */
  276.     
  277.     SetPort( dlog );      /* without this, can't highlite <itemNumber> */
  278.     
  279.        if ( item == ok )
  280.            other = cancel;
  281.        else
  282.            other = ok;
  283.     
  284.     if ( item == ok OR item == cancel )
  285.     {
  286.         PenMode( srcBic );
  287.         
  288.         highlightDefault( dlog, other ); /* This erases previous border */
  289.         
  290.         PenMode( srcOr );
  291.         
  292.         highlightDefault( dlog, item );
  293.         
  294.         /* We disable ( gray out ) the ok button if the default is cancel */
  295.         
  296.         if ( item == ok )
  297.             enableDItem( dlog, ok );
  298.         else
  299.             disableDItem( dlog, ok );
  300.     }
  301.  
  302.     SetPort( oldPort );
  303. }
  304.  
  305.  
  306. /*********************************************************************** doSaveChanges() ************/
  307. /* Warning: this routine uses ParamText(), so you can't use ParamText() elsewhere to modify your     */
  308. /* input text.                                                                                        */
  309.  
  310. short        doSaveChanges( StringPtr actionText, Str255 docName )
  311. {
  312.     DialogPtr    dlog;
  313.     short        item;
  314.     GrafPtr        oldPort;
  315.     OSErr        err;
  316.  
  317.     dlog = GetNewDialog( rSaveChangesDLOG, 0L, kMoveToFront );
  318.     
  319.     if ( dlog != nil )
  320.     {
  321.         GetPort( &oldPort );
  322.         SetPort( dlog );
  323.  
  324.         ParamText( docName, actionText, "\p", "\p" );
  325.         
  326.         ShowWindow( dlog );
  327.  
  328.         highlightDefault( dlog, dSaveChangesOK );
  329.         
  330.         do 
  331.         {
  332.             ModalDialog( nil, &item );
  333.         } while( item != dSaveChangesOK AND item != dSaveChangesCancel AND item != dSaveChangesNo );
  334.                 
  335.         DisposDialog( dlog );
  336.         SetPort( oldPort );
  337.         
  338.         return( item );
  339.     }
  340.         
  341.     return( dSaveChangesOK ); /* Save the changes as a default */
  342. }
  343.  
  344.  
  345. /**************************************************************************** promptForString() *****/
  346. /* This brings up a dialog with a prompt, an edit text field, and an 'ok' button.  It won't return    */
  347. /* until the edit text field contains a string of the length indicated by the args.                    */
  348. /* Returns which button was pressed.                                                                */
  349.  
  350. short        promptForString( StringPtr prompt, StringPtr defaultText, short minLength, 
  351.                 short maxLength, StringPtr dest )
  352. {
  353.     DialogPtr    dlog;
  354.     short        item;
  355.     GrafPtr        oldPort;
  356.     OSErr        err;
  357.     Str255        minString;
  358.     Str255        maxString;
  359.  
  360.     dlog = GetNewDialog( rPromptForStringDLOG, 0L, kMoveToFront );
  361.     
  362.     if ( dlog != nil )
  363.     {
  364.         GetPort( &oldPort );
  365.         SetPort( dlog );
  366.         
  367.         setDItemText( dlog, dPromptForStringPrompt, prompt );
  368.         setDItemText( dlog, dPromptForStringText, defaultText );
  369.         SelIText( dlog, dPromptForStringText, 0, kEntireText );
  370.         
  371.         ShowWindow( dlog );
  372.  
  373.         highlightDefault( dlog, dPromptForStringOK );
  374.  
  375.         NumToString( minLength, minString );
  376.         NumToString( maxLength, maxString );
  377.  
  378.         ( ( DialogPeek ) dlog )->aDefItem = dPromptForStringOK;
  379.         
  380.         do 
  381.         {
  382.             ModalDialog( genericFilterProc, &item );
  383.             
  384.             getDItemText( dlog, dPromptForStringText, dest );
  385.             
  386.             if ( item == dPromptForStringOK )
  387.             {
  388.                 if ( dest[ 0 ] < minLength OR dest[ 0 ] > maxLength )
  389.                 {
  390.                     ParamText( minString, maxString, "\p", "\p" );
  391.                 
  392.                     CautionAlert( rTextLengthALRT, nil );
  393.                 
  394.                     highlightDefault( dlog, dPromptForStringOK ); /* We re-highlight it */
  395.                     
  396.                     item = 0; /* This makes it so we don't exit the 'do' loop */
  397.                 }
  398.             }
  399.         } while( item != dPromptForStringOK AND item != dPromptForStringCancel );
  400.                 
  401.         DisposDialog( dlog );
  402.         SetPort( oldPort );
  403.         
  404.         return( item );
  405.     }
  406.     
  407.     return( dPromptForStringCancel );
  408. }
  409.  
  410.  
  411. /********************************************************************* doDualChoice() ***************/
  412. /* Given text and a default button number, brings up a small dialog with the text, an 'ok' and a     */
  413. /* 'cancel' button, and returns which button was clicked.  Returns ok=1 or cancel=2                    */
  414. /* A return value of zero indicates a dialog error.                                                    */
  415. /* This routine does not use ParamText(), so feel free to use ParamText to modify your prompt.        */
  416. /* If okText is nil, then "OK" is the text in the OK button.  Use this to customize the OK text.    */
  417.  
  418. short        doDualChoice( const StringPtr prompt, const short defaultButton, 
  419.                 const StringPtr okText )
  420. {
  421.     DialogPtr        dlog;
  422.     short            item;
  423.     GrafPtr            oldPort;
  424.     OSErr            err;
  425.     Str255            actionString;
  426.     ControlHandle    okButtonHandle;
  427.  
  428.     dlog = GetNewDialog( rDualChoiceDLOG, 0L, kMoveToFront );
  429.     
  430.     if ( dlog != nil )
  431.     {
  432.         GetPort( &oldPort );
  433.         SetPort( dlog );
  434.  
  435.         setDItemText( dlog, dDualChoiceText, prompt );
  436.         
  437.         okButtonHandle = ( ControlHandle ) getDItemHandle( dlog, dDualChoiceOK );
  438.         
  439.         if ( okText == nil )
  440.         {
  441.             GetIndString( actionString, rDialogUtilsText, kDialogUtilsTextOK );
  442.  
  443.             SetCTitle( okButtonHandle, actionString );
  444.         }
  445.         else
  446.         {
  447.             SetCTitle( okButtonHandle, okText );
  448.         }
  449.         
  450.         ShowWindow( dlog );
  451.  
  452.         highlightDefault( dlog, defaultButton );
  453.  
  454.         ( ( DialogPeek ) dlog )->aDefItem = defaultButton;
  455.         
  456.         do 
  457.         {
  458.             ModalDialog( genericFilterProc, &item );
  459.         } while( item != dDualChoiceOK AND item != dDualChoiceCancel );
  460.                 
  461.         DisposDialog( dlog );
  462.         SetPort( oldPort );
  463.         
  464.         return( item );
  465.     }
  466.     
  467.     return( 0 );
  468. }
  469.  
  470.  
  471. /************************************************************************ genericFilterProc() *******/
  472.  
  473. pascal Boolean    genericFilterProc( DialogPtr dlog,EventRecord *event,short *itemHit )
  474. {
  475.     char         theChar;
  476.     short        mouseClick;
  477.     Point        localPoint;
  478.  
  479.     mouseClick = -1;
  480.     
  481.     localPoint = event->where;
  482.     GlobalToLocal( &localPoint );
  483.     
  484.     switch( event->what )
  485.     {
  486.         case osEvt:
  487.             break;
  488.         case mouseDown:
  489.             break;
  490.         case keyDown:
  491.         case autoKey:
  492.             theChar = event->message & charCodeMask;
  493.             
  494.             if ( ( ( event->modifiers & cmdKey) != 0 AND ( theChar == '.' ) ) OR theChar == kEscape )
  495.             {
  496.                 /* Simulates a Mouse Click in the Cancel Button */
  497.                 mouseClick = *itemHit = cancel;
  498.             }
  499.             else
  500.             if ( theChar == kReturn OR theChar == kEnter )
  501.             {
  502.                 /* Simulates a Mouse Click in the default Button */
  503.                 mouseClick = *itemHit = ( ( DialogPeek ) dlog )->aDefItem;
  504.             }
  505.             else
  506.             {
  507.                 switch ( theChar )
  508.                 {
  509.                     default:
  510.                         return( false );
  511.                         break;
  512.                 }
  513.             }
  514.             break;
  515.         case updateEvt:
  516.             if ( ( DialogPtr ) event->message == dlog )
  517.                 highlightDefault( dlog, ( ( DialogPeek ) dlog )->aDefItem );
  518.             break;
  519.         default:
  520.             return( false );
  521.     }
  522.     
  523.     if ( mouseClick != -1 )
  524.     {
  525.         fakeMouseClick( dlog, mouseClick );
  526.         
  527.         return( true );
  528.     }
  529.     else
  530.         return( false );
  531. }
  532.  
  533.  
  534.