home *** CD-ROM | disk | FTP | other *** search
- // Program : TEXPDLG.CPP
- // Author : Eric Woodruff, CIS ID: 72134,1150
- // Updated : Wed 08/25/93 10:44:26
- // Note : Copyright 1993, Eric Woodruff, All rights reserved
- // Compiler: Borland C++ 3.1
- //
- // This file contains the member functions for the TExplodeDialog 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_TDialog
- #define Uses_TFrame
- #define Uses_TRect
- #define Uses_TStreamableClass
- #define Uses_ipstream
- #define Uses_opstream
- #include <tv.h>
-
- __link(RDialog)
-
- #define Uses_TExplodeDialog
- #include <texplode.h>
-
- // ****************************************************************************
- // Make it streamable.
- //
- const char * const near TExplodeDialog::name = "TExplodeDialog";
-
- // Register it with the stream manager.
- TStreamableClass RExplodeDialog(TExplodeDialog::name, TExplodeDialog::build,
- __DELTA(TExplodeDialog));
-
- void TExplodeDialog::write(opstream& os)
- {
- TDialog::write(os);
-
- os << WillExplode << WillImplode << Is_Exploding_Imploding << msDelay;
- }
-
- void *TExplodeDialog::read(ipstream& is)
- {
- TDialog::read(is);
-
- is >> (int)WillExplode >> (int)WillImplode >>
- (int)Is_Exploding_Imploding >> msDelay;
-
- return this;
- }
-
- TStreamable *TExplodeDialog::build()
- {
- return new TExplodeDialog(streamableInit);
- }
-
- // ****************************************************************************
-
- // Implode the dialog box before everything inside it has been been destroyed.
- void TExplodeDialog::close(void)
- {
- if(valid(cmClose))
- {
- // If necessary, implode the dialog box.
- if(WillImplode)
- Implode();
-
- // Now destroy the dialog box.
- TDialog::close();
- }
- }
-
- // Catch calls to set the sfVisible flag to false.
- void TExplodeDialog::setState(ushort aState, Boolean enable)
- {
- if(aState == sfVisible && (state & sfSelected))
- if((state & sfVisible) && !enable && WillImplode)
- {
- Implode();
- WillExplode = True; // When unhidden, explode it again.
- }
-
- TDialog::setState(aState, enable);
- }
-
- // When exploding or imploding the dialog box, don't change any of the views
- // owned by it. They get really messed up if you do.
- void TExplodeDialog::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 TExplodeDialog::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
- TDialog::sizeLimits(min, max);
- }
-
- // The only difference is that a check is made on the first call
- // to see if the dialog box should explode to the proper size.
- // If not, it'll act like a normal TDialog.
- void TExplodeDialog::draw(void)
- {
- // Check for the need to explode. This will generally only be
- // true just after construction when the dialog box is inserted into
- // the desktop.
- if(WillExplode)
- Explode();
-
- if(Is_Exploding_Imploding)
- ExpImpDraw(); // Explode or implode draw.
- else
- TDialog::draw(); // Normal draw.
- }
-
- // This function controls the specialized explode or implode draw.
- void TExplodeDialog::ExpImpDraw(void)
- {
- lock();
- TDialog::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 dialog box, so this'll stop them showing up over the
- // right side and bottom frame lines.
- TDrawBuffer b;
- b.moveChar(0, '\xBA', getColor(2), size.y);
- writeLine(size.x - 1, 1, size.x, size.y - 2, b);
- b.moveChar(0, '\xCD', getColor(2), size.x);
- writeLine(1, size.y - 1, size.x - 2, size.y, b);
- b.moveChar(1, '\xBC ', getColor(2), 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 TExplodeDialog::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 dialog box.
-
- Is_Exploding_Imploding = expNeither; // Adhere to limits now.
- }
-
- // Here's the code that performs the actual implosion process.
- void TExplodeDialog::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 dialog box.
-
- Is_Exploding_Imploding = expNeither;
- }
-