home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / pstreams.pak / STREAM2.CPP < prev    next >
C/C++ Source or Header  |  1997-07-23  |  73KB  |  1,844 lines

  1. /*------------------------------------------------------------------------*/
  2. /*                                                                        */
  3. /*  STREAM2.CPP                                                           */
  4. /*                                                                        */
  5. /*  Copyright Borland International, 1993                                 */
  6. /*                                                                        */
  7. /*  Streaming example, version 2                                          */
  8. /*                                                                        */
  9. /*  Streams enhanced objects but stays compatible with streams created    */
  10. /*  with version 1.                                                       */
  11. /*                                                                        */
  12. /*------------------------------------------------------------------------*/
  13.  
  14. #include <owl\owlpch.h>
  15.  
  16. #include <new.h>
  17. #include <cstring.h>
  18.  
  19. #include <classlib\sets.h>
  20. #include <classlib\objstrm.h>
  21.  
  22. #include <owl\point.h>
  23. #include <owl\window.h>
  24. #include <owl\dc.h>
  25. #include <owl\applicat.h>
  26. #include <owl\framewin.h>
  27. #include <owl\dialog.h>
  28. #include <owl\opensave.h>
  29.  
  30. #include "streams.h"
  31.  
  32. /*------------------------------------------------------------------------*/
  33. /*                                                                        */
  34. /*  class GraphicalObject                                                 */
  35. /*                                                                        */
  36. /*      class GraphicalObject provides the abstract interface             */
  37. /*      to all of the graphical objects that can be displayed             */
  38. /*      by this graphical system.  It should be a virtual base            */
  39. /*      of any class derived from it.                                     */
  40. /*                                                                        */
  41. /*  Member functions:                                                     */
  42. /*                                                                        */
  43. /*      GraphicalObject();                                                */
  44. /*                                                                        */
  45. /*          Creates a GraphicalObject with undefined initial              */
  46. /*          coordinates. Needed only in multiple inheritance when         */
  47. /*          we know that GraphicalObject(const TRect&) will be used       */
  48. /*          by derived classes.                                           */
  49. /*                                                                        */
  50. /*      GraphicalObject( TPoint p1, TPoint p2 );                          */
  51. /*                                                                        */
  52. /*          Creates a GraphicalObject with the location and size          */
  53. /*          specified by p1 and p2.                                       */
  54. /*                                                                        */
  55. /*      virtual ~GraphicalObject();                                       */
  56. /*                                                                        */
  57. /*          Destructor.                                                   */
  58. /*                                                                        */
  59. /*      void Draw( TDC& );                                                */
  60. /*                                                                        */
  61. /*          Does some preliminary setup of the device context, then       */
  62. /*          calls DoDraw() to draw the object.                            */
  63. /*                                                                        */
  64. /*      virtual void DoDraw( TDC& ) = 0;                                  */
  65. /*                                                                        */
  66. /*          Draws the object.  In GraphicalObject this does               */
  67. /*          nothing.  It should be overridden in any class                */
  68. /*          that will be displayed on the screen.                         */
  69. /*                                                                        */
  70. /*      int operator == ( const GraphicalObject& ) const;                 */
  71. /*                                                                        */
  72. /*          This operator must exist so that we can put GraphicalObjects  */
  73. /*          into the Set that is used in TGraphWindow.                    */
  74. /*                                                                        */
  75. /*------------------------------------------------------------------------*/
  76.  
  77. class GraphicalObject : public TStreamableBase
  78. {
  79.  
  80. public:
  81.  
  82.     GraphicalObject();
  83.     GraphicalObject( TPoint p1, TPoint p2 );
  84.     virtual ~GraphicalObject();
  85.  
  86.     void Draw( TDC& );
  87.     int operator == ( const GraphicalObject& obj ) const;
  88.  
  89. protected:
  90.  
  91.     TRect bbox;
  92.  
  93.     void SetFill();             // Changed
  94.  
  95. private:
  96.  
  97.     int Filled;                 // Changed
  98.     virtual void DoDraw( TDC& ) = 0;
  99.  
  100.     class GraphicalObjectDC
  101.     {
  102.     public:
  103.         GraphicalObjectDC( TDC& dc, int filled );       // Changed
  104.         ~GraphicalObjectDC();
  105.         operator TDC&() const;
  106.     private:
  107.         TDC& DC;
  108.     };
  109.  
  110.     DECLARE_ABSTRACT_STREAMABLE( , GraphicalObject, 2 );// Changed
  111.  
  112. };
  113.  
  114. inline GraphicalObject::GraphicalObject() : Filled(0)   // Changed
  115. {
  116. }
  117.  
  118. inline GraphicalObject::GraphicalObject( TPoint p1, TPoint p2 ) :
  119.     bbox( p1, p2 ), Filled(0)
  120. {
  121. }
  122.  
  123. inline GraphicalObject::~GraphicalObject()
  124. {
  125. }
  126.  
  127. void GraphicalObject::Draw( TDC& dc )
  128. {
  129.     GraphicalObjectDC gdc( dc, Filled );                // Changed
  130.     DoDraw( gdc );
  131. }
  132.  
  133. inline int GraphicalObject::operator == ( const GraphicalObject& obj ) const
  134. {
  135.     return this == &obj;
  136. }
  137.  
  138. // Changed
  139. void GraphicalObject::SetFill()
  140. {
  141.     Filled = 1;
  142. }
  143.  
  144. GraphicalObject::GraphicalObjectDC::GraphicalObjectDC( TDC& dc, int filled ) :
  145.     DC(dc)
  146. {
  147.     if( filled )        // Changed
  148.         DC.SelectStockObject( BLACK_BRUSH );
  149.     else 
  150.         DC.SelectStockObject( NULL_BRUSH );
  151. }
  152.  
  153. GraphicalObject::GraphicalObjectDC::~GraphicalObjectDC()
  154. {
  155. }
  156.  
  157. GraphicalObject::GraphicalObjectDC::operator TDC&() const
  158. {
  159.     return DC;
  160. }
  161.  
  162. IMPLEMENT_CASTABLE( GraphicalObject );
  163. IMPLEMENT_ABSTRACT_STREAMABLE( GraphicalObject );
  164.  
  165. // Changed
  166. void *GraphicalObject::Streamer::Read( ipstream& in, uint32 ver ) const
  167. {
  168.     in >> GetObject()->bbox;
  169.     if( ver > 1 )
  170.         in >> GetObject()->Filled;
  171.     else
  172.         GetObject()->Filled = 0;    // old objects didn't write this field
  173.     return GetObject();
  174. }
  175.  
  176. void GraphicalObject::Streamer::Write( opstream& out ) const
  177. {
  178.     out << GetObject()->bbox << GetObject()->Filled;    // Changed
  179. }
  180.  
  181. /*------------------------------------------------------------------------*/
  182. /*                                                                        */
  183. /*  class Line                                                            */
  184. /*                                                                        */
  185. /*      class Line draws a line between two specified points.             */
  186. /*                                                                        */
  187. /*  Member functions:                                                     */
  188. /*                                                                        */
  189. /*      Line( TPoint p1, TPoint p2 );                                     */
  190. /*                                                                        */
  191. /*          Creates a line between the points p1 and p2.                  */
  192. /*                                                                        */
  193. /*      void ImplementDraw( TDC& );                                       */
  194. /*                                                                        */
  195. /*          Draws the line.                                               */
  196. /*                                                                        */
  197. /*      virtual void DoDraw( TDC& );                                      */
  198. /*                                                                        */
  199. /*          Overrides GraphicalObject::DoDraw and draws the line by       */
  200. /*          calling ImplementDraw().                                      */
  201. /*                                                                        */
  202. /*------------------------------------------------------------------------*/
  203.  
  204. class Line : public virtual GraphicalObject
  205. {
  206.  
  207. public:
  208.  
  209.     Line( TPoint p1, TPoint p2 );
  210.  
  211. protected:
  212.  
  213.     void ImplementDraw( TDC& );
  214.  
  215. private:
  216.  
  217.     virtual void DoDraw( TDC& );
  218.  
  219.     DECLARE_STREAMABLE_FROM_BASE( , Line, GraphicalObject );
  220.  
  221. };
  222.  
  223. inline Line::Line( TPoint p1, TPoint p2 ) : GraphicalObject( p1, p2 )
  224. {
  225. }
  226.  
  227. void Line::ImplementDraw( TDC& dc )
  228. {
  229.     dc.MoveTo( bbox.left, bbox.top );
  230.     dc.LineTo( bbox.right, bbox.bottom );
  231. }
  232.  
  233. void Line::DoDraw( TDC& dc )
  234. {
  235.     ImplementDraw( dc );
  236. }
  237.  
  238. IMPLEMENT_CASTABLE1( Line, GraphicalObject );
  239. IMPLEMENT_STREAMABLE_FROM_BASE( Line, GraphicalObject );
  240.  
  241. /*------------------------------------------------------------------------*/
  242. /*                                                                        */
  243. /*  class TRectangle                                                      */
  244. /*                                                                        */
  245. /*      class TRectangle draws a rectangle.                               */
  246. /*                                                                        */
  247. /*  Member functions:                                                     */
  248. /*                                                                        */
  249. /*      TRectangle( TPoint p1, TPoint p2 );                               */
  250. /*                                                                        */
  251. /*          Creates a TRectangle whose upper left corner is at p1         */
  252. /*          and whose lower right corner is at p2.                        */
  253. /*                                                                        */
  254. /*      void ImplementDraw( TDC& );                                       */
  255. /*                                                                        */
  256. /*          Draws the rectangle.                                          */
  257. /*                                                                        */
  258. /*      virtual void DoDraw( TDC& );                                      */
  259. /*                                                                        */
  260. /*          Overrides GraphicalObject::DoDraw and draws the rectangle by  */
  261. /*          calling ImplementDraw().                                      */
  262. /*                                                                        */
  263. /*------------------------------------------------------------------------*/
  264.  
  265. class TRectangle : public virtual GraphicalObject
  266. {
  267.  
  268. public:
  269.  
  270.     TRectangle( TPoint p1, TPoint p2 );
  271.  
  272. protected:
  273.  
  274.     void ImplementDraw( TDC& );
  275.  
  276. private:
  277.  
  278.     virtual void DoDraw( TDC& );
  279.  
  280.     DECLARE_STREAMABLE_FROM_BASE( , TRectangle, GraphicalObject );
  281.  
  282. };
  283.  
  284. inline TRectangle::TRectangle( TPoint p1, TPoint p2 ) :
  285.     GraphicalObject( p1, p2 )
  286. {
  287. }
  288.  
  289. void TRectangle::ImplementDraw( TDC& dc )
  290. {
  291.     dc.Rectangle( bbox );
  292. }
  293.  
  294. void TRectangle::DoDraw( TDC& dc )
  295. {
  296.     ImplementDraw( dc );
  297. }
  298.  
  299. IMPLEMENT_CASTABLE1( TRectangle, GraphicalObject );
  300. IMPLEMENT_STREAMABLE_FROM_BASE( TRectangle, GraphicalObject );
  301.  
  302. /*------------------------------------------------------------------------*/
  303. /*                                                                        */
  304. /*  class TEllipse                                                        */
  305. /*                                                                        */
  306. /*      class TEllipse draws an ellipse.                                  */
  307. /*                                                                        */
  308. /*  Member functions:                                                     */
  309. /*                                                                        */
  310. /*      TEllipse( TPoint p1, TPoint p2 );                                 */
  311. /*                                                                        */
  312. /*          Creates a TEllipse whose bounding box is defined by p1 and p2 */
  313. /*                                                                        */
  314. /*      void ImplementDraw( TDC& );                                       */
  315. /*                                                                        */
  316. /*          Draws the ellipse.                                            */
  317. /*                                                                        */
  318. /*      virtual void DoDraw( TDC& );                                      */
  319. /*                                                                        */
  320. /*          Overrides GraphicalObject::DoDraw and draws the ellipse by    */
  321. /*          calling ImplementDraw().                                      */
  322. /*                                                                        */
  323. /*------------------------------------------------------------------------*/
  324.  
  325. class TEllipse : public virtual GraphicalObject
  326. {
  327.  
  328. public:
  329.  
  330.     TEllipse( TPoint p1, TPoint p2 );
  331.  
  332. protected:
  333.  
  334.     void ImplementDraw( TDC& );
  335.  
  336. private:
  337.  
  338.     virtual void DoDraw( TDC& );
  339.  
  340.     DECLARE_STREAMABLE_FROM_BASE( , TEllipse, GraphicalObject );
  341.  
  342. };
  343.  
  344. TEllipse::TEllipse( TPoint p1, TPoint p2 ) :
  345.     GraphicalObject( p1, p2 )
  346. {
  347. }
  348.  
  349. void TEllipse::ImplementDraw( TDC& dc )
  350. {
  351.     dc.Ellipse( bbox );
  352. }
  353.  
  354. void TEllipse::DoDraw( TDC& dc )
  355. {
  356.     ImplementDraw( dc );
  357. }
  358.  
  359. IMPLEMENT_CASTABLE1( TEllipse, GraphicalObject );
  360. IMPLEMENT_STREAMABLE_FROM_BASE( TEllipse, GraphicalObject );
  361.  
  362. /*------------------------------------------------------------------------*/
  363. /*                                                                        */
  364. /*  class Caption                                                         */
  365. /*                                                                        */
  366. /*      class Caption draws its text on the screen.                       */
  367. /*      Note that Caption is an abstract class.  It                       */
  368. /*      must have a bounding box, but it does not                         */
  369. /*      have a constructor that takes any coordinates.                    */
  370. /*      Each class derived from Caption will provide                      */
  371. /*      a bounding box in the virtual base GraphicalObject.               */
  372. /*                                                                        */
  373. /*  Type definitions:                                                     */
  374. /*                                                                        */
  375. /*      TextLoc                                                           */
  376. /*                                                                        */
  377. /*          An enum used to specify how y-coordinate values               */
  378. /*          should be interpreted when displaying text.                   */
  379. /*                                                                        */
  380. /*  Member functions:                                                     */
  381. /*                                                                        */
  382. /*      Caption( const string& txt, TextLoc where );                      */
  383. /*                                                                        */
  384. /*          Creates a Caption with the specified text,                    */
  385. /*          which will be drawn in its bounding box                       */
  386. /*          at the top, center, or bottom, depending                      */
  387. /*          on the value of its argument 'where'.                         */
  388. /*                                                                        */
  389. /*      virtual void ImplementDraw( TDC& );                               */
  390. /*                                                                        */
  391. /*          Draws the caption.                                            */
  392. /*                                                                        */
  393. /*------------------------------------------------------------------------*/
  394.  
  395. class Caption : public virtual GraphicalObject
  396. {
  397.  
  398. public:
  399.  
  400.     enum TextLoc{ T_TOP, T_CENTER, T_BOTTOM };
  401.  
  402.     Caption( const string& txt, TextLoc where );
  403.  
  404. protected:
  405.  
  406.     void ImplementDraw( TDC& );
  407.  
  408. private:
  409.  
  410.     string Text;
  411.     TextLoc Where;
  412.  
  413.     DECLARE_ABSTRACT_STREAMABLE( , Caption, 1 );
  414.  
  415. };
  416.  
  417. Caption::Caption( const string& text, TextLoc where ) :
  418.     Text( text ), Where(where)
  419. {
  420. }
  421.  
  422. #pragma warn -def
  423. void Caption::ImplementDraw( TDC& dc )
  424. {
  425.     TEXTMETRIC tm;
  426.     dc.GetTextMetrics(tm);
  427.     int textHeight = tm.tmHeight+tm.tmExternalLeading;
  428.  
  429.     int yDelta;
  430.     switch( Where )
  431.     {
  432.     case T_TOP:
  433.         yDelta = textHeight/2;
  434.         break;
  435.     case T_CENTER:
  436.         yDelta = (bbox.Height()-textHeight)/2;
  437.         break;
  438.     case T_BOTTOM:
  439.         yDelta = bbox.Height()-3*textHeight/2;
  440.         break;
  441.     }
  442.     dc.TextOut( bbox.left+bbox.Width()/2,
  443.                 bbox.top+yDelta,
  444.                 Text.c_str(), Text.length() );
  445. }
  446. #pragma warn .def
  447.  
  448. IMPLEMENT_CASTABLE1( Caption, GraphicalObject );
  449. IMPLEMENT_ABSTRACT_STREAMABLE1( Caption, GraphicalObject );
  450.  
  451. void *Caption::Streamer::Read( ipstream& in, uint32 ) const
  452. {
  453.     ReadVirtualBase( STATIC_CAST(GraphicalObject *,GetObject()), in );
  454.     int temp;
  455.     in >> GetObject()->Text >> temp;
  456.     GetObject()->Where = TextLoc(temp);
  457.     return GetObject();
  458. }
  459.  
  460. void Caption::Streamer::Write( opstream& out ) const
  461. {
  462.     WriteVirtualBase( STATIC_CAST(GraphicalObject *,GetObject()), out );
  463.     out << GetObject()->Text << int(GetObject()->Where);
  464. }
  465.  
  466. /*------------------------------------------------------------------------*/
  467. /*                                                                        */
  468. /*  class CaptionedRectangle                                              */
  469. /*                                                                        */
  470. /*      class CaptionedRectangle draws a rectangle on the                 */
  471. /*      screen, with a caption horizontally centered at the               */
  472. /*      top, in the center, or at the bottom.                             */
  473. /*                                                                        */
  474. /*  Member functions:                                                     */
  475. /*                                                                        */
  476. /*      CaptionedRectangle( TPoint p1, TPoint p2,                         */
  477. /*                          const string& txt,                            */
  478. /*                          TextLoc loc = T_TOP )                         */
  479. /*                                                                        */
  480. /*          Creates a CaptionedRectangle with the specified               */
  481. /*          location, size, and text.                                     */
  482. /*                                                                        */
  483. /*      void ImplementDraw( TDC& );                                       */
  484. /*                                                                        */
  485. /*          Draws the rectangle and its text.                             */
  486. /*                                                                        */
  487. /*      virtual void DoDraw( TDC& );                                      */
  488. /*                                                                        */
  489. /*          Overrides GraphicalObject::DoDraw and draws the rectangle by  */
  490. /*          calling ImplementDraw().                                      */
  491. /*                                                                        */
  492. /*------------------------------------------------------------------------*/
  493.  
  494. class CaptionedRectangle : public TRectangle, public Caption
  495. {
  496.  
  497. public:
  498.  
  499.     CaptionedRectangle( TPoint p1, TPoint p2,
  500.                         const string& txt,
  501.                         TextLoc loc = T_TOP );
  502.  
  503. protected:
  504.  
  505.     void ImplementDraw( TDC& );
  506.  
  507. private:
  508.  
  509.     virtual void DoDraw( TDC& );
  510.  
  511.     DECLARE_STREAMABLE( , CaptionedRectangle, 1 );
  512.  
  513. };
  514.  
  515. CaptionedRectangle::CaptionedRectangle( TPoint p1, TPoint p2,
  516.                                         const string& txt,
  517.                                         TextLoc loc ) :
  518.     GraphicalObject( p1, p2 ),
  519.     TRectangle( p1, p2 ),
  520.     Caption( txt, loc )
  521. {
  522. }
  523.  
  524. void CaptionedRectangle::ImplementDraw( TDC& dc )
  525. {
  526.     TRectangle::ImplementDraw( dc );
  527.     Caption::ImplementDraw( dc );
  528. }
  529.  
  530. void CaptionedRectangle::DoDraw( TDC& dc )
  531. {
  532.     ImplementDraw( dc );
  533. }
  534.  
  535. IMPLEMENT_CASTABLE2( CaptionedRectangle, TRectangle, Caption );
  536. IMPLEMENT_STREAMABLE3( CaptionedRectangle, TRectangle, Caption, GraphicalObject );
  537.  
  538. void *CaptionedRectangle::Streamer::Read( ipstream& in, uint32 ) const
  539. {
  540.     ReadBaseObject( STATIC_CAST(TRectangle *,GetObject()), in );
  541.     ReadBaseObject( STATIC_CAST(Caption *,GetObject()), in );
  542.     return GetObject();
  543. }
  544.  
  545. void CaptionedRectangle::Streamer::Write( opstream& out ) const
  546. {
  547.     WriteBaseObject( STATIC_CAST(TRectangle *,GetObject()), out );
  548.     WriteBaseObject( STATIC_CAST(Caption *,GetObject()), out );
  549. }
  550.  
  551. /*------------------------------------------------------------------------*/
  552. /*                                                                        */
  553. /*  class CaptionedEllipse                                                */
  554. /*                                                                        */
  555. /*      class CaptionedEllipse draws an ellipse on the                    */
  556. /*      screen, with a caption centered in the ellipse.                   */
  557. /*                                                                        */
  558. /*  Member functions:                                                     */
  559. /*                                                                        */
  560. /*      CaptionedEllipse( TPoint p1, TPoint p2,                           */
  561. /*                        const string& txt )                             */
  562. /*                                                                        */
  563. /*          Creates a CaptionedEllipse with the specified                 */
  564. /*          bounding box and text.                                        */
  565. /*                                                                        */
  566. /*      void ImplementDraw( TDC& );                                       */
  567. /*                                                                        */
  568. /*          Draws the ellipse and its text.                               */
  569. /*                                                                        */
  570. /*      virtual void DoDraw( TDC& );                                      */
  571. /*                                                                        */
  572. /*          Overrides GraphicalObject::DoDraw and draws the ellipse by    */
  573. /*          calling ImplementDraw().                                      */
  574. /*                                                                        */
  575. /*------------------------------------------------------------------------*/
  576.  
  577. class CaptionedEllipse : public TEllipse, public Caption
  578. {
  579.  
  580. public:
  581.  
  582.     CaptionedEllipse( TPoint p1, TPoint p2, const string& txt );
  583.  
  584. protected:
  585.  
  586.     void ImplementDraw( TDC& );
  587.  
  588. private:
  589.  
  590.     virtual void DoDraw( TDC& );
  591.  
  592.     DECLARE_STREAMABLE( , CaptionedEllipse, 1 );
  593.  
  594. };
  595.  
  596. CaptionedEllipse::CaptionedEllipse( TPoint p1, TPoint p2, const string& txt ) :
  597.     GraphicalObject( p1, p2 ),
  598.     TEllipse( p1, p2 ),
  599.     Caption( txt, T_CENTER )
  600. {
  601. }
  602.  
  603. void CaptionedEllipse::ImplementDraw( TDC& dc )
  604. {
  605.     TEllipse::ImplementDraw( dc );
  606.     Caption::ImplementDraw( dc );
  607. }
  608.  
  609. void CaptionedEllipse::DoDraw( TDC& dc )
  610. {
  611.     ImplementDraw( dc );
  612. }
  613.  
  614. IMPLEMENT_CASTABLE2( CaptionedEllipse, TEllipse, Caption );
  615. IMPLEMENT_STREAMABLE3( CaptionedEllipse, TEllipse, Caption, GraphicalObject );
  616.  
  617. void *CaptionedEllipse::Streamer::Read( ipstream& in, uint32 ) const
  618. {
  619.     ReadBaseObject( STATIC_CAST(TEllipse *,GetObject()), in );
  620.     ReadBaseObject( STATIC_CAST(Caption *,GetObject()), in );
  621.     return GetObject();
  622. }
  623.  
  624. void CaptionedEllipse::Streamer::Write( opstream& out ) const
  625. {
  626.     WriteBaseObject( STATIC_CAST(TEllipse *,GetObject()), out );
  627.     WriteBaseObject( STATIC_CAST(Caption *,GetObject()), out );
  628. }
  629.  
  630. /*------------------------------------------------------------------------*/
  631. /*                                                                        */
  632. /*  class TFilledRectangle                                                */
  633. /*                                                                        */
  634. /*      class TFilledRectangle draws a black rectangle on the screen.     */
  635. /*                                                                        */
  636. /*  Member functions:                                                     */
  637. /*                                                                        */
  638. /*      TFilledRectangle( TPoint p1, TPoint p2 );                         */
  639. /*                                                                        */
  640. /*          Creates a TFilledRectangle whose upper left corner is at p1   */
  641. /*          and whose lower right corner is at p2.                        */
  642. /*                                                                        */
  643. /*------------------------------------------------------------------------*/
  644.  
  645. class TFilledRectangle : public TRectangle
  646. {
  647.  
  648. public:
  649.  
  650.     TFilledRectangle::TFilledRectangle( TPoint p1, TPoint p2 );
  651.  
  652.     DECLARE_STREAMABLE_FROM_BASE( , TFilledRectangle, TRectangle );
  653. };
  654.  
  655. TFilledRectangle::TFilledRectangle( TPoint p1, TPoint p2 ) :
  656.     TRectangle( p1, p2 ), GraphicalObject( p1, p2 )
  657. {
  658.     SetFill();
  659. }
  660.  
  661. IMPLEMENT_CASTABLE1( TFilledRectangle, TRectangle );
  662. IMPLEMENT_STREAMABLE_FROM_BASE( TFilledRectangle, TRectangle );
  663.  
  664. /*------------------------------------------------------------------------*/
  665. /*                                                                        */
  666. /*  class TFilledEllipse                                                  */
  667. /*                                                                        */
  668. /*      class TFilledEllipse draws a black ellipse on the screen.         */
  669. /*                                                                        */
  670. /*  Member functions:                                                     */
  671. /*                                                                        */
  672. /*      TFilledEllipse( TPoint p1, TPoint p2 );                           */
  673. /*                                                                        */
  674. /*          Creates a TFilledEllipse whose bounding box is defined by     */
  675. /*          p1 and p2                                                     */
  676. /*                                                                        */
  677. /*------------------------------------------------------------------------*/
  678.  
  679. class TFilledEllipse : public TEllipse
  680. {
  681.  
  682. public:
  683.  
  684.     TFilledEllipse::TFilledEllipse( TPoint p1, TPoint p2 );
  685.  
  686.     DECLARE_STREAMABLE_FROM_BASE( , TFilledEllipse, TEllipse );
  687. };
  688.  
  689. TFilledEllipse::TFilledEllipse( TPoint p1, TPoint p2 ) :
  690.     TEllipse( p1, p2 ), GraphicalObject( p1, p2 )
  691. {
  692.     SetFill();
  693. }
  694.  
  695. IMPLEMENT_CASTABLE1( TFilledEllipse, TEllipse );
  696. IMPLEMENT_STREAMABLE_FROM_BASE( TFilledEllipse, TEllipse );
  697.  
  698. /*------------------------------------------------------------------------*/
  699. /*                                                                        */
  700. /*  class TObjectBuilder                                                  */
  701. /*                                                                        */
  702. /*      class TObjectBuilder provides the core functionality for          */
  703. /*      building objects derived from GraphicalObject in a Windows        */
  704. /*      environment. It handles changing the cursor to one that           */
  705. /*      indicates the type of object being built, clipping the cursor     */
  706. /*      so that it stays within the application's client area,            */
  707. /*      handles anchoring the object's bounding box and dragging the      */
  708. /*      unanchored corner of the bounding box.                            */
  709. /*                                                                        */
  710. /*  Public member functions:                                              */
  711. /*                                                                        */
  712. /*      TObjectBuilder( TWindow& owner, int cursorId );                   */
  713. /*                                                                        */
  714. /*          Clips the cursor so that it stays within the owner's          */
  715. /*          client area and replaces the default cursor with the          */
  716. /*          cursor contained in the resource identified by cursorId.      */
  717. /*                                                                        */
  718. /*      ~TObjectBuilder();                                                */
  719. /*                                                                        */
  720. /*          Restores the default cursor and ends the clipping.            */
  721. /*                                                                        */
  722. /*                                                                        */
  723. /*      void SetAnchor( TPoint pos );                                     */
  724. /*                                                                        */
  725. /*          Sets the anchor point of the bounding box to the point pos.   */
  726. /*                                                                        */
  727. /*      void Drag( TPoint pos );                                          */
  728. /*                                                                        */
  729. /*          Moves the unanchored corner of the bounding box to the        */
  730. /*          point pos, drawing the object's skeleton as appropriate.      */
  731. /*          See DrawSkeleton().                                           */
  732. /*                                                                        */
  733. /*      GraphicalObject *CreateObject();                                  */
  734. /*                                                                        */
  735. /*          Returns a pointer to the newly created object derived         */
  736. /*          from GraphicalObject and contained within the bounding box    */
  737. /*          delimited by the anchor point and the unanchored corner as    */
  738. /*          set up by SetAnchor() and Drag() and cleans up whatever       */
  739. /*          needs to be cleaned up. See BuildObject().                    */
  740. /*                                                                        */
  741. /*      void Cancel()                                                     */
  742. /*                                                                        */
  743. /*          Cleans up whatever needs to be cleaned up when the object is  */
  744. /*          not wanted.                                                   */
  745. /*                                                                        */
  746. /*  Protected member functions:                                           */
  747. /*                                                                        */
  748. /*      const TWindow& GetOwner() const;                                  */
  749. /*                                                                        */
  750. /*          Returns a reference to the TWindow that owns the client       */
  751. /*          area that we're drawing to.                                   */
  752. /*                                                                        */
  753. /*  Virtual functions:                                                    */
  754. /*                                                                        */
  755. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const = 0;     */
  756. /*                                                                        */
  757. /*          This must be overridden by the derived class. It is called    */
  758. /*          from Drag() to erase the previously drawn skeleton which      */
  759. /*          was drawn at p1 and p2, and it is called again to draw the    */
  760. /*          new skeleton at positions p1 and p2. The skeleton should be   */
  761. /*          some sort of simple line representation of the object being   */
  762. /*          built.                                                        */
  763. /*                                                                        */
  764. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 ) = 0;         */
  765. /*                                                                        */
  766. /*          Called from CreateObject() to actually build the desired      */
  767. /*          object, with its bounding box defined by p1 and p2. Typically */
  768. /*          this just calls a constructor for the desired object.         */
  769. /*                                                                        */
  770. /*------------------------------------------------------------------------*/
  771.  
  772. class TObjectBuilder
  773. {
  774.  
  775. public:
  776.  
  777.     TObjectBuilder( TWindow& owner, int cursorId );
  778.     virtual ~TObjectBuilder();
  779.  
  780.     void SetAnchor( TPoint pos );
  781.     void Drag( TPoint pos );
  782.     GraphicalObject *CreateObject();
  783.     void Cancel() const;
  784.  
  785. protected:
  786.  
  787.     const TWindow& GetOwner() const { return Owner; }
  788.  
  789.  
  790. private:
  791.  
  792.     class BuilderDC : public TClientDC
  793.     {
  794.     public:
  795.         BuilderDC( HWND wnd );
  796.         ~BuilderDC();
  797.     };
  798.  
  799.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const = 0;
  800.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 ) = 0;
  801.  
  802.     TPoint Anchor;
  803.     TPoint Current;
  804.     int Anchored;
  805.  
  806.     HCURSOR OldCursor;
  807.     TWindow& Owner;
  808.  
  809.     TObjectBuilder( const TObjectBuilder& );
  810.     const TObjectBuilder& operator = ( const TObjectBuilder& );
  811.  
  812. };
  813.  
  814. TObjectBuilder::TObjectBuilder( TWindow& owner, int cursorId ) :
  815.     Owner(owner),
  816.     Anchored(0)
  817. {
  818.     TRect Rect;
  819.     Owner.GetWindowRect( Rect );
  820.     ClipCursor( &Rect );
  821.     Owner.SetCursor( Owner.GetApplication(), cursorId );
  822. }
  823.  
  824. TObjectBuilder::~TObjectBuilder()
  825. {
  826.     Owner.SetCursor( 0, IDC_ARROW );
  827.     ClipCursor(0);
  828. }
  829.  
  830. void TObjectBuilder::SetAnchor( TPoint point )
  831. {
  832.     Anchor = Current = point;
  833.     BuilderDC dc( Owner );
  834.     DrawSkeleton( dc, Anchor, Current );
  835.     Anchored = 1;
  836. }
  837.  
  838. void TObjectBuilder::Drag( TPoint point )
  839. {
  840.     if( Anchored )
  841.         {
  842.         BuilderDC dc( Owner );
  843.         DrawSkeleton( dc, Anchor, Current );
  844.         Current = point;
  845.         DrawSkeleton( dc, Anchor, Current );
  846.         }
  847. }
  848.  
  849. GraphicalObject *TObjectBuilder::CreateObject()
  850. {
  851.     return BuildObject( Anchor, Current );
  852. }
  853.  
  854. void TObjectBuilder::Cancel() const
  855. {
  856.     if( Anchored )
  857.         {
  858.         BuilderDC dc( Owner );
  859.         DrawSkeleton( dc, Anchor, Current );
  860.         }
  861. }
  862.  
  863. TObjectBuilder::BuilderDC::BuilderDC( HWND wnd ) : TClientDC( wnd )
  864. {
  865.     SelectStockObject(WHITE_PEN);
  866.     SetROP2( R2_XORPEN );
  867.     SelectStockObject(NULL_BRUSH);
  868. }
  869.  
  870. TObjectBuilder::BuilderDC::~BuilderDC()
  871. {
  872. }
  873.  
  874. /*------------------------------------------------------------------------*/
  875. /*                                                                        */
  876. /*  class LineBuilder                                                     */
  877. /*                                                                        */
  878. /*      class LineBuilder builds a Line object using the mechanisms       */
  879. /*      provided by TObjectBuilder.                                       */
  880. /*                                                                        */
  881. /*  Member functions:                                                     */
  882. /*                                                                        */
  883. /*      LineBuilder( TWindow& owner );                                    */
  884. /*                                                                        */
  885. /*          Initializes a LineBuilder that will draw its skeleton inside  */
  886. /*          the client area of owner.                                     */
  887. /*                                                                        */
  888. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  889. /*                                                                        */
  890. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  891. /*          for a line, which is just a line from p1 to p2.               */
  892. /*                                                                        */
  893. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  894. /*                                                                        */
  895. /*          Overrides TObjectBuilder::BuildObject to build a Line         */
  896. /*          object with its endpoints at p1 and p2.                       */
  897. /*                                                                        */
  898. /*------------------------------------------------------------------------*/
  899.  
  900. class LineBuilder : public TObjectBuilder
  901. {
  902.  
  903. public:
  904.  
  905.     LineBuilder( TWindow& owner );
  906.  
  907. private:
  908.  
  909.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
  910.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  911.  
  912. };
  913.  
  914. LineBuilder::LineBuilder( TWindow& owner ) :
  915.     TObjectBuilder( owner, LINE_CURSOR )
  916. {
  917. }
  918.  
  919. void LineBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
  920. {
  921.     dc.MoveTo( p1.x, p1.y );
  922.     dc.LineTo( p2.x, p2.y );
  923. }
  924.  
  925. GraphicalObject *LineBuilder::BuildObject( TPoint p1, TPoint p2 )
  926. {
  927.     return new Line( p1, p2 );
  928. }
  929.  
  930. /*------------------------------------------------------------------------*/
  931. /*                                                                        */
  932. /*  class RectangleBuilder                                                */
  933. /*                                                                        */
  934. /*      class RectangleBuilder builds a TRectangle object using the       */
  935. /*      mechanisms provided by TObjectBuilder.                            */
  936. /*                                                                        */
  937. /*  Member functions:                                                     */
  938. /*                                                                        */
  939. /*      RectangleBuilder( TWindow& owner );                               */
  940. /*                                                                        */
  941. /*          Initializes a RectangleBuilder that will draw its skeleton    */
  942. /*          inside the client area of owner.                              */
  943. /*                                                                        */
  944. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  945. /*                                                                        */
  946. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  947. /*          for a TRectangle, which is a rectangle whose upper left       */
  948. /*          corner is at p1 and whose lower right corner is at p2.        */
  949. /*                                                                        */
  950. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  951. /*                                                                        */
  952. /*          Overrides TObjectBuilder::BuildObject to build a TRectangle   */
  953. /*          object with its upper left corner at p1 and its lower right   */
  954. /*          corner at p2.                                                 */
  955. /*                                                                        */
  956. /*------------------------------------------------------------------------*/
  957.  
  958. class RectangleBuilder : public TObjectBuilder
  959. {
  960.  
  961. public:
  962.  
  963.     RectangleBuilder( TWindow& owner );
  964.  
  965. private:
  966.  
  967.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
  968.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  969.  
  970. };
  971.  
  972. RectangleBuilder::RectangleBuilder( TWindow& owner ) :
  973.     TObjectBuilder( owner, RECT_CURSOR )
  974. {
  975. }
  976.  
  977. void RectangleBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
  978. {
  979.     dc.Rectangle( p1, p2 );
  980. }
  981.  
  982. GraphicalObject *RectangleBuilder::BuildObject( TPoint p1, TPoint p2 )
  983. {
  984.     return new TRectangle( p1, p2 );
  985. }
  986.  
  987. /*------------------------------------------------------------------------*/
  988. /*                                                                        */
  989. /*  class EllipseBuilder                                                  */
  990. /*                                                                        */
  991. /*      class EllipseBuilder builds a TEllipse object using the           */
  992. /*      mechanisms provided by TObjectBuilder.                            */
  993. /*                                                                        */
  994. /*  Member functions:                                                     */
  995. /*                                                                        */
  996. /*      EllipseBuilder( TWindow& owner );                                 */
  997. /*                                                                        */
  998. /*          Initializes an EllipseBuilder that will draw its skeleton     */
  999. /*          inside the client area of owner.                              */
  1000. /*                                                                        */
  1001. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  1002. /*                                                                        */
  1003. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  1004. /*          for a TEllipse, which is an ellipse with a bounding box whose */
  1005. /*          upper left corner is at p1 and whose lower right corner is    */
  1006. /*          at p2.                                                        */
  1007. /*                                                                        */
  1008. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  1009. /*                                                                        */
  1010. /*          Overrides TObjectBuilder::BuildObject to build a TEllipse     */
  1011. /*          object with a bounding box whose upper left corner is at p1   */
  1012. /*          and whose lower right corner is at p2.                        */
  1013. /*                                                                        */
  1014. /*------------------------------------------------------------------------*/
  1015.  
  1016. class EllipseBuilder : public TObjectBuilder
  1017. {
  1018.  
  1019. public:
  1020.  
  1021.     EllipseBuilder( TWindow& owner );
  1022.  
  1023. private:
  1024.  
  1025.     virtual void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;
  1026.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  1027.  
  1028. };
  1029.  
  1030. EllipseBuilder::EllipseBuilder( TWindow& owner ) :
  1031.     TObjectBuilder( owner, ELLIPSE_CURSOR )
  1032. {
  1033. }
  1034.  
  1035. void EllipseBuilder::DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const
  1036.  
  1037. {
  1038.     dc.Ellipse( p1, p2 );
  1039. }
  1040.  
  1041. GraphicalObject *EllipseBuilder::BuildObject( TPoint p1, TPoint p2 )
  1042. {
  1043.     return new TEllipse( p1, p2 );
  1044. }
  1045.  
  1046. /*------------------------------------------------------------------------*/
  1047. /*                                                                        */
  1048. /*  class CaptionBuilder                                                  */
  1049. /*                                                                        */
  1050. /*      class CaptionBuilder provides a base class for use by builders    */
  1051. /*      of captioned objects. It does not inherit from TObjectBuilder.    */
  1052. /*      It is expected that this class will be mixed in with a class      */
  1053. /*      that does inherit from TObjectBuilder. See, for example,          */
  1054. /*      CaptionedRectangleBuilder.                                        */
  1055. /*                                                                        */
  1056. /*  Member functions:                                                     */
  1057. /*                                                                        */
  1058. /*      CaptionBuilder( TWindow& owner, int allowPosition );              */
  1059. /*                                                                        */
  1060. /*          Initializes a CaptionBuilder that will belong to the TWindow  */
  1061. /*          owner. allowPosition is a flag that indicates whether the     */
  1062. /*          user should be allowed to specify the placement of the        */
  1063. /*          caption. If allowPosition is non-zero, the dialog box that    */
  1064. /*          prompts for the caption also allows the user to specify       */
  1065. /*          whether the caption should be at the top, in the center, or   */
  1066. /*          at the bottom of the object. If allowPosition is 0 this       */
  1067. /*          part of the dialog box is grayed out.                         */
  1068. /*                                                                        */
  1069. /*      string GetCaption();                                              */
  1070. /*                                                                        */
  1071. /*          Retrieves the text of the caption specified by the user. If   */
  1072. /*          the user hasn't been asked for the caption yet GetCaption()   */
  1073. /*          puts up a dialog box requesting input from the user.          */
  1074. /*                                                                        */
  1075. /*      Caption::TextLoc GetLocation();                                   */
  1076. /*                                                                        */
  1077. /*          Retrieves the location for the caption specified by the user. */
  1078. /*          If the user hasn't been asked for the caption yet             */
  1079. /*          GetLocation() puts up a dialog box requesting input from the  */
  1080. /*          user. If allowPosition was 0 GetLocation() returns T_TOP.     */
  1081. /*                                                                        */
  1082. /*------------------------------------------------------------------------*/
  1083.  
  1084. class CaptionBuilder
  1085. {
  1086.  
  1087. public:
  1088.  
  1089.     CaptionBuilder( TWindow& owner, int allowPosition = 1 );
  1090.     string GetCaption();
  1091.     Caption::TextLoc GetLocation();
  1092.  
  1093. private:
  1094.  
  1095.     void GetData();
  1096.     int HaveData;
  1097.     string Caption;
  1098.     Caption::TextLoc Location;
  1099.     TWindow& Owner;
  1100.     int AllowPosition;
  1101.  
  1102.     class CaptionDialog : public TDialog
  1103.     {
  1104.     public:
  1105.         CaptionDialog( TWindow& parent, CaptionBuilder& builder );
  1106.         BOOL CanClose();
  1107.         void SetupWindow();
  1108.     private:
  1109.         void TopClicked();
  1110.         void CenterClicked();
  1111.         void BottomClicked();
  1112.         CaptionBuilder& Builder;
  1113.     DECLARE_RESPONSE_TABLE( CaptionDialog );
  1114.     };
  1115.  
  1116.     friend CaptionDialog;
  1117.  
  1118. };
  1119.  
  1120. CaptionBuilder::CaptionBuilder( TWindow& owner, int allowPosition ) :
  1121.     HaveData(0),
  1122.     Location(Caption::T_TOP),
  1123.     Owner(owner),
  1124.     AllowPosition(allowPosition)
  1125. {
  1126. }
  1127.  
  1128. void CaptionBuilder::GetData()
  1129. {
  1130.     if( !HaveData )
  1131.         {
  1132.         CaptionDialog dialog( Owner, *this );
  1133.         dialog.Execute();
  1134.         HaveData = 1;
  1135.         }
  1136. }
  1137.  
  1138. string CaptionBuilder::GetCaption()
  1139. {
  1140.     GetData();
  1141.     return Caption;
  1142. }
  1143.  
  1144. Caption::TextLoc CaptionBuilder::GetLocation()
  1145. {
  1146.     GetData();
  1147.     return Location;
  1148. }
  1149.  
  1150. DEFINE_RESPONSE_TABLE1( CaptionBuilder::CaptionDialog, TDialog )
  1151.     EV_CHILD_NOTIFY( IDD_TOP, BN_CLICKED, TopClicked ),
  1152.     EV_CHILD_NOTIFY( IDD_CENTER, BN_CLICKED, CenterClicked ),
  1153.     EV_CHILD_NOTIFY( IDD_BOTTOM, BN_CLICKED, BottomClicked ),
  1154. END_RESPONSE_TABLE;
  1155.  
  1156. CaptionBuilder::CaptionDialog::CaptionDialog( TWindow& parent, CaptionBuilder& builder ) :
  1157.     TDialog( &parent, "CaptionDlg" ),
  1158.     Builder(builder)
  1159. {
  1160. }
  1161.  
  1162. void CaptionBuilder::CaptionDialog::SetupWindow()
  1163. {
  1164.     if( Builder.AllowPosition )
  1165.         SendDlgItemMessage( IDD_TOP, BM_SETCHECK, 1, 0L );
  1166.     else
  1167.         {
  1168.         ::EnableWindow( GetDlgItem( IDD_TOP ), 0 );
  1169.         ::EnableWindow( GetDlgItem( IDD_CENTER ), 0 );
  1170.         ::EnableWindow( GetDlgItem( IDD_BOTTOM ), 0 );
  1171.         ::EnableWindow( GetDlgItem( IDD_POSITIONBOX ), 0 );
  1172.         }
  1173. }
  1174.  
  1175. BOOL CaptionBuilder::CaptionDialog::CanClose()
  1176. {
  1177.     char buf[256];
  1178.     GetDlgItemText( IDD_INPUTEDITBOX, buf, sizeof(buf) );
  1179.     Builder.Caption = buf;
  1180.     return TRUE;
  1181. }
  1182.  
  1183. void CaptionBuilder::CaptionDialog::TopClicked()
  1184. {
  1185.     Builder.Location = Caption::T_TOP;
  1186. }
  1187.  
  1188. void CaptionBuilder::CaptionDialog::CenterClicked()
  1189. {
  1190.     Builder.Location = Caption::T_CENTER;
  1191. }
  1192.  
  1193. void CaptionBuilder::CaptionDialog::BottomClicked()
  1194. {
  1195.     Builder.Location = Caption::T_BOTTOM;
  1196. }
  1197.  
  1198. /*------------------------------------------------------------------------*/
  1199. /*                                                                        */
  1200. /*  class CaptionedRectangleBuilder                                       */
  1201. /*                                                                        */
  1202. /*      class CaptionedRectangleBuilder builds a CaptionedRectangle       */
  1203. /*      object using the mechanisms provided by TObjectBuilder.           */
  1204. /*                                                                        */
  1205. /*  Member functions:                                                     */
  1206. /*                                                                        */
  1207. /*      CaptionedRectangleBuilder( TWindow& owner );                      */
  1208. /*                                                                        */
  1209. /*          Initializes a CaptionedRectangleBuilder that will draw its    */
  1210. /*          skeleton inside the client area of owner and prompt for the   */
  1211. /*          caption after the bounding box has been defined.              */
  1212. /*                                                                        */
  1213. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  1214. /*                                                                        */
  1215. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  1216. /*          for a CaptionedRectangle, which is a rectangle whose upper    */
  1217. /*          left corner is at p1 and whose lower right corner is at p2.   */
  1218. /*                                                                        */
  1219. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  1220. /*                                                                        */
  1221. /*          Overrides TObjectBuilder::BuildObject to build a              */
  1222. /*          CaptionedRectangle object with its upper left corner at p1    */
  1223. /*          and its lower right corner at p2.                             */
  1224. /*                                                                        */
  1225. /*------------------------------------------------------------------------*/
  1226.  
  1227. class CaptionedRectangleBuilder : public RectangleBuilder, private CaptionBuilder
  1228. {
  1229.  
  1230. public:
  1231.  
  1232.     CaptionedRectangleBuilder( TWindow& owner );
  1233.  
  1234. private:
  1235.  
  1236.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  1237.  
  1238. };
  1239.  
  1240. CaptionedRectangleBuilder::CaptionedRectangleBuilder( TWindow& owner ) :
  1241.     RectangleBuilder( owner ),
  1242.     CaptionBuilder( owner )
  1243. {
  1244. }
  1245.  
  1246. GraphicalObject *CaptionedRectangleBuilder::BuildObject( TPoint p1, TPoint p2 )
  1247. {
  1248.     return new CaptionedRectangle( p1, p2, GetCaption(), GetLocation() );
  1249. }
  1250.  
  1251. /*------------------------------------------------------------------------*/
  1252. /*                                                                        */
  1253. /*  class CaptionedEllipseBuilder                                         */
  1254. /*                                                                        */
  1255. /*      class CaptionedEllipseBuilder builds a CaptionedEllipse           */
  1256. /*      object using the mechanisms provided by TObjectBuilder.           */
  1257. /*                                                                        */
  1258. /*  Member functions:                                                     */
  1259. /*                                                                        */
  1260. /*      CaptionedEllipseBuilder( TWindow& owner );                        */
  1261. /*                                                                        */
  1262. /*          Initializes a CaptionedRectangleBuilder that will draw its    */
  1263. /*          skeleton inside the client area of owner and prompt for the   */
  1264. /*          caption after the bounding box has been defined.              */
  1265. /*                                                                        */
  1266. /*      void DrawSkeleton( TDC& dc, TPoint p1, TPoint p2 ) const;         */
  1267. /*                                                                        */
  1268. /*          Overrides TObjectBuilder::DrawSkeleton to draw the skeleton   */
  1269. /*          for a CaptionedEllipse, which is an ellipse with a bounding   */
  1270. /*          box whose upper left corner is at p1 and whose lower right    */
  1271. /*          corner is at p2.                                              */
  1272. /*                                                                        */
  1273. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  1274. /*                                                                        */
  1275. /*          Overrides TObjectBuilder::BuildObject to build a              */
  1276. /*          CaptionedEllipse object with a bounding box whose upper left  */
  1277. /*          corner is at p1 and whose lower right corner is at p2.        */
  1278. /*                                                                        */
  1279. /*------------------------------------------------------------------------*/
  1280.  
  1281. class CaptionedEllipseBuilder : public EllipseBuilder, public CaptionBuilder
  1282. {
  1283.  
  1284. public:
  1285.  
  1286.     CaptionedEllipseBuilder( TWindow& owner );
  1287.  
  1288. private:
  1289.  
  1290.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  1291.  
  1292. };
  1293.  
  1294. CaptionedEllipseBuilder::CaptionedEllipseBuilder( TWindow& owner ) :
  1295.     EllipseBuilder( owner ),
  1296.     CaptionBuilder( owner, 0 )
  1297. {
  1298. }
  1299.  
  1300. GraphicalObject *CaptionedEllipseBuilder::BuildObject( TPoint p1, TPoint p2 )
  1301. {
  1302.     return new CaptionedEllipse( p1, p2, GetCaption() );
  1303. }
  1304.  
  1305. /*------------------------------------------------------------------------*/
  1306. /*                                                                        */
  1307. /*  class FilledRectangleBuilder                                          */
  1308. /*                                                                        */
  1309. /*      class FilledRectangleBuilder builds a TFilledRectangle object.    */
  1310. /*                                                                        */
  1311. /*  Member functions:                                                     */
  1312. /*                                                                        */
  1313. /*      FilledRectangleBuilder( TWindow& owner );                         */
  1314. /*                                                                        */
  1315. /*          Initializes a FilledRectangleBuilder.                         */
  1316. /*                                                                        */
  1317. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  1318. /*                                                                        */
  1319. /*          Overrides RectangleBuilder::BuildObject to build a            */
  1320. /*          TFilledRectangle object with its upper left corner at p1 and  */
  1321. /*          its lower right corner at p2.                                 */
  1322. /*                                                                        */
  1323. /*------------------------------------------------------------------------*/
  1324.  
  1325. class FilledRectangleBuilder : public RectangleBuilder
  1326. {
  1327.  
  1328. public:
  1329.  
  1330.     FilledRectangleBuilder( TWindow& owner );
  1331.  
  1332. private:
  1333.  
  1334.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  1335.  
  1336. };
  1337.  
  1338. FilledRectangleBuilder::FilledRectangleBuilder( TWindow& owner ) :
  1339.     RectangleBuilder( owner )
  1340. {
  1341. }
  1342.  
  1343. GraphicalObject *FilledRectangleBuilder::BuildObject( TPoint p1, TPoint p2 )
  1344. {
  1345.     return new TFilledRectangle( p1, p2 );
  1346. }
  1347.  
  1348. /*------------------------------------------------------------------------*/
  1349. /*                                                                        */
  1350. /*  class FilledEllipseBuilder                                            */
  1351. /*                                                                        */
  1352. /*      class FilledEllipseBuilder builds a TFilledEllipse object.        */
  1353. /*                                                                        */
  1354. /*  Member functions:                                                     */
  1355. /*                                                                        */
  1356. /*      FilledEllipseBuilder( TWindow& owner );                           */
  1357. /*                                                                        */
  1358. /*          Initializes a FilledEllipseBuilder.                           */
  1359. /*                                                                        */
  1360. /*      GraphicalObject *BuildObject( TPoint p1, TPoint p2 );             */
  1361. /*                                                                        */
  1362. /*          Overrides EllipseBuilder::BuildObject to build a              */
  1363. /*          TFilledEllipse object with its bounding box defined by        */
  1364. /*          p1 and p2.                                                    */
  1365. /*                                                                        */
  1366. /*------------------------------------------------------------------------*/
  1367.  
  1368. class FilledEllipseBuilder : public EllipseBuilder
  1369. {
  1370.  
  1371. public:
  1372.  
  1373.     FilledEllipseBuilder( TWindow& owner );
  1374.  
  1375. private:
  1376.  
  1377.     virtual GraphicalObject *BuildObject( TPoint p1, TPoint p2 );
  1378.  
  1379. };
  1380.  
  1381. FilledEllipseBuilder::FilledEllipseBuilder( TWindow& owner ) :
  1382.     EllipseBuilder( owner )
  1383. {
  1384. }
  1385.  
  1386. GraphicalObject *FilledEllipseBuilder::BuildObject( TPoint p1, TPoint p2 )
  1387. {
  1388.     return new TFilledEllipse( p1, p2 );
  1389. }
  1390.  
  1391. /*------------------------------------------------------------------------*/
  1392. /*                                                                        */
  1393. /*  class TGraphWindow                                                    */
  1394. /*                                                                        */
  1395. /*      class TGraphWindow pulls all of the forgoing together into a      */
  1396. /*      rather limited shape editor. It uses a TISetAsVector to hold      */
  1397. /*      the various objects that are in the current drawing.              */
  1398. /*                                                                        */
  1399. /*  Member functions:                                                     */
  1400. /*                                                                        */
  1401. /*      TGraphWindow();                                                   */
  1402. /*                                                                        */
  1403. /*          Initializes the window.                                       */
  1404. /*                                                                        */
  1405. /*      void Paint( TDC&, BOOL, TRect& );                                 */
  1406. /*                                                                        */
  1407. /*          Called whenever the window receives a WM_PAINT message. Draws */
  1408. /*          the objects by calling each of their Draw() functions.        */
  1409. /*                                                                        */
  1410. /*      void CmNew();                                                     */
  1411. /*                                                                        */
  1412. /*          Called when the user selects File/New from the menu. Removes  */
  1413. /*          all objects from the current drawing.                         */
  1414. /*                                                                        */
  1415. /*      void CmLine();                                                    */
  1416. /*                                                                        */
  1417. /*          Called when the user selects Edit/Line from the menu. Adds    */
  1418. /*          a line to the drawing.                                        */
  1419. /*                                                                        */
  1420. /*      void CmRectangle();                                               */
  1421. /*                                                                        */
  1422. /*          Called when the user selects Edit/Rectangle from the menu.    */
  1423. /*          Adds a rectangle to the drawing.                              */
  1424. /*                                                                        */
  1425. /*      void CmCaptionedRectangle();                                      */
  1426. /*                                                                        */
  1427. /*          Called when the user selects Edit/CaptionedRectangle from the */
  1428. /*          menu. Adds a captioned rectangle to the drawing.              */
  1429. /*                                                                        */
  1430. /*      void CmEllipse();                                                 */
  1431. /*                                                                        */
  1432. /*          Called when the user selects Edit/Ellipse from the menu.      */
  1433. /*          Adds an ellipse to the drawing.                               */
  1434. /*                                                                        */
  1435. /*      void CmCaptionedEllipse();                                        */
  1436. /*                                                                        */
  1437. /*          Called when the user selects Edit/CaptionedEllipse from the   */
  1438. /*          menu. Adds a captioned ellipse to the drawing.                */
  1439. /*                                                                        */
  1440. /*      void CmAbout();                                                   */
  1441. /*                                                                        */
  1442. /*          Called when the user selects Help/About from the menu.        */
  1443. /*          Displays the About box.                                       */
  1444. /*                                                                        */
  1445. /*      void EvLButtonDown();                                             */
  1446. /*                                                                        */
  1447. /*          Called when the user presses the left mouse button. During    */
  1448. /*          building of an object, this anchors the object's bounding     */
  1449. /*          box at the current position of the mouse.                     */
  1450. /*                                                                        */
  1451. /*      void EvLButtonUp();                                               */
  1452. /*                                                                        */
  1453. /*          Called when the user releases the left mouse button. During   */
  1454. /*          building of an object, this creates the actual object with    */
  1455. /*          its bounding box defined by the previous anchor position and  */
  1456. /*          the current position of the mouse.                            */
  1457. /*                                                                        */
  1458. /*      void EvRButtonDown();                                             */
  1459. /*                                                                        */
  1460. /*          Called when the user presses the right mouse button. During   */
  1461. /*          building of an object, this terminates building.              */
  1462. /*                                                                        */
  1463. /*      void EvMouseMove();                                               */
  1464. /*                                                                        */
  1465. /*          Called when the user moves the mouse. During building of an   */
  1466. /*          object, if the object's bounding box has been anchored, this  */
  1467. /*          drags the free corner of the bounding box.                    */
  1468. /*                                                                        */
  1469. /*------------------------------------------------------------------------*/
  1470.  
  1471. class TGraphWindow : public TWindow
  1472. {
  1473.  
  1474. public:
  1475.  
  1476.     TGraphWindow();
  1477.  
  1478.     void Paint(TDC&, BOOL, TRect&);
  1479.  
  1480.     void CmNew();
  1481.     void CmLine();
  1482.     void CmRectangle();
  1483.     void CmCaptionedRectangle();
  1484.     void CmFilledRectangle();           // Changed
  1485.     void CmEllipse();
  1486.     void CmCaptionedEllipse();
  1487.     void CmFilledEllipse();             // Changed
  1488.     void CmAbout();
  1489.  
  1490.     void CmFileOpen();
  1491.     void CmFileSave();
  1492.     void CmFileSaveAs();
  1493.  
  1494.     void EvLButtonDown( UINT modKeys, TPoint& point );
  1495.     void EvLButtonUp( UINT modKeys, TPoint& point );
  1496.     void EvRButtonDown( UINT modKeys, TPoint& point );
  1497.     void EvMouseMove( UINT modKeys, TPoint& point );
  1498.  
  1499.     BOOL CanClose();
  1500.  
  1501.     TOpenSaveDialog::TData FileData;
  1502.  
  1503. private:
  1504.  
  1505.     int SaveFile();
  1506.     int SaveFileAs();
  1507.     void ReadObjects();
  1508.     void WriteObjects();
  1509.     int CheckAndClear();
  1510.     int OkToClear();
  1511.     static void WriteObject( GraphicalObject &obj, void * );
  1512.  
  1513.     TObjectBuilder *Builder;
  1514.  
  1515.     void FlushObjects();
  1516.     void AddObject( GraphicalObject *obj );
  1517.     static void DrawObject( GraphicalObject &obj, void * );
  1518.     TISetAsVector<GraphicalObject> Objects;
  1519.  
  1520.     int WindowIsDirty;
  1521.  
  1522.     class GraphWindowDC
  1523.     {
  1524.     public:
  1525.         GraphWindowDC( TDC& );
  1526.         ~GraphWindowDC();
  1527.         operator TDC&() const;
  1528.     private:
  1529.         TDC& DC;
  1530.         uint OldFlags;
  1531.         TPen Pen;
  1532.     };
  1533.  
  1534.     DECLARE_RESPONSE_TABLE(TGraphWindow);
  1535.  
  1536. };
  1537.  
  1538. DEFINE_RESPONSE_TABLE1( TGraphWindow, TWindow )
  1539.     EV_COMMAND( CM_FILENEW, CmNew ),
  1540.     EV_COMMAND( CM_FILEOPEN, CmFileOpen ),
  1541.     EV_COMMAND( CM_FILESAVE, CmFileSave ),
  1542.     EV_COMMAND( CM_FILESAVEAS, CmFileSaveAs ),
  1543.     EV_COMMAND( CM_EDITLINE, CmLine ),
  1544.     EV_COMMAND( CM_EDITRECTANGLE, CmRectangle ),
  1545.     EV_COMMAND( CM_EDITCAPTIONEDRECTANGLE, CmCaptionedRectangle ),
  1546.     EV_COMMAND( CM_EDITFILLEDRECTANGLE, CmFilledRectangle ),    // Changed
  1547.     EV_COMMAND( CM_EDITELLIPSE, CmEllipse ),
  1548.     EV_COMMAND( CM_EDITCAPTIONEDELLIPSE, CmCaptionedEllipse ),
  1549.     EV_COMMAND( CM_EDITFILLEDELLIPSE, CmFilledEllipse ),        // Changed
  1550.     EV_COMMAND( CM_HELPABOUT, CmAbout ),
  1551.     EV_WM_LBUTTONDOWN,
  1552.     EV_WM_LBUTTONUP,
  1553.     EV_WM_RBUTTONDOWN,
  1554.     EV_WM_MOUSEMOVE,
  1555. END_RESPONSE_TABLE;
  1556.  
  1557. TGraphWindow::GraphWindowDC::GraphWindowDC( TDC& dc ) :
  1558.     DC(dc),
  1559.     Pen(::GetSysColor(COLOR_WINDOWTEXT))
  1560. {
  1561.     OldFlags = DC.SetTextAlign( TA_CENTER );
  1562.     DC.SelectObject( Pen );
  1563.     DC.SetBkColor( ::GetSysColor( COLOR_WINDOW ) );
  1564. }
  1565.  
  1566. TGraphWindow::GraphWindowDC::~GraphWindowDC()
  1567. {
  1568.     DC.RestorePen();
  1569.     DC.SetTextAlign( OldFlags );
  1570. }
  1571.  
  1572. TGraphWindow::GraphWindowDC::operator TDC&() const
  1573. {
  1574.     return DC;
  1575. }
  1576.  
  1577. TGraphWindow::TGraphWindow() :
  1578.     TWindow( 0, 0, 0 ),
  1579.     Builder(0),
  1580.     FileData(OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST,
  1581.              "Stream Files (*.stm)|*.stm|All Files (*.*)|*.*|",
  1582.              0, "", "*"),
  1583.     WindowIsDirty(0)
  1584. {
  1585. }
  1586.  
  1587. void TGraphWindow::DrawObject( GraphicalObject &obj, void *ptr )
  1588. {
  1589.     obj.Draw( *(GraphWindowDC *)ptr );
  1590. }
  1591.  
  1592. void TGraphWindow::Paint( TDC& dc, BOOL, TRect& )
  1593. {
  1594.     GraphWindowDC gdc(dc);
  1595.     Objects.ForEach( DrawObject, &gdc );
  1596. }
  1597.  
  1598. void TGraphWindow::CmNew()
  1599. {
  1600.     if( CheckAndClear() )
  1601.         Invalidate();
  1602. }
  1603.  
  1604. void TGraphWindow::CmFileOpen()
  1605. {
  1606.     if( CheckAndClear() )
  1607.         {
  1608.         *FileData.FileName = 0;
  1609.         TFileOpenDialog dlg( this, FileData );
  1610.         if( dlg.Execute() == IDOK )
  1611.             {
  1612.             ReadObjects();
  1613.             Invalidate();
  1614.             }
  1615.         }
  1616. }
  1617.  
  1618. void TGraphWindow::CmFileSave()
  1619. {
  1620.     SaveFile();
  1621. }
  1622.  
  1623. int TGraphWindow::SaveFile()
  1624. {
  1625.     if( *FileData.FileName == '\0' )
  1626.         return SaveFileAs();
  1627.     else
  1628.         {
  1629.         WriteObjects();
  1630.         return 1;
  1631.         }
  1632. }
  1633.  
  1634. void TGraphWindow::CmFileSaveAs()
  1635. {
  1636.     SaveFileAs();
  1637. }
  1638.  
  1639. int TGraphWindow::SaveFileAs()
  1640. {
  1641.     *FileData.FileName = '\0';
  1642.     TFileSaveDialog dlg( this, FileData );
  1643.     if( dlg.Execute() == IDOK )
  1644.         {
  1645.         WriteObjects();
  1646.         return 1;
  1647.         }
  1648.     else
  1649.         return 0;
  1650. }
  1651.  
  1652. void TGraphWindow::ReadObjects()
  1653. {
  1654.     ifpstream in( FileData.FileName );
  1655.     int count;
  1656.     in >> count;
  1657.     while( count-- != 0 )
  1658.         {
  1659.         GraphicalObject *object;
  1660.         in >> object;
  1661.         AddObject( object );
  1662.         }
  1663.     WindowIsDirty = 0;
  1664. }
  1665.  
  1666. void TGraphWindow::WriteObject( GraphicalObject& obj, void *data )
  1667. {
  1668.     *(ofpstream *)data << &obj;
  1669. }
  1670.  
  1671. void TGraphWindow::WriteObjects()
  1672. {
  1673.     ofpstream out( FileData.FileName );
  1674.     out << Objects.GetItemsInContainer();
  1675.     Objects.ForEach( WriteObject, &out );
  1676.     WindowIsDirty = 0;
  1677. }
  1678.  
  1679. int TGraphWindow::CheckAndClear()
  1680. {
  1681.     if( OkToClear() )
  1682.         {
  1683.         FlushObjects();
  1684.         return 1;
  1685.         }
  1686.     else
  1687.         return 0;
  1688. }
  1689.  
  1690. int TGraphWindow::OkToClear()
  1691. {
  1692.     if( !WindowIsDirty )
  1693.         return 1;
  1694.     else
  1695.         {
  1696.         string msg;
  1697.         if( *FileData.FileName == 0 )
  1698.             msg = "<untitled>";
  1699.         else
  1700.             msg = FileData.FileName;
  1701.         msg += " has not been saved. Save before closing?";
  1702.         int res = MessageBox( msg.c_str(), GetApplication()->GetName(),
  1703.                               MB_ICONEXCLAMATION | MB_YESNOCANCEL );
  1704.         switch( res )
  1705.             {
  1706.             case IDYES:
  1707.                 return SaveFile();
  1708.             case IDNO:
  1709.                 return 1;
  1710.             case IDCANCEL:
  1711.                 return 0;
  1712.             }
  1713.         return 0;
  1714.         }
  1715. }
  1716.  
  1717. void TGraphWindow::CmLine()
  1718. {
  1719.     Builder = new LineBuilder( *this );
  1720. }
  1721.  
  1722. void TGraphWindow::CmRectangle()
  1723. {
  1724.     Builder = new RectangleBuilder( *this );
  1725. }
  1726.  
  1727. void TGraphWindow::CmCaptionedRectangle()
  1728. {
  1729.     Builder = new CaptionedRectangleBuilder( *this );
  1730. }
  1731.  
  1732. // Changed
  1733. void TGraphWindow::CmFilledRectangle()
  1734. {
  1735.     Builder = new FilledRectangleBuilder( *this );
  1736. }
  1737.  
  1738. void TGraphWindow::CmEllipse()
  1739. {
  1740.     Builder = new EllipseBuilder( *this );
  1741. }
  1742.  
  1743. void TGraphWindow::CmCaptionedEllipse()
  1744. {
  1745.     Builder = new CaptionedEllipseBuilder( *this );
  1746. }
  1747.  
  1748. // Changed
  1749. void TGraphWindow::CmFilledEllipse()
  1750. {
  1751.     Builder = new FilledEllipseBuilder( *this );
  1752. }
  1753.  
  1754. void TGraphWindow::CmAbout()
  1755. {
  1756.     TDialog dlg( this, "About" );
  1757.     dlg.Execute();
  1758. }
  1759.  
  1760. BOOL TGraphWindow::CanClose()
  1761. {
  1762.     return CheckAndClear();
  1763. }
  1764.  
  1765. void TGraphWindow::AddObject( GraphicalObject *object )
  1766. {
  1767.     Objects.Add( object );
  1768.     WindowIsDirty = 1;
  1769. }
  1770.  
  1771. void TGraphWindow::FlushObjects()
  1772. {
  1773.     Objects.Flush();
  1774.     WindowIsDirty = 0;
  1775. }
  1776.  
  1777. void TGraphWindow::EvLButtonDown( UINT modKeys, TPoint& point )
  1778. {
  1779.     if( Builder == 0 )
  1780.         TWindow::EvLButtonDown( modKeys, point );
  1781.     else
  1782.         Builder->SetAnchor(point);
  1783. }
  1784.  
  1785. void TGraphWindow::EvLButtonUp( UINT modKeys, TPoint& point )
  1786. {
  1787.     if( Builder == 0 )
  1788.         TWindow::EvLButtonUp( modKeys, point );
  1789.     else
  1790.         {
  1791.         AddObject( Builder->CreateObject() );
  1792.         delete Builder;
  1793.         Builder = 0;
  1794.         Invalidate();
  1795.         }
  1796. }
  1797.  
  1798. void TGraphWindow::EvRButtonDown( UINT modKeys, TPoint& point )
  1799. {
  1800.     if( Builder == 0 )
  1801.         TWindow::EvRButtonDown( modKeys, point );
  1802.     else
  1803.         {
  1804.         Builder->Cancel();
  1805.         delete Builder;
  1806.         Builder = 0;
  1807.         }
  1808. }
  1809.  
  1810. void TGraphWindow::EvMouseMove( UINT modKeys, TPoint& point )
  1811. {
  1812.     if( Builder == 0 )
  1813.         TWindow::EvMouseMove( modKeys, point );
  1814.     else
  1815.         Builder->Drag( point );
  1816. }
  1817.  
  1818. class TStreamApp : public TApplication 
  1819. {
  1820.  
  1821. public:
  1822.  
  1823.     TStreamApp() : TApplication() {}
  1824.  
  1825.     void InitMainWindow();
  1826.  
  1827. };
  1828.  
  1829. void TStreamApp::InitMainWindow()
  1830. {
  1831.     MainWindow = new TFrameWindow( 0, "Streaming Example, version 2",
  1832.                                    new TGraphWindow );
  1833.     MainWindow->AssignMenu("COMMANDS");
  1834.  
  1835. }
  1836.  
  1837. int OwlMain( int, char ** )
  1838. {
  1839.     TStreamApp app;
  1840.     return app.Run();
  1841. }
  1842.  
  1843.  
  1844.