home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / term43-source.lha / Extras / Source / gtlayout-Source.lha / LTP_LayoutGroup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-18  |  13.8 KB  |  590 lines

  1. /*  GadTools layout toolkit
  2. **
  3. **  Copyright © 1993-1994 by Olaf `Olsen' Barthel
  4. **  Freely distributable.
  5. */
  6.  
  7. #include "gtlayout_global.h"
  8.  
  9. VOID __regargs
  10. LTP_LayoutGroup(LayoutHandle *Handle,ObjectNode *Group)
  11. {
  12.     if(!Handle -> Failed)
  13.     {
  14.         ObjectNode    *Node;
  15.         ObjectNode    *ReturnKey;
  16.         ObjectNode    *EscKey;
  17.         ObjectNode    *CursorKey;
  18.         ObjectNode    *TabKey;
  19.         LONG         Left;
  20.         LONG         Top;
  21.         LONG         Width;
  22.         LONG         Height;
  23.  
  24.         Left        = 0;
  25.         Top        = 0;
  26.         ReturnKey    = NULL;
  27.         EscKey        = NULL;
  28.         CursorKey    = NULL;
  29.         TabKey        = NULL;
  30.  
  31.         if(Group -> Special . Group . SameSize)
  32.         {
  33.             LONG MaxWidth  = 0;
  34.             LONG MaxHeight = 0;
  35.  
  36.             SCANGROUP(Group,Node)
  37.             {
  38.                 LTP_DetermineSize(Handle,Node);
  39.  
  40.                 if(Node -> Type == BUTTON_KIND)
  41.                 {
  42.                     if(Node -> Special . Button . ReturnKey)
  43.                         ReturnKey = Node;
  44.                     else
  45.                     {
  46.                         if(Node -> Special . Button . EscKey)
  47.                             EscKey = Node;
  48.                     }
  49.                 }
  50.  
  51.                 if(Node -> Type == CYCLE_KIND)
  52.                 {
  53.                     if(Node -> Special . Cycle . TabKey)
  54.                         TabKey = Node;
  55.                 }
  56.  
  57.                 if(Node -> Type == MX_KIND)
  58.                 {
  59.                     if(Node -> Special . Radio . TabKey)
  60.                         TabKey = Node;
  61.                 }
  62.  
  63.                 if(Node -> Type == LISTVIEW_KIND && Node -> Special . List . CursorKey)
  64.                     CursorKey = Node;
  65.  
  66.                 if(Node -> Width > MaxWidth)
  67.                     MaxWidth = Node -> Width;
  68.  
  69.                 if(Node -> Height > MaxHeight)
  70.                     MaxHeight = Node -> Height;
  71.             }
  72.  
  73.             if(ReturnKey)
  74.             {
  75.                 SCANGROUP(Group,Node)
  76.                 {
  77.                     Node -> GroupIndent = TRUE;
  78.  
  79.                     Node -> Width    += 4 + 4;
  80.                     Node -> Height    += 2 + 2;
  81.  
  82.                     if(Node -> Width > MaxWidth)
  83.                         MaxWidth = Node -> Width;
  84.  
  85.                     if(Node -> Height > MaxHeight)
  86.                         MaxHeight = Node -> Height;
  87.                 }
  88.             }
  89.  
  90.             SCANGROUP(Group,Node)
  91.             {
  92.                 if(Node -> Width < MaxWidth)
  93.                 {
  94.                     if(Node -> Type == GROUP_KIND)
  95.                         Node -> Special . Group . ExtraLeft += (MaxWidth - Node -> Width) / 2;
  96.  
  97.                     Node -> Width = MaxWidth;
  98.                 }
  99.  
  100.                 if(Node -> Height < MaxHeight)
  101.                 {
  102.                     if(Node -> Type == GROUP_KIND)
  103.                         Node -> Special . Group . ExtraTop += (MaxHeight - Node -> Height) / 2;
  104.  
  105.                     Node -> Height = MaxHeight;
  106.                 }
  107.             }
  108.         }
  109.         else
  110.         {
  111.             SCANGROUP(Group,Node)
  112.             {
  113.                 LTP_DetermineSize(Handle,Node);
  114.  
  115.                 if(Node -> Type == BUTTON_KIND)
  116.                 {
  117.                     if(Node -> Special . Button . ReturnKey)
  118.                         ReturnKey = Node;
  119.                     else
  120.                     {
  121.                         if(Node -> Special . Button . EscKey)
  122.                             EscKey = Node;
  123.                     }
  124.                 }
  125.  
  126.                 if(Node -> Type == LISTVIEW_KIND && Node -> Special . List . CursorKey)
  127.                     CursorKey = Node;
  128.  
  129.                 if(Node -> Type == CYCLE_KIND)
  130.                 {
  131.                     if(Node -> Special . Cycle . TabKey)
  132.                         TabKey = Node;
  133.                 }
  134.  
  135.                 if(Node -> Type == MX_KIND)
  136.                 {
  137.                     if(Node -> Special . Radio . TabKey)
  138.                         TabKey = Node;
  139.                 }
  140.             }
  141.  
  142.             if(ReturnKey)
  143.             {
  144.                 SCANGROUP(Group,Node)
  145.                 {
  146.                     Node -> GroupIndent = TRUE;
  147.  
  148.                     Node -> Width    += 4 + 4;
  149.                     Node -> Height    += 2 + 2;
  150.                 }
  151.             }
  152.         }
  153.  
  154.         if(Group -> Special . Group . Horizontal)
  155.         {
  156.             LONG x,y,w,MaxTop = 0,MaxWidth = 0,MaxHeight = 0,Count = 0;
  157.  
  158.             if(Group -> Node . mln_Pred -> mln_Pred && Group -> Special . Group . LastAttributes)
  159.             {
  160.                 ObjectNode *LastGroup = (ObjectNode *)Group -> Node . mln_Pred;
  161.  
  162.                 MaxTop        = LastGroup -> Special . Group . MaxOffset;
  163.                 MaxHeight    = LastGroup -> Special . Group . MaxSize;
  164.             }
  165.  
  166.             SCANGROUP(Group,Node)
  167.             {
  168.                 if(!LIKE_STRING_KIND(Node) || Node -> Special . String . LinkID == -1)
  169.                 {
  170.                     if(!Group -> Special . Group . Paging && Count++)
  171.                     {
  172.                         if(Node -> ExtraSpace > 0)
  173.                             x = Left + Node -> ExtraSpace * Handle -> InterWidth;
  174.                         else
  175.                         {
  176.                             if(Node -> ExtraSpace < 0)
  177.                                 x = Left - Node -> ExtraSpace;
  178.                             else
  179.                                 x = Left + Handle -> InterWidth;
  180.                         }
  181.                     }
  182.                     else
  183.                         x = Left;
  184.  
  185.                     y = Top;
  186.                     w = Node -> Width;
  187.  
  188.                     switch(Node -> LabelPlace)
  189.                     {
  190.                         case PLACE_LEFT:
  191.  
  192.                             if(Node -> Type == MX_KIND)
  193.                             {
  194.                                 x += Node -> Special . Radio . LabelWidth + INTERWIDTH;
  195.  
  196.                                 if(Node -> Label)
  197.                                 {
  198.                                     if(Node -> Special . Radio . TitlePlace == PLACETEXT_LEFT)
  199.                                         x += Node -> LabelWidth + INTERWIDTH;
  200.                                     else
  201.                                         w += INTERWIDTH + Node -> LabelWidth;
  202.                                 }
  203.                             }
  204.                             else
  205.                             {
  206.                                 if(Node -> Label || Node -> Type == BOX_KIND)
  207.                                     x += Node -> LabelWidth + INTERWIDTH;
  208.                             }
  209.  
  210.                             break;
  211.  
  212.                         case PLACE_RIGHT:
  213.  
  214.                             if(Node -> Type == MX_KIND)
  215.                             {
  216.                                 w += INTERWIDTH + Node -> Special . Radio . LabelWidth;
  217.  
  218.                                 if(Node -> Label)
  219.                                 {
  220.                                     if(Node -> Special . Radio . TitlePlace == PLACETEXT_LEFT)
  221.                                         x += Node -> LabelWidth + INTERWIDTH;
  222.                                     else
  223.                                         w += INTERWIDTH + Node -> LabelWidth;
  224.                                 }
  225.                             }
  226.                             else
  227.                             {
  228.                                 if(Node -> Label || Node -> Type == BOX_KIND)
  229.                                     w += INTERWIDTH + Node -> LabelWidth;
  230.                             }
  231.  
  232.                             break;
  233.  
  234.                         case PLACE_ABOVE:
  235.  
  236.                             if(Node -> Label || Node -> Type == BOX_KIND)
  237.                                 y += Handle -> RPort . TxHeight + INTERHEIGHT;
  238.  
  239.                             break;
  240.  
  241.                         case PLACE_BELOW:
  242.  
  243.                             break;
  244.  
  245.                         case PLACE_IN:
  246.  
  247.                             break;
  248.                     }
  249.  
  250.                     if(Node -> Type == SLIDER_KIND)
  251.                     {
  252.                         if(Node -> Special . Slider . LevelPlace == PLACETEXT_RIGHT)
  253.                             w += INTERWIDTH + Node -> Special . Slider . LevelWidth;
  254.  
  255.                         if(Node -> Special . Slider . LevelPlace == PLACETEXT_LEFT && Node -> LabelPlace != PLACE_LEFT)
  256.                             x += INTERWIDTH + Node -> Special . Slider . LevelWidth;
  257.                     }
  258.  
  259. #ifdef DO_LEVEL_KIND
  260.                     if(Node -> Type == LEVEL_KIND)
  261.                     {
  262.                         if(Node -> Special . Level . LevelPlace == PLACETEXT_RIGHT)
  263.                             w += INTERWIDTH + Node -> Special . Level . MaxLevelWidth;
  264.  
  265.                         if(Node -> Special . Level . LevelPlace == PLACETEXT_LEFT && Node -> LabelPlace != PLACE_LEFT)
  266.                             x += INTERWIDTH + Node -> Special . Level . MaxLevelWidth;
  267.                     }
  268. #endif    /* DO_LEVEL_KIND */
  269.  
  270.                     if(Node -> Type == LISTVIEW_KIND && Node -> Special . List . ExtraLabelWidth)
  271.                         x += Node -> Special . List . ExtraLabelWidth + INTERWIDTH;
  272.  
  273.                     if(y > MaxTop)
  274.                         MaxTop = y;
  275.  
  276.                     if(Node -> Height > MaxHeight)
  277.                         MaxHeight = Node -> Height;
  278.  
  279.                     if(Node -> LabelPlace == PLACE_BELOW && Node -> Label)
  280.                     {
  281.                         LONG Height = Node -> Height + INTERHEIGHT + Handle -> RPort . TxHeight;
  282.  
  283.                         if(Height > MaxHeight)
  284.                             MaxHeight = Height;
  285.                     }
  286.                     else
  287.                     {
  288.                         if(Node -> Height > MaxHeight)
  289.                             MaxHeight = Node -> Height;
  290.                     }
  291.  
  292.                     if(x + w > MaxWidth)
  293.                         MaxWidth = x+w;
  294.  
  295.                     Node -> Left = x;
  296.  
  297.                     if(!Group -> Special . Group . Paging)
  298.                         Left = x + w;
  299.                 }
  300.             }
  301.  
  302.             SCANGROUP(Group,Node)
  303.             {
  304.                 if(!LIKE_STRING_KIND(Node) || Node -> Special . String . LinkID == -1)
  305.                 {
  306.                     Node -> Top = MaxTop;
  307.  
  308.                     if(Node -> Height < MaxHeight)
  309.                     {
  310.                         if(Node -> Type == LISTVIEW_KIND || Node -> Type == PALETTE_KIND)
  311.                             Node -> Height = MaxHeight;
  312.                         else
  313.                         {
  314.                             if(Node -> Type == GROUP_KIND)
  315.                             {
  316.                                 if(Node -> Special . Group . Spread)
  317.                                     LTP_Spread(Handle,Node,Node -> Width,MaxHeight);
  318.                                 else
  319.                                     Node -> Special . Group . ExtraTop += (MaxHeight - Node -> Height) / 2; /* !FIX! */
  320.  
  321.                                 Node -> Height = MaxHeight;
  322.                             }
  323.                         }
  324.                     }
  325.                 }
  326.             }
  327.  
  328.             Group -> Special . Group . MaxOffset = MaxTop;
  329.             Group -> Special . Group . MaxSize   = MaxHeight;
  330.  
  331.             if(Group -> Special . Group . Paging)
  332.                 Width = MaxWidth;
  333.             else
  334.                 Width = Left;
  335.  
  336.             Height    = MaxTop + MaxHeight;
  337.         }
  338.         else
  339.         {
  340.             LONG x,y,w,MaxLeft = 0,MaxWidth = 0,MaxHeight = 0,Count = 0;
  341.  
  342.             if(Group -> Node . mln_Pred -> mln_Pred && Group -> Special . Group . LastAttributes)
  343.             {
  344.                 ObjectNode *LastGroup = (ObjectNode *)Group -> Node . mln_Pred;
  345.  
  346.                 MaxLeft     = LastGroup -> Special . Group . MaxOffset;
  347.                 MaxWidth    = LastGroup -> Special . Group . MaxSize;
  348.             }
  349.  
  350.             SCANGROUP(Group,Node)
  351.             {
  352.                 if(!LIKE_STRING_KIND(Node) || Node -> Special . String . LinkID == -1)
  353.                 {
  354.                     if(!Group -> Special . Group . Paging && Count++)
  355.                     {
  356.                         if(Node -> ExtraSpace > 0)
  357.                             y = Top + Node -> ExtraSpace * Handle -> InterHeight;
  358.                         else
  359.                         {
  360.                             if(Node -> ExtraSpace < 0)
  361.                                 y = Top - Node -> ExtraSpace;
  362.                             else
  363.                                 y = Top + Handle -> InterHeight;
  364.                         }
  365.                     }
  366.                     else
  367.                         y = Top;
  368.  
  369.                     w = Node -> Width;
  370.                     x = Left;
  371.  
  372.                     switch(Node -> LabelPlace)
  373.                     {
  374.                         case PLACE_LEFT:
  375.  
  376.                             if(Node -> Type == MX_KIND)
  377.                             {
  378.                                 x += Node -> Special . Radio . LabelWidth + INTERWIDTH;
  379.  
  380.                                 if(Node -> Label)
  381.                                 {
  382.                                     if(Node -> Special . Radio . TitlePlace == PLACETEXT_LEFT)
  383.                                         x += Node -> LabelWidth + INTERWIDTH;
  384.                                 }
  385.                             }
  386.                             else
  387.                             {
  388.                                 if(Node -> Label || Node -> Type == BOX_KIND)
  389.                                     x += Node -> LabelWidth + INTERWIDTH;
  390.                             }
  391.  
  392.                             break;
  393.  
  394.                         case PLACE_RIGHT:
  395.  
  396.                             if(Node -> Type == MX_KIND)
  397.                             {
  398.                                 w += INTERWIDTH + Node -> Special . Radio . LabelWidth;
  399.  
  400.                                 if(Node -> Label)
  401.                                 {
  402.                                     if(Node -> Special . Radio . TitlePlace == PLACETEXT_LEFT)
  403.                                         x += Node -> LabelWidth + INTERWIDTH;
  404.                                     else
  405.                                         w += INTERWIDTH + Node -> LabelWidth;
  406.                                 }
  407.                             }
  408.                             else
  409.                             {
  410.                                 if(Node -> Label || Node -> Type == BOX_KIND)
  411.                                     w += INTERWIDTH + Node -> LabelWidth;
  412.                             }
  413.  
  414.                             break;
  415.  
  416.                         case PLACE_ABOVE:
  417.  
  418.                             if(Node -> Label || Node -> Type == BOX_KIND)
  419.                                 y += Handle -> RPort . TxHeight + INTERHEIGHT;
  420.  
  421.                             break;
  422.  
  423.                         case PLACE_BELOW:
  424.  
  425.                             break;
  426.  
  427.                         case PLACE_IN:
  428.  
  429.                             break;
  430.                     }
  431.  
  432.                     if(Node -> Type == SLIDER_KIND)
  433.                     {
  434.                         if(Node -> Special . Slider . LevelPlace == PLACETEXT_RIGHT)
  435.                             w += INTERWIDTH + Node -> Special . Slider . LevelWidth;
  436.  
  437.                         if(Node -> Special . Slider . LevelPlace == PLACETEXT_LEFT && Node -> LabelPlace != PLACE_LEFT)
  438.                             x += INTERWIDTH + Node -> Special . Slider . LevelWidth;
  439.                     }
  440.  
  441. #ifdef DO_LEVEL_KIND
  442.                     if(Node -> Type == LEVEL_KIND)
  443.                     {
  444.                         if(Node -> Special . Level . LevelPlace == PLACETEXT_RIGHT)
  445.                             w += INTERWIDTH + Node -> Special . Level . MaxLevelWidth;
  446.  
  447.                         if(Node -> Special . Level . LevelPlace == PLACETEXT_LEFT && Node -> LabelPlace != PLACE_LEFT)
  448.                             x += INTERWIDTH + Node -> Special . Level . MaxLevelWidth;
  449.                     }
  450. #endif    /* DO_LEVEL_KIND */
  451.                     if(Node -> Type == LISTVIEW_KIND && Node -> Special . List . ExtraLabelWidth)
  452.                         x += Node -> Special . List . ExtraLabelWidth + INTERWIDTH;
  453.  
  454.                     if(x > MaxLeft)
  455.                         MaxLeft = x;
  456.  
  457.                     if(w > MaxWidth)
  458.                         MaxWidth = w;
  459.  
  460.                     if(y + Node -> Height > MaxHeight)
  461.                         MaxHeight = y + Node -> Height;
  462.  
  463.                     Node -> Top = y;
  464.  
  465.                     if(!Group -> Special . Group . Paging)
  466.                         Top = y + Node -> Height;
  467.  
  468.                     if(Node -> LabelPlace == PLACE_BELOW && Node -> Label)
  469.                         Top += INTERHEIGHT + Handle -> RPort . TxHeight;
  470.                 }
  471.             }
  472.  
  473.             SCANGROUP(Group,Node)
  474.             {
  475.                 if(!LIKE_STRING_KIND(Node) || Node -> Special . String . LinkID == -1)
  476.                 {
  477.                     Node -> Left = MaxLeft;
  478.  
  479.                     if(Node -> Type == GROUP_KIND && Group -> Special . Group . Paging)
  480.                         Node -> Special . Group . ExtraTop += (MaxHeight - Node -> Height) / 2;
  481.  
  482.                     if(Node -> Width < MaxWidth)
  483.                     {
  484.                         if(Node -> Type == GROUP_KIND)
  485.                         {
  486.                             if(Node -> Special . Group . Spread)
  487.                                 LTP_Spread(Handle,Node,MaxWidth,Node -> Height);
  488.                             else
  489.                                 Node -> Special . Group . ExtraLeft += (MaxWidth - Node -> Width) / 2;
  490.  
  491.                             Node -> Width = MaxWidth;
  492.                         }
  493.                         else
  494.                         {
  495.                             if(Node -> Type == LISTVIEW_KIND || Node -> Type == TEXT_KIND || Node -> Type == GAUGE_KIND || Node -> Type == NUMBER_KIND || Node -> Type == CYCLE_KIND || Node -> Type == PALETTE_KIND || LIKE_STRING_KIND(Node) || Node -> Type == INTEGER_KIND || Node -> Type == BUTTON_KIND || Node -> Type == SLIDER_KIND || Node -> Type == BOX_KIND || Node -> Type == SCROLLER_KIND || Node -> Type == LEVEL_KIND)
  496.                             {
  497.                                 if(Node -> Type != LISTVIEW_KIND || !Node -> Special . List . LockSize)
  498.                                 {
  499.                                     if(Node -> Label && Node -> LabelPlace == PLACE_RIGHT)
  500.                                         Node -> Width = MaxWidth - (INTERWIDTH + Node -> LabelWidth);
  501.                                     else
  502.                                         Node -> Width = MaxWidth;
  503.                                 }
  504.                             }
  505.                             else
  506.                             {
  507.                                 if(Node -> Type == SLIDER_KIND)
  508.                                 {
  509.                                     if(Node -> Special . Slider . LevelPlace == PLACE_RIGHT)
  510.                                     {
  511.                                         if(Node -> Width + Node -> Special . Slider . LevelWidth + INTERWIDTH < MaxWidth)
  512.                                             Node -> Width = MaxWidth - (Node -> Special . Slider . LevelWidth + INTERWIDTH);
  513.                                     }
  514.                                     else
  515.                                         Node -> Width = MaxWidth;
  516.                                 }
  517.  
  518. #ifdef DO_LEVEL_KIND
  519.                                 if(Node -> Type == LEVEL_KIND)
  520.                                 {
  521.                                     if(Node -> Special . Level . LevelPlace == PLACE_RIGHT)
  522.                                     {
  523.                                         if(Node -> Width + Node -> Special . Level . MaxLevelWidth + INTERWIDTH < MaxWidth)
  524.                                             Node -> Width = MaxWidth - (Node -> Special . Level . MaxLevelWidth + INTERWIDTH);
  525.                                     }
  526.                                     else
  527.                                         Node -> Width = MaxWidth;
  528.                                 }
  529. #endif    /* DO_LEVEL_KIND */
  530.                             }
  531.                         }
  532.                     }
  533.                 }
  534.             }
  535.  
  536.             Group -> Special . Group . MaxOffset  = MaxLeft;
  537.             Group -> Special . Group . MaxSize    = MaxWidth;
  538.  
  539.             if(Group -> Special . Group . Paging)
  540.                 Height = MaxHeight;
  541.             else
  542.                 Height = Top;
  543.  
  544.             Width = MaxLeft + MaxWidth;
  545.         }
  546.  
  547.         Group -> Left    = 0;
  548.         Group -> Top    = 0;
  549.         Group -> Width    = Width;
  550.         Group -> Height = Height;
  551.  
  552.         if(Group -> Label || Group -> Special . Group . Frame)
  553.         {
  554.             if(Group -> Label)
  555.             {
  556.                 Group -> LabelWidth = LT_LabelWidth(Handle,Group -> Label) + 2 * Handle -> GlyphWidth;
  557.  
  558.                 Group -> Height += Handle -> RPort . TxHeight + 2 * Handle -> InterHeight + 3;
  559.             }
  560.             else
  561.             {
  562.                 Group -> LabelWidth = 0;
  563.  
  564.                 Group -> Height += 2 + 2 * Handle -> InterHeight + 3;
  565.             }
  566.  
  567.             if(Group -> LabelWidth > Group -> Width)
  568.             {
  569.                 Group -> Special . Group . ExtraLeft += (Group -> LabelWidth - Group -> Width) / 2;
  570.  
  571.                 Group -> Width = Group -> LabelWidth;
  572.             }
  573.  
  574.             Group -> Width += 2 * (Handle -> GlyphWidth + Handle -> InterWidth) + 8;
  575.         }
  576.  
  577.         if(ReturnKey)
  578.             Handle -> ReturnKey = ReturnKey;
  579.  
  580.         if(EscKey)
  581.             Handle -> EscKey = EscKey;
  582.  
  583.         if(CursorKey)
  584.             Handle -> CursorKey = CursorKey;
  585.  
  586.         if(TabKey)
  587.             Handle -> TabKey = TabKey;
  588.     }
  589. }
  590.