home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / xpwndg / texpdlg.cpp < prev    next >
C/C++ Source or Header  |  1993-08-25  |  8KB  |  266 lines

  1. // Program : TEXPDLG.CPP
  2. // Author  : Eric Woodruff,  CIS ID: 72134,1150
  3. // Updated : Wed 08/25/93 10:44:26
  4. // Note    : Copyright 1993, Eric Woodruff, All rights reserved
  5. // Compiler: Borland C++ 3.1
  6. //
  7. // This file contains the member functions for the TExplodeDialog class.
  8. //
  9. // If you use these classes in your own programs, please send $10 to:
  10. //
  11. // Eric Woodruff
  12. // 16719 Lakeside Drive
  13. // Medical Lake WA 99022
  14. //
  15. // Feel free to distribute these files to anyone, but please distribute them
  16. // in UNMODIFIED form.  If you find any bugs or make any interesting changes,
  17. // please let me know so that I can maintain these classes and distribute
  18. // the updates.
  19. //
  20. // I can be reached on CompuServe at 72134,1150 if you have any
  21. // questions or comments.  Thanks for trying these classes out!
  22. //
  23.  
  24. #include <dos.h>
  25. #include <values.h>
  26.  
  27. #define Uses_TDialog
  28. #define Uses_TFrame
  29. #define Uses_TRect
  30. #define Uses_TStreamableClass
  31. #define Uses_ipstream
  32. #define Uses_opstream
  33. #include <tv.h>
  34.  
  35. __link(RDialog)
  36.  
  37. #define Uses_TExplodeDialog
  38. #include <texplode.h>
  39.  
  40. // ****************************************************************************
  41. // Make it streamable.
  42. //
  43. const char * const near TExplodeDialog::name = "TExplodeDialog";
  44.  
  45. // Register it with the stream manager.
  46. TStreamableClass RExplodeDialog(TExplodeDialog::name, TExplodeDialog::build,
  47.     __DELTA(TExplodeDialog));
  48.  
  49. void TExplodeDialog::write(opstream& os)
  50. {
  51.     TDialog::write(os);
  52.  
  53.     os << WillExplode << WillImplode << Is_Exploding_Imploding << msDelay;
  54. }
  55.  
  56. void *TExplodeDialog::read(ipstream& is)
  57. {
  58.     TDialog::read(is);
  59.  
  60.     is >> (int)WillExplode >> (int)WillImplode >>
  61.           (int)Is_Exploding_Imploding >> msDelay;
  62.  
  63.     return this;
  64. }
  65.  
  66. TStreamable *TExplodeDialog::build()
  67. {
  68.     return new TExplodeDialog(streamableInit);
  69. }
  70.  
  71. // ****************************************************************************
  72.  
  73. // Implode the dialog box before everything inside it has been been destroyed.
  74. void TExplodeDialog::close(void)
  75. {
  76.     if(valid(cmClose))
  77.     {
  78.         // If necessary, implode the dialog box.
  79.         if(WillImplode)
  80.             Implode();
  81.  
  82.         // Now destroy the dialog box.
  83.         TDialog::close();
  84.     }
  85. }
  86.  
  87. // Catch calls to set the sfVisible flag to false.
  88. void TExplodeDialog::setState(ushort aState, Boolean enable)
  89. {
  90.     if(aState == sfVisible && (state & sfSelected))
  91.         if((state & sfVisible) && !enable && WillImplode)
  92.         {
  93.             Implode();
  94.             WillExplode = True;        // When unhidden, explode it again.
  95.         }
  96.  
  97.     TDialog::setState(aState, enable);
  98. }
  99.  
  100. // When exploding or imploding the dialog box, don't change any of the views
  101. // owned by it.  They get really messed up if you do.
  102. void TExplodeDialog::changeBounds(const TRect& bounds)
  103. {
  104.     TPoint delta;
  105.  
  106.     // Calculate change in size.
  107.     delta.x = (bounds.b.x - bounds.a.x) - size.x;
  108.     delta.y = (bounds.b.y - bounds.a.y) - size.y;
  109.  
  110.     if(!delta.x && !delta.y)
  111.     {
  112.         setBounds(bounds);
  113.         drawView();
  114.     }
  115.     else
  116.     {
  117.         freeBuffer();
  118.         setBounds(bounds);
  119.         clip = getExtent();
  120.  
  121.         lock();
  122.  
  123.         // Don't adjust any of the views belonging to the window during
  124.         // explosion or implosion.  They tend to get trashed if you do.
  125.         if(!Is_Exploding_Imploding)
  126.         {
  127.             // doCalcChange() is a function in TGROUP.CPP.
  128.             getBuffer();
  129.             forEach(doCalcChange, &delta);
  130.         }
  131.         else
  132.         {
  133.             frame->size = size;     // Do adjust the frame though.
  134.             drawView();
  135.         }
  136.         unlock();
  137.     }
  138. }
  139.  
  140. // Size limits would mess up the explosion/implosion process.  During
  141. // those processes, ignore size limits.
  142. void TExplodeDialog::sizeLimits(TPoint& min, TPoint& max)
  143. {
  144.     // Ignore limits when imploding or exploding.
  145.     if(Is_Exploding_Imploding)
  146.     {
  147.         min.x = min.y = 0;
  148.         max.x = max.y = MAXINT;
  149.     }
  150.     else
  151.         TDialog::sizeLimits(min, max);
  152. }
  153.  
  154. // The only difference is that a check is made on the first call
  155. // to see if the dialog box should explode to the proper size.
  156. // If not, it'll act like a normal TDialog.
  157. void TExplodeDialog::draw(void)
  158. {
  159.     // Check for the need to explode.  This will generally only be
  160.     // true just after construction when the dialog box is inserted into
  161.     // the desktop.
  162.     if(WillExplode)
  163.         Explode();
  164.  
  165.     if(Is_Exploding_Imploding)
  166.         ExpImpDraw();           // Explode or implode draw.
  167.     else
  168.         TDialog::draw();        // Normal draw.
  169. }
  170.  
  171. // This function controls the specialized explode or implode draw.
  172. void TExplodeDialog::ExpImpDraw(void)
  173. {
  174.     lock();
  175.     TDialog::draw();    // Draw the dialog box.
  176.  
  177.     // This is a kludge to keep the frame in one piece.  It
  178.     // didn't want to cooperate in drawing itself over the sub-views
  179.     // of the dialog box, so this'll stop them showing up over the
  180.     // right side and bottom frame lines.
  181.     TDrawBuffer b;
  182.     b.moveChar(0, '\xBA', getColor(2), size.y);
  183.     writeLine(size.x - 1, 1, size.x, size.y - 2, b);
  184.     b.moveChar(0, '\xCD', getColor(2), size.x);
  185.     writeLine(1, size.y - 1, size.x - 2, size.y, b);
  186.     b.moveChar(1, '\xBC ', getColor(2), 1);
  187.     writeLine(size.x - 2, size.y - 1, size.x - 1, size.y, b);
  188.  
  189.     unlock();
  190. }
  191.  
  192. // Here's the code that performs the actual explosion process.
  193. void TExplodeDialog::Explode(void)
  194. {
  195.     TRect r;
  196.     TRect bounds = TRect(origin, origin + size);
  197.  
  198.     WillExplode = False;                     // No need to do it anymore.
  199.     WillImplode = True;                      // Implode on closing though.
  200.     Is_Exploding_Imploding = expExploding;   // Ignore size limits.
  201.  
  202.     // Set minimum size for explosion start.
  203.     r.a.x = origin.x + (bounds.b.x - bounds.a.x) / 2;
  204.     r.b.x = r.a.x + 4;                    // <-- Anything less 4 here and
  205.     r.a.y = origin.y + (bounds.b.y - bounds.a.y) / 2;
  206.     r.b.y = r.a.y + 2;                    // <-- 2 here can cause a crash!
  207.  
  208.     while(r != bounds)
  209.     {
  210.         locate(r);            // Redraw with new size and delay between
  211.         delay(msDelay);       // draws to make the process visible.
  212.  
  213.         if(r.a.x > bounds.a.x)      // Grow by one on all sides.
  214.             r.a.x--;
  215.  
  216.         if(r.b.x < bounds.b.x)
  217.             r.b.x++;
  218.  
  219.         if(r.a.y > bounds.a.y)
  220.             r.a.y--;
  221.  
  222.         if(r.b.y < bounds.b.y)
  223.             r.b.y++;
  224.     }
  225.     locate(r);     // Draw the final full size dialog box.
  226.  
  227.     Is_Exploding_Imploding = expNeither;        // Adhere to limits now.
  228. }
  229.  
  230. // Here's the code that performs the actual implosion process.
  231. void TExplodeDialog::Implode(void)
  232. {
  233.     TRect r = TRect(origin, origin + size);
  234.     TRect bounds;
  235.  
  236.     WillImplode = False;                          // Don't do it again.
  237.     Is_Exploding_Imploding = expImploding;        // Ignore size limits.
  238.  
  239.     // Set minimum size for implosion end.
  240.     bounds.a.x = origin.x + (r.b.x - r.a.x) / 2;
  241.     bounds.b.x = bounds.a.x + 4;            // <-- Anything less than 4 here
  242.     bounds.a.y = origin.y + (r.b.y - r.a.y) / 2;
  243.     bounds.b.y = bounds.a.y + 2;            // <-- or 2 here can cause a crash!
  244.  
  245.     while(r != bounds)
  246.     {
  247.         locate(r);            // Redraw with new size and delay between
  248.         delay(msDelay);       // draws to make the process visible.
  249.  
  250.         if(r.a.x < bounds.a.x)      // Shrink by one on all sides.
  251.             r.a.x++;
  252.  
  253.         if(r.b.x > bounds.b.x)
  254.             r.b.x--;
  255.  
  256.         if(r.a.y < bounds.a.y)
  257.             r.a.y++;
  258.  
  259.         if(r.b.y > bounds.b.y)
  260.             r.b.y--;
  261.     }
  262.     locate(r);     // Draw the final minimum size dialog box.
  263.  
  264.     Is_Exploding_Imploding = expNeither;
  265. }
  266.