home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
VSCPPv8.zip
/
VACPP
/
IBMCPP
/
samples
/
IOC
/
BIGCPP
/
BIGCPP.CPP
next >
Wrap
Text File
|
1995-04-07
|
24KB
|
587 lines
/******************************************************************************/
/* BIGCPP SAMPLE PROGRAM - Version 1: Class Implementation */
/* */
/* COPYRIGHT: Copyright (C) International Business Machines Corp., 1992,1993. */
/* */
/* DISCLAIMER OF WARRANTIES: */
/* The following [enclosed] code is sample code created by IBM */
/* Corporation. This sample code is not part of any standard IBM product */
/* and is provided to you solely for the purpose of assisting you in the */
/* development of your applications. The code is provided "AS IS", */
/* without warranty of any kind. IBM shall not be liable for any damages */
/* arising out of your use of the sample code, even if they have been */
/* advised of the possibility of such damages. */
/******************************************************************************/
#ifndef _IBASE_ //Make sure ibase.hpp is included
#include <ibase.hpp> // since that is where IC_<environ>
#endif // is defined.
extern "C"
{
#define INCL_GPI
#include <os2.h>
}
#include "bigcpp.hpp"
#include <igrafctx.hpp>
#include <iglist.hpp>
#include <igbundle.hpp>
#include <itrnsfrm.hpp>
#include <iptarray.hpp>
//*************************************************************************
// main - Application entry point *
//*************************************************************************
int main()
{
MainWindow mainWindow(0x1000); //Create our main window on the desktop
IApplication::current().run(); //Get the current application and
// run it
return 0;
} /* end main */
/*------------------------------------------------------------------------------
| AMainWindow::AMainWindow |
| |
| |
------------------------------------------------------------------------------*/
MainWindow::MainWindow(unsigned long windowIdentifier)
: IFrameWindow ("BIGCPP SAMPLE", //Call IFrameWindow constructor
windowIdentifier, // Main Window ID
IFrameWindow::defaultStyle() // Use default plus
| IFrameWindow::animated), // Set to show with "animation"
drawingCanvas( windowIdentifier+1, this, this ),
bigC(IRectangle()),
border(IRectangle(), 20, false ),
resizeHandler(*this)
{
resizeHandler.handleEventsFor(&drawingCanvas);
setClient( &drawingCanvas );
drawingCanvas.setGraphicList( new IGList() );
drawingCanvas.graphicList()->addAsLast( bigC );
drawingCanvas.graphicList()->addAsLast( border );
// Set a background color for the drawing canvas.
drawingCanvas.setBackgroundColor( IColor::brown );
// Set the color of the big C Plus Plus
IGraphicBundle graphicBundle;
graphicBundle.setPenColor( IColor::yellow )
.setFillColor( IColor::green )
.setFillPattern( IGraphicBundle::dense6 );
bigC.setGraphicBundle( graphicBundle );
setFocus();
show();
}
/*------------------------------------------------------------------------------
| MainWindow::MainWindow |
| |
| |
------------------------------------------------------------------------------*/
MainWindow::~MainWindow()
{
resizeHandler.stopHandlingEventsFor(&drawingCanvas);
delete drawingCanvas.graphicList();
}
/*------------------------------------------------------------------------------
| MainWindow::resizeGraphics |
| |
| |
------------------------------------------------------------------------------*/
MainWindow& MainWindow::resizeGraphics( const ISize& size )
{
IRectangle client(IPoint(0,0), size);
border.setEnclosingRect(client);
client.shrinkBy( border.thickness()+1 );
bigC.setEnclosingRect( client );
return *this;
}
/*------------------------------------------------------------------------------
| ICPlusPlus::ICPlusPlus |
| |
| |
------------------------------------------------------------------------------*/
ICPlusPlus::ICPlusPlus( const IRectangle& rectangle )
: ICPlusPlus::Inherited(), fRect(rectangle)
{ }
/*------------------------------------------------------------------------------
| ICPlusPlus::~ICPlusPlus |
| |
| |
------------------------------------------------------------------------------*/
ICPlusPlus::~ICPlusPlus( )
{ }
/*------------------------------------------------------------------------------
| ICPlusPlus::drawOn |
| |
| |
------------------------------------------------------------------------------*/
ICPlusPlus& ICPlusPlus::drawOn( IGraphicContext& graphicContext )
{
IGraphicBundle* currentBundle;
ITransformMatrix* currentTransform;
// Check if the graphic object contains a transformation matrix
// and set it on the graphic context.
if (this->hasTransformMatrix())
{
currentTransform = new ITransformMatrix(
graphicContext.worldTransformMatrix());
graphicContext.setWorldTransformMatrix(
this->transformMatrix(), this->transformMethod());
}
// Check if the graphic object contains a graphic bundle and
// set it on the graphic context.
if (this->hasGraphicBundle())
{
currentBundle = new IGraphicBundle(graphicContext);
graphicContext.setGraphicBundle(this->graphicBundle());
}
// Reset hit selected to false
setHitSelected( false );
// The interior of an object should be drawn first becuase the
// frame of the object will overlap the interior of the object if
// the pen width is greater than one.
if (graphicContext.drawOperation() == IGraphicBundle::fill ||
graphicContext.drawOperation() == IGraphicBundle::fillAndFrame)
{
// Presentation Manager does not have a fill color or fill pattern.
// Fill colors and fill patterns are implemented by setting the
// pen (foreground color) to the current fill color when drawing
// the interior of an object. After the interior has been drawn,
// the current pen color and pen pattern should be restored.
IColor currentPenColor( graphicContext.penColor() );
unsigned long currentPenPattern( graphicContext.penPattern() );
// Set the pen color and pen pattern to the fill color and
// fill pattern respectively.
graphicContext.setPenColor( graphicContext.fillColor() );
graphicContext.setPenPattern( graphicContext.fillPattern() );
draw( graphicContext, IGraphicBundle::fill );
// Restore the original pen color and pen pattern.
graphicContext.setPenColor( currentPenColor );
graphicContext.setPenPattern( currentPenPattern );
}
// Draw the outline
if (graphicContext.drawOperation() == IGraphicBundle::frame ||
graphicContext.drawOperation() == IGraphicBundle::fillAndFrame)
draw( graphicContext, IGraphicBundle::frame );
// Restore the graphic context attributes if the object
// has a graphic bundle.
if (this->hasGraphicBundle())
{
graphicContext.setGraphicBundle(*currentBundle);
delete currentBundle;
}
// Restore the graphic context attributes if the objext
// has a transform matrix.
if (this->hasTransformMatrix())
{
graphicContext.setWorldTransformMatrix(*currentTransform, IGraphic::replace );
delete currentTransform;
}
return *this;
}
/*------------------------------------------------------------------------------
| ICPlusPlus::draw |
| |
| |
------------------------------------------------------------------------------*/
ICPlusPlus& ICPlusPlus::draw( IGraphicContext& graphicContext,
IGraphicBundle::DrawOperation drawOperation )
{
// whole fraction
FIXED fxOuter(MAKEFIXED( 1, 0 ));
FIXED fxInner(MAKEFIXED( 0, 0xE000 ));
FIXED fxStart(MAKEFIXED( 30, 0 ));
FIXED fxSweep(MAKEFIXED( 300, 0 )); // 360 - 2*fxStart
ARCPARAMS arcp; // default is circle
POINTL ptl;
long rc;
ptl.x = fRect.center().x();
ptl.y = fRect.center().y();
arcp.lP = fRect.size().width() / 2; //horizontal
arcp.lQ = fRect.size().height() / 2; //vertical
arcp.lR = 0; //no shear
arcp.lS = 0; //no shear
arcp.lQ = -arcp.lQ; //outline use clockwise
GpiSetArcParams( graphicContext.handle(), &arcp );
// Set the pen type to invisible. We want to move the pen without
// drawing.
IGraphicBundle::PenType currentPenType(graphicContext.penType());
graphicContext.setPenType( IGraphicBundle::invisible );
GpiPartialArc( graphicContext.handle() //Move to outer start
, &ptl
, fxOuter
, fxStart
, 0 ); //move only
// If the pen width is greater than 1, begin a path so we can stroke it
// Or create a path if we are going to fill the object.
if (graphicContext.penWidth() > 1 || drawOperation == IGraphicBundle::fill)
GpiBeginPath( graphicContext.handle(), 1L );
// Reset the pen to its original pen type.
graphicContext.setPenType( currentPenType );
rc = GpiPartialArc( graphicContext.handle() //inner line - counterclockwise
, &ptl
, fxInner
, fxStart
, fxSweep );
if (rc == GPI_HITS)
this->setHitSelected(true);
// Change the arc parameters so that the arc is drawn clockwise
arcp.lQ = -arcp.lQ;
GpiSetArcParams( graphicContext.handle(), &arcp );
rc = GpiPartialArc( graphicContext.handle() //outer line - clockwise
, &ptl
, fxOuter
, fxStart
, fxSweep );
if (drawOperation == IGraphicBundle::frame &&
graphicContext.penWidth() > 1)
{
GpiEndPath( graphicContext.handle() );
rc = GpiStrokePath( graphicContext.handle(), 1L, 0 );
}
else if (drawOperation == IGraphicBundle::fill)
{
GpiEndPath( graphicContext.handle() );
rc = GpiFillPath( graphicContext.handle(), 1L, FPATH_ALTERNATE );
}
// Did we get a hit? If so set hit selected to true.
if (rc == GPI_HITS)
this->setHitSelected(true);
//-----------------------------------------------
// 10 9
// ┌─┐
// 11│ │8 plus array indices
// 0 ┌───┘ └───┐7
// 1 └───┐ ┌───┘6
// 2│ │5
// └─┘
// 3 4
//-----------------------------------------------
// Set the pen type to invisible to move the pen to top of the plus
graphicContext.setPenType( IGraphicBundle::invisible );
POINTL plus[13];
GpiPartialArc( graphicContext.handle() //move to top-center
, &ptl
, MAKEFIXED( 0, 0xF000 )
, MAKEFIXED( 7, 0x8000 ) // +7.5 degrees
, 0 ); //move only
// Get the location of the top of the plus
GpiQueryCurrentPosition( graphicContext.handle(), &plus[10] );
// Move to the bottom of the plus
GpiPartialArc( graphicContext.handle() //move to bottom-center
, &ptl
, MAKEFIXED( 0, 0xF000 )
, MAKEFIXED( 352, 0x8000 ) // -7.5 degrees
, 0 ); //move only
GpiQueryCurrentPosition( graphicContext.handle(), &plus[3] );
int incr = (plus[10].y - plus[3].y + 4) / 5;
incr += (incr % 2);
plus[0].x = plus[1].x = fRect.right() - 12 * incr;
plus[2].x = plus[3].x = plus[11].x = plus[10].x = fRect.right() - 10 * incr;
plus[4].x = plus[5].x = plus[8].x = plus[9].x = fRect.right() - 9 * incr;
plus[6].x = plus[7].x = fRect.right() - 7 * incr;
plus[10].y = plus[9].y = fRect.center().y() + 5 * incr / 2;
plus[0].y = plus[11].y = plus[8].y = plus[7].y = fRect.center().y() + incr / 2;
plus[1].y = plus[2].y = plus[5].y = plus[6].y = fRect.center().y() - incr / 2;
plus[3].y = plus[4].y = fRect.center().y() - 5 * incr / 2;
plus[12] = plus[0];
// Reset the pen type
graphicContext.setPenType( currentPenType );
GpiMove( graphicContext.handle(), &plus[0] );
// If the pen width is greater than 1, begin a path so we can stroke it
// Or create a path if we are going to fill the object.
if (graphicContext.penWidth() > 1 || drawOperation == IGraphicBundle::fill)
GpiBeginPath( graphicContext.handle(), 1L );
// Draw the first plus
GpiPolyLine( graphicContext.handle(), 13, plus );
incr *= 6;
// Move the points horizontally
for( int i = 13; i--; plus[i].x += incr );
GpiMove( graphicContext.handle(), &plus[0] );
// Draw the second plus
GpiPolyLine( graphicContext.handle(), 13, plus );
if (drawOperation == IGraphicBundle::frame &&
graphicContext.penWidth() > 1)
{
GpiEndPath( graphicContext.handle() );
rc = GpiStrokePath( graphicContext.handle(), 1L, 0 );
}
else if (drawOperation == IGraphicBundle::fill)
{
GpiEndPath( graphicContext.handle() );
rc = GpiFillPath( graphicContext.handle(), 1L, FPATH_ALTERNATE );
}
// Did we get a hit? If so set hit selected to true.
if (rc == GPI_HITS)
this->setHitSelected(true);
return *this;
}
/*------------------------------------------------------------------------------
| ICPlusPlus::setEnclosingRect |
| |
| |
------------------------------------------------------------------------------*/
ICPlusPlus& ICPlusPlus::setEnclosingRect( const IRectangle& rectangle )
{
fRect = rectangle;
return *this;
}
/*------------------------------------------------------------------------------
| ICPlusPlus::enclosingRect |
| |
| |
------------------------------------------------------------------------------*/
IRectangle ICPlusPlus::enclosingRect( ) const
{
return fRect;
}
/*------------------------------------------------------------------------------
| IGBorder::IGBorder |
| |
| |
------------------------------------------------------------------------------*/
IGBorder::IGBorder( const IRectangle& rectangle,
unsigned long thickness,
Boolean outside,
Boolean raised)
: IGBorder::Inherited(), fTopBorder( IPointArray( 6 )),
fBottomBorder( IPointArray( 6 )), fThickness(thickness),
fOutside( outside ), fRaised( raised )
{
setEnclosingRect( rectangle );
}
/*------------------------------------------------------------------------------
| IGBorder::~IGBorder |
| |
| |
------------------------------------------------------------------------------*/
IGBorder::~IGBorder()
{
}
/*------------------------------------------------------------------------------
| IGBorder::drawOn |
| |
| |
------------------------------------------------------------------------------*/
IGBorder& IGBorder::drawOn( IGraphicContext& graphicContext )
{
fTopBorder.setHitSelected(false);
fBottomBorder.setHitSelected(false);
fTopBorder.drawOn( graphicContext );
if (fTopBorder.isHitSelected())
this->setHitSelected(true);
fBottomBorder.drawOn( graphicContext );
if (fBottomBorder.isHitSelected())
this->setHitSelected(true);
return(*this);
}
/*------------------------------------------------------------------------------
| IGBorder::setEnclosingRect |
| |
| |
------------------------------------------------------------------------------*/
IGBorder& IGBorder::setEnclosingRect( const IRectangle& rectangle )
{
IGraphicBundle bundle;
IRectangle insideRect(rectangle),
outsideRect(rectangle);
if (fOutside)
{
outsideRect.expandBy(fThickness);
}
else
{
insideRect.shrinkBy(fThickness);
}
// 0 1
// *-----------------*
// | /
// | *-------------* 2
// | |3
// | *4
// |/
// *5
fTopBorder.setPoint(0, outsideRect.topLeft())
.setPoint(1, outsideRect.topRight())
.setPoint(2, insideRect.topRight())
.setPoint(3, insideRect.topLeft())
.setPoint(4, insideRect.bottomLeft())
.setPoint(5, outsideRect.bottomLeft());
if (fRaised)
{
bundle.setFillColor( IColor::paleGray );
}
else
{
bundle.setFillColor( IColor::darkGray );
}
fTopBorder.setGraphicBundle( bundle );
// *4
// 3 /|
// * |
// | |
// 2| |
// 1*---------* |
// / |
// 0*-------------*5
//
fBottomBorder.setPoint(0, outsideRect.bottomLeft())
.setPoint(1, insideRect.bottomLeft())
.setPoint(2, insideRect.bottomRight())
.setPoint(3, insideRect.topRight())
.setPoint(4, outsideRect.topRight())
.setPoint(5, outsideRect.bottomRight());
if (fRaised)
{
bundle.setFillColor( IColor::darkGray );
}
else
{
bundle.setFillColor( IColor::paleGray );
}
fBottomBorder.setGraphicBundle( bundle );
return *this;
}
/*------------------------------------------------------------------------------
| IGBorder::enclosingRect |
| |
| |
------------------------------------------------------------------------------*/
IRectangle IGBorder::enclosingRect( ) const
{
const IPointArray& ptArray(fBottomBorder.pointArray());
return IRectangle(ptArray[0], ptArray[4]);
}
/*------------------------------------------------------------------------------
| IGBorder::setThickness |
| |
| |
------------------------------------------------------------------------------*/
IGBorder& IGBorder::setThickness( unsigned long thickness )
{
fThickness = thickness;
setEnclosingRect( enclosingRect() );
return *this;
}
/*------------------------------------------------------------------------------
| IGBorder::thickness |
| |
| |
------------------------------------------------------------------------------*/
unsigned long IGBorder::thickness( ) const
{
return fThickness;
}
/*------------------------------------------------------------------------------
| ResizeHandler::ResizeHandler |
| |
| |
------------------------------------------------------------------------------*/
ResizeHandler::ResizeHandler( MainWindow& mainWindow )
: fMainWindow( mainWindow )
{
}
/*------------------------------------------------------------------------------
| ResizeHandler::~ResizeHandler |
| |
| |
------------------------------------------------------------------------------*/
ResizeHandler::~ResizeHandler( )
{}
/*------------------------------------------------------------------------------
| ResizeHandler::windowResize |
| |
| |
------------------------------------------------------------------------------*/
Boolean ResizeHandler::windowResize( IResizeEvent& event )
{
fMainWindow.resizeGraphics( event.newSize() );
return false;
}