home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / AlignBox.C < prev    next >
C/C++ Source or Header  |  1998-11-23  |  10KB  |  405 lines

  1. // $Id: AlignBox.C,v 1.9 1998/11/23 15:00:13 zeller Exp $
  2. // Box alignments
  3.  
  4. // Copyright (C) 1995 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of DDD.
  8. // 
  9. // DDD is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // DDD is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU General Public
  20. // License along with DDD -- see the file COPYING.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // DDD is the data display debugger.
  25. // For details, see the DDD World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ddd/',
  27. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  28.  
  29. #ifdef __GNUG__
  30. #pragma implementation
  31. #endif
  32.  
  33. char AlignBox_rcsid[] = 
  34.     "$Id: AlignBox.C,v 1.9 1998/11/23 15:00:13 zeller Exp $";
  35.  
  36. #include "assert.h"
  37. #include "misc.h"
  38. #include "AlignBox.h"
  39.  
  40. DEFINE_TYPE_INFO_1(AlignBox, CompositeBox)
  41. DEFINE_TYPE_INFO_1(HAlignBox, AlignBox)
  42. DEFINE_TYPE_INFO_1(TAlignBox, AlignBox)
  43. DEFINE_TYPE_INFO_1(UAlignBox, AlignBox)
  44. DEFINE_TYPE_INFO_1(VAlignBox, AlignBox)
  45.  
  46.  
  47. // Draw alignment (horizontal or vertical)
  48. void AlignBox::drawAlign(Widget w, 
  49.              const BoxRegion& r, 
  50.              const BoxRegion& exposed, 
  51.              GC gc,
  52.              bool context_selected, 
  53.              BoxDimension dimen) const
  54. {
  55.     BoxSize space   = r.space();
  56.     BoxPoint origin = r.origin();
  57.  
  58.     // Compute remaining space and remaining space per child
  59.     BoxCoordinate remainder = space[dimen] - size(dimen);
  60.     BoxCoordinate remainder_per_extend =
  61.     (extend(dimen) == 0 || remainder < 0) ? 0 : remainder / extend(dimen);
  62.     BoxCoordinate pixel_stuff =
  63.     (extend(dimen) == 0 || remainder < 0) ? 0 : remainder % extend(dimen);
  64.  
  65.     BoxPoint child_origin = origin;
  66.     BoxSize  child_space  = space;
  67.  
  68.     for (int i = 0; i < nchildren(); i++)
  69.     {
  70.     Box *child = (Box *)(*this)[i];
  71.  
  72.     // If child is extensible, add remaining space per child
  73.     child_space[dimen] = child->size(dimen) + 
  74.         remainder_per_extend * child->extend(dimen);
  75.     
  76.     // Add remaining pixels
  77.     if (pixel_stuff > 0)
  78.     {
  79.         BoxCoordinate stuff = min(remainder_per_extend, pixel_stuff);
  80.         child_space[dimen] += stuff;
  81.         pixel_stuff -= stuff;
  82.     }
  83.  
  84.     // Draw child
  85.     child->draw(w, 
  86.             BoxRegion(child_origin, child_space), 
  87.             exposed, gc, context_selected);
  88.  
  89.     // Draw next child at offset of CHILD_SPACE
  90.     child_origin[dimen] += child_space[dimen];
  91.     }
  92. }
  93.  
  94. // Recompute size
  95. Box *AlignBox::resize()
  96. {
  97.     for (int i = 0; i < nchildren(); i++)
  98.     {
  99.     Box* child = (*this)[i];
  100.     if (i == 0)
  101.         setSize(child->resize());
  102.     else
  103.         addSize(child->resize());
  104.     }
  105.     return this;
  106. }
  107.  
  108.  
  109.  
  110.  
  111.  
  112. // HAlignBox
  113.  
  114. // Add to horizontal alignment
  115. void HAlignBox::addSize(Box *b)
  116. {
  117.     thesize()   &= b->size();
  118.     theextend() &= b->extend();
  119.  
  120.     // Reuse free space in lower right corner
  121.     if (b->size(X) > 0)
  122.     _corner = b->corner();
  123. }
  124.  
  125.  
  126. void HAlignBox::_print(ostream& os, 
  127.                const BoxRegion& region, 
  128.                const PrintGC& gc) const
  129. {
  130.     int i;
  131.  
  132.     BoxSize space   = region.space();
  133.     BoxPoint origin = region.origin();
  134.  
  135.     BoxCoordinate rem = space[X] - size(X);
  136.     BoxCoordinate perextend = 
  137.     (extend(X) == 0 || rem <= 0) ? 0 : rem / extend(X);
  138.     BoxCoordinate pixels = 
  139.     (extend(X) == 0 || rem <= 0) ? 0 : rem % extend(X);
  140.     
  141.     BoxPoint child_origin = origin;
  142.     BoxSize  child_space;
  143.  
  144.     for (i = 0; i < nchildren(); i++ ) {
  145.     Box *child = (Box *)(*this)[i];
  146.  
  147.     child_space[Y] = space[Y];
  148.     child_space[X] = child->size(X) + perextend * child->extend(X);
  149.         
  150.     if (pixels > 0) {
  151.         BoxCoordinate stuff = min(perextend, pixels);
  152.         child_space[X] += stuff;
  153.         pixels -= stuff;
  154.     }
  155.  
  156.     child->_print(os, BoxRegion (child_origin, child_space), gc);
  157.     
  158.     child_origin[X] += child_space[X];
  159.     }
  160. }
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167. // VAlignBox
  168.  
  169. // Add to vertical alignment
  170. void VAlignBox::addSize(Box *b) 
  171. {
  172.     thesize()   |= b->size();
  173.     theextend() |= b->extend();
  174.  
  175.     // Compute free space in lower right corner
  176.     if (b->size(Y) > 0)
  177.     {
  178.     _corner[Y] = b->corner()[Y];
  179.     _corner[X] = b->extend(X) ? 0 : 
  180.         size(X) - (b->size(X) - b->corner()[X]);
  181.     }
  182. }
  183.  
  184. void VAlignBox::_print(ostream& os, 
  185.                const BoxRegion& region, 
  186.                const PrintGC& gc) const
  187. {
  188.     int i;
  189. #if DEBUG
  190.     os << "#\n";
  191.     os << "# VAlignBox\n";
  192.     os << "# Requiered Region:" << region << "\n";
  193.     os << "# Actual Size:" << size();
  194.     os << "# Extend:" << extend() << "\n";
  195. #endif
  196.     BoxPoint origin = region.origin();
  197.     BoxSize space = region.space();
  198.  
  199.     BoxCoordinate rem = space[Y] - size(Y);
  200.     BoxCoordinate perextend = 
  201.     (extend(Y) == 0 || rem <= 0) ? 0 : rem / extend(Y);
  202.     BoxCoordinate pixels = 
  203.     (extend(Y) == 0 || rem <= 0) ? 0 : rem % extend(Y);
  204.     
  205.     BoxPoint child_origin = origin;
  206.     BoxSize  child_space;
  207.  
  208.     for (i = 0; i < nchildren(); i++ ) {
  209.     Box *child = (Box *)(*this)[i];
  210.  
  211.     child_space[X] = space[X];
  212.     child_space[Y] = child->size(Y) + perextend * child->extend(Y);
  213.     
  214.     if (pixels > 0) {
  215.         BoxCoordinate stuff = min (perextend, pixels);
  216.         child_space[X] += stuff;
  217.         pixels -= stuff;
  218.     }
  219.  
  220.     child->_print(os, BoxRegion (child_origin, child_space), gc);
  221.     child_origin[Y] += child_space[Y];
  222.     }
  223. }
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234. // UAlignBox
  235.  
  236. // Add box to unaligned alignment
  237. void UAlignBox::addSize(Box *b)
  238. {
  239.     thesize()   ^= b->size();
  240.     theextend() ^= b->extend();
  241.  
  242.     // Reuse free space in lower right corner
  243.     if (b->size() > BoxSize(0, 0))
  244.     _corner = b->corner();
  245. }
  246.  
  247. // Draw
  248. void UAlignBox::_draw(Widget w, 
  249.               const BoxRegion& r, 
  250.               const BoxRegion& exposed, 
  251.               GC gc,
  252.               bool context_selected) const
  253. {
  254.     // Draw all children at the same place
  255.     for (int i = 0; i < nchildren(); i++)
  256.     {
  257.     Box *child = (Box *)(*this)[i];
  258.     child->draw(w, r, exposed, gc, context_selected);
  259.     }
  260. }
  261.  
  262. // Print
  263. void UAlignBox::_print(ostream& os, 
  264.                const BoxRegion& region, 
  265.                const PrintGC& gc) const
  266. {
  267.     for (int i = 0; i < nchildren(); i++) {
  268.     (*this)[i]->_print(os, region, gc);
  269.     }
  270. }
  271.  
  272.  
  273.  
  274.  
  275.  
  276. // TAlignBox
  277.  
  278. // Add box to textual alignment
  279. void TAlignBox::addSize(Box *b) 
  280. {
  281.     // Fit into lower right corner
  282.     thesize()   += (b->size() ^ _corner) - _corner;
  283.     theextend() &= b->extend();
  284.  
  285.     // Adapt corner
  286.     if (b->size(X) >= _corner[X])
  287.     {
  288.     // Reuse corner
  289.     _corner = b->corner();  
  290.     }
  291.     else
  292.     {
  293.     // Resize corner
  294.     _corner[X] -= b->size(X);
  295.     _corner[Y]  = max(b->size(Y), _corner[Y]);
  296.     }
  297. }
  298.  
  299. // Draw
  300. void TAlignBox::_draw(Widget w, 
  301.               const BoxRegion& r, 
  302.               const BoxRegion& exposed, 
  303.               GC gc,
  304.               bool context_selected) const
  305. {
  306.     BoxSize space   = r.space();
  307.     BoxPoint origin = r.origin();
  308.  
  309.     // If this is non-extensible, use minimal space
  310.     if (extend(X) == 0)
  311.     space[X] = size(X);
  312.     if (extend(Y) == 0)
  313.     space[Y] = size(Y);
  314.  
  315.     // Compute remaining space and remaining space per child
  316.     BoxCoordinate remainder = space[X] - size(X);
  317.     BoxCoordinate remainder_per_extend = 
  318.     (extend(X) == 0 || remainder < 0) ? 0 : remainder / extend(X);
  319.     BoxCoordinate pixel_stuff = 
  320.     (extend(X) == 0 || remainder < 0) ? 0 : remainder % extend(X);
  321.  
  322.     BoxPoint child_origin = origin;
  323.     BoxSize  child_space  = space;
  324.  
  325.     for (int i = 0; i < nchildren(); i++)
  326.     {
  327.     Box *child = (Box *)(*this)[i];
  328.  
  329.     // If child is extensible, add remaining space per child
  330.     child_space[X] = child->size(X) + 
  331.         remainder_per_extend * child->extend(X);
  332.     
  333.     // Add remaining pixels
  334.     if (pixel_stuff > 0)
  335.     {
  336.         BoxCoordinate stuff = min(remainder_per_extend, pixel_stuff);
  337.         child_space[X] += stuff;
  338.         pixel_stuff -= stuff;
  339.     }
  340.  
  341.     // Draw child
  342.     child->draw(w, BoxRegion(child_origin, child_space), 
  343.             exposed, gc, context_selected);
  344.     
  345.     // Fit next child into corner
  346.     child_origin[X] += (child_space[X] - child->corner()[X]);
  347.     child_origin[Y] += (child->size(Y) - child->corner()[Y]);
  348.     }
  349. }
  350.  
  351. void TAlignBox::_print(ostream& os, 
  352.                const BoxRegion& region, 
  353.                const PrintGC& gc) const
  354. {
  355.     BoxSize space   = region.space();
  356.     BoxPoint origin = region.origin();
  357.  
  358.     // if not extendible, reduce to minimum space
  359.     
  360.     if (extend(X) == 0)
  361.     space[X] = size(X);
  362.     if (extend(Y) == 0)
  363.     space[Y] = size(Y);
  364.     
  365.     // calculate remaining space and rem. space per child
  366.  
  367.     BoxCoordinate remainder = space[X] - size(X);
  368.     BoxCoordinate remainder_per_extend = 
  369.     (extend(X) == 0 || remainder < 0) ? 
  370.     0 : remainder / extend(X);
  371.     BoxCoordinate pixel_stuff = 
  372.     (extend(X) == 0 || remainder < 0) ? 
  373.     0 : remainder % extend(X);
  374.     
  375.     BoxPoint child_origin = origin;
  376.     BoxSize  child_space  = space;
  377.  
  378.     for (int i = 0; i < nchildren(); i++)     {
  379.         Box *child = (Box *)(*this)[i];
  380.  
  381.     // if child extendible, add space per child
  382.  
  383.     child_space[X] = child->size(X) + 
  384.         remainder_per_extend * child->extend(X);
  385.     
  386.     // Add remaining space
  387.     
  388.     if (pixel_stuff > 0) {
  389.         BoxCoordinate stuff = 
  390.         min (remainder_per_extend, pixel_stuff);
  391.         child_space[X] += stuff;
  392.         pixel_stuff -= stuff;
  393.     }
  394.  
  395.     // print child
  396.     
  397.     child->_print(os, BoxRegion(child_origin, child_space), gc);
  398.     
  399.     // move child to corner
  400.  
  401.     child_origin[X] += (child_space[X] - child->corner()[X]);
  402.     child_origin[Y] += (child->size(Y) - child->corner()[Y]);
  403.     }
  404. }
  405.