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 / ODF / Framewrk / FWViews / Sources / FWView.cpp < prev   
Encoding:
Text File  |  1996-08-16  |  34.0 KB  |  1,096 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWView.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFrameW.hpp"
  11.  
  12. #ifndef FWVIEW_H
  13. #include "FWView.h"
  14. #endif
  15.  
  16. #ifndef FWSVIEW_H
  17. #include "FWSView.h"
  18. #endif
  19.  
  20. #ifndef FWFRAME_H
  21. #include "FWFrame.h"
  22. #endif
  23.  
  24. #ifndef FWDRGDRP_H
  25. #include "FWDrgDrp.h"
  26. #endif
  27.  
  28. #ifndef FWEVENT_H
  29. #include "FWEvent.h"
  30. #endif
  31.  
  32. #ifndef FWSELECT_H
  33. #include "FWSelect.h"
  34. #endif
  35.  
  36. #ifndef FWPRESEN_H
  37. #include "FWPresen.h"
  38. #endif
  39.  
  40. #ifndef FWODGEOM_H
  41. #include "FWODGeom.h"
  42. #endif
  43.  
  44. #ifndef FWWINDOW_H
  45. #include "FWWindow.h"
  46. #endif
  47.  
  48. #ifndef FWCURSOR_H
  49. #include "FWCursor.h"
  50. #endif
  51.  
  52. // ----- Foundation Layer -----
  53.  
  54. #ifndef FWAROPER_H
  55. #include "FWArOper.h"
  56. #endif
  57.  
  58. // ----- OpenDoc Includes -----
  59.  
  60. #ifndef SOM_ODFrame_xh
  61. #include <Frame.xh>
  62. #endif
  63.  
  64. #ifndef SOM_ODShape_xh
  65. #include <Shape.xh>
  66. #endif
  67.  
  68. #if defined(__MWERKS__) && GENERATING68K
  69. // A hack to work around a bug
  70. #pragma import list somGetGlobalEnvironment
  71. #endif
  72.  
  73. //========================================================================================
  74. // Runtime Informations
  75. //========================================================================================
  76.  
  77. #ifdef FW_BUILD_MAC
  78. #pragma segment fwview
  79. #endif
  80.  
  81. //========================================================================================
  82. // class FW_CViewCollection
  83. //========================================================================================
  84.  
  85. FW_DEFINE_AUTO(FW_CViewCollection)
  86.  
  87. //========================================================================================
  88. // class FW_CViewCollectionIterator
  89. //========================================================================================
  90.  
  91. FW_DEFINE_AUTO(FW_CViewCollectionIterator)
  92.  
  93. //========================================================================================
  94. // CLASS FW_CView
  95. //========================================================================================
  96.  
  97. FW_DEFINE_CLASS_M1(FW_CView, FW_MEventHandler)
  98.  
  99. //----------------------------------------------------------------------------------------
  100. // FW_CView::FW_CView
  101. //----------------------------------------------------------------------------------------
  102.  
  103. FW_CView::FW_CView(Environment* ev, FW_CSuperView* container, const FW_CRect& bounds,
  104.                         ODID viewId) :
  105.     FW_MEventHandler(ev, container, kNoPriority),
  106.     fViewId(viewId),
  107.     fSuperView(container),
  108.     fBounds(bounds),
  109.     fAdorners(NULL),
  110.     fVisible(TRUE),
  111.     fResizeForceRedraw(TRUE),
  112.     fBindings(FW_kFixedLocation + FW_kFixedSize),
  113.     fViewToFrameTransform(NULL),
  114.     fTopPrintedView(FALSE)
  115. {
  116.     FW_ASSERT(container != NULL);
  117.  
  118.     // add new view to the parent's SubView list
  119.     fSuperView->AddSubView(ev, this);
  120. }
  121.  
  122. //----------------------------------------------------------------------------------------
  123. // FW_CView::FW_CView
  124. //----------------------------------------------------------------------------------------
  125.  
  126. FW_CView::FW_CView(Environment* ev) :
  127.     FW_MEventHandler(ev, NULL, kNoPriority),
  128.     fViewId(kNoIdentifier),
  129.     fSuperView(NULL),
  130.     fBounds(FW_kZeroRect),
  131.     fAdorners(NULL),
  132.     fVisible(TRUE),
  133.     fResizeForceRedraw(TRUE),
  134.     fBindings(FW_kFixedLocation + FW_kFixedSize),
  135.     fViewToFrameTransform(NULL),
  136.     fTopPrintedView(FALSE)
  137. {
  138. }
  139.  
  140. //----------------------------------------------------------------------------------------
  141. // FW_CView::~FW_CView
  142. //----------------------------------------------------------------------------------------
  143.  
  144. FW_CView::~FW_CView()
  145. {
  146.     Environment *ev = somGetGlobalEnvironment();
  147.  
  148.     if (fViewToFrameTransform)
  149.     {    
  150.         fViewToFrameTransform->Release(ev);
  151.         fViewToFrameTransform = NULL;
  152.     }
  153.         
  154.     if (fSuperView != NULL)    
  155.         fSuperView->RemoveSubView(ev, this);
  156. }
  157.  
  158. //----------------------------------------------------------------------------------------
  159. // FW_CView::SetViewId
  160. //----------------------------------------------------------------------------------------
  161. void    FW_CView::SetViewId(Environment* ev, ODID id)
  162. {
  163. FW_UNUSED(ev);
  164.     fViewId = id;
  165. }
  166.  
  167. //----------------------------------------------------------------------------------------
  168. // FW_CView::FindViewById
  169. //----------------------------------------------------------------------------------------
  170.  
  171. FW_CView*    FW_CView::FindViewById(Environment* ev, ODID id)
  172. {
  173. FW_UNUSED(ev);
  174.     if (fViewId == id)
  175.         return this;
  176.     else
  177.         return NULL;
  178. }
  179.  
  180. //----------------------------------------------------------------------------------------
  181. // FW_CView::Invalidate
  182. //----------------------------------------------------------------------------------------
  183. // rect is in content coordinates
  184.  
  185. void FW_CView::Invalidate(Environment* ev, const FW_CRect& rect, FW_Boolean allFrames)
  186. {
  187.     if (fVisible) 
  188.     {
  189.         FW_CAcquiredODShape aqInvalidShape = ::FW_NewODShape(ev, rect);
  190.         FW_CFrame* frame = GetFrame(ev);
  191.         if (allFrames)
  192.             frame->GetPresentation(ev)->Invalidate(ev, aqInvalidShape, frame->GetSequenceNumber(ev));
  193.         else
  194.         {
  195.             ViewContentToFrame(ev, aqInvalidShape);
  196.             frame->GetODFrame(ev)->Invalidate(ev, aqInvalidShape, NULL);
  197.         }
  198.     }
  199. }
  200.  
  201. //----------------------------------------------------------------------------------------
  202. // FW_CView::Validate
  203. //----------------------------------------------------------------------------------------
  204. // rect is in content coordinates
  205.  
  206. void FW_CView::Validate(Environment* ev, const FW_CRect& rect, FW_Boolean allFrames)
  207. {
  208.     if (fVisible) 
  209.     {
  210.         FW_CAcquiredODShape aqValidShape = ::FW_NewODShape(ev, rect);
  211.         FW_CFrame* frame = GetFrame(ev);
  212.         if (allFrames)
  213.             frame->GetPresentation(ev)->Validate(ev, aqValidShape, frame->GetSequenceNumber(ev));
  214.         else
  215.         {
  216.             ViewContentToFrame(ev, aqValidShape);
  217.             frame->GetODFrame(ev)->Validate(ev, aqValidShape, NULL);
  218.         }
  219.     }
  220. }
  221.  
  222. //----------------------------------------------------------------------------------------
  223. // FW_CView::Invalidate
  224. //----------------------------------------------------------------------------------------
  225. // invalidShape is in content coordinates
  226.  
  227. void FW_CView::Invalidate(Environment* ev, ODShape* invalidShape, FW_Boolean allFrames)
  228. {
  229.     if (fVisible) {
  230.         if (invalidShape == NULL)
  231.         {
  232.             FW_CRect bounds = GetBoundsInContent(ev);
  233.             Invalidate(ev, bounds, allFrames);
  234.         }
  235.         else
  236.         {
  237.             FW_CFrame* frame = GetFrame(ev);
  238.             if (allFrames)
  239.                 frame->GetPresentation(ev)->Invalidate(ev, invalidShape, frame->GetSequenceNumber(ev));
  240.             else
  241.             {
  242.                 FW_CAcquiredODShape aCopy = invalidShape->Copy(ev);
  243.                 ViewContentToFrame(ev, aCopy);
  244.                 frame->GetODFrame(ev)->Invalidate(ev, aCopy, NULL);
  245.             }
  246.         }
  247.     }
  248. }
  249.  
  250. //----------------------------------------------------------------------------------------
  251. // FW_CView::Validate
  252. //----------------------------------------------------------------------------------------
  253. // invalidShape is in content coordinates
  254.  
  255. void FW_CView::Validate(Environment* ev, ODShape* validShape, FW_Boolean allFrames)
  256. {
  257.     if (fVisible) {
  258.         if (validShape == NULL)
  259.         {
  260.             FW_CRect bounds = GetBoundsInContent(ev);
  261.             Validate(ev, bounds, allFrames);
  262.         }
  263.         else
  264.         {
  265.             FW_CFrame* frame = GetFrame(ev);
  266.             if (allFrames)
  267.                 frame->GetPresentation(ev)->Validate(ev, validShape, frame->GetSequenceNumber(ev));
  268.             else
  269.             {
  270.                 FW_CAcquiredODShape aCopy = validShape->Copy(ev);
  271.                 ViewContentToFrame(ev, aCopy);
  272.                 frame->GetODFrame(ev)->Validate(ev, aCopy, NULL);
  273.             }
  274.         }
  275.     }
  276. }
  277.  
  278. //----------------------------------------------------------------------------------------
  279. //     FW_CSuperView::GetBoundsInContent
  280. //----------------------------------------------------------------------------------------
  281. //    returns the bounds in content coordinates
  282.  
  283. FW_CRect FW_CView::GetBoundsInContent(Environment *ev) const
  284. {
  285.     FW_CRect bounds = GetBounds(ev);
  286.     bounds.Place(FW_kFixed0, FW_kFixed0);    
  287.     return bounds;
  288. }
  289.  
  290. //----------------------------------------------------------------------------------------
  291. //    FW_CView::AdjustCursor
  292. //----------------------------------------------------------------------------------------
  293. // where is in frame coordinate
  294.  
  295. FW_Boolean FW_CView::AdjustCursor(Environment *ev, ODFacet* odFacet, const FW_CPoint& theMousePoint)
  296. {
  297.     // [LSD] ok?
  298.     return fSuperView ? fSuperView->AdjustCursor(ev, odFacet, theMousePoint) : FALSE;
  299. }
  300.  
  301. //----------------------------------------------------------------------------------------
  302. // FW_CView::IsSubViewOf
  303. //----------------------------------------------------------------------------------------
  304.  
  305. FW_Boolean FW_CView::IsSubViewOf(Environment* ev, const FW_CSuperView* parentView) const
  306. {
  307.     if (fSuperView == NULL) 
  308.         return FALSE;
  309.     else if (fSuperView == parentView) 
  310.         return TRUE;
  311.     else
  312.         return fSuperView->IsSubViewOf(ev, parentView);
  313. }
  314.  
  315. //----------------------------------------------------------------------------------------
  316. // FW_CView::HasSubViews
  317. //----------------------------------------------------------------------------------------
  318.  
  319. FW_Boolean FW_CView::HasSubViews(Environment* ev) const
  320. {
  321. FW_UNUSED(ev);
  322.     return FALSE;
  323. }
  324.  
  325. //----------------------------------------------------------------------------------------
  326. // FW_CView::IsMouseWithin
  327. //----------------------------------------------------------------------------------------
  328. //    theMousePoint is in frame coordinate
  329.  
  330. FW_Boolean FW_CView::IsMouseWithin(Environment* ev, ODFacet* odFacet, const FW_CPoint& theMousePoint) const
  331. {
  332.     // We get a NULL facet when clicking outside a modal dialog box.
  333.     if (odFacet == NULL)
  334.         return FALSE;
  335.     
  336.     FW_CPoint where(theMousePoint);
  337.     FrameToView(ev, where);
  338.     
  339.     return FW_CRect(FW_kZeroPoint, GetSize(ev)).Contains(where);
  340. }
  341.  
  342. //----------------------------------------------------------------------------------------
  343. //     FW_CView::GetViewContaining
  344. //----------------------------------------------------------------------------------------
  345. //    Find the visible & enabled view containing a point (in frame coordinates)
  346.  
  347. FW_CView* FW_CView::GetViewContaining(Environment* ev, ODFacet* odFacet, 
  348.                                     const FW_CPoint& theMousePoint)
  349. {
  350.     if (fVisible && IsEnabled(ev)  && IsMouseWithin(ev, odFacet, theMousePoint))
  351.         return this;
  352.     else 
  353.         return NULL;
  354. }
  355.  
  356. //----------------------------------------------------------------------------------------
  357. // FW_CView::SetLocation
  358. //----------------------------------------------------------------------------------------
  359.  
  360. void FW_CView::SetLocation(Environment* ev, const FW_CPoint& location, FW_Boolean refresh)
  361. {
  362.     FW_CPoint oldLocation = fBounds.TopLeft();
  363.     
  364.     if (oldLocation != location) 
  365.     {
  366.         if (refresh) Invalidate(ev, NULL);
  367.         
  368.         fBounds.right = location.x + (fBounds.right - fBounds.left);
  369.         fBounds.bottom = location.y + (fBounds.bottom - fBounds.top);
  370.         fBounds.left = location.x;
  371.         fBounds.top = location.y;
  372.  
  373.         PrivInvalidateCachedTransforms(ev);
  374.         
  375.         LocationChanged(ev, oldLocation);    // used by controls on Windows
  376.  
  377.         if (refresh) Invalidate(ev, NULL);
  378.     }
  379. }
  380.  
  381. //----------------------------------------------------------------------------------------
  382. // FW_CView::LocationChanged
  383. //----------------------------------------------------------------------------------------
  384.  
  385. void FW_CView::LocationChanged(Environment* ev, const FW_CPoint& oldLocation)
  386. {
  387. FW_UNUSED(ev);
  388. FW_UNUSED(oldLocation);
  389. }
  390.  
  391. //----------------------------------------------------------------------------------------
  392. // FW_CView::SetSize
  393. //----------------------------------------------------------------------------------------
  394.  
  395. void FW_CView::SetSize(Environment* ev, const FW_CPoint& size, FW_Boolean refresh)
  396. {
  397.     FW_CPoint oldSize = fBounds.Size();
  398.     if (oldSize != size) 
  399.     {
  400.         if (refresh && fResizeForceRedraw) 
  401.         {
  402.             Invalidate(ev, NULL);        // refresh old bounds
  403.         }
  404.         
  405.         // Change the bounds
  406.         fBounds.right = fBounds.left + size.x; 
  407.         fBounds.bottom = fBounds.top + size.y;
  408.         
  409.         SizeChanged(ev, oldSize);        // used by controls on Windows
  410.  
  411.         if (refresh) 
  412.         {
  413.             if (fResizeForceRedraw)
  414.                 Invalidate(ev, NULL);    // refresh new bounds
  415.             else
  416.             {
  417.                 // Invalidate only the region that changed (optimization for views whose
  418.                 // content appearance doesn't depend on its size).
  419.                 
  420.                 FW_CRect oldBounds(FW_kZeroPoint, oldSize);
  421.                 FW_CRect newBounds(FW_kZeroPoint, size);
  422.                 
  423.                 FW_CAcquiredODShape aqOldShape = ::FW_NewODShape(ev, oldBounds);
  424.                 aqOldShape->SetGeometryMode(ev, kODLoseGeometry);
  425.             
  426.                 FW_CAcquiredODShape aqNewShape = ::FW_NewODShape(ev, newBounds);
  427.                 aqNewShape->SetGeometryMode(ev, kODLoseGeometry);
  428.  
  429.                 FW_CAcquiredODShape aqUnionShape = aqOldShape->Copy(ev);
  430.                 aqUnionShape->SetGeometryMode(ev, kODLoseGeometry);
  431.                 
  432.                 aqUnionShape->Union(ev, aqNewShape);
  433.                 aqOldShape->Intersect(ev, aqNewShape);
  434.                 aqUnionShape->Subtract(ev, aqOldShape);
  435.  
  436.                 // Shape must be converted to frame coordinates before calling Invalidate
  437.                 ViewToFrame(ev, aqUnionShape);
  438.                 
  439.                 GetFrame(ev)->GetODFrame(ev)->Invalidate(ev, aqUnionShape, NULL);                
  440.             }
  441.         }
  442.     }
  443. }
  444.  
  445. //----------------------------------------------------------------------------------------
  446. // FW_CView::SizeChanged
  447. //----------------------------------------------------------------------------------------
  448.  
  449. void FW_CView::SizeChanged(Environment* ev, const FW_CPoint& oldSize)
  450. {
  451. FW_UNUSED(ev);
  452. FW_UNUSED(oldSize);
  453. }
  454.  
  455. //----------------------------------------------------------------------------------------
  456. // FW_CView::IsVisible
  457. //----------------------------------------------------------------------------------------
  458.  
  459. FW_Boolean FW_CView::IsVisible(Environment* ev) const
  460. {
  461.     // If my parent is not visible I am also not visible
  462.     return fVisible && (fSuperView != NULL ? fSuperView->IsVisible(ev) : TRUE);
  463. }
  464.  
  465. //----------------------------------------------------------------------------------------
  466. // FW_CView::PrivInvalidateCachedTransforms
  467. //----------------------------------------------------------------------------------------
  468.  
  469. void FW_CView::PrivInvalidateCachedTransforms(Environment* ev)
  470. {
  471.     if (fViewToFrameTransform)
  472.     {
  473.         fViewToFrameTransform->Release(ev);
  474.         fViewToFrameTransform = NULL;
  475.     }
  476. }
  477.  
  478. //----------------------------------------------------------------------------------------
  479. //    FW_CView::AdjustToNewLayout
  480. //----------------------------------------------------------------------------------------
  481. // Simple layout management based on 6 binding flags (or rubber bands)
  482. //
  483. //        +-------------------------------------------+ 
  484. //        |                       |                    | 
  485. //        |                   Top Binding?                |... SuperView whose extent changed
  486. //        |                       |                    |     from oldExtent to newExtent
  487. //        |            +-------------------+             |
  488. //        |            |           |        |...........|... View being adjusted
  489. //        |            |           |        |            |
  490. //        |<--Left--->|<--Fixed--+------->|<--Right-->|
  491. //        |  Binding?    |    Width? |        |  Binding? |
  492. //        |            |           |        |            |
  493. //        |            |     Fixed Height?    |            |
  494. //        |            |           |        |            |
  495. //        |            +-------------------+            |
  496. //        |                       |                    |
  497. //        |                Bottom Binding?                |
  498. //        |                       |                    |
  499. //        +-------------------------------------------+
  500. //
  501.  
  502. void FW_CView::AdjustToNewLayout(Environment *ev, const FW_CPoint& oldExtent, const FW_CPoint& newExtent, 
  503.                                 FW_Boolean refresh)    
  504. {
  505.     // Nothing to do if view is fixed in size and position
  506.     if ((fBindings & FW_kLeftBinding) && (fBindings & FW_kFixedWidth) &&
  507.             (fBindings & FW_kTopBinding) && (fBindings & FW_kFixedHeight))
  508.         return;
  509.         
  510.     FW_Fixed    deltaWidth = newExtent.x - oldExtent.x;
  511.     FW_Fixed    deltaWidth2 = FW_Half(deltaWidth);
  512.     FW_Fixed    deltaHeight = newExtent.y - oldExtent.y;
  513.     FW_Fixed    deltaHeight2 = FW_Half(deltaHeight);
  514.     FW_CRect    bounds = GetBounds(ev);
  515.     FW_Fixed    width = bounds.right - bounds.left;
  516.     FW_Fixed    height = bounds.bottom - bounds.top;
  517.     
  518.     // Note: we don't check for errors when all 3 bindings are set horizontally
  519.     //        or vertically. In this case we ignore FW_kRightBinding & FW_kBottomBinding
  520.     
  521.     // ----- Horizontal adjustement
  522.     
  523.     if (fBindings & FW_kLeftBinding) 
  524.     {
  525.         // left edge doesn't move
  526.         // right edge moves only if the width is not fixed
  527.         if (fBindings & FW_kRightBinding) 
  528.         {
  529.             // right edge moves by the same amount
  530.             bounds.right += deltaWidth;
  531.         }
  532.         else if (!fBindings & FW_kFixedWidth)
  533.         {
  534.             // width is not fixed so right edge moves proportionally
  535.             bounds.right = bounds.left + 
  536.                         (width / (oldExtent.x - bounds.left)) * (newExtent.x - bounds.left);
  537.         }
  538.     }
  539.     else 
  540.     {
  541.         if (fBindings & FW_kRightBinding) 
  542.         {
  543.             // right edge moves by the same amount
  544.             bounds.right += deltaWidth;
  545.  
  546.             if (fBindings & FW_kFixedWidth) {
  547.                 // width is fixed so left edge moves by the same amount
  548.                 bounds.left += deltaWidth;            
  549.             }
  550.             else 
  551.             {
  552.                 // width is not fixed so left edge moves proportionally
  553.                 bounds.left = (bounds.left / (bounds.left + width)) * bounds.right;
  554.             }
  555.         }
  556.         else
  557.         {
  558.             // both left and right edges move proportionally
  559.             bounds.left = (bounds.left / oldExtent.x) * newExtent.x;;
  560.             if (fBindings & FW_kFixedWidth)
  561.                 bounds.right = bounds.left + width;            
  562.             else 
  563.                 bounds.right = (bounds.right / oldExtent.x) * newExtent.x;
  564.         }
  565.     }
  566.     
  567.     // ----- Vertical adjustement 
  568.     
  569.     if (fBindings & FW_kTopBinding) 
  570.     {
  571.         if (fBindings & FW_kBottomBinding) 
  572.             bounds.bottom += deltaHeight;
  573.         else if (!fBindings & FW_kFixedHeight)
  574.             bounds.bottom = bounds.top + 
  575.                         (height / (oldExtent.y - bounds.top)) * (newExtent.y - bounds.top);
  576.     }
  577.     else 
  578.     {
  579.         if (fBindings & FW_kBottomBinding) 
  580.         {
  581.             bounds.bottom += deltaHeight;
  582.  
  583.             if (fBindings & FW_kFixedHeight) 
  584.                 bounds.top += deltaHeight;            
  585.             else 
  586.                 bounds.top = (bounds.top / (bounds.top + height)) * bounds.bottom;
  587.         }
  588.         else
  589.         {
  590.             bounds.top = (bounds.top / oldExtent.y) * newExtent.y;;
  591.             if (fBindings & FW_kFixedHeight)
  592.                 bounds.bottom = bounds.top + height;            
  593.             else 
  594.                 bounds.bottom = (bounds.bottom / oldExtent.y) * newExtent.y;
  595.         }
  596.     }
  597.     
  598.     // ----- We're done.  Adjust location and size (SetSize may in turn adjust subviews)
  599.     SetLocation(ev, bounds.TopLeft(), refresh);
  600.     SetSize(ev, bounds.Size(), refresh);
  601.     
  602.     return;
  603. }
  604.  
  605. //----------------------------------------------------------------------------------------
  606. // FW_CView::AcquireViewToFrameTransform
  607. //----------------------------------------------------------------------------------------
  608. // returns the transform to convert view coordinates to frame coordinates
  609.  
  610. ODTransform* FW_CView::AcquireViewToFrameTransform(Environment* ev) const
  611. {
  612.     FW_CView* self = (FW_CView*)this;
  613.     
  614.     if (fViewToFrameTransform == NULL)
  615.     {
  616.         FW_CPoint location = GetLocation(ev);
  617.         self->fViewToFrameTransform = ::FW_NewODTransform(ev, location);
  618.         
  619.         if (fSuperView != NULL)
  620.         {
  621.             FW_CAcquiredODTransform aqViewContentTransform = fSuperView->AcquireViewContentToFrameTransform(ev);
  622.             self->fViewToFrameTransform->PostCompose(ev, aqViewContentTransform);
  623.         }
  624.     }
  625.     
  626.     self->fViewToFrameTransform->Acquire(ev);    
  627.     
  628.             
  629.     return fViewToFrameTransform;
  630. }
  631.  
  632. //----------------------------------------------------------------------------------------
  633. // FW_CView::AcquireViewContentToFrameTransform
  634. //----------------------------------------------------------------------------------------
  635. // returns the transform to convert view content coordinates to frame coordinates
  636.  
  637. ODTransform* FW_CView::AcquireViewContentToFrameTransform(Environment* ev) const
  638. {
  639.     return FW_CView::AcquireViewToFrameTransform(ev);
  640. }
  641.  
  642. //----------------------------------------------------------------------------------------
  643. // FW_CView::PrivInvalidateViewIternalTransform
  644. //----------------------------------------------------------------------------------------
  645.  
  646. void FW_CView::PrivInvalidateViewIternalTransform(Environment* ev)
  647. {
  648. FW_UNUSED(ev);
  649.     // Noting to do: can't scroll can't scale
  650. }
  651.  
  652. //----------------------------------------------------------------------------------------
  653. //     FW_CView::FrameToViewContent
  654. //----------------------------------------------------------------------------------------
  655.  
  656. void FW_CView::FrameToViewContent(Environment *ev, FW_CPoint& point) const
  657. {
  658.     FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewContentToFrameTransform(ev));    
  659.     point.InverseTransform(ev, aqViewToFrameTransform);
  660. }
  661.  
  662. void FW_CView::FrameToViewContent(Environment *ev, FW_CRect& rect) const
  663. {
  664.     FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewContentToFrameTransform(ev));    
  665.     rect.InverseTransform(ev, aqViewToFrameTransform);
  666. }
  667.  
  668. void FW_CView::FrameToViewContent(Environment *ev, ODShape* shape) const
  669. {
  670.     FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewContentToFrameTransform(ev));    
  671.     shape->InverseTransform(ev, aqViewToFrameTransform);
  672. }
  673.  
  674. //----------------------------------------------------------------------------------------
  675. //     FW_CView::ViewContentToFrame
  676. //----------------------------------------------------------------------------------------
  677.  
  678. void FW_CView::ViewContentToFrame(Environment *ev, FW_CPoint& point) const
  679. {
  680.     FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewContentToFrameTransform(ev));        
  681.     point.Transform(ev, aqViewToFrameTransform);
  682. }
  683.  
  684. void FW_CView::ViewContentToFrame(Environment *ev, FW_CRect& rect) const
  685. {
  686.     FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewContentToFrameTransform(ev));        
  687.     rect.Transform(ev, aqViewToFrameTransform);
  688. }
  689.  
  690. void FW_CView::ViewContentToFrame(Environment *ev, ODShape* shape) const
  691. {
  692.     FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewContentToFrameTransform(ev));        
  693.     shape->Transform(ev, aqViewToFrameTransform);
  694. }
  695.  
  696. //----------------------------------------------------------------------------------------
  697. //     FW_CView::FrameToView
  698. //----------------------------------------------------------------------------------------
  699.  
  700. void FW_CView::FrameToView(Environment *ev, FW_CPoint& point) const
  701. {
  702.     if (IsFrame(ev) == FALSE) {
  703.         FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewToFrameTransform(ev));    
  704.         point.InverseTransform(ev, aqViewToFrameTransform);
  705.     }
  706. }
  707.  
  708. void FW_CView::FrameToView(Environment *ev, FW_CRect& rect) const
  709. {
  710.     if (IsFrame(ev) == FALSE) {
  711.         FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewToFrameTransform(ev));    
  712.         rect.InverseTransform(ev, aqViewToFrameTransform);
  713.     }
  714. }
  715.  
  716. void FW_CView::FrameToView(Environment *ev, ODShape* shape) const
  717. {
  718.     if (IsFrame(ev) == FALSE) {
  719.         FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewToFrameTransform(ev));
  720.         shape->InverseTransform(ev, aqViewToFrameTransform);
  721.     }
  722. }
  723.  
  724. //----------------------------------------------------------------------------------------
  725. //     FW_CView::ViewToFrame
  726. //----------------------------------------------------------------------------------------
  727.  
  728. void FW_CView::ViewToFrame(Environment *ev, FW_CPoint& point) const
  729. {
  730.     if (IsFrame(ev) == FALSE) {
  731.         FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewToFrameTransform(ev));    
  732.         point.Transform(ev, aqViewToFrameTransform);
  733.     }
  734. }
  735.  
  736. void FW_CView::ViewToFrame(Environment *ev, FW_CRect& rect) const
  737. {
  738.     if (IsFrame(ev) == FALSE) {
  739.         FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewToFrameTransform(ev));
  740.         rect.Transform(ev, aqViewToFrameTransform);
  741.     }
  742. }
  743.  
  744. void FW_CView::ViewToFrame(Environment *ev, ODShape* shape) const
  745. {
  746.     if (IsFrame(ev) == FALSE) {
  747.         FW_CAcquiredODTransform aqViewToFrameTransform(AcquireViewToFrameTransform(ev));
  748.         shape->Transform(ev, aqViewToFrameTransform);
  749.     }
  750. }
  751.  
  752. //----------------------------------------------------------------------------------------
  753. //     FW_CView::GetFrame
  754. //----------------------------------------------------------------------------------------
  755. FW_CFrame* FW_CView::GetFrame(Environment* ev) const
  756. {
  757.     FW_CView* container = GetSuperView(ev);
  758.  
  759.     // a null ParentView means that it's a CFrame
  760.     return container ? container->GetFrame(ev) : (FW_CFrame*)this;
  761. }
  762.  
  763. //----------------------------------------------------------------------------------------
  764. //     FW_CView::HandleMouseDown
  765. //----------------------------------------------------------------------------------------
  766.  
  767. FW_Boolean FW_CView::HandleMouseDown(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  768. {
  769.     FW_Boolean handled = FALSE;
  770.     FW_CFrame* frame = GetFrame(ev);
  771.     
  772.     if (frame->IsRoot(ev) == FALSE && 
  773.             frame->PrivActiveWindowOnMouseDown(ev, theMouseEvent.GetFacet(ev), TRUE))
  774.         return TRUE;    // didn't want the first click on non-active frame
  775.     
  776.     if (frame->GetWindow(ev)->IsActive(ev))
  777.     {
  778.         if (this->WantsToBeTarget(ev))    
  779.         {
  780.             // Must be sure target's frame is active, else key events won't get there 
  781.             // (handles case of root frame containing an active embedded frame)
  782.             frame->PrivActivateFrame(ev, theMouseEvent.GetFacet(ev));
  783.             
  784.             this->BecomeTarget(ev);
  785.         }
  786.         
  787.         handled = FW_MEventHandler::HandleMouseDown(ev, theMouseEvent);
  788.     }
  789.     
  790.     return handled;
  791. }
  792.  
  793. //----------------------------------------------------------------------------------------
  794. //     FW_CView::HandleBGMouseDown
  795. //----------------------------------------------------------------------------------------
  796.  
  797. FW_Boolean FW_CView::HandleBGMouseDown(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  798. {
  799.     FW_CFrame* frame = GetFrame(ev);
  800.     FW_ASSERT(frame);
  801.  
  802.     FW_CSelection* selection = frame->GetPresentation(ev)->GetSelection(ev);
  803.     if (selection)
  804.         selection->UpdateSelectionOnMouseDown(ev, theMouseEvent, NULL, FALSE, TRUE);
  805.     
  806.     return FW_MEventHandler::HandleBGMouseDown(ev, theMouseEvent);
  807. }
  808.  
  809. //----------------------------------------------------------------------------------------
  810. //    FW_CView::DoBGMouseDown
  811. //----------------------------------------------------------------------------------------
  812.  
  813. FW_Boolean FW_CView::DoBGMouseDown(Environment *ev, const FW_CMouseEvent& theMouseEvent)
  814. {
  815.     FW_CFrame* frame = GetFrame(ev);
  816.     FW_ASSERT(frame);
  817.  
  818.     FW_CSelection* selection = frame->GetPresentation(ev)->GetSelection(ev);
  819.     if (selection != NULL && selection->IsMouseInDraggableItem(ev, frame, theMouseEvent, TRUE))
  820.     {
  821.         FW_MDraggableFrame* draggable = frame->GetDraggable(ev);
  822.         if (draggable)
  823.             return draggable->Drag(ev, theMouseEvent);
  824.     }
  825.     
  826.     // return FALSE because I am not doing anything. Let the process manager do its job.
  827.     return FALSE;     
  828. }
  829.  
  830. //----------------------------------------------------------------------------------------
  831. //     FW_CView::HandleMouseUp
  832. //----------------------------------------------------------------------------------------
  833.  
  834. FW_Boolean FW_CView::HandleMouseUp(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  835. {
  836.     FW_CFrame* frame = GetFrame(ev);
  837.     FW_ASSERT(frame);
  838.  
  839.     frame->PrivActivateFrame(ev, theMouseEvent.GetFacet(ev));    // Will test if it can be the activeframe
  840.  
  841.     return FW_MEventHandler::HandleMouseUp(ev, theMouseEvent);
  842. }
  843.  
  844. //----------------------------------------------------------------------------------------
  845. // FW_CView::DoMouseEnter
  846. //----------------------------------------------------------------------------------------
  847.  
  848. FW_Boolean FW_CView::DoMouseEnter(Environment* ev, ODFacet* odFacet, const FW_CPoint& theMousePoint)
  849. {
  850. FW_UNUSED(ev);
  851. FW_UNUSED(odFacet);
  852. FW_UNUSED(theMousePoint);
  853.     return FALSE;
  854. }
  855.  
  856. //----------------------------------------------------------------------------------------
  857. // FW_CView::DoMouseWithin
  858. //----------------------------------------------------------------------------------------
  859.  
  860. FW_Boolean FW_CView::DoMouseWithin(Environment* ev, ODFacet* odFacet, const FW_CPoint& theMousePoint)
  861. {
  862. FW_UNUSED(ev);
  863. FW_UNUSED(odFacet);
  864. FW_UNUSED(theMousePoint);
  865.     return FALSE;
  866. }
  867.  
  868. //----------------------------------------------------------------------------------------
  869. // FW_CView::DoMouseLeave
  870. //----------------------------------------------------------------------------------------
  871.  
  872. FW_Boolean FW_CView::DoMouseLeave(Environment* ev, ODFacet* odFacet)
  873. {
  874. FW_UNUSED(ev);
  875. FW_UNUSED(odFacet);
  876.     return FALSE;
  877. }
  878.  
  879. //----------------------------------------------------------------------------------------
  880. //    FW_CView::HandleActivateEvent
  881. //----------------------------------------------------------------------------------------
  882.  
  883. void FW_CView::HandleActivateEvent(Environment* ev, const FW_CActivateEvent& theActivateEvent)
  884. {
  885.     DoActivateEvent(ev, theActivateEvent);
  886. }
  887.  
  888. //----------------------------------------------------------------------------------------
  889. // FW_CView::DoMouseLeave
  890. //----------------------------------------------------------------------------------------
  891.  
  892. void FW_CView::DoActivateEvent(Environment* ev, const FW_CActivateEvent& theActivateEvent)
  893. {
  894. FW_UNUSED(ev);
  895. FW_UNUSED(theActivateEvent);
  896. }
  897.  
  898. //----------------------------------------------------------------------------------------
  899. // FW_CView::GetExtent
  900. //----------------------------------------------------------------------------------------
  901.  
  902. FW_CPoint FW_CView::GetExtent(Environment* ev) const 
  903. {    
  904. FW_UNUSED(ev);
  905.     return fBounds.Size();
  906. }
  907.  
  908. //----------------------------------------------------------------------------------------
  909. //    FW_CView::GetVisibleBounds
  910. //----------------------------------------------------------------------------------------
  911. //    Returns the visible bounds of the view through all its superviews (in frame coordinate)
  912.  
  913. FW_CRect FW_CView::GetVisibleBounds(Environment *ev) const
  914. {
  915.     FW_CView* aView = (FW_CView*)this;
  916.     FW_CFrame* frame = aView->GetFrame(ev);
  917.     FW_CRect visibleRect = frame->GetBounds(ev);
  918.     
  919.     // go up superview chain and stop at the frame
  920.     while (aView != frame && !visibleRect.IsEmpty())
  921.     {
  922.         FW_CRect bounds = aView->GetBounds(ev);
  923.  
  924.         FW_CSuperView* superView = aView->fSuperView;    
  925.         if (superView)
  926.             superView->ViewContentToFrame(ev, bounds);
  927.         
  928.         visibleRect.Intersection(bounds);
  929.         
  930.         aView = superView;
  931.     }
  932.     
  933.     return visibleRect;
  934. }
  935.  
  936. //----------------------------------------------------------------------------------------
  937. //    FW_CView::HandleDraw
  938. //----------------------------------------------------------------------------------------
  939. // invalidShape is in frame coordinate
  940.  
  941. FW_Boolean FW_CView::HandleDraw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  942. {    
  943.     FW_Boolean somethingToDraw = FALSE;
  944.     
  945.     if (fVisible) 
  946.     {
  947.         // [LSD] todo: handle tri-state visibility
  948.         // [LSD] todo: Draw high-priority adorners
  949.  
  950.         FW_CRect visiblebounds = GetVisibleBounds(ev);    // return in frame coordinate
  951.         if (!visiblebounds.IsEmpty()) 
  952.         {
  953.             FW_CAcquiredODShape aqInvalidShape = ::FW_NewODShape(ev, visiblebounds);
  954.             aqInvalidShape->SetGeometryMode(ev, kODLoseGeometry);
  955.  
  956.             if (invalidShape)
  957.                 aqInvalidShape->Intersect(ev, invalidShape);
  958.             
  959.             if (!aqInvalidShape->IsEmpty(ev)) 
  960.             {                
  961.                 FrameToViewContent(ev, aqInvalidShape); 
  962.                 Draw(ev, odFacet, aqInvalidShape);
  963.                 somethingToDraw = TRUE;    
  964.             }
  965.         }
  966.  
  967.         // [LSD] todo: Draw low-priority adorners
  968.     }
  969.     
  970.     return somethingToDraw;
  971. }
  972.  
  973. //----------------------------------------------------------------------------------------
  974. //    FW_CView::Draw
  975. //----------------------------------------------------------------------------------------
  976. //    invalidShape is in content coordinate of this view
  977.  
  978. void FW_CView::Draw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  979. {
  980. FW_UNUSED(ev);
  981. FW_UNUSED(odFacet);
  982. FW_UNUSED(invalidShape);
  983. }
  984.  
  985. //----------------------------------------------------------------------------------------
  986. // FW_CView::SetVisible
  987. //----------------------------------------------------------------------------------------
  988.  
  989. void FW_CView::SetVisible(Environment* ev, FW_Boolean visible, FW_Boolean propagate)
  990. {
  991. FW_UNUSED(ev);
  992. FW_UNUSED(propagate);
  993.     // Not allowed to make the Frame invisible!
  994.     FW_ASSERT(IsFrame(ev) == FALSE || visible == TRUE);
  995.     
  996.     if (fVisible != visible)
  997.     {
  998.         fVisible = visible;
  999.         Invalidate(ev, NULL, false);
  1000.     }
  1001. }
  1002.  
  1003. //----------------------------------------------------------------------------------------
  1004. // FW_CView::PrivAcquireContentScrollShape
  1005. //----------------------------------------------------------------------------------------
  1006.  
  1007. void FW_CView::PrivAcquireContentScrollShape(Environment* ev,
  1008.                                             FW_Boolean horizontalScroll, 
  1009.                                             FW_Boolean verticalScroll,
  1010.                                             ODShape* scrollShape) const
  1011. {
  1012. FW_UNUSED(ev);
  1013. FW_UNUSED(horizontalScroll);
  1014. FW_UNUSED(verticalScroll);
  1015. FW_UNUSED(scrollShape);
  1016.     // nothing to do: can't scroll, can't have subviews
  1017. }
  1018.  
  1019. //----------------------------------------------------------------------------------------
  1020. //    FW_CView::Write
  1021. //----------------------------------------------------------------------------------------
  1022.  
  1023. void FW_CView::Write(FW_CWritableStream& stream, FW_ClassTypeConstant type, const void *object)
  1024. {
  1025. FW_UNUSED(type);
  1026.     FW_SOMEnvironment ev;
  1027.     ((const FW_CView *) object)->Flatten(ev, stream);
  1028. }
  1029.  
  1030. //----------------------------------------------------------------------------------------
  1031. //    FW_CView::Read
  1032. //----------------------------------------------------------------------------------------
  1033.  
  1034. void FW_CView::Read(FW_CReadableStream& stream, FW_ClassTypeConstant type, void* object)
  1035. {
  1036. FW_UNUSED(type);
  1037.     FW_SOMEnvironment ev;
  1038.     ((FW_CView *) object)->InitializeFromStream(ev, stream);
  1039. }
  1040.  
  1041. //----------------------------------------------------------------------------------------
  1042. //    FW_CView::Flatten
  1043. //----------------------------------------------------------------------------------------
  1044.  
  1045. void FW_CView::Flatten(Environment* ev, FW_CWritableStream& stream) const
  1046. {
  1047. FW_UNUSED(ev);
  1048.  
  1049.     FW_CSuperView* superView = fSuperView;
  1050.     FW_WRITE_DYNAMIC_OBJECT(stream, superView, FW_CSuperView);
  1051.     
  1052.     stream << fViewId;
  1053.     stream << fBounds;
  1054.     stream << fBindings;    
  1055. }
  1056.  
  1057. //----------------------------------------------------------------------------------------
  1058. //    FW_CView::InitializeFromStream
  1059. //----------------------------------------------------------------------------------------
  1060.  
  1061. void    FW_CView::InitializeFromStream(Environment* ev, FW_CReadableStream& stream)
  1062. {
  1063.     FW_READ_DYNAMIC_OBJECT(stream, &fSuperView, FW_CSuperView);
  1064.     SetNextEventHandler(ev, fSuperView);
  1065.     
  1066.     // [JEL] Currently, FW_MEventHandler's are not archivable. This means that FW_CView must
  1067.     // properly initialize the inherited FW_MEventHandler.  The NextEventHandler field
  1068.     // is easily done, but what about the priority? Should every view resource have a 
  1069.     // priority field?  For now we punt and set the priority to kNoPriority.
  1070.     SetPriority(ev, kNoPriority);
  1071.     
  1072.     stream >> fViewId;
  1073.     stream >> fBounds;
  1074.     stream >> fBindings;    
  1075.     
  1076.     FW_ASSERT(fBounds.left < fBounds.right && fBounds.top < fBounds.bottom);
  1077.  
  1078.     // add new view to the parent's SubView list
  1079.     fSuperView->AddSubView(ev, this);
  1080. }
  1081.  
  1082. //----------------------------------------------------------------------------------------
  1083. //    FW_CView::PostCreateViewFromStream
  1084. //----------------------------------------------------------------------------------------
  1085.  
  1086. void FW_CView::PostCreateViewFromStream(Environment* ev)
  1087. {
  1088. FW_UNUSED(ev);
  1089.     // Nothing to do
  1090.     // Subclasses of Views that cache references to other objects
  1091.     // or otherwise maintain state that cannot be initialized from a
  1092.     // stream will need to update that state information by
  1093.     // overriding this method.  FW_CSuperView must propogate
  1094.     // this message to every subview.
  1095. }
  1096.