home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / code / bcpp / file18 / texpwin.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  8.1 KB  |  279 lines

  1. // Program : TEXPWIN.CPP
  2. // Author  : Eric Woodruff,  CIS ID: 72134,1150
  3. // Updated : Wed 08/25/93 10:44:43
  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 TExplodeWindow 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_TFrame
  28. #define Uses_TRect
  29. #define Uses_TStreamableClass
  30. #define Uses_TWindow
  31. #define Uses_ipstream
  32. #define Uses_opstream
  33. #include <tv.h>
  34.  
  35. __link(RWindow)
  36.  
  37. #define Uses_TExplodeWindow
  38. #include <texplode.h>
  39.  
  40. // ****************************************************************************
  41. // Make it streamable.
  42. //
  43. const char * const near TExplodeWindow::name = "TExplodeWindow";
  44.  
  45. // Register it with the stream manager.
  46. TStreamableClass RExplodeWindow(TExplodeWindow::name, TExplodeWindow::build,
  47.     __DELTA(TExplodeWindow));
  48.  
  49. void TExplodeWindow::write(opstream& os)
  50. {
  51.     TWindow::write(os);
  52.  
  53.     os << WillExplode << WillImplode << Is_Exploding_Imploding << msDelay;
  54. }
  55.  
  56. void *TExplodeWindow::read(ipstream& is)
  57. {
  58.     TWindow::read(is);
  59.  
  60.     is >> (int)WillExplode >> (int)WillImplode >>
  61.           (int)Is_Exploding_Imploding >> msDelay;
  62.  
  63.     return this;
  64. }
  65.  
  66. TStreamable *TExplodeWindow::build()
  67. {
  68.     return new TExplodeWindow(streamableInit);
  69. }
  70.  
  71. // ****************************************************************************
  72.  
  73. // Implode the window before everything inside it has been been destroyed.
  74. void TExplodeWindow::close(void)
  75. {
  76.     if(valid(cmClose))
  77.     {
  78.         // If necessary, implode the window.
  79.         if(WillImplode)
  80.             Implode();
  81.  
  82.         // Now destroy the window.
  83.         TWindow::close();
  84.     }
  85. }
  86.  
  87. // Catch calls to set the sfVisible flag to false.
  88. void TExplodeWindow::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.     TWindow::setState(aState, enable);
  98. }
  99.  
  100. // When exploding or imploding the window, don't change any of the views
  101. // owned by it.  They get really messed up if you do.
  102. void TExplodeWindow::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 TExplodeWindow::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.         TWindow::sizeLimits(min, max);
  152. }
  153.  
  154. // The only difference is that a check is made on the first call
  155. // to see if the window should explode to the proper size.
  156. // If not, it'll act like a normal TWindow.
  157. void TExplodeWindow::draw(void)
  158. {
  159.     // Check for the need to explode.  This will generally only be
  160.     // true just after construction when the window 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.         TWindow::draw();        // Normal draw.
  169. }
  170.  
  171. // This function controls the specialized explode or implode draw.
  172. void TExplodeWindow::ExpImpDraw(void)
  173. {
  174.     lock();
  175.     TWindow::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 window, so this'll stop them showing up over the
  180.     // right side and bottom frame lines when exploding or imploding.
  181.     TDrawBuffer b;
  182.     char  lb = '\xB3', bb = '\xC4', bc = '\xD9';
  183.     short color = getColor(1);
  184.  
  185.     // Borders and color are different for implosion of a window
  186.     // or an exploding modal window.
  187.     if(Is_Exploding_Imploding == expImploding || (state & sfModal))
  188.     {
  189.         lb = '\xBA';
  190.         bb = '\xCD';
  191.         bc = '\xBC';
  192.         color = getColor(2);
  193.     }
  194.  
  195.     b.moveChar(0, lb, color, size.y);
  196.     writeLine(size.x - 1, 1, size.x, size.y - 2, b);
  197.     b.moveChar(0, bb, color, size.x);
  198.     writeLine(1, size.y - 1, size.x - 2, size.y, b);
  199.     b.moveChar(1, bc, color, 1);
  200.     writeLine(size.x - 2, size.y - 1, size.x - 1, size.y, b);
  201.  
  202.     unlock();
  203. }
  204.  
  205. // Here's the code that performs the actual explosion process.
  206. void TExplodeWindow::Explode(void)
  207. {
  208.     TRect r;
  209.     TRect bounds = TRect(origin, origin + size);
  210.  
  211.     WillExplode = False;                      // No need to do it anymore.
  212.     WillImplode = True;                       // Implode on closing though.
  213.     Is_Exploding_Imploding = expExploding;    // Ignore size limits.
  214.  
  215.     // Set minimum size for explosion start.
  216.     r.a.x = origin.x + (bounds.b.x - bounds.a.x) / 2;
  217.     r.b.x = r.a.x + 4;                    // <-- Anything less 4 here and
  218.     r.a.y = origin.y + (bounds.b.y - bounds.a.y) / 2;
  219.     r.b.y = r.a.y + 2;                    // <-- 2 here can cause a crash!
  220.  
  221.     while(r != bounds)
  222.     {
  223.         locate(r);            // Redraw with new size and delay between
  224.         delay(msDelay);       // draws to make the process visible.
  225.  
  226.         if(r.a.x > bounds.a.x)      // Grow by one on all sides.
  227.             r.a.x--;
  228.  
  229.         if(r.b.x < bounds.b.x)
  230.             r.b.x++;
  231.  
  232.         if(r.a.y > bounds.a.y)
  233.             r.a.y--;
  234.  
  235.         if(r.b.y < bounds.b.y)
  236.             r.b.y++;
  237.     }
  238.     locate(r);     // Draw the final full size window.
  239.  
  240.     Is_Exploding_Imploding = expNeither;        // Adhere to limits now.
  241. }
  242.  
  243. // Here's the code that performs the actual implosion process.
  244. void TExplodeWindow::Implode(void)
  245. {
  246.     TRect r = TRect(origin, origin + size);
  247.     TRect bounds;
  248.  
  249.     WillImplode = False;                          // Don't do it again.
  250.     Is_Exploding_Imploding = expImploding;        // Ignore size limits.
  251.  
  252.     // Set minimum size for implosion end.
  253.     bounds.a.x = origin.x + (r.b.x - r.a.x) / 2;
  254.     bounds.b.x = bounds.a.x + 4;            // <-- Anything less than 4 here
  255.     bounds.a.y = origin.y + (r.b.y - r.a.y) / 2;
  256.     bounds.b.y = bounds.a.y + 2;            // <-- or 2 here can cause a crash!
  257.  
  258.     while(r != bounds)
  259.     {
  260.         locate(r);            // Redraw with new size and delay between
  261.         delay(msDelay);       // draws to make the process visible.
  262.  
  263.         if(r.a.x < bounds.a.x)      // Shrink by one on all sides.
  264.             r.a.x++;
  265.  
  266.         if(r.b.x > bounds.b.x)
  267.             r.b.x--;
  268.  
  269.         if(r.a.y < bounds.a.y)
  270.             r.a.y++;
  271.  
  272.         if(r.b.y > bounds.b.y)
  273.             r.b.y--;
  274.     }
  275.     locate(r);     // Draw the final minimum size window.
  276.  
  277.     Is_Exploding_Imploding = expNeither;
  278. }
  279.