home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / VSCPPv8.zip / VACPP / IBMCPP / samples / VISBUILD / DOODLE / DAREA / DAREA.CPP next >
Text File  |  1995-05-10  |  31KB  |  864 lines

  1. /******************************************************************************/
  2. /* DOODLE PROGRAM - Version 1: Class Implementation   (DAREA.CPP)             */
  3. /*                                                                            */
  4. /* COPYRIGHT: Copyright (C) International Business Machines Corp., 1995.      */
  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. #include "darea.hpp"
  20. #include <igline.hpp>
  21. #include <igpyline.hpp>
  22. #include <igelipse.hpp>
  23. #include <igarc.hpp>
  24. #include <igpie.hpp>
  25. #include <igstring.hpp>
  26. #include <igbitmap.hpp>
  27. #include <icolor.hpp>
  28. #include <iglist.hpp>
  29. #include <math.h>
  30.  
  31. /*------------------------------------------------------------------------------
  32. | angleFromPoints                                                              |
  33. |                                                                              |
  34. | Given two points determine the angle between the horizontal line through     |
  35. | the first point and the line from the first point to the second point.       |
  36. ------------------------------------------------------------------------------*/
  37. double angleFromPoints( const IPoint& center, const IPoint& drop )
  38. {
  39.   IPoint temp;
  40.   double angle;
  41.  
  42.   temp  = drop - center;
  43.   angle = atan2((double)temp.y(), (double)temp.x());
  44.   angle *= 57.295779;
  45.  
  46.   if ( angle < 0.0 )
  47.     angle += 360.0;
  48.  
  49.   return angle;
  50. }
  51.  
  52. /*------------------------------------------------------------------------------
  53. | DrawingArea::DrawingArea                                                     |
  54. |                                                                              |
  55. |                                                                              |
  56. ------------------------------------------------------------------------------*/
  57. DrawingArea::DrawingArea( unsigned long id, IWindow* parent,
  58.                           IWindow* owner, const IRectangle& rect )
  59.   : IDrawingCanvas( id, parent, owner, rect ),
  60.     gc(handle()),
  61.     currentfont(),
  62.     currentBundle(),
  63.     currentBitmap(),
  64.     dState( notDrawing ),
  65.     currentObj( move ),
  66.     iGraphic(0),
  67.     moveGraphic(0),
  68.     moveRect(IRectangle()),
  69.     startingPt(), previousPt(), tempPt(),
  70.     pointCount(0),
  71.     flyOverHandler(0)
  72. {
  73.   currentBundle.setPenColor(IGraphicContext::defaultPenColor())
  74.                .setFillColor(IGraphicContext::defaultFillColor())
  75.                .setMixMode(IGraphicContext::defaultMixMode())
  76.                .setPenJoiningStyle(IGraphicBundle::miter)
  77.                .setDrawOperation( IGraphicBundle::fillAndFrame );
  78.  
  79.   gc.setMixMode( IGraphicBundle::xor ).setPenColor( IColor::white )
  80.     .setFillColor( IColor::white )
  81.     .setDrawOperation( IGraphicBundle::frame )
  82.     .setHitApertureSize( ISize(2,2) );
  83.   setGraphicContext( &gc );
  84.  
  85.   setGraphicList( new IGList() );
  86.  
  87.   // Load the pointers.
  88.  
  89. //  IResourceLibrary reslib;
  90.   IDynamicLinkLibrary reslib("CPPOV53R");
  91.   ptrLine      = reslib.loadPointer( POINTER_LINE );
  92.   ptrFreehand  = reslib.loadPointer( POINTER_FREEHAND );
  93.   ptrRectangle = reslib.loadPointer( POINTER_RECTANGLE );
  94.   ptrEllipse   = reslib.loadPointer( POINTER_ELLIPSE );
  95.   ptrPolyline  = reslib.loadPointer( POINTER_POLYLINE );
  96.   ptrPolygon   = reslib.loadPointer( POINTER_POLYGON );
  97.   ptrArc       = reslib.loadPointer( POINTER_ARC );
  98.   ptrPie       = reslib.loadPointer( POINTER_PIE );
  99.   ptrChord     = reslib.loadPointer( POINTER_CHORD );
  100.   ptrText      = reslib.loadPointer( POINTER_TEXT );
  101.   ptrBitmap    = reslib.loadPointer( POINTER_BITMAP );
  102.   ptrStyleCan  = reslib.loadPointer( POINTER_STYLECAN );
  103.   ptrEraser    = reslib.loadPointer( POINTER_ERASER );
  104.  
  105.   ((IMouseHandler*)this)->handleEventsFor(this);
  106. }
  107.  
  108. /*------------------------------------------------------------------------------
  109. | DrawingArea::DrawingArea                                                     |
  110. |                                                                              |
  111. |                                                                              |
  112. ------------------------------------------------------------------------------*/
  113. DrawingArea::~DrawingArea( )
  114. {
  115.   // Delete all the graphic objects in the drawing canvas.
  116.   IGList::Cursor graphicsCursor( *graphicList() );
  117.   for ( graphicsCursor.setToFirst();
  118.         graphicsCursor.isValid();
  119.         graphicsCursor.setToNext() )
  120.   {
  121.     IGraphic* graphic(&(graphicList()->graphicAt(graphicsCursor)));
  122.     delete graphic;
  123.   } /* endfor */
  124.   delete graphicList();
  125. }
  126.  
  127. /*------------------------------------------------------------------------------
  128. | DrawingArea::changeMousePointer                                              |
  129. |                                                                              |
  130. | Change the cursor to reflect the object being drawn.                         |
  131. ------------------------------------------------------------------------------*/
  132. Boolean DrawingArea::mousePointerChange( IMousePointerEvent& event )
  133. {
  134.   Boolean fReturn(true);
  135.  
  136. //  if (event.windowId() != 32776)
  137. //    return(false);
  138. //  if (infoArea)
  139. //  {
  140. //    infoArea->setText("Set the damn text!");
  141. //  }
  142.  
  143.   switch (drawObject())
  144.   {
  145.     case POINTER_MOVE:
  146.       return fReturn = false;
  147.     break;
  148.     case POINTER_LINE:
  149.       event.setMousePointer( ptrLine );
  150.     break;
  151.     case POINTER_FREEHAND:
  152.       event.setMousePointer( ptrFreehand );
  153.     break;
  154.     case POINTER_RECTANGLE:
  155.       event.setMousePointer( ptrRectangle );
  156.     break;
  157.     case POINTER_ELLIPSE:
  158.       event.setMousePointer( ptrEllipse );
  159.     break;
  160.     case POINTER_POLYLINE:
  161.       event.setMousePointer( ptrPolyline );
  162.     break;
  163.     case POINTER_POLYGON:
  164.       event.setMousePointer( ptrPolygon );
  165.     break;
  166.     case POINTER_ARC:
  167.       event.setMousePointer( ptrArc );
  168.     break;
  169.     case POINTER_PIE:
  170.       event.setMousePointer( ptrPie );
  171.     break;
  172.     case POINTER_CHORD:
  173.       event.setMousePointer( ptrChord );
  174.     break;
  175.     case POINTER_TEXT:
  176.       event.setMousePointer( ptrText );
  177.     break;
  178.     case POINTER_BITMAP:
  179.       event.setMousePointer( ptrBitmap );
  180.     break;
  181.     case POINTER_STYLECAN:
  182.       event.setMousePointer( ptrStyleCan );
  183.     break;
  184.     case POINTER_ERASER:
  185.       event.setMousePointer( ptrEraser );
  186.     break;
  187.     default:
  188.       fReturn = false;
  189.     break;
  190.   } // end switch
  191.  
  192.   return fReturn;
  193. }
  194.  
  195. /*------------------------------------------------------------------------------
  196. | DrawingArea::mouseClicked                                                    |
  197. |                                                                              |
  198. | Translate the mouse clicked events.                                          |
  199. ------------------------------------------------------------------------------*/
  200. Boolean DrawingArea::mouseClicked( IMouseClickEvent& event )
  201. {
  202.   Boolean bRc = false;
  203.   if ( event.mouseButton() == IMouseClickEvent::button1 &&
  204.        event.mouseAction() == IMouseClickEvent::down )
  205.   {
  206.     button1Down(event.mousePosition());
  207.     bRc = false;
  208.   }
  209.   else if ( event.mouseButton() == IMouseClickEvent::button1 &&
  210.             event.mouseAction() == IMouseClickEvent::up )
  211.   {
  212.     button1Up(event.mousePosition());
  213.     bRc = true;
  214.   }
  215.   else if ( event.mouseButton() == IMouseClickEvent::button1 &&
  216.             event.mouseAction() == IMouseClickEvent::doubleClick )
  217.   {
  218.     button1DoubleClick(event.mousePosition());
  219.     bRc = true;
  220.   }
  221.   else if ( event.mouseButton() == IMouseClickEvent::button2 &&
  222.             event.mouseAction() == IMouseClickEvent::down )
  223.   {
  224.     button2Down(event.mousePosition());
  225.   }
  226.   else if ( event.mouseButton() == IMouseClickEvent::button2 &&
  227.             event.mouseAction() == IMouseClickEvent::up )
  228.   {
  229.     button2Up(event.mousePosition());
  230.   }
  231.  
  232.   return bRc;
  233. }
  234.  
  235.  
  236. /*------------------------------------------------------------------------------
  237. | DrawingArea::button1Down                                                     |
  238. |                                                                              |
  239. | Handle button 1 down messages.  This event indicates a new graphic object is |
  240. | to be created of additional data points to add to an existing graphic object.|
  241. ------------------------------------------------------------------------------*/
  242. DrawingArea& DrawingArea::button1Down( const IPoint& point )
  243. {
  244.   switch (currentObj)
  245.   {
  246.     case move: // Button 1 drag
  247.       if (drawState() == notDrawing)
  248.       {
  249.         moveGraphic = graphicList()->topGraphicUnderPoint( point, gc );
  250.         if ( moveGraphic )
  251.         {
  252.           moveRect.setEnclosingRect(moveGraphic->boundingRect( gc ));
  253.           previousPt = point;
  254.           startingPt = point;
  255.           capturePointer();
  256.         }
  257.       }
  258.     break;
  259.     case eraser:
  260.       {
  261.         // Delete the object under the pointer
  262.         moveGraphic = graphicList()->topGraphicUnderPoint( point, gc );
  263.         if ( moveGraphic )
  264.         {
  265.           moveRect.setEnclosingRect(moveGraphic->boundingRect( gc ));
  266.           IGList::Cursor cursor( *graphicList(), gc, point );
  267.           for (cursor.setToFirst(); cursor.isValid(); cursor.setToNext())
  268.           {
  269.              IGraphic* graphic(&(graphicList()->graphicAt(cursor)));
  270.              if (graphic == moveGraphic)
  271.              {
  272.                graphicList()->removeAt(cursor);
  273.                delete graphic;
  274.                this->refresh( moveRect.boundingRect(gc).expandBy(2) );
  275.                moveRect.resetTransformMatrix();
  276.                moveGraphic = 0;
  277.                break;
  278.              }
  279.           }
  280.         }
  281.       }
  282.     break;
  283.     case stylecan:
  284.     {
  285.       // Change all objects to the current pen and fill color.
  286.       IRectangle tempRect;
  287.       moveGraphic = graphicList()->topGraphicUnderPoint( point, gc );
  288.       if( moveGraphic )
  289.       {
  290.         tempRect = moveGraphic->boundingRect( gc );
  291.         moveGraphic->setGraphicBundle( currentBundle );
  292.         moveGraphic->drawOn( gc );
  293.         tempRect |= moveGraphic->boundingRect( gc );
  294.         this->refresh( tempRect.expandBy(2) );
  295.         moveGraphic = 0;
  296.       }
  297.     }
  298.     break;
  299.     case line:
  300.       startingPt = point;
  301.       previousPt = point;
  302.       iGraphic = new IGLine( startingPt, previousPt );
  303.       setDrawState();
  304.     break;
  305.     case freehand:
  306.       iGraphic = new IGPolygon(IPointArray());
  307.       ((IGPolygon*)iGraphic)->addPoint( point );
  308.       setDrawState();
  309.     break;
  310.     case rectangle:
  311.       startingPt = point;
  312.       previousPt = point;
  313.       iGraphic = new IGRectangle(IRectangle(startingPt, previousPt));
  314.       setDrawState();
  315.     break;
  316.     case ellipse:
  317.       startingPt = point;
  318.       previousPt = point;
  319.       iGraphic = new IGEllipse( startingPt, 0L );
  320.       setDrawState();
  321.     break;
  322.     case polyline:
  323.     case polygon:
  324.       if (drawState() == notDrawing)
  325.       {
  326.         startingPt = point;
  327.         previousPt = point;
  328.         if (currentObj == polyline)
  329.           iGraphic = new IGPolyline(IPointArray());
  330.         else
  331.           iGraphic = new IGPolygon(IPointArray());
  332.  
  333.         ((IGPolyline*)iGraphic)->addPoint( startingPt );
  334.         ((IGPolyline*)iGraphic)->addPoint( previousPt );
  335.         setDrawState();
  336.       }
  337.       else
  338.       {
  339.         ((IGPolyline*)iGraphic)->IGPolyline::drawOn( gc );
  340.         ((IGPolyline*)iGraphic)->addPoint( point );
  341.         ((IGPolyline*)iGraphic)->IGPolyline::drawOn( gc );
  342.       }
  343.     break;
  344.     case arc:
  345.       pointCount++;
  346.       if (drawState() == notDrawing)
  347.       {
  348.         iGraphic = new IG3PointArc( point, IPoint(0,0), IPoint(0,0) );
  349.         startingPt = point;
  350.         previousPt = point;
  351.       }
  352.       else if ( pointCount == 2 )
  353.       {
  354.         previousPt = point;
  355.         IGLine tempLine( ((IG3PointArc*)iGraphic)->startingPoint(), point );
  356.         tempLine.drawOn( gc );
  357.       }
  358.       else if ( pointCount == 3 )
  359.       {
  360.         IGLine tempLine( ((IG3PointArc*)iGraphic)->startingPoint(), previousPt );
  361.         tempLine.drawOn( gc );
  362.         previousPt = point;
  363.         ((IG3PointArc*)iGraphic)->setEndingPoint( point );
  364.         iGraphic->drawOn( gc );
  365.       }
  366.       setDrawState();
  367.     break;
  368.     case pie:
  369.     case chord:
  370.       pointCount++;
  371.       if (drawState() == notDrawing)
  372.       {
  373.         if (currentObj == pie)
  374.           iGraphic = new IGPie( IRectangle(), 0, 0);
  375.         else
  376.           iGraphic = new IGChord( IRectangle(), 0, 0);
  377.  
  378.         ((IGPie*)iGraphic)->setEnclosingRect(
  379.                              ((IGPie*)iGraphic)->enclosingRect().centerAt( point ));
  380.         startingPt = point;
  381.         previousPt = point;
  382.       }
  383.       else if ( pointCount == 2 )
  384.       {
  385.         previousPt = point;
  386.         IGLine tempLine( ((IGPie*)iGraphic)->enclosingRect().center(), point );
  387.         tempLine.drawOn( gc );
  388.       }
  389.       else if ( pointCount == 3 )
  390.       {
  391.         IGLine tempLine( ((IGPie*)iGraphic)->enclosingRect().center(), previousPt );
  392.         tempLine.drawOn( gc );
  393.         previousPt = point;
  394.         double sweep(angleFromPoints( ((IGPie*)iGraphic)->enclosingRect().center(), point ));
  395.         if ( sweep < ((IGPie*)iGraphic)->startAngle() )
  396.           ((IGPie*)iGraphic)->setSweepAngle( 360.0 -
  397.                                 ( ((IGPie*)iGraphic)->startAngle() - sweep ));
  398.         else
  399.           ((IGPie*)iGraphic)->setSweepAngle( sweep -
  400.                                             ((IGPie*)iGraphic)->startAngle());
  401.         iGraphic->drawOn( gc );
  402.       }
  403.       setDrawState();
  404.     break;
  405.     case text:
  406.       setDrawState();
  407.     break;
  408.     case bitmap:
  409.       setDrawState();
  410.     break;
  411.   } /* endswitch */
  412.   return *this;
  413. }
  414.  
  415. /*------------------------------------------------------------------------------
  416. | DrawingArea::button1Up                                                       |
  417. |                                                                              |
  418. | Handle button 1 up events.  This indicates a data points final location.     |
  419. ------------------------------------------------------------------------------*/
  420. DrawingArea& DrawingArea::button1Up( const IPoint& point )
  421. {
  422.   if ( drawState() == drawing )
  423.   {
  424.     switch (currentObj)
  425.     {
  426.       case move:
  427.       break;
  428.       case eraser:
  429.       break;
  430.       case stylecan:
  431.       break;
  432.       case line:
  433.         ((IGLine*)iGraphic)->setEndingPoint( point );
  434.         iGraphic->setGraphicBundle( currentBundle );
  435.         iGraphic->drawOn( gc );
  436.         setDrawState( notDrawing );
  437.         graphicList()->addAsLast( *iGraphic );
  438.       break;
  439.       case freehand:
  440.         ((IGPolygon*)iGraphic)->addPoint( point );
  441.         iGraphic->setGraphicBundle( currentBundle );
  442.         iGraphic->drawOn( gc );
  443.         setDrawState( notDrawing );
  444.         graphicList()->addAsLast( *iGraphic );
  445.       break;
  446.       case rectangle:
  447.       {
  448.         IRectangle rc(((IGRectangle*)iGraphic)->enclosingRect());
  449.         rc.sizeTo( rc.size() + point - previousPt );
  450.         ((IGRectangle*)iGraphic)->setEnclosingRect( rc );
  451.         iGraphic->setGraphicBundle( currentBundle );
  452.         iGraphic->drawOn( gc );
  453.         setDrawState( notDrawing );
  454.         graphicList()->addAsLast( *iGraphic );
  455.       }
  456.       break;
  457.       case ellipse:
  458.       {
  459.         IRectangle rc(((IGEllipse*)iGraphic)->enclosingRect());
  460.         rc.sizeTo( rc.size() + point - previousPt );
  461.         ((IGEllipse*)iGraphic)->setEnclosingRect( rc );
  462.  
  463.         iGraphic->setGraphicBundle( currentBundle );
  464.         iGraphic->drawOn( gc );
  465.         setDrawState( notDrawing );
  466.         graphicList()->addAsLast( *iGraphic );
  467.       }
  468.       break;
  469.       case polyline:
  470.       case polygon:
  471.         previousPt = point;
  472.         ((IGPolyline*)iGraphic)->setPoint(
  473.                          ((IGPolyline*)iGraphic)->numberOfPoints()-1, point );
  474.         setDrawState( waitingForInput );
  475.       break;
  476.       case arc:
  477.       if ( pointCount == 2 )
  478.       {
  479.         ((IG3PointArc*)iGraphic)->setIntermediatePoint( point );
  480.         gc.setMixMode( IGraphicBundle::xor ).setPenColor( IColor::white );
  481.         IGLine tempLine( ((IG3PointArc*)iGraphic)->startingPoint(), previousPt );
  482.         tempLine.drawOn( gc );
  483.         tempLine.setEndingPoint( point );
  484.         tempLine.drawOn( gc );
  485.         setDrawState( waitingForInput );
  486.       }
  487.       else if ( pointCount == 3 )
  488.       {
  489.         gc.setMixMode( IGraphicBundle::xor ).setPenColor( IColor::white );
  490.         iGraphic->drawOn( gc );
  491.         ((IG3PointArc*)iGraphic)->setEndingPoint( point );
  492.         iGraphic->setGraphicBundle( currentBundle );
  493.         iGraphic->drawOn( gc );
  494.         setDrawState( notDrawing );
  495.         graphicList()->addAsLast( *iGraphic );
  496.         pointCount = 0;
  497.       }
  498.       break;
  499.       case pie:
  500.       case chord:
  501.       if ( pointCount == 2 )
  502.       {
  503.         gc.setMixMode( IGraphicBundle::xor ).setPenColor( IColor::white );
  504.         setDrawState( waitingForInput );
  505.         IPoint centerPt(((IGPie*)iGraphic)->enclosingRect().center());
  506.  
  507.         ((IGPie*)iGraphic)->setStartAngle( angleFromPoints( centerPt, point ));
  508.  
  509.         unsigned a(abs(centerPt.x()) - abs(point.x()));
  510.         unsigned b(abs(centerPt.y()) - abs(point.y()));
  511.  
  512.         unsigned long radius((unsigned long)sqrt(a*a + b*b));
  513.  
  514.         ((IGPie*)iGraphic)->setEnclosingRect(
  515.            ((IGPie*)iGraphic)->enclosingRect().expandBy(radius));
  516.       }
  517.       else if ( pointCount == 3 )
  518.       {
  519.         gc.setMixMode( IGraphicBundle::xor ).setPenColor( IColor::white );
  520.         iGraphic->drawOn( gc );
  521.  
  522.         double sweep(angleFromPoints(
  523.                               ((IGPie*)iGraphic)->enclosingRect().center(), point ));
  524.  
  525.         if ( sweep < ((IGPie*)iGraphic)->startAngle() )
  526.           ((IGPie*)iGraphic)->setSweepAngle( 360.0 -
  527.                                 ( ((IGPie*)iGraphic)->startAngle() - sweep ));
  528.         else
  529.           ((IGPie*)iGraphic)->setSweepAngle( sweep -
  530.                                             ((IGPie*)iGraphic)->startAngle());
  531.  
  532.         iGraphic->setGraphicBundle( currentBundle );
  533.         iGraphic->drawOn( gc );
  534.         setDrawState( notDrawing );
  535.         graphicList()->addAsLast( *iGraphic );
  536.         pointCount = 0;
  537.       }
  538.       break;
  539.       case text:
  540.       {
  541.         IString input;
  542.  
  543.         IDynamicLinkLibrary reslib("CPPOV53R");
  544.  
  545.         if (point.x() % 2)
  546.           input = reslib.loadString( STRING_SAMPLE1 );
  547.         else if ((point.y() % 5)==1)
  548.           input = reslib.loadString( STRING_SAMPLE3 );
  549.         else if ((point.y() % 5)==3)
  550.           input = reslib.loadString( STRING_SAMPLE4 );
  551.         else
  552.           input = reslib.loadString( STRING_SAMPLE2 );
  553.  
  554.         IGString* text = new IGString( input.x2c(), point, currentFont());
  555. //      IGString* text = new IGString( "Doodle", point, currentFont());
  556.         text->rotateBy( 10.0, point );
  557.         text->setGraphicBundle( currentBundle );
  558.         text->drawOn( gc );
  559.         setDrawState( notDrawing );
  560.         graphicList()->addAsLast( *text );
  561.       }
  562.       break;
  563.       case bitmap:
  564.       {
  565.         IGBitmap *bmp;
  566. //      if (bitmapFileName().length() > 0)
  567. //      {
  568. //        bmp = new IGBitmap(bitmapFileName());
  569. //      }
  570.  
  571.         // Select a bitmap to load
  572.         IDynamicLinkLibrary reslib("CPPOV53R");
  573.  
  574.         if (point.x() % 2)
  575.           bmp = new IGBitmap(reslib.loadBitmap( BITMAP_SAMPLE1 ));
  576.         else if ((point.y() % 5)==1)
  577.           bmp = new IGBitmap(reslib.loadBitmap( BITMAP_SAMPLE3 ));
  578.         else if ((point.y() % 5)==3)
  579.           bmp = new IGBitmap(reslib.loadBitmap( BITMAP_SAMPLE4 ));
  580.         else
  581.           bmp = new IGBitmap(reslib.loadBitmap( BITMAP_SAMPLE2 ));
  582.  
  583.         bmp->moveTo( point );
  584.         bmp->drawOn( gc );
  585.         setDrawState( notDrawing );
  586.         graphicList()->addAsLast( *bmp );
  587.       }
  588.       break;
  589.     } /* endswitch */
  590.   } /* endif */
  591.   else  // not drawing
  592.   {
  593.     switch (currentObj)
  594.     {
  595.       case move:
  596.         if (moveGraphic && capturePointer)
  597.         {
  598.           moveRect.translateBy( point - previousPt );
  599.           moveRect.drawOn( gc );
  600.           moveRect.resetTransformMatrix();
  601.           this->refresh( moveRect.boundingRect(gc).expandBy(2) );
  602.           moveGraphic->translateBy( point - startingPt );
  603.           moveGraphic->drawOn( gc );
  604.           moveGraphic = 0;
  605.           capturePointer(false);
  606.         }
  607.       break;
  608.     }
  609.   }
  610.   return *this;
  611. }
  612.  
  613. /*------------------------------------------------------------------------------
  614. | DrawingArea::button1DoubleClick                                              |
  615. |                                                                              |
  616. | Handle button 1 up double click events.  In the case of polyline and polygon |
  617. | a double click indicates the user has finished adding data points to the     |
  618. | object.                                                                      |
  619. ------------------------------------------------------------------------------*/
  620. DrawingArea& DrawingArea::button1DoubleClick( const IPoint& point )
  621. {
  622.   if (drawState() == waitingForInput )
  623.   {
  624.     switch (currentObj)
  625.     {
  626.       case polyline:
  627.       {
  628.         iGraphic->drawOn( gc );
  629.         iGraphic->setGraphicBundle( currentBundle );
  630.         iGraphic->drawOn( gc );
  631.         setDrawState( notDrawing );
  632.         graphicList()->addAsLast( *iGraphic );
  633.       }
  634.       break;
  635.       case polygon:
  636.       {
  637.         ((IGPolyline*)iGraphic)->IGPolyline::drawOn( gc );
  638.         iGraphic->setGraphicBundle( currentBundle );
  639.         iGraphic->drawOn( gc );
  640.         setDrawState( notDrawing );
  641.         graphicList()->addAsLast( *iGraphic );
  642.       }
  643.       break;
  644.     }
  645.   }
  646.   return *this;
  647. }
  648.  
  649. /*------------------------------------------------------------------------------
  650. | DrawingArea::button2Down                                                     |
  651. |                                                                              |
  652. | Determine the object under the mouse and start moving.                       |
  653. ------------------------------------------------------------------------------*/
  654. DrawingArea& DrawingArea::button2Down( const IPoint& point )
  655. {
  656.   if (drawState() == notDrawing)
  657.   {
  658.     moveGraphic = graphicList()->topGraphicUnderPoint( point, gc );
  659.     if ( moveGraphic )
  660.     {
  661.       moveRect.setEnclosingRect(moveGraphic->boundingRect( gc ));
  662.       previousPt = point;
  663.       startingPt = point;
  664.       capturePointer();
  665.     }
  666.   }
  667.   return *this;
  668. }
  669.  
  670. /*------------------------------------------------------------------------------
  671. | DrawingArea::button2Up                                                       |
  672. |                                                                              |
  673. ------------------------------------------------------------------------------*/
  674. DrawingArea& DrawingArea::button2Up( const IPoint& point )
  675. {
  676.   if (moveGraphic)
  677.   {
  678.     moveRect.translateBy( point - previousPt );
  679.     moveRect.drawOn( gc );
  680.     moveRect.resetTransformMatrix();
  681.     this->refresh( moveRect.boundingRect(gc).expandBy(2) );
  682.     moveGraphic->translateBy( point - startingPt );
  683.     moveGraphic->drawOn( gc );
  684.     moveGraphic = 0;
  685.     capturePointer(false);
  686.   }
  687.   return *this;
  688. }
  689.  
  690. /*------------------------------------------------------------------------------
  691. | DrawingArea::mouseMoved                                                      |
  692. |                                                                              |
  693. | Handle button 1 down mouse move events.  This allows data points to be       |
  694. | moved while the object is drawn with a rubber band effect.                   |
  695. ------------------------------------------------------------------------------*/
  696. Boolean DrawingArea::mouseMoved( IMouseEvent& event )
  697. {
  698.   IPoint point(event.mousePosition());
  699.   if ( hasPointerCaptured() )
  700.   {
  701.     IRectangle windowRect(this->rect());
  702.     windowRect.moveTo(IPoint(0,0));
  703.     if (!windowRect.contains(point))
  704.     {
  705.       if ((short)point.x() < (short)windowRect.left())
  706.         point.setX(windowRect.left());
  707.       else if ((short)point.x() > (short)windowRect.right())
  708.         point.setX(windowRect.right());
  709.       else if ((short)point.y() < (short)windowRect.bottom())
  710.         point.setY(windowRect.bottom());
  711.       else if ((short)point.y() > (short)windowRect.top())
  712.         point.setY(windowRect.top());
  713.  
  714.       IPoint mapPt( IWindow::mapPoint( point,
  715.                                        this->handle(),
  716.                                        IWindow::desktopWindow()->handle()));
  717.  
  718.       IWindow::movePointerTo( mapPt );
  719.     }
  720.   }
  721.  
  722.   // If we're not moving an object
  723.   if (!moveGraphic)
  724.   {
  725.     if (( drawState() == drawing ) || ( drawState() == waitingForInput ))
  726.     {
  727.       switch (currentObj)
  728.       {
  729.         case move:
  730.         break;
  731.         case eraser:
  732.         break;
  733.         case stylecan:
  734.         break;
  735.         case line:
  736.           ((IGLine*)iGraphic)->drawOn( gc );
  737.           ((IGLine*)iGraphic)->setEndingPoint( point );
  738.           ((IGLine*)iGraphic)->drawOn( gc );
  739.         break;
  740.         case freehand:
  741.           ((IGPolygon*)iGraphic)->addPoint( point );
  742.           ((IGPolyline*)iGraphic)->IGPolyline::drawOn( gc );
  743.         break;
  744.         case rectangle:
  745.         {
  746.           IRectangle rc(((IGRectangle*)iGraphic)->enclosingRect());
  747.           iGraphic->drawOn( gc );
  748.           rc.sizeTo( rc.size() + point - previousPt );
  749.           ((IGRectangle*)iGraphic)->setEnclosingRect( rc );
  750.           iGraphic->drawOn( gc );
  751.           previousPt = point;
  752.         }
  753.         break;
  754.         case ellipse:
  755.         {
  756.           iGraphic->drawOn( gc );
  757.           IRectangle rc(((IGEllipse*)iGraphic)->enclosingRect());
  758.           rc.sizeTo( rc.size() + point - previousPt );
  759.           ((IGEllipse*)iGraphic)->setEnclosingRect( rc );
  760.           iGraphic->drawOn( gc );
  761.           previousPt = point;
  762.         }
  763.         break;
  764.         case polyline:
  765.         case polygon:
  766.           ((IGPolyline*)iGraphic)->IGPolyline::drawOn( gc );
  767.           ((IGPolyline*)iGraphic)->setPoint(
  768.                            ((IGPolyline*)iGraphic)->numberOfPoints()-1, point );
  769.           ((IGPolyline*)iGraphic)->IGPolyline::drawOn( gc );
  770.         break;
  771.         case arc:
  772.           if (drawState() != waitingForInput)
  773.           {
  774.             if ( pointCount == 2 )
  775.             {
  776.               IGLine tempLine( ((IG3PointArc*)iGraphic)->startingPoint(), previousPt );
  777.               tempLine.drawOn( gc );
  778.               tempLine.setEndingPoint( point );
  779.               tempLine.drawOn( gc );
  780.               previousPt = point;
  781.             } else if ( pointCount == 3 ) {
  782.               iGraphic->drawOn( gc );
  783.               ((IG3PointArc*)iGraphic)->setEndingPoint( point );
  784.               iGraphic->drawOn( gc );
  785.             }
  786.           } /* endif */
  787.         break;
  788.         case pie:
  789.         case chord:
  790.           if (drawState() != waitingForInput)
  791.           {
  792.             if ( pointCount == 2 )
  793.             {
  794.               IGLine tempLine( ((IGPie*)iGraphic)->enclosingRect().center(), previousPt );
  795.               tempLine.drawOn( gc );
  796.               tempLine.setEndingPoint( point );
  797.               tempLine.drawOn( gc );
  798.               previousPt = point;
  799.             } else if ( pointCount == 3 ) {
  800.               iGraphic->drawOn( gc );
  801.               double sweep(angleFromPoints( ((IGPie*)iGraphic)->enclosingRect().center(), point ));
  802.               if ( sweep < ((IGPie*)iGraphic)->startAngle() )
  803.                 ((IGPie*)iGraphic)->setSweepAngle( 360.0 -
  804.                                     ( ((IGPie*)iGraphic)->startAngle() - sweep ));
  805.               else
  806.                 ((IGPie*)iGraphic)->setSweepAngle( sweep -
  807.                                                 ((IGPie*)iGraphic)->startAngle());
  808.               iGraphic->drawOn( gc );
  809.             }
  810.           } /* endif */
  811.         break;
  812.       } /* endswitch */
  813.     }
  814.   }
  815.   else  // We are moving a graphic
  816.   {
  817.     moveRect.drawOn( gc );
  818.     moveRect.translateBy( point - previousPt );
  819.     moveRect.drawOn( gc );
  820.     previousPt = point;
  821.   }
  822.   return false;
  823. }
  824.  
  825. /*------------------------------------------------------------------------------
  826. | DrawingArea::setDrawState                                                    |
  827. |                                                                              |
  828. |                                                                              |
  829. ------------------------------------------------------------------------------*/
  830. DrawingArea& DrawingArea::setDrawState( const DrawState newState )
  831. {
  832.   dState = newState;
  833.   if (dState == drawing)
  834.   {
  835.     if (!hasPointerCaptured())
  836.       capturePointer();
  837.   }
  838.   else if (dState == notDrawing)
  839.     capturePointer(false);
  840.   return *this;
  841. }
  842.  
  843. /*------------------------------------------------------------------------------
  844. | DrawingArea::setFont                                                         |
  845. |                                                                              |
  846. |                                                                              |
  847. ------------------------------------------------------------------------------*/
  848. DrawingArea& DrawingArea::setCurrentFont( const IFont& font )
  849. {
  850.   currentfont = font;
  851.   return *this;
  852. }
  853.  
  854. /*------------------------------------------------------------------------------
  855. | DrawingArea::font                                                            |
  856. |                                                                              |
  857. |                                                                              |
  858. ------------------------------------------------------------------------------*/
  859. IFont DrawingArea::currentFont( ) const
  860. {
  861.   return currentfont;
  862. }
  863.  
  864.