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 >
Text File  |  1995-04-07  |  24KB  |  587 lines

  1. /******************************************************************************/
  2. /* BIGCPP SAMPLE PROGRAM - Version 1: Class Implementation                    */
  3. /*                                                                            */
  4. /* COPYRIGHT: Copyright (C) International Business Machines Corp., 1992,1993. */
  5. /*                                                                            */
  6. /* DISCLAIMER OF WARRANTIES:                                                  */
  7. /*   The following [enclosed] code is sample code created by IBM              */
  8. /*   Corporation.  This sample code is not part of any standard IBM product   */
  9. /*   and is provided to you solely for the purpose of assisting you in the    */
  10. /*   development of your applications.  The code is provided "AS IS",         */
  11. /*   without warranty of any kind.  IBM shall not be liable for any damages   */
  12. /*   arising out of your use of the sample code, even if they have been       */
  13. /*   advised of the possibility of such damages.                              */
  14. /******************************************************************************/
  15.  
  16. #ifndef _IBASE_                         //Make sure ibase.hpp is included
  17.   #include <ibase.hpp>                  //  since that is where IC_<environ>
  18. #endif                                  //  is defined.
  19. extern "C"
  20. {
  21.   #define INCL_GPI
  22.   #include <os2.h>
  23. }
  24.  
  25. #include "bigcpp.hpp"
  26. #include <igrafctx.hpp>
  27. #include <iglist.hpp>
  28. #include <igbundle.hpp>
  29. #include <itrnsfrm.hpp>
  30. #include <iptarray.hpp>
  31.  
  32.  
  33. //*************************************************************************
  34. // main  - Application entry point                                        *
  35. //*************************************************************************
  36. int main()
  37. {
  38.   MainWindow  mainWindow(0x1000);       //Create our main window on the desktop
  39.  
  40.   IApplication::current().run();        //Get the current application and
  41.                                         // run it
  42.   return 0;
  43. } /* end main */
  44.  
  45.  
  46. /*------------------------------------------------------------------------------
  47. | AMainWindow::AMainWindow                                                     |
  48. |                                                                              |
  49. |                                                                              |
  50. ------------------------------------------------------------------------------*/
  51. MainWindow::MainWindow(unsigned long windowIdentifier)
  52.   : IFrameWindow ("BIGCPP SAMPLE",      //Call IFrameWindow constructor
  53.     windowIdentifier,                  //  Main Window ID
  54.     IFrameWindow::defaultStyle()        //  Use default plus
  55.     | IFrameWindow::animated),           //  Set to show with "animation"
  56.     drawingCanvas( windowIdentifier+1, this, this ),
  57.     bigC(IRectangle()),
  58.     border(IRectangle(), 20, false ),
  59.     resizeHandler(*this)
  60. {
  61.   resizeHandler.handleEventsFor(&drawingCanvas);
  62.   setClient( &drawingCanvas );
  63.   drawingCanvas.setGraphicList( new IGList() );
  64.   drawingCanvas.graphicList()->addAsLast( bigC );
  65.   drawingCanvas.graphicList()->addAsLast( border );
  66.  
  67.   // Set a background color for the drawing canvas.
  68.   drawingCanvas.setBackgroundColor( IColor::brown );
  69.  
  70.   // Set the color of the big C Plus Plus
  71.   IGraphicBundle graphicBundle;
  72.   graphicBundle.setPenColor( IColor::yellow )
  73.                .setFillColor( IColor::green )
  74.                .setFillPattern( IGraphicBundle::dense6 );
  75.  
  76.   bigC.setGraphicBundle( graphicBundle );
  77.  
  78.   setFocus();
  79.   show();
  80. }
  81.  
  82. /*------------------------------------------------------------------------------
  83. | MainWindow::MainWindow                                                       |
  84. |                                                                              |
  85. |                                                                              |
  86. ------------------------------------------------------------------------------*/
  87. MainWindow::~MainWindow()
  88. {
  89.   resizeHandler.stopHandlingEventsFor(&drawingCanvas);
  90.   delete drawingCanvas.graphicList();
  91. }
  92.  
  93. /*------------------------------------------------------------------------------
  94. | MainWindow::resizeGraphics                                                   |
  95. |                                                                              |
  96. |                                                                              |
  97. ------------------------------------------------------------------------------*/
  98. MainWindow& MainWindow::resizeGraphics( const ISize& size )
  99. {
  100.   IRectangle client(IPoint(0,0), size);
  101.  
  102.   border.setEnclosingRect(client);
  103.  
  104.   client.shrinkBy( border.thickness()+1 );
  105.  
  106.   bigC.setEnclosingRect( client );
  107.  
  108.   return *this;
  109. }
  110.  
  111. /*------------------------------------------------------------------------------
  112. | ICPlusPlus::ICPlusPlus                                                       |
  113. |                                                                              |
  114. |                                                                              |
  115. ------------------------------------------------------------------------------*/
  116. ICPlusPlus::ICPlusPlus( const IRectangle& rectangle )
  117.   : ICPlusPlus::Inherited(), fRect(rectangle)
  118. { }
  119.  
  120. /*------------------------------------------------------------------------------
  121. | ICPlusPlus::~ICPlusPlus                                                      |
  122. |                                                                              |
  123. |                                                                              |
  124. ------------------------------------------------------------------------------*/
  125. ICPlusPlus::~ICPlusPlus( )
  126. { }
  127.  
  128. /*------------------------------------------------------------------------------
  129. | ICPlusPlus::drawOn                                                           |
  130. |                                                                              |
  131. |                                                                              |
  132. ------------------------------------------------------------------------------*/
  133. ICPlusPlus& ICPlusPlus::drawOn( IGraphicContext& graphicContext )
  134. {
  135.   IGraphicBundle*   currentBundle;
  136.   ITransformMatrix* currentTransform;
  137.  
  138.   // Check if the graphic object contains a transformation matrix
  139.   // and set it on the graphic context.
  140.   if (this->hasTransformMatrix())
  141.   {
  142.     currentTransform = new ITransformMatrix(
  143.                                          graphicContext.worldTransformMatrix());
  144.     graphicContext.setWorldTransformMatrix(
  145.                               this->transformMatrix(), this->transformMethod());
  146.   }
  147.  
  148.   // Check if the graphic object contains a graphic bundle and
  149.   // set it on the graphic context.
  150.   if (this->hasGraphicBundle())
  151.   {
  152.     currentBundle = new IGraphicBundle(graphicContext);
  153.     graphicContext.setGraphicBundle(this->graphicBundle());
  154.   }
  155.  
  156.   // Reset hit selected to false
  157.   setHitSelected( false );
  158.  
  159.   // The interior of an object should be drawn first becuase the
  160.   // frame of the object will overlap the interior of the object if
  161.   // the pen width is greater than one.
  162.   if (graphicContext.drawOperation() == IGraphicBundle::fill ||
  163.       graphicContext.drawOperation() == IGraphicBundle::fillAndFrame)
  164.   {
  165.     // Presentation Manager does not have a fill color or fill pattern.
  166.     // Fill colors and fill patterns are implemented by setting the
  167.     // pen (foreground color) to the current fill color when drawing
  168.     // the interior of an object.  After the interior has been drawn,
  169.     // the current pen color and pen pattern should be restored.
  170.  
  171.     IColor currentPenColor( graphicContext.penColor() );
  172.     unsigned long currentPenPattern( graphicContext.penPattern() );
  173.  
  174.     // Set the pen color and pen pattern to the fill color and
  175.     // fill pattern respectively.
  176.     graphicContext.setPenColor( graphicContext.fillColor() );
  177.     graphicContext.setPenPattern( graphicContext.fillPattern() );
  178.  
  179.     draw( graphicContext, IGraphicBundle::fill );
  180.  
  181.     // Restore the original pen color and pen pattern.
  182.     graphicContext.setPenColor( currentPenColor );
  183.     graphicContext.setPenPattern( currentPenPattern );
  184.   }
  185.  
  186.   // Draw the outline
  187.   if (graphicContext.drawOperation() == IGraphicBundle::frame ||
  188.       graphicContext.drawOperation() == IGraphicBundle::fillAndFrame)
  189.     draw( graphicContext, IGraphicBundle::frame );
  190.  
  191.   // Restore the graphic context attributes if the object
  192.   // has a graphic bundle.
  193.   if (this->hasGraphicBundle())
  194.   {
  195.     graphicContext.setGraphicBundle(*currentBundle);
  196.     delete currentBundle;
  197.   }
  198.  
  199.   // Restore the graphic context attributes if the objext
  200.   // has a transform matrix.
  201.   if (this->hasTransformMatrix())
  202.   {
  203.     graphicContext.setWorldTransformMatrix(*currentTransform, IGraphic::replace );
  204.     delete currentTransform;
  205.   }
  206.   return *this;
  207. }
  208.  
  209. /*------------------------------------------------------------------------------
  210. | ICPlusPlus::draw                                                             |
  211. |                                                                              |
  212. |                                                                              |
  213. ------------------------------------------------------------------------------*/
  214. ICPlusPlus& ICPlusPlus::draw( IGraphicContext&               graphicContext,
  215.                               IGraphicBundle::DrawOperation  drawOperation )
  216. {
  217.   //                         whole    fraction
  218.   FIXED     fxOuter(MAKEFIXED(  1,       0      ));
  219.   FIXED     fxInner(MAKEFIXED(  0,       0xE000 ));
  220.   FIXED     fxStart(MAKEFIXED(  30,      0      ));
  221.   FIXED     fxSweep(MAKEFIXED(  300,     0      ));   // 360 - 2*fxStart
  222.   ARCPARAMS arcp;      // default is circle
  223.   POINTL    ptl;
  224.   long      rc;
  225.  
  226.   ptl.x   = fRect.center().x();
  227.   ptl.y   = fRect.center().y();
  228.  
  229.   arcp.lP =  fRect.size().width() / 2;      //horizontal
  230.   arcp.lQ =  fRect.size().height() / 2;     //vertical
  231.   arcp.lR =  0;                             //no shear
  232.   arcp.lS =  0;                             //no shear
  233.   arcp.lQ = -arcp.lQ;                       //outline use clockwise
  234.  
  235.   GpiSetArcParams( graphicContext.handle(), &arcp );
  236.  
  237.   // Set the pen type to invisible.  We want to move the pen without
  238.   // drawing.
  239.  
  240.   IGraphicBundle::PenType currentPenType(graphicContext.penType());
  241.   graphicContext.setPenType( IGraphicBundle::invisible );
  242.  
  243.   GpiPartialArc( graphicContext.handle() //Move to outer start
  244.                , &ptl
  245.                , fxOuter
  246.                , fxStart
  247.                , 0 );                    //move only
  248.  
  249.   // If the pen width is greater than 1, begin a path so we can stroke it
  250.   // Or create a path if we are going to fill the object.
  251.  
  252.   if (graphicContext.penWidth() > 1 || drawOperation == IGraphicBundle::fill)
  253.     GpiBeginPath( graphicContext.handle(), 1L );
  254.  
  255.   // Reset the pen to its original pen type.
  256.   graphicContext.setPenType( currentPenType );
  257.  
  258.   rc = GpiPartialArc( graphicContext.handle()  //inner line - counterclockwise
  259.                     , &ptl
  260.                     , fxInner
  261.                     , fxStart
  262.                     , fxSweep );
  263.   if (rc == GPI_HITS)
  264.     this->setHitSelected(true);
  265.  
  266.   // Change the arc parameters so that the arc is drawn clockwise
  267.   arcp.lQ = -arcp.lQ;
  268.   GpiSetArcParams( graphicContext.handle(), &arcp );
  269.  
  270.   rc = GpiPartialArc( graphicContext.handle()  //outer line - clockwise
  271.                     , &ptl
  272.                     , fxOuter
  273.                     , fxStart
  274.                     , fxSweep );
  275.  
  276.   if (drawOperation == IGraphicBundle::frame &&
  277.       graphicContext.penWidth() > 1)
  278.   {
  279.     GpiEndPath( graphicContext.handle() );
  280.     rc = GpiStrokePath( graphicContext.handle(), 1L, 0 );
  281.   }
  282.   else if (drawOperation == IGraphicBundle::fill)
  283.   {
  284.     GpiEndPath( graphicContext.handle() );
  285.     rc = GpiFillPath( graphicContext.handle(), 1L, FPATH_ALTERNATE );
  286.   }
  287.  
  288.   // Did we get a hit?  If so set hit selected to true.
  289.   if (rc == GPI_HITS)
  290.     this->setHitSelected(true);
  291.  
  292.   //-----------------------------------------------
  293.   //                10 9
  294.   //                 ┌─┐
  295.   //               11│ │8          plus array indices
  296.   //           0 ┌───┘ └───┐7
  297.   //           1 └───┐ ┌───┘6
  298.   //                2│ │5
  299.   //                 └─┘
  300.   //                 3 4
  301.   //-----------------------------------------------
  302.  
  303.   // Set the pen type to invisible to move the pen to top of the plus
  304.  
  305.   graphicContext.setPenType( IGraphicBundle::invisible );
  306.  
  307.   POINTL plus[13];
  308.   GpiPartialArc( graphicContext.handle()  //move to top-center
  309.                , &ptl
  310.                , MAKEFIXED( 0, 0xF000 )
  311.                , MAKEFIXED( 7, 0x8000 )   // +7.5 degrees
  312.                , 0 );                     //move only
  313.  
  314.   // Get the location of the top of the plus
  315.   GpiQueryCurrentPosition( graphicContext.handle(), &plus[10] );
  316.  
  317.   // Move to the bottom of the plus
  318.   GpiPartialArc( graphicContext.handle()  //move to bottom-center
  319.                , &ptl
  320.                , MAKEFIXED( 0, 0xF000 )
  321.                , MAKEFIXED( 352, 0x8000 ) // -7.5 degrees
  322.                , 0 );                     //move only
  323.  
  324.   GpiQueryCurrentPosition( graphicContext.handle(), &plus[3] );
  325.  
  326.   int    incr = (plus[10].y - plus[3].y + 4) / 5;
  327.   incr += (incr % 2);
  328.   plus[0].x = plus[1].x = fRect.right() - 12 * incr;
  329.   plus[2].x = plus[3].x = plus[11].x = plus[10].x = fRect.right() - 10 * incr;
  330.   plus[4].x = plus[5].x = plus[8].x = plus[9].x = fRect.right() - 9 * incr;
  331.   plus[6].x = plus[7].x = fRect.right() - 7 * incr;
  332.   plus[10].y = plus[9].y = fRect.center().y() + 5 * incr / 2;
  333.   plus[0].y = plus[11].y = plus[8].y = plus[7].y = fRect.center().y() + incr / 2;
  334.   plus[1].y = plus[2].y = plus[5].y = plus[6].y = fRect.center().y() - incr / 2;
  335.   plus[3].y = plus[4].y = fRect.center().y() - 5 * incr / 2;
  336.   plus[12] = plus[0];
  337.  
  338.   // Reset the pen type
  339.   graphicContext.setPenType( currentPenType );
  340.  
  341.   GpiMove( graphicContext.handle(), &plus[0] );
  342.  
  343.   // If the pen width is greater than 1, begin a path so we can stroke it
  344.   // Or create a path if we are going to fill the object.
  345.  
  346.   if (graphicContext.penWidth() > 1 || drawOperation == IGraphicBundle::fill)
  347.     GpiBeginPath( graphicContext.handle(), 1L );
  348.  
  349.   // Draw the first plus
  350.   GpiPolyLine( graphicContext.handle(), 13, plus );
  351.  
  352.   incr *= 6;
  353.  
  354.   // Move the points horizontally
  355.   for( int i = 13; i--; plus[i].x += incr );
  356.  
  357.   GpiMove( graphicContext.handle(), &plus[0] );
  358.  
  359.   // Draw the second plus
  360.   GpiPolyLine( graphicContext.handle(), 13, plus );
  361.  
  362.   if (drawOperation == IGraphicBundle::frame &&
  363.       graphicContext.penWidth() > 1)
  364.   {
  365.     GpiEndPath( graphicContext.handle() );
  366.     rc = GpiStrokePath( graphicContext.handle(), 1L, 0 );
  367.   }
  368.   else if (drawOperation == IGraphicBundle::fill)
  369.   {
  370.     GpiEndPath( graphicContext.handle() );
  371.     rc = GpiFillPath( graphicContext.handle(), 1L, FPATH_ALTERNATE );
  372.   }
  373.  
  374.   // Did we get a hit?  If so set hit selected to true.
  375.   if (rc == GPI_HITS)
  376.     this->setHitSelected(true);
  377.  
  378.   return *this;
  379. }
  380.  
  381.  
  382. /*------------------------------------------------------------------------------
  383. | ICPlusPlus::setEnclosingRect                                                 |
  384. |                                                                              |
  385. |                                                                              |
  386. ------------------------------------------------------------------------------*/
  387. ICPlusPlus& ICPlusPlus::setEnclosingRect( const IRectangle& rectangle )
  388. {
  389.   fRect = rectangle;
  390.   return *this;
  391. }
  392.  
  393. /*------------------------------------------------------------------------------
  394. | ICPlusPlus::enclosingRect                                                    |
  395. |                                                                              |
  396. |                                                                              |
  397. ------------------------------------------------------------------------------*/
  398. IRectangle ICPlusPlus::enclosingRect( ) const
  399. {
  400.   return fRect;
  401. }
  402.  
  403. /*------------------------------------------------------------------------------
  404. | IGBorder::IGBorder                                                           |
  405. |                                                                              |
  406. |                                                                              |
  407. ------------------------------------------------------------------------------*/
  408. IGBorder::IGBorder( const IRectangle& rectangle,
  409.                     unsigned long thickness,
  410.                     Boolean outside,
  411.                     Boolean raised)
  412.   : IGBorder::Inherited(), fTopBorder( IPointArray( 6 )),
  413.     fBottomBorder( IPointArray( 6 )), fThickness(thickness),
  414.     fOutside( outside ), fRaised( raised )
  415. {
  416.   setEnclosingRect( rectangle );
  417. }
  418.  
  419. /*------------------------------------------------------------------------------
  420. | IGBorder::~IGBorder                                                          |
  421. |                                                                              |
  422. |                                                                              |
  423. ------------------------------------------------------------------------------*/
  424. IGBorder::~IGBorder()
  425. {
  426. }
  427.  
  428. /*------------------------------------------------------------------------------
  429. | IGBorder::drawOn                                                             |
  430. |                                                                              |
  431. |                                                                              |
  432. ------------------------------------------------------------------------------*/
  433. IGBorder& IGBorder::drawOn( IGraphicContext& graphicContext )
  434. {
  435.   fTopBorder.setHitSelected(false);
  436.   fBottomBorder.setHitSelected(false);
  437.  
  438.   fTopBorder.drawOn( graphicContext );
  439.   if (fTopBorder.isHitSelected())
  440.     this->setHitSelected(true);
  441.  
  442.   fBottomBorder.drawOn( graphicContext );
  443.   if (fBottomBorder.isHitSelected())
  444.     this->setHitSelected(true);
  445.  
  446.   return(*this);
  447. }
  448.  
  449. /*------------------------------------------------------------------------------
  450. | IGBorder::setEnclosingRect                                                   |
  451. |                                                                              |
  452. |                                                                              |
  453. ------------------------------------------------------------------------------*/
  454. IGBorder& IGBorder::setEnclosingRect( const IRectangle& rectangle )
  455. {
  456.   IGraphicBundle bundle;
  457.  
  458.   IRectangle insideRect(rectangle),
  459.              outsideRect(rectangle);
  460.  
  461.   if (fOutside)
  462.   {
  463.     outsideRect.expandBy(fThickness);
  464.   }
  465.   else
  466.   {
  467.     insideRect.shrinkBy(fThickness);
  468.   }
  469.  
  470.   //    0                 1
  471.   //    *-----------------*
  472.   //    |                /
  473.   //    | *-------------* 2
  474.   //    | |3
  475.   //    | *4
  476.   //    |/
  477.   //    *5
  478.  
  479.   fTopBorder.setPoint(0, outsideRect.topLeft())
  480.             .setPoint(1, outsideRect.topRight())
  481.             .setPoint(2, insideRect.topRight())
  482.             .setPoint(3, insideRect.topLeft())
  483.             .setPoint(4, insideRect.bottomLeft())
  484.             .setPoint(5, outsideRect.bottomLeft());
  485.  
  486.   if (fRaised)
  487.   {
  488.     bundle.setFillColor( IColor::paleGray );
  489.   }
  490.   else
  491.   {
  492.     bundle.setFillColor( IColor::darkGray );
  493.   }
  494.  
  495.   fTopBorder.setGraphicBundle( bundle );
  496.  
  497.   //                  *4
  498.   //               3 /|
  499.   //                * |
  500.   //                | |
  501.   //               2| |
  502.   //     1*---------* |
  503.   //     /            |
  504.   //   0*-------------*5
  505.   //
  506.  
  507.   fBottomBorder.setPoint(0, outsideRect.bottomLeft())
  508.                .setPoint(1, insideRect.bottomLeft())
  509.                .setPoint(2, insideRect.bottomRight())
  510.                .setPoint(3, insideRect.topRight())
  511.                .setPoint(4, outsideRect.topRight())
  512.                .setPoint(5, outsideRect.bottomRight());
  513.  
  514.   if (fRaised)
  515.   {
  516.     bundle.setFillColor( IColor::darkGray );
  517.   }
  518.   else
  519.   {
  520.     bundle.setFillColor( IColor::paleGray );
  521.   }
  522.   fBottomBorder.setGraphicBundle( bundle );
  523.   return *this;
  524. }
  525.  
  526. /*------------------------------------------------------------------------------
  527. | IGBorder::enclosingRect                                                      |
  528. |                                                                              |
  529. |                                                                              |
  530. ------------------------------------------------------------------------------*/
  531. IRectangle IGBorder::enclosingRect( ) const
  532. {
  533.   const IPointArray& ptArray(fBottomBorder.pointArray());
  534.   return IRectangle(ptArray[0], ptArray[4]);
  535. }
  536.  
  537. /*------------------------------------------------------------------------------
  538. | IGBorder::setThickness                                                       |
  539. |                                                                              |
  540. |                                                                              |
  541. ------------------------------------------------------------------------------*/
  542. IGBorder& IGBorder::setThickness( unsigned long thickness )
  543. {
  544.   fThickness = thickness;
  545.   setEnclosingRect( enclosingRect() );
  546.   return *this;
  547. }
  548.  
  549. /*------------------------------------------------------------------------------
  550. | IGBorder::thickness                                                          |
  551. |                                                                              |
  552. |                                                                              |
  553. ------------------------------------------------------------------------------*/
  554. unsigned long IGBorder::thickness( ) const
  555. {
  556.   return fThickness;
  557. }
  558.  
  559. /*------------------------------------------------------------------------------
  560. | ResizeHandler::ResizeHandler                                                 |
  561. |                                                                              |
  562. |                                                                              |
  563. ------------------------------------------------------------------------------*/
  564. ResizeHandler::ResizeHandler( MainWindow& mainWindow )
  565.   : fMainWindow( mainWindow )
  566. {
  567. }
  568.  
  569. /*------------------------------------------------------------------------------
  570. | ResizeHandler::~ResizeHandler                                                |
  571. |                                                                              |
  572. |                                                                              |
  573. ------------------------------------------------------------------------------*/
  574. ResizeHandler::~ResizeHandler( )
  575. {}
  576.  
  577. /*------------------------------------------------------------------------------
  578. | ResizeHandler::windowResize                                                  |
  579. |                                                                              |
  580. |                                                                              |
  581. ------------------------------------------------------------------------------*/
  582. Boolean ResizeHandler::windowResize( IResizeEvent& event )
  583. {
  584.   fMainWindow.resizeGraphics( event.newSize() );
  585.   return false;
  586. }
  587.