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