home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / Container / Sources / Proxy.cpp < prev    next >
Encoding:
Text File  |  1996-08-16  |  16.1 KB  |  550 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                Proxy.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "Container.hpp"
  11.  
  12. #ifndef PROXY_H
  13. #include "Proxy.h"
  14. #endif
  15.  
  16. #ifndef PART_H
  17. #include "Part.h"
  18. #endif
  19.  
  20. // ----- Part Layer -----
  21.  
  22. #ifndef FWITERS_H
  23. #include "FWIters.h"
  24. #endif
  25.  
  26. #ifndef FWPXYITE_H
  27. #include "FWPxyIte.h"
  28. #endif
  29.  
  30. #ifndef FWUTIL_H
  31. #include "FWUtil.h"
  32. #endif
  33.  
  34. #ifndef FWPART_H
  35. #include "FWPart.h"
  36. #endif
  37.  
  38. #ifndef FWPRTITE_H
  39. #include "FWPrtIte.h"
  40. #endif
  41.  
  42. #ifndef FWPRESEN_H
  43. #include "FWPresen.h"
  44. #endif
  45.  
  46. #ifndef FWPXYFRM_H
  47. #include "FWPxyFrm.h"
  48. #endif
  49.  
  50. #ifndef FWFCTCLP_H
  51. #include "FWFctClp.h"
  52. #endif
  53.  
  54. // ----- OS Layer -----
  55.  
  56. #ifndef FWRECT_H
  57. #include "FWRect.h"
  58. #endif
  59.  
  60. #ifndef FWODGEOM_H
  61. #include "FWODGeom.h"
  62. #endif
  63.  
  64. #ifndef FWEVENT_H
  65. #include "FWEvent.h"
  66. #endif
  67.  
  68. #ifndef FWINK_H
  69. #include "FWInk.h"
  70. #endif
  71.  
  72. #ifndef FWSTYLE_H
  73. #include "FWStyle.h"
  74. #endif
  75.  
  76. #ifndef FWLINSHP_H
  77. #include "FWLinShp.h"
  78. #endif
  79.  
  80. #ifndef SLSHATTR_H
  81. #include "SLShAttr.h"
  82. #endif
  83.  
  84. // ----- Foundation Includes -----
  85.  
  86. #ifndef FWSTREAM_H
  87. #include "FWStream.h"
  88. #endif
  89.  
  90. // ----- OpenDoc Includes -----
  91.  
  92. #ifndef SOM_ODShape_xh
  93. #include <Shape.xh>
  94. #endif
  95.  
  96. #ifndef SOM_ODTransform_xh
  97. #include <Trnsform.xh>
  98. #endif
  99.  
  100. //========================================================================================
  101. //    Runtime Information
  102. //========================================================================================
  103.  
  104. #ifdef FW_BUILD_MAC
  105. #pragma segment odfcontainer
  106. #endif
  107.  
  108. //========================================================================================
  109. // Globals
  110. //========================================================================================
  111.  
  112. FW_CRectShape* CProxy::gWorkingHandle = NULL;
  113. unsigned long CProxy::gProxyCount = 0;
  114.  
  115. //========================================================================================
  116. //    CProxy
  117. //========================================================================================
  118.  
  119. //----------------------------------------------------------------------------------------
  120. //    CProxy::CProxy
  121. //----------------------------------------------------------------------------------------
  122.  
  123. CProxy::CProxy(Environment* ev, const FW_CRect& bounds, CContainerPart* part) :
  124.     FW_MProxy(ev, part, part->GetMainPresentation()),
  125.     fContainerPart(part),
  126.     fBounds(bounds),
  127.     fSelected(false)
  128. {
  129.     InitStatic();
  130.     CProxy::gProxyCount++;
  131. }
  132.  
  133. //----------------------------------------------------------------------------------------
  134. // CProxy::~CProxy
  135. //----------------------------------------------------------------------------------------
  136.  
  137. CProxy::~CProxy()
  138. {
  139.     CProxy::gProxyCount--;
  140.     if (CProxy::gProxyCount == 0)
  141.         delete CProxy::gWorkingHandle;
  142. }
  143.     
  144. //----------------------------------------------------------------------------------------
  145. //    CProxy::InitStatic
  146. //----------------------------------------------------------------------------------------
  147.  
  148. void CProxy::InitStatic()
  149. {
  150.     if (gProxyCount == 0)
  151.     {
  152.         CProxy::gWorkingHandle = FW_NEW(FW_CRectShape, (FW_kZeroRect, FW_kFill));
  153.         CProxy::gWorkingHandle->SetInk(FW_kInvertInk);
  154.     }
  155. }
  156.  
  157. //----------------------------------------------------------------------------------------
  158. //    CProxy::FrameShapeRequested
  159. //----------------------------------------------------------------------------------------
  160.  
  161. ODShape* CProxy::FrameShapeRequested(Environment* ev, 
  162.                                      FW_CEmbeddingFrame* embeddingFrame, 
  163.                                      ODFrame* odEmbeddedFrame, 
  164.                                      ODShape* requestedFrameShape)
  165. {
  166.     // ----- get the bounding box of the asked frame shape
  167.     FW_CRect frameRect = FW_GetShapeBoundingBox(ev, requestedFrameShape);
  168.     
  169.     fBounds.right = fBounds.left + frameRect.Width();
  170.     fBounds.bottom = fBounds.top + frameRect.Height();
  171.  
  172.     // ----- Invalidate the old used Shape in case the embedded frame doesn't do it-----
  173.     FW_CAcquiredODShape aqUsedShape = odEmbeddedFrame->AcquireUsedShape(ev, NULL);
  174.     odEmbeddedFrame->Invalidate(ev, aqUsedShape, NULL);
  175.     
  176.     // ----- Don't forget to bump the refcount
  177.     requestedFrameShape->Acquire(ev);
  178.     return requestedFrameShape;
  179. }
  180.  
  181. //----------------------------------------------------------------------------------------
  182. //    CProxy::UsedShapeChanged
  183. //----------------------------------------------------------------------------------------
  184.  
  185. void CProxy::UsedShapeChanged(Environment* ev, FW_CEmbeddingFrame* embeddingFrame, ODFrame* odEmbeddedFrame)
  186. {
  187. FW_UNUSED(odEmbeddedFrame);
  188.  
  189.     // ----- Recalcul the clip -----
  190.     FW_CAcquiredODShape changedShape = ::FW_NewODShape(ev, fBounds);
  191.     FW_CFacetClipper facetClipper(ev, fContainerPart);
  192.     facetClipper.Clip(ev, embeddingFrame, NULL /*changedShape*/);
  193.  
  194.     // ----- Invalidate
  195.     embeddingFrame->Invalidate(ev, fBounds);
  196. }
  197.  
  198. //----------------------------------------------------------------------------------------
  199. // CProxy::GetHandleCenter
  200. //----------------------------------------------------------------------------------------
  201.  
  202. void CProxy::GetHandleCenter(short whichHandle, FW_CPoint& center) const
  203. {
  204.     const FW_Fixed fxHalf = FW_ODFixedToFixed(0x00008000);
  205.     const FW_Fixed fxTwo = FW_IntToFixed(2);
  206.     const FW_Fixed fxThree = FW_IntToFixed(3);
  207.  
  208.     switch (whichHandle)
  209.     {
  210.         case kInTopLeftCorner:
  211.             center.x = fBounds.left - fxThree;
  212.             center.y = fBounds.top - fxThree;
  213.             break;
  214.         case kInTopRightCorner:
  215.             center.x = fBounds.right + fxTwo;
  216.             center.y = fBounds.top - fxThree;
  217.             break;
  218.         case kInBottomLeftCorner:
  219.             center.x = fBounds.left - fxThree;
  220.             center.y = fBounds.bottom + fxTwo;
  221.             break;
  222.         case kInBottomRightCorner:
  223.             center.x = fBounds.right + fxTwo;
  224.             center.y = fBounds.bottom + fxTwo;
  225.             break;
  226.  
  227.         case kInTopMiddle:
  228.             center.x = fBounds.left + (fBounds.Width() * fxHalf);
  229.             center.y = fBounds.top - fxThree;
  230.             break;
  231.         case kInLeftMiddle:
  232.             center.x = fBounds.left - fxThree;
  233.             center.y = fBounds.top + (fBounds.Height() * fxHalf);
  234.             break;
  235.         case kInBottomMiddle:
  236.             center.x = fBounds.left + (fBounds.Width() * fxHalf);
  237.             center.y = fBounds.bottom + fxTwo;
  238.             break;
  239.         case kInRightMiddle:
  240.             center.x = fBounds.right + fxTwo;
  241.             center.y = fBounds.top + (fBounds.Height() * fxHalf);
  242.             break;
  243.     }
  244. }
  245.  
  246.  
  247. //----------------------------------------------------------------------------------------
  248. // CProxy::ResizeProxy
  249. //----------------------------------------------------------------------------------------
  250.  
  251. void CProxy::ResizeProxy(Environment* ev, const FW_CRect& srcRect, const FW_CRect& dstRect)
  252. {
  253.     FW_CRect bounds(fBounds);
  254.     bounds.Map(srcRect, dstRect);    
  255.     bounds.Sort();
  256.     
  257.     SetBounds(ev, bounds);
  258. }
  259.  
  260. //----------------------------------------------------------------------------------------
  261. // CProxy::OffsetProxy
  262. //----------------------------------------------------------------------------------------
  263.  
  264. void CProxy::OffsetProxy(Environment* ev, FW_Fixed xDelta, FW_Fixed yDelta)
  265. {    
  266.     FW_CRect bounds(fBounds);
  267.     bounds.Offset(xDelta, yDelta);
  268.     SetBounds(ev, bounds);
  269. }
  270.         
  271. //----------------------------------------------------------------------------------------
  272. // CProxy::SelectProxy
  273. //----------------------------------------------------------------------------------------
  274. void CProxy::SelectProxy(Environment* ev, FW_Boolean state)
  275. {
  276.     fSelected = state;
  277.     
  278.     // ----- Select all the embedded facet ----
  279.     SetSelectState(ev, state);
  280. }
  281.  
  282. //----------------------------------------------------------------------------------------
  283. // CProxy::SubtractToWindowClip
  284. //----------------------------------------------------------------------------------------
  285. //    ATTENTION: windowClip is in Window coordinates. tempShape is just a working shape. It is
  286. //    used by CProxy so I don't have to allocate a shape every time.
  287.  
  288. void CProxy::SubtractToWindowClip(Environment* ev, 
  289.                                   FW_CFacetClipper* facetClipper, 
  290.                                   ODFacet* containingFacet, 
  291.                                   ODShape* windowClip, ODShape* tempShape)
  292. {
  293. FW_UNUSED(tempShape);
  294.  
  295.     FW_CEmbeddedODFacetsIterator ite(ev, this, containingFacet, kODFrontToBack);
  296.     for (ODFacet *embeddedODFacet = ite.First(ev); ite.IsNotComplete(ev); embeddedODFacet = ite.Next(ev))
  297.     {
  298.         facetClipper->ClipOneEmbeddedFacet(ev, embeddedODFacet, windowClip);
  299.     }
  300. }
  301.  
  302. //----------------------------------------------------------------------------------------
  303. // CProxy::HitTest
  304. //----------------------------------------------------------------------------------------
  305.  
  306. FW_Boolean CProxy::HitTest(Environment* ev, FW_CGraphicContext& gc, const FW_CPoint& where) const
  307. {    
  308.     FW_CRectShape rectShape(fBounds, FW_kFill);
  309.     return rectShape.HitTest(gc, where, FW_kFixed0);
  310. }
  311.  
  312. //----------------------------------------------------------------------------------------
  313. // CProxy::CalcHandle
  314. //----------------------------------------------------------------------------------------
  315.  
  316. void CProxy::CalcHandle(short whichHandle, FW_CRectShape* handle, const FW_CPoint& penSize) const
  317. {
  318.     FW_CPoint pt;
  319.     GetHandleCenter(whichHandle, pt);
  320.     
  321.     FW_Fixed fx = penSize.x + FW_ODFixedToFixed(0x00008000);
  322.     FW_Fixed fy = penSize.y + FW_ODFixedToFixed(0x00008000);
  323. //    const FW_Fixed fx25 = FW_DoubleToFixed(2.5);
  324.     FW_CRect rect(pt.x - fx, pt.y - fy, pt.x + fx, pt.y + fy);
  325.     
  326.     handle->SetRectangle(rect);
  327. }
  328.  
  329. //----------------------------------------------------------------------------------------
  330. // CProxy::RenderSelectionFrame
  331. //----------------------------------------------------------------------------------------
  332.  
  333. void CProxy::RenderSelectionFrame(FW_CGraphicContext& gc)
  334. {
  335.     FW_CInk ink(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
  336.     FW_CStyle style(FW_kFixed0, FW_kGrayPat);
  337.     
  338.     FW_CRect rect;
  339.     GetHandleCenter(kInTopLeftCorner, rect[FW_kTopLeft]);
  340.     GetHandleCenter(kInBottomRightCorner, rect[FW_kBotRight]);
  341.     rect[FW_kBotRight] += FW_CPoint(FW_kFixedPos1, FW_kFixedPos1);    // adjust for penSize
  342.     FW_CRectShape::RenderRect(gc, rect, FW_kFrame, ink, style);
  343. }
  344.  
  345. //----------------------------------------------------------------------------------------
  346. // CProxy::RenderHandles
  347. //----------------------------------------------------------------------------------------
  348.  
  349. void CProxy::RenderHandles(FW_CGraphicContext& gc)
  350. {
  351.     // First draw the lines connecting the handles
  352.     RenderSelectionFrame(gc);
  353.     
  354.     // Now draw the handles themselves
  355.     FW_CPoint penSize = gc.DeviceToLogical(2, 2);
  356.     for (short i=1; i<=kNumberOfHandles; i++)
  357.     {
  358.         CalcHandle(i, CProxy::gWorkingHandle, penSize);    
  359.         CProxy::gWorkingHandle->Render(gc);
  360.     }
  361. }
  362.  
  363. //----------------------------------------------------------------------------------------
  364. // CProxy::WhichHandle
  365. //----------------------------------------------------------------------------------------
  366.  
  367. short CProxy::WhichHandle(FW_CGraphicContext& gc, const FW_CPoint& mouse) const
  368. {
  369.     FW_CPoint penSize = gc.DeviceToLogical(4, 4);
  370.     for (short i=1; i<=kNumberOfHandles; i++)
  371.     {
  372.         CalcHandle(i, CProxy::gWorkingHandle, penSize);
  373.         if (CProxy::gWorkingHandle->HitTest(gc, mouse, FW_kFixed0))
  374.             return i;
  375.     }
  376.         
  377.     return 0;
  378. }
  379.  
  380. //----------------------------------------------------------------------------------------
  381. // CProxy::CreateProxyOutline
  382. //----------------------------------------------------------------------------------------
  383.  
  384. ODShape* CProxy::CreateProxyOutline(Environment* ev)
  385. {
  386.     // We don't acquire it because we return it
  387.     ODShape* dragShape = ::FW_NewODShape(ev, fBounds);
  388.  
  389.     ::FW_OutlineODShape(ev, dragShape, FW_kFixed0);
  390.  
  391.     return dragShape;
  392. }
  393.  
  394. //----------------------------------------------------------------------------------------
  395. // CProxy::GetMappedRects
  396. //----------------------------------------------------------------------------------------
  397.  
  398. void CProxy::GetMappedRects(short whichHandle, const FW_CPoint& mouseLoc, FW_CRect& srcRect, FW_CRect& dstRect)
  399. {
  400.     dstRect = srcRect = fBounds;
  401.     
  402.     switch (whichHandle)
  403.     {
  404.         case kInTopLeftCorner:
  405.             dstRect.left = mouseLoc.x;
  406.             dstRect.top = mouseLoc.y;
  407.             break;
  408.         case kInTopRightCorner:
  409.             dstRect.right = mouseLoc.x;
  410.             dstRect.top = mouseLoc.y;
  411.             break;
  412.         case kInBottomLeftCorner:
  413.             dstRect.left = mouseLoc.x;
  414.             dstRect.bottom = mouseLoc.y;
  415.             break;
  416.         case kInBottomRightCorner:
  417.             dstRect.right = mouseLoc.x;
  418.             dstRect.bottom = mouseLoc.y;
  419.             break;
  420.  
  421.         case kInTopMiddle:
  422.             dstRect.top = mouseLoc.y;
  423.             break;
  424.         case kInLeftMiddle:
  425.             dstRect.left = mouseLoc.x;
  426.             break;
  427.         case kInBottomMiddle:
  428.             dstRect.bottom = mouseLoc.y;
  429.             break;
  430.         case kInRightMiddle:
  431.             dstRect.right = mouseLoc.x;
  432.             break;
  433.     }
  434. }
  435.  
  436. //----------------------------------------------------------------------------------------
  437. // CProxy::ResizeFeedback
  438. //----------------------------------------------------------------------------------------
  439.  
  440. void CProxy::ResizeFeedback(FW_CGraphicContext& gc, 
  441.                             const FW_CInk& ink, 
  442.                             const FW_CStyle& style, 
  443.                             short whichHandle, 
  444.                             const FW_CPoint& mouseLoc)
  445. {
  446.     FW_CRect srcRect, dstRect;
  447.     GetMappedRects(whichHandle, mouseLoc, srcRect, dstRect);
  448.     dstRect.Inset(FW_IntToFixed(-3) - FW_Half(style.GetPenSize()));
  449.  
  450.     dstRect.Sort();
  451.     
  452.     FW_CRectShape::RenderRect(gc,
  453.                               dstRect,
  454.                               FW_kFrame,
  455.                               ink, 
  456.                               style);
  457. }
  458.  
  459. //----------------------------------------------------------------------------------------
  460. // CProxy::InSelectionRect
  461. //----------------------------------------------------------------------------------------
  462.  
  463. FW_Boolean CProxy::InSelectionRect(const FW_CRect& selectRect) const
  464. {
  465.     FW_CRect temp(fBounds);
  466.     temp.Intersection(selectRect);
  467.     
  468.     return fBounds == temp;
  469. }
  470.  
  471. //----------------------------------------------------------------------------------------
  472. // CProxy::GetUpdateBox
  473. //----------------------------------------------------------------------------------------
  474.  
  475. void CProxy::GetUpdateBox(Environment* ev, ODShape* updateBox) const
  476. {
  477.     FW_CRect bounds(fBounds);
  478.     bounds.Inset(FW_IntToFixed(-6));
  479.     updateBox->SetRectangle(ev, (ODRect*)&bounds);
  480. }
  481.  
  482. //----------------------------------------------------------------------------------------
  483. // CProxy::SetBounds
  484. //----------------------------------------------------------------------------------------
  485.  
  486. void CProxy::SetBounds(Environment* ev, const FW_CRect& bounds)
  487. {
  488.     fBounds = bounds;
  489.  
  490.     // ----- Resize/Move every embedded frame -----
  491.     ChangeExternalTransforms(ev, fBounds.left, fBounds.top);
  492.     ChangeFrameShapes(ev, fBounds.right - fBounds.left, fBounds.bottom - fBounds.top);
  493. }
  494.  
  495. //----------------------------------------------------------------------------------------
  496. // CProxy::Render
  497. //----------------------------------------------------------------------------------------
  498. //    Because there can be multiple CProxy pointing on an embedded
  499. //    frame, I only draw those belonging to this frame.
  500.  
  501. void CProxy::Render(Environment *ev, ODFacet* facet, FW_CGraphicContext& gc)
  502. {
  503.     // if the canvas is not dynamic (printing) I let OpenDoc draw embedded facets
  504.     if (!facet->GetCanvas(ev)->IsDynamic(ev))
  505.         return;
  506.         
  507.     FW_CAcquiredODShape aqTempShape = ::FW_NewODShape(ev);
  508.     FW_CAcquiredODShape aqTempClipShape(gc.AcquireClip());    // GetClip returns a copy in content coordinate
  509.  
  510.     // ----- Because we are calling the draw method of an embedded facet, we want
  511.     // ----- to save our context. The embedded facet will be using the same grafport 
  512.     // ----- and may not be restoring it.    
  513.     FW_CSaveRestoreContext src(gc);
  514.     
  515.     FW_CEmbeddedODFacetsIterator ite(ev, this, facet, kODFrontToBack);
  516.     for (ODFacet *embeddedODFacet = ite.First(ev); ite.IsNotComplete(ev); embeddedODFacet = ite.Next(ev))
  517.     {    
  518.         aqTempShape->CopyFrom(ev, aqTempClipShape);
  519.         
  520.         {
  521.             FW_CAcquiredODTransform aqFrameTransform = embeddedODFacet->AcquireExternalTransform(ev, NULL);
  522.             aqTempShape->InverseTransform(ev, aqFrameTransform);    // parent content (me) -> embedded frame
  523.         }
  524.                 
  525. #ifdef FW_BUILD_WIN
  526.         // [HLX] bug in windows? the invalidShape is expected to be in pixels instead of points
  527.         aqTempShape->Outset(ev, ff(1));    // [HLX] Because of rounding errors
  528.         FW_CGraphicDevice *device = gc.GetGraphicDevice();
  529.         device->PointToPixel(ev, aqTempShape);
  530. #endif
  531.     
  532.         embeddedODFacet->Draw(ev, aqTempShape, NULL);
  533.         embeddedODFacet->DrawChildren(ev, aqTempShape, NULL);
  534.         
  535.         {
  536.             FW_CAcquiredODShape aqClipShape = embeddedODFacet->AcquireClipShape(ev, NULL);
  537.             aqTempShape->CopyFrom(ev, aqClipShape);
  538.         }
  539.         
  540.         {
  541.             FW_CAcquiredODTransform aqExternalTransform = embeddedODFacet->AcquireExternalTransform(ev, NULL);
  542.             aqTempShape->Transform(ev, aqExternalTransform);
  543.         }
  544.         
  545.         aqTempClipShape->Subtract(ev, aqTempShape);
  546.     }
  547. }
  548.  
  549.  
  550.