home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / Framewrk / FWViews / FWView.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  36.3 KB  |  1,172 lines  |  [TEXT/MPS ]

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