home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / utils / dialoglib / vstack.c < prev   
C/C++ Source or Header  |  1993-03-06  |  8KB  |  290 lines

  1. #include <clib/macros.h>
  2. #include <proto/utility.h>
  3. #include "dialog.h"
  4. #ifdef DEBUG1
  5.     #include <stdio.h>
  6. #endif
  7.  
  8. /* filters for structure flag common among all members */
  9. static ULONG getVStackStructure( DialogElement *de )
  10. {
  11.     struct TagItem *tstate, *tag;
  12.     DialogElement *member;
  13.     ULONG structure = DESF_VBaseline;
  14.  
  15.     if( !de )
  16.         return 0;
  17.  
  18.     /* a vstack can only have a vertical baseline if the members are centered */
  19.     if( GetTagData( DA_Alignment, 0, de->taglist ) )
  20.         structure = 0;
  21.     else
  22.         for( tstate = de->taglist; tag = NextTagItem( &tstate ); )
  23.             if( tag->ti_Tag == DA_Member )
  24.                 if( member = (DialogElement *)tag->ti_Data )
  25.                     structure &= getDialogElementStructure( member );
  26.     return structure;
  27. }
  28.  
  29. static VOID setupVStack( DialogElement *de )
  30. {
  31.     struct TagItem *tstate, *tag;
  32.     DialogElement *member;
  33.     LONG minleft, minright, minwidth, maxleft, maxright, maxwidth;
  34.  
  35.     if( !de )
  36.         return;
  37.  
  38.     /* determine structure */
  39.     de->structure = getDialogElementStructure( de );
  40.  
  41.     setMinHeight( de, 0 );            /* modified later */
  42.     setMaxHeight( de, MAX_SPACE );
  43.     if( de->structure & DESF_VBaseline )
  44.     {
  45.         setMinLeftExtent( de, 0 );
  46.         setMinRightExtent( de, 0 );
  47.         setMaxLeftExtent( de, 0 );
  48.         setMaxRightExtent( de, 0 );
  49.     }
  50.     else
  51.     {
  52.         setMinWidth( de, 0 );
  53.         setMaxWidth( de, 0 );
  54.     }
  55.  
  56.     for( tstate = de->taglist; tag = NextTagItem( &tstate ); )
  57.         if( tag->ti_Tag == DA_Member )
  58.             if( member = (DialogElement *)tag->ti_Data )
  59.             {
  60.                 ULONG substructure;
  61.  
  62.                 setupDialogElement( member );
  63.                 de->idcmp_mask |= member->idcmp_mask;
  64.                 substructure = getDialogElementStructure( member );
  65.  
  66.                 /* modify Min/MaxHeight to accomodate member */
  67.                 if( substructure & DESF_HBaseline )
  68.                     setMinHeight( de, getMinHeight( de ) +
  69.                         getMinTopExtent( member ) + getMinBottomExtent( member ) );
  70.                 else
  71.                     setMinHeight( de, getMinHeight( de ) + getMinHeight( member ) );
  72.  
  73.                 /* modify Min/MaxWidth or Min/MaxLeft/RightExtent to accomodate member */
  74.                 if( substructure & DESF_VBaseline )
  75.                 {
  76.                     minleft = getMinLeftExtent( member );
  77.                     minright = getMinRightExtent( member );
  78.                     maxleft = getMaxLeftExtent( member );
  79.                     maxright = getMaxRightExtent( member );
  80.                     if( de->structure & DESF_VBaseline )
  81.                     {
  82.                         if( minleft > getMinLeftExtent( de ) )
  83.                             setMinLeftExtent( de, minleft );
  84.                         if( minright > getMinRightExtent( de ) )
  85.                             setMinRightExtent( de, minright );
  86.                         if( maxleft > getMaxLeftExtent( de ) )
  87.                             setMaxLeftExtent( de, maxleft );
  88.                         if( maxright > getMaxRightExtent( de ) )
  89.                             setMaxRightExtent( de, maxright );
  90.                     }
  91.                     else
  92.                     {
  93.                         minwidth = minleft + minright;
  94.                         maxwidth = maxleft + maxright;
  95.                         if( minwidth > getMinWidth( de ) )
  96.                             setMinWidth( de, minwidth );
  97.                         if( maxwidth > getMaxWidth( de ) )
  98.                             setMaxWidth( de, maxwidth );
  99.                     }
  100.                 }
  101.                 else
  102.                 {
  103.                     minwidth = getMinWidth( member );
  104.                     maxwidth = getMaxWidth( member );
  105.                     if( minwidth > getMinWidth( de ) )
  106.                         setMinWidth( de, minwidth );
  107.                     if( maxwidth > getMaxWidth( de ) )
  108.                         setMaxWidth( de, maxwidth );
  109.                 }
  110.             }
  111. }
  112.  
  113. static ULONG layoutVStack( DialogElement *de, LayoutMessage *lm )
  114. {
  115.     struct TagItem *tstate, *tag;
  116.     DialogElement *member;
  117.     LayoutMessage message;
  118.     LONG count, minheight, maxheight, spare, y, white;
  119.     LONG top, bottom, height;
  120.     ULONG substructure, error = DIALOGERR_OK;
  121.  
  122.     if( !de )
  123.         return DIALOGERR_BAD_ARGS;
  124.     if( !lm )
  125.         return DIALOGERR_BAD_ARGS;
  126.  
  127. #ifdef DEBUG1
  128.     printf(
  129.     "layoutVStack : x %d, y %d, width %d, height %d, left %d, right %d, top %d, bottom %d\n",
  130.         lm->lm_X, lm->lm_Y, lm->lm_Width, lm->lm_Height,
  131.         lm->lm_Left, lm->lm_Right, lm->lm_Top, lm->lm_Bottom );
  132. #endif
  133.  
  134.     y = lm->lm_Y;
  135.     count = maxheight = minheight = 0;
  136.     for( tstate = de->taglist; tag = NextTagItem( &tstate ); )
  137.         if( tag->ti_Tag == DA_Member )
  138.             if( member = (DialogElement *)tag->ti_Data )
  139.             {
  140.                 substructure = getDialogElementStructure( member );
  141.                 if( substructure & DESF_HBaseline )
  142.                 {
  143.                     minheight += getMinTopExtent( member ) + getMinBottomExtent( member );
  144.                     maxheight += getMaxTopExtent( member ) + getMaxBottomExtent( member );
  145.                 }
  146.                 else
  147.                 {
  148.                     minheight += getMinHeight( member );
  149.                     maxheight += getMaxHeight( member );
  150.                 }
  151.                 count++;
  152.             }
  153.     spare = maxheight - minheight;
  154.     white = lm->lm_Height - minheight;
  155. #ifdef DEBUG1
  156.     printf( "layoutVStack : white %d\n", white );
  157. #endif
  158.     if( white >= spare )    /* extend all members to their maximal vertical size */
  159.     {
  160.         for( tstate = de->taglist; tag = NextTagItem( &tstate ); )
  161.             if( tag->ti_Tag == DA_Member )
  162.                 if( member = (DialogElement *)tag->ti_Data )
  163.                 {
  164.                     substructure = prepareMemberLayoutH( &message, de, member, lm );
  165.                     if( substructure & DESF_HBaseline )
  166.                     {
  167.                         top = getMaxTopExtent( member );
  168.                         bottom = getMaxBottomExtent( member );
  169.                         prepareLayoutHBaseline( &message, top, bottom );
  170.                         y += top;
  171. #ifdef DEBUG1
  172.     printf( "layoutVStack : top %d, bottom %d\n", top, bottom );
  173. #endif
  174.                     }
  175.                     else
  176.                     {
  177.                         height = getMaxHeight( member );
  178.                         prepareLayoutNoHBaseline( &message, height );
  179.                     }
  180.                     prepareLayoutY( &message, y );
  181.                     error = layoutDialogElement( member, &message, lm->lm_PreviousPtr );
  182.                     if( error )
  183.                         break;
  184.                     if( count > 1 )
  185.                         y += white / ( count - 1 );
  186.                     if( substructure & DESF_HBaseline )
  187.                         y += bottom;
  188.                     else
  189.                         y += height;
  190.                 }
  191.     }
  192.     else
  193.     {
  194.         for( tstate = de->taglist; tag = NextTagItem( &tstate ); )
  195.             if( tag->ti_Tag == DA_Member )
  196.                 if( member = (DialogElement *)tag->ti_Data )
  197.                 {
  198.                     substructure = prepareMemberLayoutH( &message, de, member, lm );
  199.                     if( substructure & DESF_HBaseline )
  200.                     {
  201.                         LONG mintop, minbottom;
  202.  
  203.                         mintop = getMinTopExtent( member );
  204.                         minbottom = getMinBottomExtent( member );
  205.                         top = getMaxTopExtent( member ) - mintop;
  206.                         top = mintop + ( ( spare ) ? ( top * white ) / spare : 0 );
  207.                         bottom = getMaxBottomExtent( member ) - minbottom;
  208.                         bottom = minbottom + ( ( spare ) ? ( bottom * white ) / spare : 0 );
  209.                         prepareLayoutHBaseline( &message, top, bottom );
  210.                         y += top;
  211.                     }
  212.                     else
  213.                     {
  214.                         LONG minheight;
  215.  
  216.                         minheight = getMinHeight( member );
  217.                         height = getMaxHeight( member ) - minheight;
  218.                         height = minheight + ( ( spare ) ? ( height * white ) / spare : 0 );
  219.                         prepareLayoutNoHBaseline( &message, height );
  220.                     }
  221.                     prepareLayoutY( &message, y );
  222.                     error = layoutDialogElement( member, &message, lm->lm_PreviousPtr );
  223.                     if( error )
  224.                         break;
  225.                     if( substructure & DESF_HBaseline )
  226.                         y += bottom;
  227.                     else
  228.                         y += height;
  229.                 }
  230.     }
  231.     return error;
  232. }
  233.  
  234. static DialogElement *matchVStack( DialogElement *de, MatchMessage *mm )
  235. {
  236.     struct TagItem *tstate, *tag;
  237.     DialogElement *member, *match = NULL;
  238.  
  239.     if( !de )
  240.         return NULL;
  241.     if( !mm )
  242.         return NULL;
  243.  
  244.     for( tstate = de->taglist; tag = NextTagItem( &tstate ); )
  245.         if( tag->ti_Tag == DA_Member )
  246.             if( member = (DialogElement *)tag->ti_Data )
  247.                 if( match = mapDialogEvent( member, mm->mm_IntuiMsg ) )
  248.                     break;
  249.     return match;
  250. }
  251.  
  252. static VOID clearVStack( DialogElement *de )
  253. {
  254.     struct TagItem *tstate, *tag;
  255.     DialogElement *member;
  256.  
  257.     if( !de )
  258.         return;
  259.  
  260.     for( tstate = de->taglist; tag = NextTagItem( &tstate ); )
  261.         if( tag->ti_Tag == DA_Member )
  262.             if( member = (DialogElement *)tag->ti_Data )
  263.                 clearDialogElement( member );
  264. }
  265.  
  266. ULONG dispatchVStack( struct Hook *hook, DialogElement *de, DialogMessage *dm )
  267. {
  268.     ULONG result;
  269.  
  270.     switch( dm->dm_MethodID )
  271.     {
  272.     case DIALOGM_GETSTRUCT:
  273.         result = getVStackStructure( de );
  274.         break;
  275.     case DIALOGM_SETUP:
  276.         setupVStack( de );
  277.         break;
  278.     case DIALOGM_LAYOUT:
  279.         result = layoutVStack( de, (LayoutMessage *)dm );
  280.         break;
  281.     case DIALOGM_MATCH:
  282.         result = (ULONG)matchVStack( de, (MatchMessage *)dm );
  283.         break;
  284.     case DIALOGM_CLEAR:
  285.         clearVStack( de );
  286.         break;
  287.     }
  288.     return result;
  289. }
  290.