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 / FWSView.cpp < prev    next >
Encoding:
Text File  |  1996-08-16  |  29.3 KB  |  937 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWSView.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 "FWSView.h"
  14. #endif
  15.  
  16. #ifndef FWAROPER_H
  17. #include "FWArOper.h"
  18. #endif
  19.  
  20. #ifndef FWFRAME_H
  21. #include "FWFrame.h"
  22. #endif
  23.  
  24. #ifndef FWEVENT_H
  25. #include "FWEvent.h"
  26. #endif
  27.  
  28. #ifndef FWSELECT_H
  29. #include "FWSelect.h"
  30. #endif
  31.  
  32. #ifndef FWPRESEN_H
  33. #include "FWPresen.h"
  34. #endif
  35.  
  36. #ifndef FWODGEOM_H
  37. #include "FWODGeom.h"
  38. #endif
  39.  
  40. #ifndef FWWINDOW_H
  41. #include "FWWindow.h"
  42. #endif
  43.  
  44. #ifndef FWCURSOR_H
  45. #include "FWCursor.h"
  46. #endif
  47.  
  48. #ifndef FWCFMRES_H
  49. #include "FWCFMRes.h"
  50. #endif
  51.  
  52. #ifndef FWRESACC_H
  53. #include "FWResAcc.h"
  54. #endif
  55.  
  56. #ifndef FWRESSIN_H
  57. #include "FWResSin.h"
  58. #endif
  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. //========================================================================================
  83. // class FW_CSuperViewCollection
  84. //========================================================================================
  85.  
  86. FW_DEFINE_AUTO(FW_CSuperViewCollection)
  87.  
  88. //========================================================================================
  89. // class FW_CSuperViewCollectionIterator
  90. //========================================================================================
  91.  
  92. FW_DEFINE_AUTO(FW_CSuperViewCollectionIterator)
  93.  
  94. //========================================================================================
  95. // CLASS FW_CSuperView
  96. //========================================================================================
  97.  
  98. FW_DEFINE_CLASS_M1(FW_CSuperView, FW_CView)
  99.  
  100. //----------------------------------------------------------------------------------------
  101. // FW_CSuperView::FW_CSuperView
  102. //----------------------------------------------------------------------------------------
  103. FW_CSuperView::FW_CSuperView(Environment* ev, FW_CSuperView* container, 
  104.                     const FW_CRect& bounds, ODID theID, const FW_CPoint& extent,
  105.                     FW_EScrollingDirection scrollDir) :
  106.     FW_CView(ev, container, bounds, theID),
  107.     fSubViews(NULL),
  108.     fIsContentView(FALSE),
  109.     fViewContentToFrameTransform(NULL),
  110.     fScrollingDirection(scrollDir),
  111.     fInternalTransform(NULL)
  112. {
  113.     // Use the view's size as its default extent
  114.     fExtent = (extent == FW_kZeroPoint) ? fBounds.Size() : extent;
  115.     
  116.     // Unlike FW_CView, by default superviews are not refreshed entirely when resized
  117.     // i.e. FW_CSuperView subclasses must set the flag back to true if their content
  118.     // depends on the size.
  119.     SetResizeForceRedraw(ev, false);
  120.     
  121.     // Change the default binding, because this makes more sense for a content view
  122.     SetBindings(ev, FW_kFitToEnclosure);
  123. }
  124.  
  125. //----------------------------------------------------------------------------------------
  126. // FW_CSuperView::FW_CSuperView
  127. //----------------------------------------------------------------------------------------
  128.  
  129. FW_CSuperView::FW_CSuperView(Environment* ev) :
  130.     FW_CView(ev),
  131.     fSubViews(NULL),
  132.     fIsContentView(FALSE),
  133.     fExtent(FW_kZeroPoint),
  134.     fViewContentToFrameTransform(NULL),
  135.     fScrollingDirection(FW_kNoScrolling),
  136.     fInternalTransform(NULL)
  137. {
  138.     // this ctor should be used by CFrame only, the only CSuperView with a NULL fSuperView
  139.     SetResizeForceRedraw(ev, false);
  140. }
  141.  
  142. //----------------------------------------------------------------------------------------
  143. // FW_CSuperView::~FW_CSuperView
  144. //----------------------------------------------------------------------------------------
  145.  
  146. FW_CSuperView::~FW_CSuperView()
  147. {
  148.     Environment *ev = somGetGlobalEnvironment();
  149.  
  150.     DeleteSubViews(ev);
  151.     
  152.     if (fViewContentToFrameTransform) 
  153.     {    
  154.         fViewContentToFrameTransform->Release(ev);
  155.         fViewContentToFrameTransform = NULL;
  156.     }
  157.     
  158.     if (fInternalTransform)
  159.         fInternalTransform->Release(ev);
  160. }
  161.  
  162.  
  163. //----------------------------------------------------------------------------------------
  164. // FW_CSuperView::DeleteSubViews
  165. //----------------------------------------------------------------------------------------
  166.  
  167. void FW_CSuperView::DeleteSubViews(Environment* ev)
  168. {
  169. FW_UNUSED(ev);
  170.     if (fSubViews)
  171.     {
  172.         FW_CView* view;
  173.         while (fSubViews != NULL && (view = fSubViews->Last()) != NULL) 
  174.         {
  175.             // Delete each subview, which in turn  will remove it from its parentView
  176.             // fSubViews is deleted after the last view is removed
  177.             delete view;    
  178.         }
  179.         
  180.         // delete fSubViews;
  181.         // fSubViews = NULL;
  182.         FW_ASSERT(fSubViews == NULL);
  183.     }
  184. }
  185.  
  186. //----------------------------------------------------------------------------------------
  187. // FW_CSuperView::IsScrolling
  188. //----------------------------------------------------------------------------------------
  189.  
  190. FW_Boolean FW_CSuperView::IsScrolling(Environment* ev) const
  191. {
  192.     return IsScrollingInX(ev) || IsScrollingInY(ev);
  193. }
  194.  
  195.  
  196. //----------------------------------------------------------------------------------------
  197. // FW_CSuperView::PrivSetContentExtent
  198. //----------------------------------------------------------------------------------------
  199.  
  200. void FW_CSuperView::PrivSetContentExtent(Environment* ev, const FW_CPoint& extent)
  201. {
  202.     ODPoint odPoint = extent;
  203.     
  204.     FW_CFrame* frame = GetFrame(ev);
  205.     frame->GetODFrame(ev)->ChangeContentExtent(ev, &odPoint);
  206.     
  207.     if (IsScrolling(ev))
  208.         frame->PrivUpdateScrollParameters(ev);
  209. }
  210.  
  211. //----------------------------------------------------------------------------------------
  212. // FW_CSuperView::SetExtent
  213. //----------------------------------------------------------------------------------------
  214.  
  215. void FW_CSuperView::SetExtent(Environment* ev, const FW_CPoint& extent)
  216. {
  217.     if (fExtent != extent)
  218.     {
  219.         FW_CPoint oldExtent = fExtent;
  220.         fExtent = extent;
  221.  
  222.         // Changing the extent triggers the layout manager
  223.         FW_CViewIterator ite(this);
  224.         for (FW_CView* subview = ite.First(); ite.IsNotComplete(); subview = ite.Next())
  225.         {
  226.             // Resize each subview and update the screen
  227.             subview->AdjustToNewLayout(ev, oldExtent, extent, true);
  228.         }
  229.         
  230.         // The Content View must also udpate the ODFrame's extent and adjust scroller
  231.         if (fIsContentView)
  232.             PrivSetContentExtent(ev, extent);
  233.     }
  234. }
  235.  
  236. //----------------------------------------------------------------------------------------
  237. // FW_CSuperView::SetSize
  238. //----------------------------------------------------------------------------------------
  239. // WARNING: this method should not be called directly by instances of FW_CFrame.
  240. //            FW_CFrame calls it internally in FrameShapeChanged, you cannot control the
  241. //            size of your frame with SetSize, use FW_MProxy::ChangeFrameShapes
  242.  
  243. void FW_CSuperView::SetSize(Environment* ev, const FW_CPoint& size, FW_Boolean refresh)
  244. {
  245.     // Call base class first
  246.     FW_CView::SetSize(ev, size, refresh);
  247.     
  248.     if (IsScrolling(ev) == false)
  249.     {
  250.         // Set the extent to match the new size when the superview is not scrolling
  251.         // SetExtent will in turn adjust the layout of the superview's subviews
  252.         SetExtent(ev, size);  
  253.     }
  254.     else 
  255.     {    
  256.         // There are 3 types of scrolling views:
  257.         // - scrolling only in X -> the extent height is adjusted
  258.         // - scrolling only in Y -> the extent width is adjusted
  259.         // - scrolling in X and Y -> the extent is not changed
  260.         FW_CPoint extent = fExtent;
  261.         
  262.         if (IsScrollingInX(ev) == true && IsScrollingInY(ev) == false)
  263.             extent.y = size.y;
  264.  
  265.         if (IsScrollingInY(ev) == true && IsScrollingInX(ev) == false)
  266.             extent.x = size.x;
  267.             
  268.         SetExtent(ev, extent);
  269.     }
  270. }
  271.  
  272. //----------------------------------------------------------------------------------------
  273. // FW_CSuperView::MakeContentView
  274. //----------------------------------------------------------------------------------------
  275.  
  276. void FW_CSuperView::MakeContentView(Environment* ev)    
  277. {
  278.     FW_CFrame*    frame = GetFrame(ev);
  279.  
  280.     // Declare ContentView to the CFrame
  281.     frame->SetContentView(ev, this);
  282.     fIsContentView = TRUE;
  283.     
  284.     // Update the ODFrame's extent and the scrollbars
  285.     PrivSetContentExtent(ev, fExtent);        
  286. }
  287.  
  288. //----------------------------------------------------------------------------------------
  289. // FW_CSuperView::AddSubView
  290. //----------------------------------------------------------------------------------------
  291.  
  292. void FW_CSuperView::AddSubView(Environment* ev, FW_CView *subview)
  293. {
  294.     if (fSubViews == NULL) 
  295.     {
  296.         fSubViews = FW_NEW(FW_CViewCollection, ());
  297.     } 
  298.     else if (fSubViews->Contains(this) == true)
  299.     {
  300.         FW_DEBUG_MESSAGE("subview already added");    
  301.         return;
  302.     }
  303.     
  304.     // AddSubView can be used to replace an existing parent view
  305.     FW_CSuperView* oldParent = subview->fSuperView;
  306.     if (oldParent != this && oldParent != NULL)
  307.     {    
  308.         // This will in turn call PrivInvalidateCachedTransforms
  309.         oldParent->RemoveSubView(ev, subview);
  310.         
  311.         subview->fSuperView = this;
  312.     }
  313.     
  314.     fSubViews->AddLast(subview);
  315.     
  316.     // Virtual method for subclasses
  317.     SubViewAdded(ev, subview);
  318. }
  319.  
  320. //----------------------------------------------------------------------------------------
  321. // FW_CSuperView::SubViewAdded
  322. //----------------------------------------------------------------------------------------
  323.  
  324. void FW_CSuperView::SubViewAdded(Environment* ev, FW_CView* subview)
  325. {
  326. FW_UNUSED(ev);
  327. FW_UNUSED(subview);
  328. }
  329.  
  330. //----------------------------------------------------------------------------------------
  331. // FW_CSuperView::RemoveSubView
  332. //----------------------------------------------------------------------------------------
  333.  
  334. void FW_CSuperView::RemoveSubView(Environment* ev, FW_CView* subview)
  335. {
  336.     FW_ASSERT(fSubViews != NULL);
  337.     FW_ASSERT(fSubViews->Contains(subview));
  338.     
  339.     fSubViews->Remove(subview);
  340.     
  341.     // Reset subview geometry
  342.     subview->PrivInvalidateCachedTransforms(ev);
  343.     
  344.     // Virtual method for subclasses
  345.     SubViewRemoved(ev, subview);
  346.     
  347.     // Update fSuperView field in case it's added to another superview
  348.     subview->fSuperView = NULL;
  349.     
  350.     if (fSubViews->Last() == NULL)
  351.     {
  352.         delete fSubViews;
  353.         fSubViews = NULL;
  354.     }
  355. }
  356.  
  357. //----------------------------------------------------------------------------------------
  358. // FW_CSuperView::SubViewRemoved
  359. //----------------------------------------------------------------------------------------
  360.  
  361. void FW_CSuperView::SubViewRemoved(Environment* ev, FW_CView* subview)
  362. {
  363. FW_UNUSED(ev);
  364. FW_UNUSED(subview);
  365. }
  366.  
  367. //----------------------------------------------------------------------------------------
  368. //    FW_CSuperView::AdjustCursor
  369. //----------------------------------------------------------------------------------------
  370. // where is in frame coordinate
  371.  
  372. FW_Boolean FW_CSuperView::AdjustCursor(Environment *ev, ODFacet* odFacet, const FW_CPoint& theMousePoint)
  373. {
  374.     // If I am the content view let the frame do the job first
  375.     if (fIsContentView)  return GetFrame(ev)->AdjustCursor(ev, odFacet, theMousePoint);
  376.     
  377.     return FALSE;
  378. }
  379.  
  380. //----------------------------------------------------------------------------------------
  381. // FW_CSuperView::CountSubViews
  382. //----------------------------------------------------------------------------------------
  383.  
  384. unsigned long FW_CSuperView::CountSubViews(Environment* ev) const
  385. {
  386. FW_UNUSED(ev);
  387.     return fSubViews == NULL ? 0 : fSubViews->Count();
  388. }
  389.  
  390. //----------------------------------------------------------------------------------------
  391. // FW_CSuperView::HasSubViews
  392. //----------------------------------------------------------------------------------------
  393.  
  394. FW_Boolean FW_CSuperView::HasSubViews(Environment* ev) const
  395. {
  396. FW_UNUSED(ev);
  397.     return fSubViews != NULL;
  398. }
  399.  
  400. //----------------------------------------------------------------------------------------
  401. // FW_CSuperView::FindViewById
  402. //----------------------------------------------------------------------------------------
  403. FW_CView*    FW_CSuperView::FindViewById(Environment* ev, ODID id)
  404. {
  405.     FW_CView*    theView = NULL;
  406.  
  407.     if (GetViewId(ev) == id) {
  408.         theView = this;
  409.     } 
  410.     else {
  411.         FW_CViewIterator ite(this);
  412.         for (FW_CView* subview = ite.First(); ite.IsNotComplete(); subview = ite.Next())
  413.         {
  414.             theView = subview->FindViewById(ev, id);
  415.             if (theView) break;
  416.         }
  417.     }
  418.     return theView;
  419. }
  420.  
  421. //----------------------------------------------------------------------------------------
  422. //    FW_CSuperView::CreateSubViews
  423. //----------------------------------------------------------------------------------------
  424.  
  425. void FW_CSuperView::CreateSubViews(Environment *ev)  
  426. {
  427. FW_UNUSED(ev);
  428. }
  429.  
  430. //----------------------------------------------------------------------------------------
  431. // FW_CSuperView::CreateSubViewsFromResource
  432. //----------------------------------------------------------------------------------------
  433.  
  434. void FW_CSuperView::CreateSubViewsFromResource(Environment* ev, FW_ResourceId id)
  435. {
  436.     FW_TRY
  437.     {
  438.         FW_CSharedLibraryResourceFile resFile(ev, GetFrame(ev)->GetPart(ev)->GetPartInstance(ev));
  439.         FW_PResource viewResource(ev, resFile, id, FW_kViewLayoutType);
  440.         FW_PResourceSink sink(ev, viewResource);
  441.         FW_CReadableStream stream(sink);
  442.         CreateSubViewsFromStream(ev, stream);
  443.     }
  444.     FW_CATCH_BEGIN
  445.     FW_CATCH_REFERENCE(FW_XException, except)
  446.     {
  447.         // We use this try-catch block purely to warn about a common mistake.
  448.         // If one forgets to add the resource containing their views to their project,
  449.         // or passes in the wrong view id, the above code will throw an exception
  450.         // that probably won't get caught until the SOM entry point from OpenDoc.
  451.         // OpenDoc will display an error dialog that isn't particularly helpful
  452.         // in diagnosing the problem.
  453.         FW_DEBUG_MESSAGE("Failed to load view resource.");
  454.         FW_PlatformError error = except.GetPlatformError();
  455.         FW_THROW_SAME();
  456.     }
  457.     FW_CATCH_END
  458. }
  459.  
  460. //----------------------------------------------------------------------------------------
  461. // FW_CSuperView::CreateSubViewsFromStream
  462. //----------------------------------------------------------------------------------------
  463.  
  464. void FW_CSuperView::CreateSubViewsFromStream(Environment* ev, FW_CReadableStream& stream)
  465. {
  466.     FW_CPoint realExtent = fExtent;
  467.     
  468.     // Load the extent used in resources to define the layout of subviews
  469.     stream >> fExtent;
  470.     
  471.     // Create the subviews
  472.     PrivCreateSubViewsFromStream(ev, stream);
  473.     
  474.     // Give subclass a chance to complete subviews creation
  475.     PrivPostCreateViewFromStream(ev);
  476.     
  477.     // Reset the superview's extent like it was and adjust the subviews layout in the process
  478.     SetExtent(ev, realExtent);
  479. }
  480.  
  481. //----------------------------------------------------------------------------------------
  482. //    FW_CSuperView::PrivCreateSubViewsFromStream
  483. //----------------------------------------------------------------------------------------
  484.  
  485. void FW_CSuperView::PrivCreateSubViewsFromStream(Environment* ev, FW_CReadableStream& stream)
  486. {
  487.     FW_PREREGISTER_RUNTIME_OBJECT(stream, 
  488.                                 this, 
  489.                                 FW_kPreregisteredRootViewObject);
  490.     
  491.     PrivReadSubviewsFromStream(ev, stream);
  492. }
  493.  
  494. //----------------------------------------------------------------------------------------
  495. //    FW_CSuperView::PrivPostCreateViewFromStream
  496. //----------------------------------------------------------------------------------------
  497.  
  498. void FW_CSuperView::PrivPostCreateViewFromStream(Environment* ev)
  499. {
  500.     // Handle this view first
  501.     PostCreateViewFromStream(ev);
  502.     
  503.     // Propagate to subviews
  504.     FW_CViewIterator ite(this);
  505.     for (FW_CView* subview = ite.First(); ite.IsNotComplete(); subview = ite.Next())
  506.     {
  507.         if (subview->HasSubViews(ev))
  508.             ((FW_CSuperView *)subview)->PrivPostCreateViewFromStream(ev);
  509.         else
  510.             subview->PostCreateViewFromStream(ev);
  511.     }
  512. }
  513.  
  514. //----------------------------------------------------------------------------------------
  515. //     FW_CSuperView::GetViewContaining
  516. //----------------------------------------------------------------------------------------
  517. //    Find the visible & enabled view containing a point (in frame coordinates)
  518.  
  519. FW_CView* FW_CSuperView::GetViewContaining(Environment* ev, 
  520.                                     ODFacet* odFacet, 
  521.                                     const FW_CPoint& theMousePoint)
  522. {
  523.     FW_CView* viewUnder = NULL;
  524.     
  525.     if (fVisible && IsEnabled(ev) && IsMouseWithin(ev, odFacet, theMousePoint)) 
  526.     {
  527.         // iterate on sibling views from top to bottom
  528.         FW_CViewIterator ite(this);
  529.         for (FW_CView* subview = ite.Last(); ite.IsNotComplete() && !viewUnder; 
  530.                                                             subview = ite.Previous())
  531.         {
  532.             viewUnder = subview->GetViewContaining(ev, odFacet, theMousePoint);
  533.         }
  534.         if (viewUnder == NULL)
  535.             viewUnder = this;
  536.     }
  537.     
  538.     return viewUnder;
  539. }
  540.  
  541. //----------------------------------------------------------------------------------------
  542. // FW_CSuperView::SizeChanged
  543. //----------------------------------------------------------------------------------------
  544.  
  545. void FW_CSuperView::SizeChanged(Environment* ev, const FW_CPoint& oldSize)
  546. {
  547. FW_UNUSED(oldSize);
  548.     if (IsContentView(ev) && IsScrolling(ev))
  549.         GetFrame(ev)->PrivUpdateScrollParameters(ev);
  550. }
  551.  
  552. //----------------------------------------------------------------------------------------
  553. // FW_CSuperView::SetLocation
  554. //----------------------------------------------------------------------------------------
  555.  
  556. void FW_CSuperView::SetLocation(Environment* ev, const FW_CPoint& location, FW_Boolean refresh)
  557. {
  558.     FW_CPoint newLocation;
  559.     if (IsContentView(ev))
  560.     {
  561.         newLocation = location;
  562.         FW_CSuperView* parent = GetSuperView(ev);
  563.         if (parent)
  564.             parent->ViewContentToFrame(ev, newLocation);
  565.     }
  566.     
  567.     FW_CView::SetLocation(ev, location, refresh);
  568.     
  569.     if (IsContentView(ev))
  570.         GetFrame(ev)->PrivContentViewLocationChanged(ev, newLocation);
  571. }
  572.  
  573. //----------------------------------------------------------------------------------------
  574. // FW_CSuperView::IsInContentView
  575. //----------------------------------------------------------------------------------------
  576. // [LSD] keep that?
  577. FW_Boolean    FW_CSuperView::IsInContentView(Environment* ev) const
  578. {
  579.     if (fIsContentView)
  580.         return TRUE;            
  581.     else if (IsFrame(ev))            
  582.         return FALSE;    // this is the CFrame but its fIsContentView was FALSE
  583.     else
  584.         return fSuperView->IsInContentView(ev);
  585. }
  586.  
  587. //----------------------------------------------------------------------------------------
  588. // FW_CSuperView::AcquireViewContentToFrameTransform
  589. //----------------------------------------------------------------------------------------
  590. // returns the transform to convert view content coordinates to frame coordinates
  591.  
  592. ODTransform* FW_CSuperView::AcquireViewContentToFrameTransform(Environment* ev) const
  593. {
  594.     FW_CSuperView* self = (FW_CSuperView*)this;
  595.     
  596.     if (fViewContentToFrameTransform == NULL)
  597.     {
  598.         self->fViewContentToFrameTransform = FW_CopyAndRelease(ev, PrivAcquireViewInternalTransform(ev));
  599.         FW_CAcquiredODTransform aqViewToFrame = AcquireViewToFrameTransform(ev);
  600.         fViewContentToFrameTransform->PostCompose(ev, aqViewToFrame);
  601.     }
  602.     
  603.     self->fViewContentToFrameTransform->Acquire(ev);
  604.  
  605.     return fViewContentToFrameTransform;
  606. }
  607.  
  608. //----------------------------------------------------------------------------------------
  609. //     FW_CSuperView::GetBoundsInContent
  610. //----------------------------------------------------------------------------------------
  611. //    returns the bounds in content coordinates
  612.  
  613. FW_CRect FW_CSuperView::GetBoundsInContent(Environment *ev) const
  614. {
  615.     FW_CRect bounds = GetBounds(ev);
  616.     bounds.Place(FW_kFixed0, FW_kFixed0);
  617.     FW_CAcquiredODTransform aqInternal = PrivAcquireViewInternalTransform(ev);
  618.     bounds.InverseTransform(ev, aqInternal);
  619.     
  620.     return bounds;
  621. }
  622.  
  623. //----------------------------------------------------------------------------------------
  624. //    FW_CSuperView::HandleActivateEvent
  625. //----------------------------------------------------------------------------------------
  626.  
  627. void FW_CSuperView::HandleActivateEvent(Environment* ev, const FW_CActivateEvent& theActivateEvent)
  628. {
  629.     // Activate this view and then its subviews
  630.     FW_CView::HandleActivateEvent(ev, theActivateEvent);
  631.     
  632.     FW_CViewIterator ite(this);
  633.     for (FW_CView* view = ite.First(); ite.IsNotComplete();  view = ite.Next())
  634.     {
  635.         view->HandleActivateEvent(ev, theActivateEvent);
  636.     }
  637. }
  638.  
  639. //----------------------------------------------------------------------------------------
  640. //     FW_CSuperView::HandleMouseDown
  641. //----------------------------------------------------------------------------------------
  642.  
  643. FW_Boolean FW_CSuperView::HandleMouseDown(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  644. {
  645.     FW_CFrame* frame = GetFrame(ev);
  646.     FW_ASSERT(frame);
  647.  
  648.     FW_Boolean inActiveWindow = frame->GetWindow(ev)->IsActive(ev);
  649.  
  650.     FW_Boolean clickedInFrame = fIsContentView || !frame->IsRoot(ev);
  651.     if (frame->PrivActiveWindowOnMouseDown(ev, theMouseEvent.GetFacet(ev), clickedInFrame))
  652.         return TRUE;
  653.  
  654.     if (fIsContentView)
  655.     {
  656.         FW_CSelection* selection = frame->GetPresentation(ev)->GetSelection(ev);
  657.         if (selection)
  658.             selection->UpdateSelectionOnMouseDown(ev, theMouseEvent, NULL, FALSE, FALSE);
  659.     }
  660.     
  661.     if (inActiveWindow)
  662.     {
  663.         if (this->WantsToBeTarget(ev))
  664.             this->BecomeTarget(ev);
  665.  
  666.         FW_MEventHandler::HandleMouseDown(ev, theMouseEvent);
  667.     }
  668.     
  669.     return TRUE;
  670. }
  671.  
  672. //----------------------------------------------------------------------------------------
  673. //    FW_CSuperView::HandleDraw
  674. //----------------------------------------------------------------------------------------
  675. // invalidShape is in frame coordinate  (NULL means redraw everything)
  676.  
  677. FW_Boolean FW_CSuperView::HandleDraw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  678. {
  679.     if (FW_CView::HandleDraw(ev, odFacet, invalidShape)) {
  680.             // Draw its subviews
  681.             FW_CViewIterator ite(this);
  682.             for (FW_CView* subview = ite.First(); ite.IsNotComplete();  subview = ite.Next())
  683.             {
  684.                 subview->HandleDraw(ev, odFacet, invalidShape);
  685.             }
  686.     }
  687.     return TRUE;
  688. }
  689.  
  690. //----------------------------------------------------------------------------------------
  691. //    FW_CSuperView::Draw
  692. //----------------------------------------------------------------------------------------
  693. //    invalidShape is in content coordinate of this view
  694.  
  695. void FW_CSuperView::Draw(Environment *ev, ODFacet* odFacet, ODShape* invalidShape)
  696. {
  697. FW_UNUSED(ev);
  698. FW_UNUSED(odFacet);
  699. FW_UNUSED(invalidShape);
  700. }
  701.  
  702. //----------------------------------------------------------------------------------------
  703. // FW_CSuperView::GetExtent
  704. //----------------------------------------------------------------------------------------
  705.  
  706. FW_CPoint FW_CSuperView::GetExtent(Environment* ev) const 
  707. {    
  708. FW_UNUSED(ev);
  709.     return fExtent;
  710. }
  711.  
  712. //----------------------------------------------------------------------------------------
  713. // FW_CSuperView::SetVisible
  714. //----------------------------------------------------------------------------------------
  715. // [LSD] use tri-state later
  716.  
  717. void FW_CSuperView::SetVisible(Environment* ev, FW_Boolean visible, FW_Boolean propagate)
  718. {
  719.     FW_CView::SetVisible(ev, visible);
  720.     
  721.     if (propagate)
  722.     {
  723.         // propagates to subviews
  724.         FW_CViewIterator ite(this);
  725.         for (FW_CView* subview = ite.First(); ite.IsNotComplete();  subview = ite.Next())
  726.         {
  727.             subview->SetVisible(ev, visible, TRUE);
  728.         }    
  729.     }
  730. }
  731.  
  732. //----------------------------------------------------------------------------------------
  733. //    FW_CSuperView::Flatten
  734. //----------------------------------------------------------------------------------------
  735.  
  736. void FW_CSuperView::Flatten(Environment* ev, FW_CWritableStream& stream) const
  737. {
  738.     FW_CView::Flatten(ev, stream);
  739.     
  740.     stream << fExtent;
  741.     stream << fIsContentView;
  742.     stream << (short)fScrollingDirection;
  743.     
  744.     unsigned long count = CountSubViews(ev);
  745.     short numberSubViews = (short) count;
  746.     FW_ASSERT(count == numberSubViews);
  747.     
  748.     stream << numberSubViews;
  749.     if (numberSubViews > 0)
  750.     {
  751.         FW_CViewIterator ite(this);
  752.         for (FW_CView* view=ite.First(); ite.IsNotComplete(); view=ite.Next())
  753.             FW_WRITE_DYNAMIC_OBJECT(stream, view, FW_CView);
  754.     }
  755.     
  756. }
  757.  
  758. //----------------------------------------------------------------------------------------
  759. //    FW_CSuperView::InitializeFromStream
  760. //----------------------------------------------------------------------------------------
  761.  
  762. void FW_CSuperView::InitializeFromStream(Environment* ev, FW_CReadableStream& stream)
  763. {
  764.     FW_CView::InitializeFromStream(ev, stream);
  765.     
  766.     FW_CPoint    extent;
  767.     FW_Boolean    isContentView;
  768.     short        scrollDir;
  769.  
  770.     // [LSD] fExtent is set directly instead of calling SetExtent. Subviews are not yet
  771.     // created at this point, and their layout inside this superview is defined in resources 
  772.     // anyway. (Adjustement to the frame extent is done later in CreateSubViewsFromStream)
  773.     stream >> fExtent;
  774.     stream >> isContentView;
  775.     stream >> scrollDir;
  776.     
  777.     fScrollingDirection = FW_EScrollingDirection(scrollDir);
  778.     
  779.     // Declare the content view to the frame and update its extent and scrollbars
  780.     if (isContentView)
  781.         MakeContentView(ev);
  782.     
  783.     // Load the subviews
  784.     PrivReadSubviewsFromStream(ev, stream);
  785. }
  786.  
  787. //----------------------------------------------------------------------------------------
  788. //    FW_CSuperView::PrivReadSubviewsFromStream
  789. //----------------------------------------------------------------------------------------
  790.  
  791. void FW_CSuperView::PrivReadSubviewsFromStream(Environment* ev, FW_CReadableStream& stream)
  792. {
  793. FW_UNUSED(ev);
  794.     short numberSubViews;
  795.     stream >> numberSubViews;
  796.     for (short i=0; i<numberSubViews; i++)
  797.     {
  798.         FW_CView* view;
  799.         FW_READ_DYNAMIC_OBJECT(stream, &view, FW_CView);
  800.         FW_ASSERT(view != NULL);
  801.     }
  802. }
  803.  
  804. //----------------------------------------------------------------------------------------
  805. // FW_CSuperView::PrivInvalidateCachedTransforms
  806. //----------------------------------------------------------------------------------------
  807.  
  808. void FW_CSuperView::PrivInvalidateCachedTransforms(Environment* ev)
  809. {
  810.     FW_CView::PrivInvalidateCachedTransforms(ev);
  811.  
  812.     if (fViewContentToFrameTransform)
  813.     {
  814.         fViewContentToFrameTransform->Release(ev);
  815.         fViewContentToFrameTransform = NULL;
  816.     }
  817.  
  818.     // ----- Go further down -----
  819.     FW_CViewIterator iter(this);
  820.     for (FW_CView* subview = iter.First(); iter.IsNotComplete(); subview = iter.Next())
  821.         subview->PrivInvalidateCachedTransforms(ev);
  822. }
  823.  
  824. //----------------------------------------------------------------------------------------
  825. // FW_CSuperView::PrivInvalidateViewIternalTransform
  826. //----------------------------------------------------------------------------------------
  827.  
  828. void FW_CSuperView::PrivInvalidateViewIternalTransform(Environment* ev)
  829. {
  830.     if (IsScrolling(ev))
  831.     {
  832.         // ----- Invalidate my internal transform -------
  833.         if (fInternalTransform)
  834.         {
  835.             fInternalTransform->Release(ev);
  836.             fInternalTransform = NULL;
  837.         }
  838.  
  839.         // ----- Invalidate my viewContent to frame transform (which uses fInternalTransform) -------
  840.         if (fViewContentToFrameTransform)
  841.         {
  842.             fViewContentToFrameTransform->Release(ev);
  843.             fViewContentToFrameTransform = NULL;
  844.         }
  845.  
  846.         // ----- Invalidate all subviews cached transforms -------
  847.         FW_CViewIterator ite(this);
  848.         for (FW_CView* subview = ite.First(); ite.IsNotComplete();  subview = ite.Next())
  849.             subview->PrivInvalidateCachedTransforms(ev);
  850.     }
  851.     else
  852.     {
  853.         FW_CViewIterator ite(this);
  854.         for (FW_CView* subview = ite.First(); ite.IsNotComplete();  subview = ite.Next())
  855.             subview->PrivInvalidateViewIternalTransform(ev);
  856.     }
  857. }
  858.  
  859. //----------------------------------------------------------------------------------------
  860. // FW_CSuperView::PrivAcquireViewInternalTransform
  861. //----------------------------------------------------------------------------------------
  862.  
  863. ODTransform* FW_CSuperView::PrivAcquireViewInternalTransform(Environment* ev) const
  864. {
  865.     FW_CSuperView* self = (FW_CSuperView*)this;
  866.     if (fInternalTransform == NULL)
  867.     {
  868.         if (IsScrolling(ev))
  869.         {
  870.             FW_CFrame* frame = GetFrame(ev);
  871.             FW_CPoint contentViewOffset = frame->PrivGetContentViewOffset(ev); 
  872.             
  873.             self->fInternalTransform = FW_CopyAndRelease(ev, frame->AcquireInternalTransform(ev));
  874.             self->fInternalTransform->MoveBy(ev, (ODPoint*)&(-contentViewOffset));
  875.                     
  876.             FW_CPoint frameInternalTransformOffset, frameInternalTransformScale;
  877.             self->fInternalTransform->GetPreScaleOffset(ev, (ODPoint*)&frameInternalTransformOffset);
  878.             self->fInternalTransform->GetScale(ev, (ODPoint*)&frameInternalTransformScale);
  879.             if (!IsScrollingInX(ev))
  880.             {
  881.                 frameInternalTransformOffset.x = FW_kFixed0;
  882.                 frameInternalTransformScale.x = FW_kFixedPos1;
  883.             }
  884.             if (!IsScrollingInY(ev))
  885.             {
  886.                 frameInternalTransformOffset.y = FW_kFixed0;
  887.                 frameInternalTransformScale.y = FW_kFixedPos1;
  888.             }
  889.             self->fInternalTransform->SetOffset(ev, (ODPoint*)&frameInternalTransformOffset);
  890.             self->fInternalTransform->ScaleBy(ev, (ODPoint*)&frameInternalTransformScale);
  891.         }
  892.         else
  893.         {
  894.             self->fInternalTransform = ::FW_NewODTransform(ev);
  895.         }
  896.     }
  897.     
  898.     fInternalTransform->Acquire(ev);
  899.     return fInternalTransform;
  900. }
  901.  
  902. //----------------------------------------------------------------------------------------
  903. // FW_CSuperView::PrivAcquireContentScrollShape
  904. //----------------------------------------------------------------------------------------
  905.  
  906. void FW_CSuperView::PrivAcquireContentScrollShape(Environment* ev,
  907.                                                 FW_Boolean horizontalScroll, 
  908.                                                 FW_Boolean verticalScroll,
  909.                                                 ODShape* scrollShape) const
  910. {
  911.     //     Note: If I am scrolling it means that no other subviews can scroll. This is 'limitation'
  912.     //    of ODF because there is only one Internal transform in the ODFrame
  913.     if (IsScrolling(ev))
  914.     {
  915.         if (!IsContentView(ev) && IsVisible(ev))    // ContentView already in scrollShape. See FW_CScroller::AcquireContentScrollShape
  916.         {
  917.             if ((verticalScroll && IsScrollingInY(ev)) || (horizontalScroll && IsScrollingInX(ev)))
  918.             {        
  919.                 FW_CAcquiredODShape aqScrollShape = ::FW_NewODShape(ev, FW_CRect(FW_kZeroPoint, GetSize(ev)));
  920.                 ViewToFrame(ev, aqScrollShape);
  921.             
  922.                 scrollShape->Union(ev, aqScrollShape);
  923.             }
  924.         }
  925.     }
  926.     else
  927.     {
  928.         // ----- Look further -----
  929.         FW_CViewIterator ite(this);
  930.         for (FW_CView* subview = ite.First(); ite.IsNotComplete(); subview = ite.Next())
  931.         {
  932.             subview->PrivAcquireContentScrollShape(ev, horizontalScroll, verticalScroll, scrollShape);
  933.         }
  934.     }
  935. }
  936.  
  937.