home *** CD-ROM | disk | FTP | other *** search
- // Program : TEXPWIN.CPP
- // Author : Eric Woodruff, CIS ID: 72134,1150
- // Updated : Wed 08/25/93 10:44:43
- // Note : Copyright 1993, Eric Woodruff, All rights reserved
- // Compiler: Borland C++ 3.1
- //
- // This file contains the member functions for the TExplodeWindow class.
- //
- // If you use these classes in your own programs, please send $10 to:
- //
- // Eric Woodruff
- // 16719 Lakeside Drive
- // Medical Lake WA 99022
- //
- // Feel free to distribute these files to anyone, but please distribute them
- // in UNMODIFIED form. If you find any bugs or make any interesting changes,
- // please let me know so that I can maintain these classes and distribute
- // the updates.
- //
- // I can be reached on CompuServe at 72134,1150 if you have any
- // questions or comments. Thanks for trying these classes out!
- //
-
- #include <dos.h>
- #include <values.h>
-
- #define Uses_TFrame
- #define Uses_TRect
- #define Uses_TStreamableClass
- #define Uses_TWindow
- #define Uses_ipstream
- #define Uses_opstream
- #include <tv.h>
-
- __link(RWindow)
-
- #define Uses_TExplodeWindow
- #include <texplode.h>
-
- // ****************************************************************************
- // Make it streamable.
- //
- const char * const near TExplodeWindow::name = "TExplodeWindow";
-
- // Register it with the stream manager.
- TStreamableClass RExplodeWindow(TExplodeWindow::name, TExplodeWindow::build,
- __DELTA(TExplodeWindow));
-
- void TExplodeWindow::write(opstream& os)
- {
- TWindow::write(os);
-
- os << WillExplode << WillImplode << Is_Exploding_Imploding << msDelay;
- }
-
- void *TExplodeWindow::read(ipstream& is)
- {
- TWindow::read(is);
-
- is >> (int)WillExplode >> (int)WillImplode >>
- (int)Is_Exploding_Imploding >> msDelay;
-
- return this;
- }
-
- TStreamable *TExplodeWindow::build()
- {
- return new TExplodeWindow(streamableInit);
- }
-
- // ****************************************************************************
-
- // Implode the window before everything inside it has been been destroyed.
- void TExplodeWindow::close(void)
- {
- if(valid(cmClose))
- {
- // If necessary, implode the window.
- if(WillImplode)
- Implode();
-
- // Now destroy the window.
- TWindow::close();
- }
- }
-
- // Catch calls to set the sfVisible flag to false.
- void TExplodeWindow::setState(ushort aState, Boolean enable)
- {
- if(aState == sfVisible && (state & sfSelected))
- if((state & sfVisible) && !enable && WillImplode)
- {
- Implode();
- WillExplode = True; // When unhidden, explode it again.
- }
-
- TWindow::setState(aState, enable);
- }
-
- // When exploding or imploding the window, don't change any of the views
- // owned by it. They get really messed up if you do.
- void TExplodeWindow::changeBounds(const TRect& bounds)
- {
- TPoint delta;
-
- // Calculate change in size.
- delta.x = (bounds.b.x - bounds.a.x) - size.x;
- delta.y = (bounds.b.y - bounds.a.y) - size.y;
-
- if(!delta.x && !delta.y)
- {
- setBounds(bounds);
- drawView();
- }
- else
- {
- freeBuffer();
- setBounds(bounds);
- clip = getExtent();
-
- lock();
-
- // Don't adjust any of the views belonging to the window during
- // explosion or implosion. They tend to get trashed if you do.
- if(!Is_Exploding_Imploding)
- {
- // doCalcChange() is a function in TGROUP.CPP.
- getBuffer();
- forEach(doCalcChange, &delta);
- }
- else
- {
- frame->size = size; // Do adjust the frame though.
- drawView();
- }
- unlock();
- }
- }
-
- // Size limits would mess up the explosion/implosion process. During
- // those processes, ignore size limits.
- void TExplodeWindow::sizeLimits(TPoint& min, TPoint& max)
- {
- // Ignore limits when imploding or exploding.
- if(Is_Exploding_Imploding)
- {
- min.x = min.y = 0;
- max.x = max.y = MAXINT;
- }
- else
- TWindow::sizeLimits(min, max);
- }
-
- // The only difference is that a check is made on the first call
- // to see if the window should explode to the proper size.
- // If not, it'll act like a normal TWindow.
- void TExplodeWindow::draw(void)
- {
- // Check for the need to explode. This will generally only be
- // true just after construction when the window is inserted into
- // the desktop.
- if(WillExplode)
- Explode();
-
- if(Is_Exploding_Imploding)
- ExpImpDraw(); // Explode or implode draw.
- else
- TWindow::draw(); // Normal draw.
- }
-
- // This function controls the specialized explode or implode draw.
- void TExplodeWindow::ExpImpDraw(void)
- {
- lock();
- TWindow::draw(); // Draw the dialog box.
-
- // This is a kludge to keep the frame in one piece. It
- // didn't want to cooperate in drawing itself over the sub-views
- // of the window, so this'll stop them showing up over the
- // right side and bottom frame lines when exploding or imploding.
- TDrawBuffer b;
- char lb = '\xB3', bb = '\xC4', bc = '\xD9';
- short color = getColor(1);
-
- // Borders and color are different for implosion of a window
- // or an exploding modal window.
- if(Is_Exploding_Imploding == expImploding || (state & sfModal))
- {
- lb = '\xBA';
- bb = '\xCD';
- bc = '\xBC';
- color = getColor(2);
- }
-
- b.moveChar(0, lb, color, size.y);
- writeLine(size.x - 1, 1, size.x, size.y - 2, b);
- b.moveChar(0, bb, color, size.x);
- writeLine(1, size.y - 1, size.x - 2, size.y, b);
- b.moveChar(1, bc, color, 1);
- writeLine(size.x - 2, size.y - 1, size.x - 1, size.y, b);
-
- unlock();
- }
-
- // Here's the code that performs the actual explosion process.
- void TExplodeWindow::Explode(void)
- {
- TRect r;
- TRect bounds = TRect(origin, origin + size);
-
- WillExplode = False; // No need to do it anymore.
- WillImplode = True; // Implode on closing though.
- Is_Exploding_Imploding = expExploding; // Ignore size limits.
-
- // Set minimum size for explosion start.
- r.a.x = origin.x + (bounds.b.x - bounds.a.x) / 2;
- r.b.x = r.a.x + 4; // <-- Anything less 4 here and
- r.a.y = origin.y + (bounds.b.y - bounds.a.y) / 2;
- r.b.y = r.a.y + 2; // <-- 2 here can cause a crash!
-
- while(r != bounds)
- {
- locate(r); // Redraw with new size and delay between
- delay(msDelay); // draws to make the process visible.
-
- if(r.a.x > bounds.a.x) // Grow by one on all sides.
- r.a.x--;
-
- if(r.b.x < bounds.b.x)
- r.b.x++;
-
- if(r.a.y > bounds.a.y)
- r.a.y--;
-
- if(r.b.y < bounds.b.y)
- r.b.y++;
- }
- locate(r); // Draw the final full size window.
-
- Is_Exploding_Imploding = expNeither; // Adhere to limits now.
- }
-
- // Here's the code that performs the actual implosion process.
- void TExplodeWindow::Implode(void)
- {
- TRect r = TRect(origin, origin + size);
- TRect bounds;
-
- WillImplode = False; // Don't do it again.
- Is_Exploding_Imploding = expImploding; // Ignore size limits.
-
- // Set minimum size for implosion end.
- bounds.a.x = origin.x + (r.b.x - r.a.x) / 2;
- bounds.b.x = bounds.a.x + 4; // <-- Anything less than 4 here
- bounds.a.y = origin.y + (r.b.y - r.a.y) / 2;
- bounds.b.y = bounds.a.y + 2; // <-- or 2 here can cause a crash!
-
- while(r != bounds)
- {
- locate(r); // Redraw with new size and delay between
- delay(msDelay); // draws to make the process visible.
-
- if(r.a.x < bounds.a.x) // Shrink by one on all sides.
- r.a.x++;
-
- if(r.b.x > bounds.b.x)
- r.b.x--;
-
- if(r.a.y < bounds.a.y)
- r.a.y++;
-
- if(r.b.y > bounds.b.y)
- r.b.y--;
- }
- locate(r); // Draw the final minimum size window.
-
- Is_Exploding_Imploding = expNeither;
- }
-