home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / OS / FWGraphx / Sources / FWShpLst.cpp < prev    next >
Encoding:
Text File  |  1995-11-08  |  17.8 KB  |  611 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWShpLst.cpp
  4. //    Release Version:    $ 1.0d11 $
  5. //
  6. //    Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef FWSHPLST_H
  13. #include "FWShpLst.h"
  14. #endif
  15.  
  16. #ifndef FWSHAPE_H
  17. #include "FWShape.h"
  18. #endif
  19.  
  20. // ----- Foundation Includes -----
  21.  
  22. #ifndef FWSTREAM_H
  23. #include "FWStream.h"
  24. #endif
  25.  
  26. //========================================================================================
  27. //    RunTime Info
  28. //========================================================================================
  29.  
  30. #if FW_LIB_EXPORT_PRAGMAS
  31. #pragma lib_export on
  32. #endif
  33.  
  34. #ifdef FW_BUILD_MAC
  35. #pragma segment FWGraphx_ShapeList
  36. #endif
  37.  
  38. FW_DEFINE_CLASS_M1(FW_PShapeList, FW_CGraphicCountedPtr)
  39. FW_DEFINE_CLASS_M1(FW_CShapeListRep, FW_CGraphicCountedPtrRep)
  40. FW_REGISTER_ARCHIVABLE_CLASS(FW_LShapeList, FW_CShapeListRep, FW_CShapeListRep::Read, FW_CGraphicCountedPtrRep::Write)
  41.  
  42. FW_DEFINE_CLASS_M0(FW_CShapeListIterator)
  43.  
  44. //========================================================================================
  45. //    class FW_PShapeList
  46. //========================================================================================
  47.  
  48. //----------------------------------------------------------------------------------------
  49. // FW_PShapeList::FW_PShapeList
  50. //----------------------------------------------------------------------------------------
  51.  
  52. FW_PShapeList::FW_PShapeList()
  53. {
  54.     SetRep(new FW_CShapeListRep);
  55. }
  56.  
  57. //----------------------------------------------------------------------------------------
  58. // FW_PShapeList::FW_PShapeList
  59. //----------------------------------------------------------------------------------------
  60.  
  61. FW_PShapeList::FW_PShapeList(FW_CShapeListRep* rep)
  62. {
  63.     SetRep(rep);
  64. }
  65.     
  66. //----------------------------------------------------------------------------------------
  67. // FW_PShapeList::FW_PShapeList
  68. //----------------------------------------------------------------------------------------
  69.  
  70. FW_PShapeList::FW_PShapeList(FW_CReadableStream& archive)
  71. {
  72.     SetRep(new FW_CShapeListRep(archive));
  73. }
  74.  
  75. //----------------------------------------------------------------------------------------
  76. // FW_PShapeList::~FW_PShapeList
  77. //----------------------------------------------------------------------------------------
  78.  
  79. FW_PShapeList::~FW_PShapeList()
  80. {
  81. }
  82.     
  83. //----------------------------------------------------------------------------------------
  84. // FW_PShapeList::FW_PShapeList
  85. //----------------------------------------------------------------------------------------
  86.  
  87. FW_PShapeList::FW_PShapeList(const FW_PShapeList& other) :
  88.     FW_CGraphicCountedPtr(other)
  89. {
  90. }
  91.  
  92. //----------------------------------------------------------------------------------------
  93. // FW_PShapeList::operator=
  94. //----------------------------------------------------------------------------------------
  95.  
  96. FW_PShapeList& FW_PShapeList::operator=(const FW_PShapeList& other)
  97. {
  98.     // We don't need to test this == &other because SetRep will do it
  99.     SetRep(other.GetRep());
  100.     return *this;
  101. }
  102.  
  103. //========================================================================================
  104. //    class FW_CPrivShapeListNode
  105. //========================================================================================
  106.  
  107. class FW_CPrivShapeListNode
  108. {
  109. public:
  110.     FW_CPrivShapeListNode();
  111.     FW_CPrivShapeListNode(FW_CPrivShapeListNode* prev, FW_CShape* shape);
  112.     ~FW_CPrivShapeListNode();
  113.     
  114.     FW_CPrivShapeListNode*        fPrev;
  115.     FW_CPrivShapeListNode*        fNext;
  116.  
  117.     FW_CShape*                    fShape;
  118. };
  119.  
  120. //----------------------------------------------------------------------------------------
  121. // FW_CPrivShapeListNode::FW_CPrivShapeListNode
  122. //----------------------------------------------------------------------------------------
  123.  
  124. FW_CPrivShapeListNode::FW_CPrivShapeListNode() :
  125.     fPrev(NULL),
  126.     fNext(NULL),
  127.     fShape(NULL)
  128. {
  129. }
  130.  
  131. //----------------------------------------------------------------------------------------
  132. // FW_CPrivShapeListNode::FW_CPrivShapeListNode
  133. //----------------------------------------------------------------------------------------
  134.  
  135. FW_CPrivShapeListNode::FW_CPrivShapeListNode(FW_CPrivShapeListNode* prev, FW_CShape* shape) :
  136.     fPrev(prev),
  137.     fNext(prev->fNext),
  138.     fShape(shape)
  139. {
  140.     fPrev->fNext = this;
  141.     fNext->fPrev = this;
  142. }
  143.  
  144. //----------------------------------------------------------------------------------------
  145. // FW_CPrivShapeListNode::~FW_CPrivShapeListNode
  146. //----------------------------------------------------------------------------------------
  147.  
  148. FW_CPrivShapeListNode::~FW_CPrivShapeListNode()
  149. {
  150.     if(fPrev != NULL)
  151.         fPrev->fNext = fNext;
  152.         
  153.     if(fNext != NULL)
  154.         fNext->fPrev = fPrev;
  155. }
  156.  
  157. //========================================================================================
  158. //    class FW_CShapeListRep
  159. //========================================================================================
  160.  
  161. //----------------------------------------------------------------------------------------
  162. // FW_CShapeListRep::FW_CShapeListRep
  163. //----------------------------------------------------------------------------------------
  164.  
  165. FW_CShapeListRep::FW_CShapeListRep() :
  166.     fHead(NULL),
  167.     fTail(NULL),
  168.     fCount(0)
  169. {
  170.     fHead = new FW_CPrivShapeListNode;
  171.     fTail = new FW_CPrivShapeListNode;
  172.  
  173.     fHead->fNext = fTail;
  174.     fTail->fPrev = fHead;
  175. }
  176.  
  177. //----------------------------------------------------------------------------------------
  178. // FW_CShapeListRep::FW_CShapeListRep
  179. //----------------------------------------------------------------------------------------
  180.  
  181. FW_CShapeListRep::FW_CShapeListRep(const FW_CShapeListRep& other) :
  182.     fHead(NULL),
  183.     fTail(NULL),
  184.     fCount(0)
  185. {
  186.     fHead = new FW_CPrivShapeListNode;
  187.     fTail = new FW_CPrivShapeListNode;
  188.  
  189.     fHead->fNext = fTail;
  190.     fTail->fPrev = fHead;
  191.  
  192.     FW_CShapeListIterator ite(FW_CShapeListIterator::kFrontToBack, &other);
  193.     FW_CShape* shape;
  194.     while((shape = ite.Next()) != NULL)
  195.         AdoptAtBack(shape->Copy());
  196. }
  197.  
  198. //----------------------------------------------------------------------------------------
  199. // FW_CShapeListRep::~FW_CShapeListRep
  200. //----------------------------------------------------------------------------------------
  201.  
  202. FW_CShapeListRep::~FW_CShapeListRep()
  203. {
  204.     RemoveAll();
  205.  
  206.     delete fHead;
  207.     delete fTail;
  208. }
  209.  
  210. //----------------------------------------------------------------------------------------
  211. // FW_CShapeListRep::GetCount
  212. //----------------------------------------------------------------------------------------
  213.  
  214. unsigned long FW_CShapeListRep::GetCount() const
  215. {
  216.     return fCount;
  217. }
  218.  
  219. //----------------------------------------------------------------------------------------
  220. // FW_CShapeListRep::Purge
  221. //----------------------------------------------------------------------------------------
  222.  
  223. void FW_CShapeListRep::Purge()
  224. {
  225.     FW_CShape* shape;
  226.     FW_CShapeListIterator ite(FW_CShapeListIterator::kFrontToBack, this);
  227.     while((shape = ite.Next()) != NULL)
  228.         shape->Purge();
  229. }
  230.  
  231. //----------------------------------------------------------------------------------------
  232. // FW_CShapeListRep::AdoptAtFront
  233. //----------------------------------------------------------------------------------------
  234.  
  235. void FW_CShapeListRep::AdoptAtFront(FW_CShape* shape)
  236. {
  237.     new FW_CPrivShapeListNode(fTail->fPrev, shape);
  238.     ++ fCount;
  239. }
  240.  
  241. //----------------------------------------------------------------------------------------
  242. // FW_CShapeListRep::AdoptAtBack
  243. //----------------------------------------------------------------------------------------
  244.  
  245. void FW_CShapeListRep::AdoptAtBack(FW_CShape* shape)
  246. {
  247.     new FW_CPrivShapeListNode(fHead, shape);
  248.     ++ fCount;
  249. }
  250.  
  251. //----------------------------------------------------------------------------------------
  252. // FW_CShapeListRep::AdoptAfter
  253. //----------------------------------------------------------------------------------------
  254.  
  255. void FW_CShapeListRep::AdoptAfter(FW_CShape* shapeToAdd, FW_CShape* afterWhich)
  256. {
  257.     FW_CPrivShapeListNode* node = FindNode(afterWhich);
  258.     FW_ASSERT(node != NULL);
  259.     new FW_CPrivShapeListNode(node->fPrev, shapeToAdd);
  260. }
  261.  
  262. //----------------------------------------------------------------------------------------
  263. // FW_CShapeListRep::AdoptBefore
  264. //----------------------------------------------------------------------------------------
  265.  
  266. void FW_CShapeListRep::AdoptBefore(FW_CShape* shapeToAdd, FW_CShape* beforeWhich)
  267. {
  268.     FW_CPrivShapeListNode* node = FindNode(beforeWhich);
  269.     FW_ASSERT(node != NULL);
  270.     new FW_CPrivShapeListNode(node, shapeToAdd);
  271. }
  272.  
  273. //----------------------------------------------------------------------------------------
  274. // FW_CShapeListRep::Contains
  275. //----------------------------------------------------------------------------------------
  276.  
  277. FW_Boolean FW_CShapeListRep::Contains(FW_CShape* shape) const
  278. {    
  279.     return FindNode(shape) != NULL;
  280. }
  281.  
  282. //----------------------------------------------------------------------------------------
  283. // FW_CShapeListRep::Remove
  284. //----------------------------------------------------------------------------------------
  285.  
  286. void FW_CShapeListRep::Remove(FW_CShape* shape)
  287. {
  288.     FW_CPrivShapeListNode* node = FindNode(shape);
  289.     FW_ASSERT(node != NULL);
  290.     delete node;
  291. }
  292.  
  293. //----------------------------------------------------------------------------------------
  294. // FW_CShapeListRep::RemoveAll
  295. //----------------------------------------------------------------------------------------
  296.  
  297. void FW_CShapeListRep::RemoveAll()
  298. {
  299.     while(fCount != 0)
  300.     {
  301.         delete fHead->fNext->fShape;
  302.         delete fHead->fNext;
  303.         -- fCount;
  304.     }
  305. }
  306.  
  307. //----------------------------------------------------------------------------------------
  308. // FW_CShapeListRep::RemoveTop
  309. //----------------------------------------------------------------------------------------
  310.  
  311. FW_CShape* FW_CShapeListRep::RemoveTop()
  312. {
  313.     FW_ASSERT(fCount != 0);
  314.     FW_CShape* shape = fTail->fPrev->fShape;
  315.     delete fTail->fPrev;
  316.     return shape;
  317. }
  318.  
  319. //----------------------------------------------------------------------------------------
  320. // FW_CShapeListRep::RemoveBottom
  321. //----------------------------------------------------------------------------------------
  322.  
  323. FW_CShape* FW_CShapeListRep::RemoveBottom()
  324. {
  325.     FW_ASSERT(fCount != 0);
  326.     FW_CShape* shape = fHead->fNext->fShape;
  327.     delete fHead->fNext;
  328.     return shape;
  329. }
  330.  
  331. //----------------------------------------------------------------------------------------
  332. // FW_CShapeListRep::MoveForward
  333. //----------------------------------------------------------------------------------------
  334.  
  335. FW_Boolean FW_CShapeListRep::MoveForward(FW_CShape* shape)
  336. {
  337.     FW_CPrivShapeListNode* node = FindNode(shape);
  338.     FW_ASSERT(node != NULL);
  339.     
  340.     if(node->fNext != fTail)
  341.     {
  342.         new FW_CPrivShapeListNode(node->fNext, shape);
  343.         delete node;
  344.     }
  345.  
  346.     return FALSE;
  347. }
  348.  
  349. //----------------------------------------------------------------------------------------
  350. // FW_CShapeListRep::MoveToFront
  351. //----------------------------------------------------------------------------------------
  352.  
  353. FW_Boolean FW_CShapeListRep::MoveToFront(FW_CShape* shape)
  354. {
  355.     FW_CPrivShapeListNode* node = FindNode(shape);
  356.     FW_ASSERT(node != NULL);
  357.     
  358.     if(node->fNext != fTail)
  359.     {
  360.         new FW_CPrivShapeListNode(fTail->fPrev, shape);
  361.         delete node;
  362.     }
  363.  
  364.     return FALSE;
  365. }
  366.  
  367. //----------------------------------------------------------------------------------------
  368. // FW_CShapeListRep::MoveBack
  369. //----------------------------------------------------------------------------------------
  370.  
  371. FW_Boolean FW_CShapeListRep::MoveBack(FW_CShape* shape)
  372. {
  373.     FW_CPrivShapeListNode* node = FindNode(shape);
  374.     FW_ASSERT(node != NULL);
  375.     
  376.     if(node->fPrev != fHead)
  377.     {
  378.         new FW_CPrivShapeListNode(node->fPrev->fPrev, shape);
  379.         delete node;
  380.     }
  381.  
  382.     return FALSE;
  383. }
  384.  
  385. //----------------------------------------------------------------------------------------
  386. // FW_CShapeListRep::MoveToBack
  387. //----------------------------------------------------------------------------------------
  388.  
  389. FW_Boolean FW_CShapeListRep::MoveToBack(FW_CShape* shape)
  390. {
  391.     FW_CPrivShapeListNode* node = FindNode(shape);
  392.     FW_ASSERT(node != NULL);
  393.     
  394.     if(node->fPrev != fHead)
  395.     {
  396.         new FW_CPrivShapeListNode(fHead, shape);
  397.         delete node;
  398.     }
  399.  
  400.     return FALSE;
  401. }
  402.  
  403. //----------------------------------------------------------------------------------------
  404. // FW_CShapeListRep::FindNode
  405. //----------------------------------------------------------------------------------------
  406.  
  407. FW_CPrivShapeListNode* FW_CShapeListRep::FindNode(FW_CShape* shape) const
  408. {
  409.     for(FW_CPrivShapeListNode* node = fHead->fNext; node != fTail; node = node->fNext)
  410.     {
  411.         if(node->fShape == shape)
  412.             return node;
  413.     }
  414.     
  415.     return NULL;
  416. }
  417.  
  418. //----------------------------------------------------------------------------------------
  419. // FW_CShapeListRep::FW_CShapeListRep
  420. //----------------------------------------------------------------------------------------
  421.  
  422. FW_CShapeListRep::FW_CShapeListRep(FW_CReadableStream& archive) :
  423.     fHead(NULL),
  424.     fTail(NULL),
  425.     fCount(0)
  426. {
  427.     fHead = new FW_CPrivShapeListNode;
  428.     fTail = new FW_CPrivShapeListNode;
  429.  
  430.     fHead->fNext = fTail;
  431.     fTail->fPrev = fHead;
  432.  
  433.     // Read and add the shapes
  434.     unsigned long count;
  435.     archive >> count;
  436.     
  437.     while(count -- != 0)
  438.     {
  439.         FW_CShape* shape;
  440.         FW_READ_DYNAMIC_OBJECT(archive, &shape, FW_CShape);
  441.  
  442.         AdoptAtBack(shape);
  443.     }
  444. }
  445.  
  446. //----------------------------------------------------------------------------------------
  447. // FW_CShapeListRep::Flatten
  448. //----------------------------------------------------------------------------------------
  449.  
  450. void FW_CShapeListRep::Flatten(FW_CWritableStream& archive) const
  451. {
  452.     archive << fCount;
  453.     
  454.     FW_CShapeListIterator ite(FW_CShapeListIterator::kFrontToBack, this);
  455.     FW_CShape* shape;
  456.     while((shape = ite.Next()) != NULL)
  457.         FW_WRITE_DYNAMIC_OBJECT(archive, shape, FW_CShape);
  458. }
  459.  
  460. //----------------------------------------------------------------------------------------
  461. // FW_CShapeListRep::Read
  462. //----------------------------------------------------------------------------------------
  463.  
  464. void* FW_CShapeListRep::Read(FW_CReadableStream& archive)
  465. {
  466.     FW_CShapeListRep* shapeList = new FW_CShapeListRep(archive);
  467.     return shapeList;
  468. }
  469.  
  470. //----------------------------------------------------------------------------------------
  471. // FW_CShapeListRep::IsEqual
  472. //----------------------------------------------------------------------------------------
  473.  
  474. FW_Boolean FW_CShapeListRep::IsEqual(const FW_CGraphicCountedPtrRep* other) const
  475. {
  476.     if (other == this)
  477.         return TRUE;
  478.     
  479.     FW_CShapeListRep* rep = FW_DYNAMIC_CAST(FW_CShapeListRep, other);
  480.     if (rep != NULL)
  481.     {
  482.         if(fCount == rep->fCount)
  483.         {
  484.             FW_CShapeListIterator iteThis(FW_CShapeListIterator::kFrontToBack, this);
  485.             FW_CShapeListIterator iteThat(FW_CShapeListIterator::kFrontToBack, rep);
  486.             
  487.             for (unsigned long i = 0; i< fCount; ++ i)
  488.             {
  489.                 FW_CShape* shapeThis = iteThis.Next();
  490.                 FW_CShape* shapeThat = iteThat.Next();
  491.                 
  492.                 if(shapeThis != shapeThat)
  493.                     return FALSE;
  494.             }
  495.             return TRUE;
  496.         }
  497.     }
  498.  
  499.     return FALSE;
  500. }
  501.  
  502. //----------------------------------------------------------------------------------------
  503. // FW_CShapeListRep::Copy
  504. //----------------------------------------------------------------------------------------
  505.  
  506. FW_PShapeList FW_CShapeListRep::Copy() const
  507. {
  508.     return FW_PShapeList(new FW_CShapeListRep(*this));
  509. }
  510.  
  511. //========================================================================================
  512. //    class FW_CShapeListIterator
  513. //========================================================================================
  514.  
  515. //----------------------------------------------------------------------------------------
  516. // FW_CShapeListIterator::FW_CShapeListIterator
  517. //----------------------------------------------------------------------------------------
  518.  
  519. FW_CShapeListIterator::FW_CShapeListIterator(EDirection direction, const FW_PShapeList& shapeList)
  520. {
  521.     CommonInit(direction, shapeList->fHead, shapeList->fTail);
  522. }
  523.  
  524. //----------------------------------------------------------------------------------------
  525. // FW_CShapeListIterator::FW_CShapeListIterator
  526. //----------------------------------------------------------------------------------------
  527.  
  528. FW_CShapeListIterator::FW_CShapeListIterator(EDirection direction, const FW_CShapeListRep* rep)
  529. {
  530.     CommonInit(direction, rep->fHead, rep->fTail);
  531. }
  532.  
  533.  
  534. //----------------------------------------------------------------------------------------
  535. // FW_CShapeListIterator::CommonInit
  536. //----------------------------------------------------------------------------------------
  537.  
  538. void FW_CShapeListIterator::CommonInit(EDirection direction,
  539.                                            FW_CPrivShapeListNode* head,
  540.                                            FW_CPrivShapeListNode* tail)
  541. {
  542.     fDirection = direction;
  543.  
  544.     if(fDirection == kFrontToBack)
  545.     {
  546.         fFirst = tail->fPrev;
  547.         fPastLast = head;
  548.     }
  549.     else
  550.     {
  551.         fFirst = head->fNext;
  552.         fPastLast = tail;
  553.     }
  554.  
  555.     fCurrent = fFirst;
  556. }
  557.  
  558. //----------------------------------------------------------------------------------------
  559. // FW_CShapeListIterator::~FW_CShapeListIterator
  560. //----------------------------------------------------------------------------------------
  561.  
  562. FW_CShapeListIterator::~FW_CShapeListIterator()
  563. {
  564. }
  565.  
  566. //----------------------------------------------------------------------------------------
  567. // FW_CShapeListIterator::First
  568. //----------------------------------------------------------------------------------------
  569.  
  570. FW_CShape* FW_CShapeListIterator::First()
  571. {
  572.     if(fFirst != fPastLast)
  573.     {
  574.         fCurrent = fFirst;
  575.         return Next();
  576.     }
  577.  
  578.     return NULL;
  579. }
  580.  
  581. //----------------------------------------------------------------------------------------
  582. // FW_CShapeListIterator::Next
  583. //----------------------------------------------------------------------------------------
  584.  
  585. FW_CShape* FW_CShapeListIterator::Next()
  586. {
  587.     if(fCurrent != fPastLast)
  588.     {
  589.         FW_CShape* shape = fCurrent->fShape;
  590.  
  591.         if(fDirection == kFrontToBack)
  592.             fCurrent = fCurrent->fPrev;
  593.         else
  594.             fCurrent = fCurrent->fNext;
  595.     
  596.         return shape;
  597.     }
  598.  
  599.     return NULL;
  600. }
  601.  
  602. //----------------------------------------------------------------------------------------
  603. // FW_CShapeListIterator::IsNotComplete
  604. //----------------------------------------------------------------------------------------
  605.  
  606. FW_Boolean FW_CShapeListIterator::IsNotComplete() const
  607. {
  608.     return fCurrent != fPastLast;
  609. }
  610.  
  611.