NodeClipViewController Class Reference

ClipView controller node. This is the node which does all the hard work with respect to clipview functionality. Initially at least, it is really a more-or-less normal group, with special rendering qualities. The bottom-most (in a z-order sense) NodeRenderableInk in the group is rendered, then its path is used to create a clipping region, into which all other members of the group are rendered. More...

#include <ndclpcnt.h>

Inheritance diagram for NodeClipViewController:

NodeGroup NodeCompound NodeRenderableInk NodeRenderableBounded NodeRenderable Node CCObject SimpleCCObject List of all members.

Public Member Functions

 NodeClipViewController ()
 Default constructor.
 NodeClipViewController (Node *pContextNode, AttachNodeDirection Direction, BOOL Locked=FALSE, BOOL Mangled=FALSE, BOOL Marked=FALSE, BOOL Selected=FALSE)
 This method initialises the node and links it to pContextNode in the direction specified by Direction. All necessary tree links are updated. Most of the work is carried out by base constructors.
 ~NodeClipViewController ()
 Destructor.
virtual void GetDebugDetails (StringBase *pStr)
 Get Debug-tree details for this node. In the case of NCVC, we output our current clipping-path data. Notes: Only _implemented_ in DEBUG builds.
virtual BOOL IsANodeClipViewController () const
virtual DocRect GetBoundingRect (BOOL DontUseAttrs=FALSE, BOOL HitTest=FALSE)
 Find this node's bounding rectangle. If the rectangle is known to be valid then it is simply returned. If IsBoundingRectValid() is FALSE then the rect is recalculated before it is returned and the validity flag reset.
virtual DocRect GetBlobBoundingRect ()
 Get this NCVC's bounding rectangle when its blobs are drawn. See also: GetBoundingRect();.
virtual DocRect GetEorDragBoundingRect ()
 The rectangle calculated is the union of EorDragBoundingRect()'s for each of our keyhole nodes.
virtual SubtreeRenderState RenderSubtree (RenderRegion *pRender, Node **ppNextNode=NULL, BOOL bClip=TRUE)
 Called by the main rendering loop before this node's children are rendered, usually to allow us to muck around with how we want our children to render.
virtual void RenderEorDrag (RenderRegion *pRender)
 Render this node as eor-blobs into the given render region.
virtual void RenderEorDragSelectedChildren (Node *pParent, RenderRegion *pRender)
virtual BOOL ChildrenAreEorDragRenderedByMe ()
 Tells everyone else that I want to be responsible for rendering the drag blobs for my children.
virtual void RenderTinyBlobs (RenderRegion *pRender)
 Render our tiny-blob. This consists of a solitary blob at the top-left of our bounding rect.
virtual void RenderToolObjectBlobs (RenderRegion *pRender)
 Render our tool-object blobs.
virtual void PreExportRender (RenderRegion *pRender)
 Starts exporting a clipview group - basically writes a 'q' token out.
virtual BOOL ExportRender (RenderRegion *pRender)
 Finishes exporting a clipview group - basically write a 'Q' token out.
virtual BOOL OnClick (DocCoord dcClickPos, ClickType cType, ClickModifiers cMods, Spread *pSpread)
 Handle any click-messages passed to us from a tool, eg if we want to handle clicks on our object or tool-object blobs. Currently, you can click on an NCVC tool-object blob and either select its keyhole node, or select everything *except* its keyhole node. At some point in future, you will also be able to directly drag everything except the keyhole node (instead of clicking once to select, _then_ dragging).
virtual BOOL CanBecomeA (BecomeA *pBecomeA)
 This method is used by the convert to shapes operation. It determines whether this node or any of its children can convert themselves into a pClass Node.
virtual BOOL DoBecomeA (BecomeA *pBecomeA)
 Turn this node into another node of a particular type. This method implements make-shapes functionality, which basically means turning itself and its children into paths. Don't hold your breath if you ask it to turn into anything else...
virtual NodeGroupBecomeAGroup (UndoableOperation *pUndoOp)
 We are sometimes required to turn ourself into a normal group node, and that is exactly what this method does. If an UndoOp is supplied then it is done in an undoable fashion but it must also work non-undoably if a NULL op pointer is passed in.
virtual BOOL GroupCanTransformCached (TransformBase &Trans) const
virtual BOOL AllowOp (ObjChangeParam *pParam, BOOL SetOpPermissionState=TRUE, BOOL DoPreTriggerEdit=TRUE)
 This is the way to ask a node if you can do an op to it.
virtual ChangeCode OnChildChange (ObjChangeParam *pParam)
 Used to notify this node of changes to its children, so that if required it can update itself. This forms part of the AllowOp / UpdateChangedNodes mechanism.
virtual String Describe (BOOL Plural, BOOL Verbose)
 Get a string description, for use in menus and infobar etc.
virtual UINT32 GetNodeSize () const
 Obtain the size of a NodeClipViewController object.
void Transform (TransformBase &Trans)
 Perform a transformation on this node.
virtual BOOL WritePreChildrenWeb (BaseCamelotFilter *pFilter)
 Writes this node out to a camelot document.
virtual BOOL WritePreChildrenNative (BaseCamelotFilter *pFilter)
 Writes this node out to a camelot document.
virtual BOOL PostImport ()
 Performs any necessary post-processing once the object has been read in from a file.
virtual BOOL IsController ()
NodeClipViewGetClipView (BOOL ReportErrors=TRUE)
 Get this controller's clipview node.
PathGetKeyholePath ()
BOOL OwnsAsKeyholeNode (const Node *pTestNode)
 Test whether the given node is a keyhole node for this NCVC.
virtual void PolyCopyNodeContents (NodeRenderable *pNodeCopy)
 Polymorphically copies the contents of this node to another.

Static Public Member Functions

static INT32 EstimatePathFlatness ()
 Return an estimation of how flat paths need to be for ClipView groups, based on the current document's zoom factor. A default value will be returned if there is no current document.

Static Public Attributes

static const INT32 CLIPVIEW_TOLERANCE
static const INT32 CLIPVIEW_SOURCEFLATNESS
static const INT32 CLIPVIEW_CLIPFLATNESS = 50

Protected Member Functions

virtual void RenderClipViewBlobs (RenderRegion *pRegion)
 Render the blobs specifically used by ClipView groups. These are currently as follows: 1. A keyhole-selection blob, which is rendered at the top-left of our bounding rectangle. 2. A select-contained-objects blob, which is rendered in the centre of the group's bounding rectangle.
virtual BOOL HandleKeyholeBlobClick (ClickType cType)
 Handler for what happens when the user clicks on our keyhole-select blob.
virtual BOOL HandleContentsBlobClick (ClickType cType)
 Handler for what happens when the user clicks on our contents-select blob.
virtual NodeSimpleCopy ()
 Copy this node.
void CopyNodeContents (NodeClipViewController *pNodeCopy)
 Copy this node's contents into pNodeCopy.

Private Member Functions

 CC_DECLARE_DYNCREATE (NodeClipViewController)
BOOL KeyholeDoBecomeA (BecomeA *pBecomeA)
BOOL MakeShapeAndLine (NodePath *pNodePath, BecomeA *pBecomeA, BOOL bClipToKeyhole)
BOOL InsertClippedNode (NodePath *pNewNode, NodePath *pDestNode, AttachNodeDirection Direction, UndoableOperation *pUndoOp, BOOL bClipToKeyhole)
BOOL PassBackClippedNode (NodePath *pNewNode, BecomeA *pBecomeA, BOOL bClipToKeyhole)
BOOL InkHasClearLineColour (NodeRenderableInk *pInkNode)
 Test whether the line colour of the given NodeRenderableInk is transparent.
BOOL RemoveInkLineWidth (NodeRenderableInk *pInk)
 Make the outline of the given node transparent and set its line width to 0.
BOOL CopyInkFillColourFromLine (NodeRenderableInk *pInk)
 Obtain the line colour of the given NodeRenderableInk and re-apply it as its new fill colour.
BOOL CopyInkTransparencyFromLine (NodeRenderableInk *pInk)
 Obtain the line transparency of the given NodeRenderableInk and re-apply it as a new flat transparency.
BOOL UpdateKeyholePath ()
 Update our cached outline for our keyhole node. Note that this method only tries to update the keyhole path if it is marked as invalid. If it is already valid, you just get TRUE back. It will also only re-mark the keyhole as valid if it successfully updates the keyhole cache.
BOOL IsKeyholeValid () const
void MarkKeyholeValid ()
void MarkKeyholeInvalid ()

Private Attributes

Path m_KeyholePath
BOOL m_fKeyholeValid
DocRect m_drKeyholeBlobRect
DocRect m_drContentsBlobRect

Friends

class NodeClipView
class UpdateCachedKeyholePathAction
void OpApplyClipView::Do (OpDescriptor *pOpDesc)

Detailed Description

ClipView controller node. This is the node which does all the hard work with respect to clipview functionality. Initially at least, it is really a more-or-less normal group, with special rendering qualities. The bottom-most (in a z-order sense) NodeRenderableInk in the group is rendered, then its path is used to create a clipping region, into which all other members of the group are rendered.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/01/2000
Notes: This is how you create a ClipView group in the tree:

1. Set up the tree structure (ignoring attributes):

NCVC | |--{ Keyhole }--{ NCV }--{ Clipped Node N1 }--{ N2 }-- - etc.

2. Call the NCVC's UpdateKeyholePath() method. This method should really be public, but is not, to emphasize that you shouldn't just call it from anywhere, as it also marks the cached keyhole path as valid. To invalidate the cache (you shouldn't usually need to), you must call MarkKeyholeValid(), or if you need update on undo/redo, invoke an UpdateCachedKeyholePathAction.

3. Call the NCVC's InvalidateBoundingRect() method. See also:

Definition at line 146 of file ndclpcnt.h.


Constructor & Destructor Documentation

NodeClipViewController::NodeClipViewController  ) 
 

Default constructor.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 January 2000
Returns:
Errors: See also:

Definition at line 170 of file ndclpcnt.cpp.

00170                                                : NodeGroup()
00171 {
00172     // state initialisation.
00173     m_KeyholePath.Initialise();
00174     MarkKeyholeInvalid();
00175 }

NodeClipViewController::NodeClipViewController Node pContextNode,
AttachNodeDirection  Direction,
BOOL  Locked = FALSE,
BOOL  Mangled = FALSE,
BOOL  Marked = FALSE,
BOOL  Selected = FALSE
 

This method initialises the node and links it to pContextNode in the direction specified by Direction. All necessary tree links are updated. Most of the work is carried out by base constructors.

PREV Attach node as a previous sibling of the context node. NEXT Attach node as a next sibling of the context node. FIRSTCHILD Attach node as the first child of the context node. LASTCHILD Attach node as a last child of the context node.

Locked is node locked? Mangled is node mangled? Marked is node marked? Selected is node selected?

Returns:
Errors: An ENSURE error will occur if pContextNode is NULL. See also:

Definition at line 211 of file ndclpcnt.cpp.

00217                         : NodeGroup(pContextNode, Direction,
00218                                     Locked, Mangled, Marked, Selected) 
00219 {
00220     // state initialisation.
00221     m_KeyholePath.Initialise();
00222     MarkKeyholeInvalid();
00223 }

NodeClipViewController::~NodeClipViewController  ) 
 

Destructor.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 January 2000
Returns:
Errors: See also:

Definition at line 238 of file ndclpcnt.cpp.

00239 {
00240     m_KeyholePath.ClearPath();
00241 }


Member Function Documentation

BOOL NodeClipViewController::AllowOp ObjChangeParam pParam,
BOOL  SetOpPermissionState = TRUE,
BOOL  DoPreTriggerEdit = TRUE
[virtual]
 

This is the way to ask a node if you can do an op to it.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 19/01/2000
Date:
3/02/95
Parameters:
pParam = describes the way an op wants to change the node [INPUTS] SetOpPermissionState = if TRUE the Op permission state of this node will be set according to the outcome of the call DoPreTriggerEdit = if TRUE then calls NameGallery::PreTriggerEdit. Must* be TRUE if the calling Op may make any nodes change their bounds, eg move, line width, cut. Use TRUE if unsure.
- [OUTPUTS]
Returns:
TRUE means the node and all its parents are happy with this op, FALSE means don't do it
The ObjChangeParam class contains flags that describe how it will change the node

For example, the op could change the node's appearence (e.g. attr application, editing a path), replace the node with another node (e.g. because it uses hidden nodes to hide the original and put another node in its place, or "make shapes"), delete the node (e.g. the delete and cut ops), etc.

This function gives the node a chance to say NO. It also gives the parents a chance to say no too. E.g. a blend node will allow itself to be deleted, but it will NOT allow a child of itself to be deleted).

This call should only be made on selected, or parents of selected, nodes. It makes a decision as a straight node if it is selected. It makes a decision as a parent if it has selected children.

E.g. NodeBlend::AllowOp(...op delete...) if the node is selected, then it will return TRUE (parents permitting), i.e. I can be deleted if the node is a parent of selected it will return FALSE (i.e. can't delete children of blends).

So when the node is selected, you are asking the node if you can do the op to it. When the node is a parent of a selected node, you are asking if you can do the op to one of its children.

If the 'SetOpPermissionState' param is TRUE, the following indented lines applies: The node's op permission state is set according to the result of this function.

If TRUE is returned, then the node's op permission state will be left unchanged. AND the parent's op permission state will be set to PERMISSION_ALLOWED

if FALSE is returned, then the node's op permission state will be PERMISSION_DENIED, AND all it's parents (up to the layer) will be set to PERMISSION_DENIED

Also, all parents of this node are called via their AllowOp() func with the same state as this node. This means that after this call, you can guarantee that all of its parents will have either a PERMISSION_DENIED or PERMISSION_ALLOWED state.

Note: Even if this node tries to set all it's parents to have a PERMISSION_DENIED state, if any of its parents have previously been set to PERMISSION_ALLOWED they will remain in that state (see SetOpPermission()). Why? Well, it is possible for a parent node to have one child with a PERMISSION_DENIED and another child with a PERMISSION_ALLOWED. It this state the parent MUST be in state PERMISSION_ALLOWED, because at least one of its children will allow the op to happen to it.

So, after this call: The op permission state for this node will be either left unchanged (and therefore remain PERMISSION_UNDEFINED), or PERMISSION_DENIED.

The parent's op permission state will be either PERMISSION_ALLOWED, or PERMISSION_DENIED.

This is so UndoableOperation::UpdateChangedNodes() will only call OnChildChange() on parent nodes, because it only calls that func for nodes that have an op permission state of PERMISSION_ALLOWED.

See also:
GetOpPermission(),SetOpPermission();

Reimplemented from Node.

Definition at line 2073 of file ndclpcnt.cpp.

02075 {
02076     // input validation.
02077     ERROR2IF(pParam == NULL, FALSE, "NULL pParam");
02078 
02079     // call our base class' AllowOp().
02080     BOOL allowed = NodeGroup::AllowOp(pParam, SetOpPermissionState, DoPreTriggerEdit);
02081 
02082     // Slight misuse of the AllowOp/OnChildChange system, as that says that only our
02083     // children are meant to set our permission to PERMISSION_ALLOWED.
02084     // This will ensure that our OnChildChange() method is called after the op has finished,
02085     // allowing us to update our keyhole path after any changes.
02086     if (allowed && SetOpPermissionState)
02087         SetOpPermission(PERMISSION_ALLOWED, TRUE);
02088 
02089     return allowed;
02090 }

NodeGroup * NodeClipViewController::BecomeAGroup UndoableOperation pUndoOp  )  [virtual]
 

We are sometimes required to turn ourself into a normal group node, and that is exactly what this method does. If an UndoOp is supplied then it is done in an undoable fashion but it must also work non-undoably if a NULL op pointer is passed in.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
07 March 2000
Parameters:
pUndoOp pointer to an UndoableOperation [INPUTS]
[OUTPUTS] 
Returns:
TRUE if successful, FALSE otherwise.

Reimplemented from NodeCompound.

Definition at line 1891 of file ndclpcnt.cpp.

01892 {
01893     // ok!
01894     BOOL ok = TRUE;
01895 
01896     NodeGroup*      pGroup      = NULL;
01897     NodeClipView*   pClipView   = GetClipView(FALSE);
01898 
01899     // hide our clipview node if it exists.
01900     if (ok) ok = (pClipView != NULL);
01901     if (ok)
01902     {
01903         if (pUndoOp)
01904             ok = pUndoOp->DoHideNode(pClipView, TRUE);
01905         else
01906         {
01907             pClipView->CascadeDelete();
01908             delete pClipView;       // Scary!
01909         }
01910     }
01911 
01912     // call our base class to turn into a group.
01913     if (ok) pGroup = NodeGroup::BecomeAGroup(pUndoOp);
01914 
01915     return pGroup;
01916 }

BOOL NodeClipViewController::CanBecomeA BecomeA pBecomeA  )  [virtual]
 

This method is used by the convert to shapes operation. It determines whether this node or any of its children can convert themselves into a pClass Node.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 January 2000
Parameters:
pClass pointer to the runtime class of the node type to convert to. [INPUTS] pNumObjects pointer in which to return the number of objects of type pClass which would be created under a DoBecomeA(). Can be NULL, in which case we only return success or failure.
Returns:
TRUE if we can change ourself or our children into a pClass type of node, FALSE otherwise.
The number returned in pNumObjects (if it's not NULL) should exactly equal the total number of pClass objects which would be created by the appropriate call to DoBecomeA on this node. It should NOT contain any additional objects produced, such as group objects or attributes created by the conversion.

Unfortunately, in the case of NodeClipViewController this is impossible without changing the CanBecomeA mechanism or the rules by which NCVC converts its children to shapes. The function for number of shapes is recursive:

SetOfKidPaths = {all paths which our children return under DoBecomeA} NumObjects = SetOfKidPaths + #(members of SetOfKidPaths with non-zero line width)

, which would require CanBecomeA to return numbers of objects returned with and without zero-width outlines.

We _can_ set upper and lower bounds on the number of objects we'll return - either all of our children will have line widths, or none of them will, so NodeGroup::CanBecomeA will return a lower bound and twice that number will give an upper bound. We choose to return the upper bound, for ease of use with DMc's code.

Returns:
Errors: See also:

Reimplemented from NodeCompound.

Definition at line 993 of file ndclpcnt.cpp.

00994 {
00995     // to convert to paths we'll need to convert each of our children.
00996 
00997     // we cannot return an accurate number of created objects unless we DoBecomeA on our
00998     // children. we _can_ however return a minimum or maximum number of objects.
00999     // David Mc's contour/bevel code does not like being passed a minimum, so we'll
01000     // give him a maximum instead.
01001 
01002     // minimum = number of paths our children will return.
01003     // maximum = twice the number of paths our children will return.
01004     UINT32 GroupNumObjects = pBecomeA->GetCount();
01005     BOOL bCanDo = NodeGroup::CanBecomeA(pBecomeA);
01006     pBecomeA->AddCount(pBecomeA->GetCount()-GroupNumObjects);   // Add the same count again to double it
01007 
01008     return bCanDo;
01009 }

NodeClipViewController::CC_DECLARE_DYNCREATE NodeClipViewController   )  [private]
 

BOOL NodeClipViewController::ChildrenAreEorDragRenderedByMe  )  [virtual]
 

Tells everyone else that I want to be responsible for rendering the drag blobs for my children.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
04 April 2000
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:
TRUE.

Errors: See also:

Reimplemented from NodeRenderableInk.

Definition at line 646 of file ndclpcnt.cpp.

00647 {
00648     return TRUE;
00649 }

BOOL NodeClipViewController::CopyInkFillColourFromLine NodeRenderableInk pInk  )  [private]
 

Obtain the line colour of the given NodeRenderableInk and re-apply it as its new fill colour.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
09 March 2000
Parameters:
pInk pointer to the NodeRenderableInk to work on. [INPUTS]
pInk's fill colour should match its line colour. [OUTPUTS]
Returns:
TRUE if successful, FALSE otherwise.
NOTE: This method is *not* undoable!

Returns:
Errors: ERROR2 returning FALSE if pInk is NULL. See also:

Definition at line 1707 of file ndclpcnt.cpp.

01708 {
01709     ERROR2IF(pInk == NULL, FALSE, "NULL parameter(s)");
01710 
01711     NodeAttribute *pLineColourAttr = NULL;
01712     DocColour* pLineColour = NULL;
01713 //  DocColour* pFillColour = NULL;
01714     Node* pOldFill = NULL;
01715     AttrFlatColourFill* pNewFlatFill = NULL;
01716 
01717     // obtain the line-colour attribute and its actual colour value.
01718     pInk->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeColour), &pLineColourAttr);
01719     // DY: bodge to solve problem of creating brushes from clipview objects.  The problem was 
01720     // that we are using an inknode that is not located in a document so it sometimes does
01721     // not have an applied stroke colour, so just return true
01722     
01723     BOOL ok = (pLineColourAttr != NULL);
01724     if (ok)
01725     {
01726         pLineColour = ((AttrStrokeColour*)pLineColourAttr)->GetStartColour();
01727         ok = (pLineColour != NULL);
01728     }
01729     else
01730         return TRUE; // safe return 
01731 
01732     // search the children of the object node for its current colour fill attribute.
01733     if (ok)
01734     {
01735         BOOL bFoundFill = FALSE;
01736         pOldFill = pInk->FindFirstChild();
01737         while (!bFoundFill && pOldFill != NULL)
01738         {
01739             if ( pOldFill->IsAFillAttr() && ((NodeAttribute*)pOldFill)->IsAColourFill() )
01740                 bFoundFill = TRUE;
01741             else
01742                 pOldFill = pOldFill->FindNext();
01743         }
01744     }
01745 
01746     // create a new fill attribute.
01747     if (ok)
01748     {
01749         pNewFlatFill = new AttrFlatColourFill();
01750         ok = (pNewFlatFill != NULL);
01751     }
01752 
01753     // if we were successful, then put it all into the tree and remove any
01754     // previous fill applied.
01755     if (ok)
01756     {
01757         pNewFlatFill->SetStartColour(pLineColour);
01758         pNewFlatFill->AttachNode(pInk, LASTCHILD);
01759         if (pOldFill != NULL)
01760         {
01761             pOldFill->UnlinkNodeFromTree();
01762             delete pOldFill;
01763         }
01764     }
01765 
01766     // ensure we free allocated memory if unsuccessful.
01767     else
01768     {
01769         if (pNewFlatFill != NULL)
01770         {
01771             delete pNewFlatFill;
01772             pNewFlatFill = NULL;
01773         }
01774     }
01775 
01776     return ok;
01777 }

BOOL NodeClipViewController::CopyInkTransparencyFromLine NodeRenderableInk pInk  )  [private]
 

Obtain the line transparency of the given NodeRenderableInk and re-apply it as a new flat transparency.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
20 March 2000
Parameters:
pInk pointer to the NodeRenderableInk to work on. [INPUTS]
pInk should be given the same transparency as its outline. [OUTPUTS]
Returns:
TRUE if successful, FALSE otherwise.
NOTE: This method is *not* undoable!

Returns:
Errors: ERROR2 returning FALSE if pInk is NULL. See also:

Definition at line 1800 of file ndclpcnt.cpp.

01801 {
01802     ERROR2IF(pInk == NULL, FALSE, "NULL parameter(s)");
01803 
01804     NodeAttribute *pLineTranspAttr = NULL;
01805     UINT32* pLineTransp = NULL;
01806 //  UINT32* pFillTransp = NULL;
01807     Node* pOldFill = NULL;
01808     AttrFlatTranspFill* pNewFlatFill = NULL;
01809 
01810     // obtain the line-transparency attribute and its actual transparency value.
01811     pInk->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeTransp), &pLineTranspAttr);
01812     // DY: bodge to solve problem of creating brushes from clipview objects.  The problem was 
01813     // that we are using an inknode that is not located in a document so it sometimes does
01814     // not have an applied stroke transparency, so just return true
01815     
01816     BOOL ok = (pLineTranspAttr != NULL);
01817     if (ok)
01818     {
01819         pLineTransp = ((AttrStrokeTransp*)pLineTranspAttr)->GetStartTransp();
01820         ok = (pLineTransp != NULL);
01821     }
01822     else
01823         return TRUE;
01824 
01825     // search the children of the object node for its current transparency fill attribute.
01826     if (ok)
01827     {
01828         BOOL bFoundFill = FALSE;
01829         pOldFill = pInk->FindFirstChild();
01830         while (!bFoundFill && pOldFill != NULL)
01831         {
01832             if ( pOldFill->IsAFillAttr() && ((NodeAttribute*)pOldFill)->IsATranspFill() )
01833                 bFoundFill = TRUE;
01834             else
01835                 pOldFill = pOldFill->FindNext();
01836         }
01837     }
01838 
01839     // create a new transparency fill attribute.
01840     if (ok)
01841     {
01842         pNewFlatFill = new AttrFlatTranspFill();
01843         ok = (pNewFlatFill != NULL);
01844     }
01845 
01846     // if we were successful, then put it all into the tree and remove any
01847     // previous fill applied.
01848     if (ok)
01849     {
01850         pNewFlatFill->SetStartTransp(pLineTransp);
01851         pNewFlatFill->AttachNode(pInk, LASTCHILD);
01852         if (pOldFill != NULL)
01853         {
01854             pOldFill->UnlinkNodeFromTree();
01855             delete pOldFill;
01856         }
01857     }
01858 
01859     // ensure we free allocated memory if unsuccessful.
01860     else
01861     {
01862         if (pNewFlatFill != NULL)
01863         {
01864             delete pNewFlatFill;
01865             pNewFlatFill = NULL;
01866         }
01867     }
01868 
01869     return ok;
01870 }

void NodeClipViewController::CopyNodeContents NodeClipViewController pNodeCopy  )  [protected]
 

Copy this node's contents into pNodeCopy.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
09 February 2000
Parameters:
pNodeCopy the node to copy our contents into. [INPUTS]
Returns:
Errors: See also: Node::CopyNodeContents()

Definition at line 2497 of file ndclpcnt.cpp.

02498 {
02499     // call base-class implementation; this will also perform necessary validation for us.
02500     NodeGroup::CopyNodeContents(pNodeCopy);
02501 }

String NodeClipViewController::Describe BOOL  Plural,
BOOL  Verbose
[virtual]
 

Get a string description, for use in menus and infobar etc.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 January 2000
Parameters:
Plural whether to pluralise the description. [INPUTS] Verbose short or long version.
Returns:
A string description of this node.

Errors: See also:

Reimplemented from NodeGroup.

Definition at line 2319 of file ndclpcnt.cpp.

02320 {
02321     if (Plural)
02322         return(String(_R(IDS_CLIPVIEW_CONTROLLER_DESCRP)));
02323     else
02324         return(String(_R(IDS_CLIPVIEW_CONTROLLER_DESCRS)));
02325 }

BOOL NodeClipViewController::DoBecomeA BecomeA pBecomeA  )  [virtual]
 

Turn this node into another node of a particular type. This method implements make-shapes functionality, which basically means turning itself and its children into paths. Don't hold your breath if you ask it to turn into anything else...

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 January 2000
Parameters:
pBecomeA pointer to a BecomeA structure containing information about the [INPUTS] required transformation.
This node and its children may be hidden and replaced with other node types [OUTPUTS] representing a similar scene, eg a group of paths.
Returns:
TRUE if successful, FALSE otherwise.
Defined behaviour for ClipView DoBecomeA is that the keyhole nodes will have the DoBecomeA call passed directly on to them. Any nodes which are clipped behave differently. If these nodes have an outline, then it is first split off from them, into a separate, new shape. Both outline shape and original shape are then clipped to the keyhole path and left in the tree or passed back. These nodes will also all have their line width set to zero and their line colour set to transparent.

Notes: If this node cannot locate a full set of attributes (eg it is hidden), you may get strange results from this method.

Karim 14/06/2000 Just added Silhouette functionality to BecomeA. This means that for PASSBACK, the BecomeA object can flag that a silhouette is all that's required, which should hopefully lead to better contouring/bevelling with ClipView. If we're silhouetting, then we pass the BecomeA on to our our keyhole nodes.

Returns:
Errors: ERROR2 if pBecomeA is NULL. See also:

Reimplemented from NodeCompound.

Definition at line 1052 of file ndclpcnt.cpp.

01053 {
01054     // validate input parameter.
01055     ERROR2IF(pBecomeA == NULL, FALSE, "NULL pBecomeA");
01056 
01057     // quit unless we're converting to paths.
01058     ERROR2IF(!pBecomeA->BAPath(), FALSE, "Attempt to convert to other than a path");
01059 
01060     // ensure our keyhole path is up to date.
01061     if (!UpdateKeyholePath())
01062         return FALSE;
01063 
01064     // ok, we do different things depending on what type of BecomeA we are.
01065     switch (pBecomeA->GetReason())
01066     {
01067     case BECOMEA_REPLACE:
01068 // DEBUG
01069 //      TRACEUSER( "Karim", _T("NCVC::DoBecomeA; BECOMEA_REPLACE\n"));
01070         {
01071             // if we're doing a BECOMEA_REPLACE, we need an op.
01072             UndoableOperation* pUndoOp = pBecomeA->GetUndoOp();
01073 //          ERROR2IF(pUndoOp == NULL, FALSE, "Need an UndoOp with BECOMEA_REPLACE");
01074 
01075             // local variables.
01076             Node*               pKid        = NULL;
01077             Node*               pNextKid    = NULL;
01078 //          Node*               pAfterKey   = NULL;
01079 //          NodeHidden*         pHiddenKey  = NULL;
01080             Node*               pClipView   = GetClipView();
01081             BOOL ok = (pClipView != NULL);
01082 
01083             // localise attributes.
01084             if (ok)
01085             {
01086                 if (pUndoOp)
01087                     ok = pUndoOp->DoLocaliseCommonAttributes(this);
01088                 else
01089                     LocaliseCommonAttributes();
01090             }
01091 
01092             // first, DoBecomeA on our children.
01093             if (ok)
01094             {
01095                 // if we only have to get a silhouette, then DoBecomeA on our keyhole nodes,
01096                 // and hide the rest of the children.
01097                 if (pBecomeA->DoSilhouette())
01098                 {
01099                     pKid = FindFirstChild();
01100                     while (ok && pKid != pClipView)
01101                     {
01102                         if (pKid->IsAnObject())
01103                             ok = pKid->DoBecomeA(pBecomeA);
01104                         pKid = pKid->FindNext();
01105                     }
01106                     pKid = pClipView->FindNext();
01107                     while (ok && pKid != NULL)
01108                     {
01109                         pNextKid = pKid->FindNext();
01110                         if (pUndoOp)
01111                             ok = pUndoOp->DoHideNode(pKid, TRUE);
01112                         else
01113                         {
01114                             pKid->CascadeDelete();
01115                             delete pKid;
01116                         }
01117                         pKid = pNextKid;
01118                     }
01119                 }
01120 
01121                 // otherwise, DoBecomeA on all of our children.
01122                 else
01123                 {
01124                     pKid = FindFirstChild();
01125                     while (ok && pKid != NULL)
01126                     {
01127                         pNextKid = pKid->FindNext();
01128                         ok = pKid->DoBecomeA(pBecomeA);
01129                         pKid = pNextKid;
01130                     }
01131                 }
01132             }
01133 
01134             // now separate the outline and fill of each of our non-keyhole children out into
01135             // new ink-nodes, clipped to our keyhole path. non-keyhole means all nodes to the 
01136             // right of our NodeClipView, and we do this depth-first, so we don't miss paths
01137             // hidden underneath group hierarchies.
01138 
01139             // unfortunately, paths can sometimes be completely clipped out of the tree. if
01140             // this happens then we could end up with empty groups (not ideal behaviour), so
01141             // we need to check for these and if we find any then we hide them.
01142             if (ok && !pBecomeA->DoSilhouette())
01143             {
01144                 BOOL bFinishedAGroup = FALSE;
01145                 pKid = pClipView->FindNextDepthFirst(this);
01146                 while (ok && pKid != NULL && pKid != this)
01147                 {
01148                     pNextKid = pKid->FindNextDepthFirst(this);
01149 
01150                     // if we're about to do the last kid in a group, remember this for later.
01151                     if (IS_A(pNextKid, NodeGroup)/*->IsAGroup()*/ && pNextKid == pKid->FindParent())
01152                         bFinishedAGroup = TRUE;
01153                     else
01154                         bFinishedAGroup = FALSE;
01155 
01156                     // if this one's a NodePath, process it.
01157                     if (pKid->IsNodePath())
01158                         ok = MakeShapeAndLine((NodePath*)pKid, pBecomeA, TRUE);
01159 
01160                     // if we've just finished a group, we need to check whether we left it
01161                     // containing any ink-children - if not, we need to hide it.
01162                     if (ok && bFinishedAGroup)
01163                     {
01164                         BOOL bFoundInkKids = FALSE;
01165                         Node* pInkKid = pNextKid->FindFirstChild();
01166                         while (!bFoundInkKids && pInkKid != NULL)
01167                         {
01168                             bFoundInkKids = pInkKid->IsAnObject();
01169                             pInkKid = pInkKid->FindNext();
01170                         }
01171                         if (!bFoundInkKids)
01172                         {
01173                             // move to the next depth-first node and hide the group.
01174                             pKid = pNextKid;
01175                             pNextKid = pKid->FindNextDepthFirst(this);
01176                             if (pUndoOp)
01177                                 ok = pUndoOp->DoHideNode(pKid, TRUE);
01178                             else
01179                             {
01180                                 pKid->CascadeDelete();
01181                                 delete pKid;
01182                             }
01183                         }
01184                     }
01185 
01186                     pKid = pNextKid;
01187                 }
01188             }
01189 
01190             // make sure that all remaining common attributes are factored back out.
01191             if (ok)
01192             {
01193                 if (pUndoOp)
01194                     ok = pUndoOp->DoFactorOutCommonChildAttributes(this);
01195                 else
01196                     FactorOutCommonChildAttributes();
01197             }
01198 
01199             // mighty-morph into a group (ClipView nodes hidden and replaced by a group node).
01200             if (ok) ok = (BecomeAGroup(pUndoOp) != NULL);
01201 
01202             // return the result of our deliberations.
01203             return ok;
01204         }
01205         break;
01206 
01207     case BECOMEA_PASSBACK:
01208 // DEBUG
01209 //      TRACEUSER( "Karim", _T("NCVC::DoBecomeA; BECOMEA_PASSBACK\n"));
01210         {
01211             // local variables.
01212             Node *          pKid        = NULL;
01213             NodeGroup *     pContainer  = NULL;
01214 //          NodeHidden *    pHiddenKey  = NULL;
01215             NodeClipView *  pClipView   = GetClipView();
01216             BOOL ok = (pClipView != NULL);
01217 
01218             // passback all our keyhole nodes directly.
01219             if (ok)
01220             {
01221                 pKid = FindFirstChild();
01222                 while (ok && pKid != pClipView)
01223                 {
01224                     if (pKid->IsAnObject())
01225                         ok = pKid->DoBecomeA(pBecomeA);
01226                     pKid = pKid->FindNext();
01227                 }
01228             }
01229 
01230             // quit now if all that is required is our silhouette,
01231             // as that is fully defined by our keyhole nodes.
01232             if (pBecomeA->DoSilhouette())
01233                 return ok;
01234 
01235             // make shape copies of all our non-keyhole kids (which are right-siblings
01236             // of our clipview node) and put the result into a container node.
01237             if (ok)
01238             {
01239                 pContainer = new NodeGroup();
01240                 ok = (pContainer != NULL);
01241             }
01242             if (ok)
01243             {
01244                 CopyBecomeA refCopyBecomeA(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath), NULL);
01245                 refCopyBecomeA.SetContextNode(pContainer);
01246                 pKid = pClipView->FindNext();
01247                 while (ok && pKid != NULL)
01248                 {
01249                     if (pKid->CanBecomeA(&refCopyBecomeA))
01250                         ok = pKid->DoBecomeA(&refCopyBecomeA);
01251 
01252                     pKid = pKid->FindNext();
01253                 }
01254             }
01255 
01256             // convert the outlines of these shapes into independent shapes,
01257             // clip the output to our keyhole path and pass it all back.
01258             if (ok)
01259             {
01260                 pKid = pContainer->FindFirstDepthFirst();
01261                 while (ok && pKid != NULL)
01262                 {
01263                     if (pKid->IsNodePath())
01264                         ok = MakeShapeAndLine((NodePath*)pKid, pBecomeA, TRUE);
01265 
01266                     pKid = pKid->FindNextDepthFirst(pContainer);
01267                 }
01268             }
01269 
01270             // dispose of our child-shapes when we've finished with them.
01271             if (pContainer != NULL)
01272             {
01273                 pContainer->CascadeDelete();
01274                 delete pContainer;
01275                 pContainer = NULL;
01276             }
01277 
01278             return ok;
01279         }
01280         break;
01281 
01282     default:
01283         ERROR2(FALSE, "Unrecognised reason in convert-to-shapes");
01284         break;
01285     }
01286 
01287     return FALSE;
01288 }

INT32 NodeClipViewController::EstimatePathFlatness  )  [static]
 

Return an estimation of how flat paths need to be for ClipView groups, based on the current document's zoom factor. A default value will be returned if there is no current document.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
09 March 2000
Returns:
Flatness required for paths used by ClipView.
According to DMc, flatness is the max straight line length when a curve is approximated - smaller is smoother. We should aim for a flatness of ~0.1 pixels.
Returns:
Errors: See also:

Definition at line 2039 of file ndclpcnt.cpp.

02040 {
02041     // we use a default flatness of 75 millipoints, as this is 0.1 pixels at 100% zoom.
02042     // (100% zoom = 96 dpi @ 72000 mp per inch ==> 750 mp per dot)
02043     static const double DefaultFlatness = 75.0;
02044     DocView* pView      = DocView::GetCurrent();
02045     double ZoomFactor   = (pView == NULL) ? 1 : pView->GetZoomFactor();
02046     INT32 Flatness      = (INT32)(ZoomFactor * DefaultFlatness);
02047     return (Flatness == 0) ? 1 : Flatness;
02048 }

BOOL NodeClipViewController::ExportRender RenderRegion pRegion  )  [virtual]
 

Finishes exporting a clipview group - basically write a 'Q' token out.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
8th November 2000
Parameters:
pRegion - the RenderRegion we're exporting to. [INPUTS]
Returns:
Errors: See also: Node::ExportRender()

Reimplemented from NodeGroup.

Definition at line 2576 of file ndclpcnt.cpp.

02577 {
02578 #ifdef DO_EXPORT
02579     if (pRegion->IsKindOf(CC_RUNTIME_CLASS(EPSRenderRegion)))
02580     {
02581         // Output "end group" token
02582         EPSExportDC *pDC = (EPSExportDC *) pRegion->GetRenderDC();
02583         pDC->OutputToken(_T("Q"));
02584         pDC->OutputNewLine();
02585         
02586         // Tell caller we rendered ourselves ok
02587         return TRUE;
02588     }
02589 PORTNOTE("epsfilter", "Removed use of CMXRenderRegion")
02590 #ifndef EXCLUDE_FROM_XARALX
02591     else if(pRegion->IsKindOf(CC_RUNTIME_CLASS(CMXRenderRegion)))
02592     {
02593         // mark start of a group...
02594         CMXExportDC *pDC = (CMXExportDC *) pRegion->GetRenderDC();
02595         pDC->EndGroup();
02596 
02597         return TRUE;
02598     }
02599 #endif
02600 #endif
02601     // Render this node in the normal way
02602     return FALSE;
02603 }

DocRect NodeClipViewController::GetBlobBoundingRect  )  [virtual]
 

Get this NCVC's bounding rectangle when its blobs are drawn. See also: GetBoundingRect();.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 January 2000
Returns:
The bounding rectangle of this node with its blobs drawn.

Reimplemented from NodeGroup.

Definition at line 409 of file ndclpcnt.cpp.

00410 {
00411     // we return our bounding rectangle, inflated to account for whichever blobs we're
00412     // currently showing.
00413     DocRect drBounds = GetBoundingRect();
00414     BlobManager* pBlobMgr = GetApplication()->GetBlobManager();
00415     if (pBlobMgr != NULL)
00416     {
00417         DocCoord Low    = drBounds.LowCorner();
00418         DocCoord High   = drBounds.HighCorner();
00419 
00420         BlobStyle bsBlobs = pBlobMgr->GetCurrentInterest(TRUE);
00421         if (bsBlobs.Object)
00422         {
00423             DocRect drBlobSize;
00424             pBlobMgr->GetBlobRect(Low, &drBlobSize);
00425             drBounds = drBounds.Union(drBlobSize);
00426             pBlobMgr->GetBlobRect(High, &drBlobSize);
00427             drBounds = drBounds.Union(drBlobSize);
00428             pBlobMgr->GetBlobRect(DocCoord(Low.x, High.y), &drBlobSize);
00429             drBounds = drBounds.Union(drBlobSize);
00430             pBlobMgr->GetBlobRect(DocCoord(High.x, Low.y), &drBlobSize);
00431             drBounds = drBounds.Union(drBlobSize);
00432         }
00433 
00434         if (bsBlobs.Tiny)
00435         {
00436             DocRect drBlobSize;
00437             pBlobMgr->GetBlobRect(DocCoord(Low.x, High.y), &drBlobSize);
00438             drBounds = drBounds.Union(drBlobSize);
00439         }
00440 
00441         if (bsBlobs.ToolObject)
00442         {
00443             DocRect drBlobSize;
00444             pBlobMgr->GetBlobRect(DocCoord(0, 0), &drBlobSize);
00445             drBounds.Inflate(drBlobSize.Width(), drBlobSize.Height());
00446         }
00447     }
00448 
00449     // this well-named method includes the blob-bounds of any child-attrs,
00450     // but only if we're showing fill blobs (!!?!?).
00451     IncludeChildrensBoundingRects(&drBounds);
00452 
00453     return drBounds;
00454 }

DocRect NodeClipViewController::GetBoundingRect BOOL  DontUseAttrs = FALSE,
BOOL  HitTest = FALSE
[virtual]
 

Find this node's bounding rectangle. If the rectangle is known to be valid then it is simply returned. If IsBoundingRectValid() is FALSE then the rect is recalculated before it is returned and the validity flag reset.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 January 2000
Parameters:
DontUseAttrs TRUE of you want to ignore all the node's attributes. [INPUTS] HitTest TRUE if being called during a hit-test.
Returns:
The bounding rectangle of this node.
The bounding rect of a NCVC is the union of the bounds of all its keyhole nodes.

See also: GetBlobBoundingRect().

Reimplemented from NodeGroup.

Definition at line 367 of file ndclpcnt.cpp.

00368 {
00369 // DEBUG:
00370 //  TRACEUSER( "Karim", _T("NCVC::GetBoundingRect\n"));
00371 
00372     // ensure our cached keyhole path is up to date.
00373 //  UpdateKeyholePath();
00374 
00375     // start off with a zeroed bounding rect, and union it with the bounds of all keyhole
00376     // nodes, ie ink-nodes to the left of our NodeClipView.
00377     BoundingRectangle = DocRect(0, 0, 0, 0);
00378     NodeClipView* pClipView = GetClipView();
00379     if (pClipView != NULL)
00380     {
00381         Node* pKeyhole = pClipView->FindPrevious();
00382         while (pKeyhole != NULL)
00383         {
00384             if (pKeyhole->IsAnObject())
00385             {
00386                 IsBoundingRectValid = TRUE;
00387                 BoundingRectangle = BoundingRectangle.Union(((NodeRenderableInk*)pKeyhole)->GetBoundingRect(DontUseAttrs, HitTest));
00388             }
00389             pKeyhole = pKeyhole->FindPrevious();
00390         }
00391     }
00392 
00393     return BoundingRectangle;
00394 }

NodeClipView * NodeClipViewController::GetClipView BOOL  ReportErrors = TRUE  ) 
 

Get this controller's clipview node.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
18 February 2000
Parameters:
ReportErrors if set to FALSE then this method will not ERROR3 if it [INPUTS] cannot find the clipview node.
Returns:
The ClipView node which is associated with this NodeClipViewController, or NULL if unsuccessful.

Errors: ERROR3 if no relevant NodeClipView is found. See also:

Definition at line 288 of file ndclpcnt.cpp.

00289 {
00290     Node* pClipView = FindFirstChild();
00291     while (pClipView != NULL && !pClipView->IsANodeClipView())
00292         pClipView = pClipView->FindNext();
00293 
00294     ERROR3IF(ReportErrors && pClipView == NULL, "NCVC has no ClipView node!");
00295 
00296     return (NodeClipView*)pClipView;
00297 }

void NodeClipViewController::GetDebugDetails StringBase pStr  )  [virtual]
 

Get Debug-tree details for this node. In the case of NCVC, we output our current clipping-path data. Notes: Only _implemented_ in DEBUG builds.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/25/00
Parameters:
pStr ptr to the string to hold the debug output. [INPUTS]
pStr gets our debug output put in it. [OUTPUTS]

Reimplemented from NodeRenderableBounded.

Definition at line 258 of file ndclpcnt.cpp.

00259 {
00260 #ifdef _DEBUG
00261     // Get base class debug info.
00262     NodeGroup::GetDebugDetails(pStr);
00263 
00264     // output the data for our keyhole path.
00265     String_256 TempStr;
00266     (*pStr) += TEXT( "\r\nClipping Path Data\r\n" );
00267     m_KeyholePath.GetDebugDetails(pStr);
00268 #endif
00269 }

DocRect NodeClipViewController::GetEorDragBoundingRect  )  [virtual]
 

The rectangle calculated is the union of EorDragBoundingRect()'s for each of our keyhole nodes.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
03 April 2000
Returns:
The bounding rect of this ClipView group to draw when dragging it around, or a zeroed DocRect if we have no keyhole nodes (a *bad* thing).

Errors: See also:

Reimplemented from NodeGroup.

Definition at line 472 of file ndclpcnt.cpp.

00473 {
00474     // start off with a zeroed bounding rect, and union it with the bounds of all keyhole
00475     // nodes, ie ink-nodes to the left of our NodeClipView.
00476     DocRect drBounds(0, 0, 0, 0);
00477     NodeClipView* pClipView = GetClipView();
00478     if (pClipView != NULL)
00479     {
00480         Node* pKeyhole = pClipView->FindPrevious();
00481         while (pKeyhole != NULL)
00482         {
00483             if (pKeyhole->IsAnObject())
00484                 drBounds = drBounds.Union(((NodeRenderableInk*)pKeyhole)->GetEorDragBoundingRect());
00485 
00486             pKeyhole = pKeyhole->FindPrevious();
00487         }
00488     }
00489 
00490     return drBounds;
00491 }

Path* NodeClipViewController::GetKeyholePath  )  [inline]
 

Definition at line 268 of file ndclpcnt.h.

00268 { return &m_KeyholePath; }

UINT32 NodeClipViewController::GetNodeSize  )  const [virtual]
 

Obtain the size of a NodeClipViewController object.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
02 February 2000
Returns:
The size of the node in bytes.
See also: Node::GetSubtreeSize

Reimplemented from NodeGroup.

Definition at line 2341 of file ndclpcnt.cpp.

02342 {
02343     return sizeof(NodeClipViewController);
02344 }

virtual BOOL NodeClipViewController::GroupCanTransformCached TransformBase Trans  )  const [inline, virtual]
 

Reimplemented from NodeGroup.

Definition at line 209 of file ndclpcnt.h.

00209 {return TRUE;}

BOOL NodeClipViewController::HandleContentsBlobClick ClickType  cType  )  [protected, virtual]
 

Handler for what happens when the user clicks on our contents-select blob.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
23 March 2000
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:
TRUE if we handled the click, FALSE if we passed.
We select all our NodeRenderableInk children *except* for our keyhole node.
Returns:
Errors: See also:

Definition at line 895 of file ndclpcnt.cpp.

00896 {
00897 
00898 // DEBUG
00899 //  TRACEUSER( "Karim", _T("NCVC::HandleContentsBlobClick; cType %s\n"),
00900 //                                                  (cType == CLICKTYPE_DRAG)   ? "DRAG" :
00901 //                                                  (cType == CLICKTYPE_UP)     ? "UP" : "");
00902 
00903     // quit immediately unless it's the selector tool.
00904     Tool* pTool = Tool::GetCurrent();
00905     if (pTool == NULL || pTool->GetID() != TOOLID_SELECTOR)
00906         return FALSE;
00907 
00908     // also quit if we don't like the click type.
00909     if (cType != CLICKTYPE_DRAG && cType != CLICKTYPE_UP)
00910         return FALSE;
00911 
00912     // deselect everything, then select all non-keyhole nodes,
00913     // ie all nodes which are right-siblings of our clipview node.
00914     BOOL bChangedSelection  = FALSE;
00915     Node* pFirstKid         = NULL;
00916     NodeClipView* pClipView = GetClipView();
00917     if (pClipView != NULL)
00918     {
00919         Node* pKid = pClipView->FindNext();
00920         while (pKid != NULL)
00921         {
00922             if (pKid->IsAnObject())
00923             {
00924                 if (!bChangedSelection)
00925                 {
00926                     DeselectAll();
00927                     pFirstKid           = pKid;
00928                     bChangedSelection   = TRUE;
00929                 }
00930 
00931                 ((NodeRenderableInk*)pKid)->Select(TRUE);
00932             }
00933             pKid = pKid->FindNext();
00934         }
00935     }
00936 
00937     if (bChangedSelection)
00938     {
00939         SelRange* pSel = GetApplication()->FindSelection();
00940         if (pSel != NULL)
00941             pSel->Update(TRUE, pFirstKid);
00942     }
00943 
00944     // ok, if we successfully changed the selection, we
00945     // may need to start a drag with the selector tool.
00946     if (bChangedSelection && cType == CLICKTYPE_DRAG)
00947         ((SelectorTool*)pTool)->PublicDoTranslate();
00948 
00949     return bChangedSelection;
00950 }

BOOL NodeClipViewController::HandleKeyholeBlobClick ClickType  cType  )  [protected, virtual]
 

Handler for what happens when the user clicks on our keyhole-select blob.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
23 March 2000
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:
TRUE if we handled the click, FALSE if we passed.
All we do is try to select our keyhole nodes.
Returns:
Errors: See also:

Definition at line 831 of file ndclpcnt.cpp.

00832 {
00833 // DEBUG
00834 //  TRACEUSER( "Karim", _T("NCVC::HandleKeyholeBlobClick!\n"));
00835 
00836     // quit immediately unless it's a button-up click with the selector tool.
00837     Tool* pTool = Tool::GetCurrent();
00838     if (cType != CLICKTYPE_UP || pTool == NULL || pTool->GetID() != TOOLID_SELECTOR)
00839         return FALSE;
00840 
00841     // select all our keyhole nodes, which are those nodes to the left of our NodeClipView.
00842     // if for some reason we can't select any nodes, we'll return FALSE.
00843     BOOL bChangedSelection  = FALSE;
00844     Node* pFirstKeyhole     = NULL;
00845     NodeClipView* pClipView = GetClipView();
00846     if (pClipView != NULL)
00847     {
00848         Node* pKeyhole      = pClipView->FindPrevious();
00849         while (pKeyhole != NULL)
00850         {
00851             if (pKeyhole->IsAnObject())
00852             {
00853                 if (!bChangedSelection)
00854                 {
00855                     DeselectAll();
00856                     pFirstKeyhole       = pKeyhole;
00857                     bChangedSelection   = TRUE;
00858                 }
00859 
00860                 ((NodeRenderableInk*)pKeyhole)->Select(TRUE);
00861             }
00862             pKeyhole = pKeyhole->FindPrevious();
00863         }
00864     }
00865 
00866     if (bChangedSelection)
00867     {
00868         SelRange* pSel = GetApplication()->FindSelection();
00869         if (pSel != NULL)
00870             pSel->Update(TRUE, pFirstKeyhole);
00871     }
00872 
00873     return bChangedSelection;
00874 }

BOOL NodeClipViewController::InkHasClearLineColour NodeRenderableInk pInkNode  )  [private]
 

Test whether the line colour of the given NodeRenderableInk is transparent.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
08 March 2000
Parameters:
InkNode const reference to a NodeRenderableInk. [INPUTS]
Returns:
TRUE if we can definitely confirm the node has a transparent line width, FALSE for any other result.

Errors: See also:

Definition at line 1622 of file ndclpcnt.cpp.

01623 {
01624     NodeAttribute *pAppliedAttr = NULL;
01625     pInkNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeColour), &pAppliedAttr);
01626     if (pAppliedAttr != NULL)
01627     {
01628         DocColour* pLineColour = ((AttrStrokeColour*)pAppliedAttr)->GetStartColour();
01629         if (pLineColour != NULL)
01630             return pLineColour->IsTransparent();
01631     }
01632     return FALSE;
01633 }

BOOL NodeClipViewController::InsertClippedNode NodePath pNewNode,
NodePath pDestNode,
AttachNodeDirection  Direction,
UndoableOperation pUndoOp,
BOOL  bClipToKeyhole
[private]
 

Definition at line 1455 of file ndclpcnt.cpp.

01460 {
01461     // input validation.
01462     if (pNewNode == NULL /*|| pUndoOp == NULL*/)
01463     {
01464         ERROR3("NCVC::InsertClippedNode; NULL parameters");
01465         return FALSE;
01466     }
01467 
01468     // make the node's line transparent, if necessary clip to the keyhole node,
01469     // and then undoably insert it into the tree.
01470     // note that we *don't* abort the whole operation if clipping the
01471     // path went badly, we just don't insert it into the tree.
01472     BOOL clipok = TRUE;
01473     BOOL ok     = RemoveInkLineWidth(pNewNode);
01474     if (ok)
01475     {
01476         if (bClipToKeyhole)
01477         {
01478             Path* pWorkPath = &(pNewNode->InkPath);
01479             m_KeyholePath.ClipPathToPath(*pWorkPath, pWorkPath, 2,  CLIPVIEW_TOLERANCE,
01480                                                                     CLIPVIEW_SOURCEFLATNESS,
01481                                                                     CLIPVIEW_CLIPFLATNESS);
01482             if (pWorkPath->GetNumCoords() < 2)
01483                 clipok = FALSE;
01484             else
01485                 pWorkPath->InitialiseFlags();
01486         }
01487         if (clipok)
01488         {
01489             if (pUndoOp)
01490                 ok = pUndoOp->DoInsertNewNode(  pNewNode, pDestNode, Direction, FALSE,
01491                                                 FALSE, pDestNode->IsSelected(), TRUE );
01492             else
01493                 pNewNode->AttachNode(pDestNode, Direction);
01494         }
01495     }
01496 
01497     // tidy up if necessary.
01498     if ((!clipok || !ok) && pNewNode != NULL)
01499     {
01500         pNewNode->CascadeDelete();
01501         delete pNewNode;
01502     }
01503     pNewNode = NULL;
01504 
01505     return ok;
01506 }

virtual BOOL NodeClipViewController::IsANodeClipViewController  )  const [inline, virtual]
 

Reimplemented from Node.

Definition at line 171 of file ndclpcnt.h.

00171 { return TRUE; }

virtual BOOL NodeClipViewController::IsController  )  [inline, virtual]
 

Reimplemented from Node.

Definition at line 260 of file ndclpcnt.h.

00260 { return TRUE; }

BOOL NodeClipViewController::IsKeyholeValid  )  const [inline, private]
 

Definition at line 228 of file ndclpcnt.h.

00228 { return m_fKeyholeValid; }

BOOL NodeClipViewController::KeyholeDoBecomeA BecomeA pBecomeA  )  [private]
 

BOOL NodeClipViewController::MakeShapeAndLine NodePath pNodePath,
BecomeA pBecomeA,
BOOL  bClipToKeyhole
[private]
 

Definition at line 1313 of file ndclpcnt.cpp.

01316 {
01317 // DEBUG
01318 //  TRACEUSER( "Karim", _T("NCVC::MakeShapeAndLine\n"));
01319 
01320     // validate inputs.
01321     if (pNodePath == NULL || pBecomeA == NULL)
01322     {
01323         ERROR3("NCVC::MakeShapeAndLine; NULL parameters");
01324         return FALSE;
01325     }
01326     BecomeAReason Reason = pBecomeA->GetReason();
01327     if (Reason != BECOMEA_REPLACE && Reason != BECOMEA_PASSBACK)
01328     {
01329         ERROR3("NCVC::MakeShapeAndLine; Invalid parameters");
01330         return FALSE;
01331     }
01332     UndoableOperation* pUndoOp = pBecomeA->GetUndoOp();
01333 //  if (Reason == BECOMEA_REPLACE && pUndoOp == NULL)
01334 //  {
01335 //      ERROR3("NCVC::MakeShapeAndLine; Invalid parameters");
01336 //      return FALSE;
01337 //  }
01338 
01339     // local variables.
01340     BOOL        ok              = TRUE;
01341     NodePath*   pNewNode        = NULL;
01342     CCAttrMap*  pAttrMap        = NULL;
01343 
01344     // if the path is filled then insert/passback a doctored copy of it,
01345     // complete with attached copies of all the node's attributes.
01346     // note that we don't want to find indirectly applied GLAs here (eg feathers).
01347     if (pNodePath->InkPath.IsFilled)
01348     {
01349         if (ok)
01350         {
01351             pNewNode = (NodePath*)pNodePath->SimpleCopy();
01352             ok = (pNewNode != NULL);
01353         }
01354         if (ok)
01355         {
01356             pAttrMap = NULL;
01357             ALLOC_WITH_FAIL(pAttrMap, new CCAttrMap, pUndoOp);
01358             ok = (pAttrMap != NULL);
01359         }
01360         if (ok) ok = pNodePath->FindAppliedAttributes(pAttrMap, 5000, NULL, TRUE);
01361         if (ok) ok = pNewNode->ApplyAttributes(pAttrMap);
01362         if (ok)
01363         {
01364             if (Reason == BECOMEA_REPLACE)
01365             {
01366                 ok = InsertClippedNode(pNewNode, pNodePath, PREV, pUndoOp, bClipToKeyhole);
01367                 if (ok) pBecomeA->PassBack(pNewNode, this, pAttrMap->Copy());
01368             }
01369             else
01370                 ok = PassBackClippedNode(pNewNode, pBecomeA, bClipToKeyhole);
01371         }
01372         if (pAttrMap != NULL)
01373         {
01374             delete pAttrMap;
01375             pAttrMap = NULL;
01376         }
01377     }
01378 
01379     // if the path has an outline, then stroke its outline and pass it back/insert it,
01380     // complete with copies of the node's attributes.
01381     if (ok && !InkHasClearLineColour(pNodePath))
01382     {
01383         if (ok)
01384         {
01385             INT32 Flatness = EstimatePathFlatness();
01386             pNewNode = pNodePath->MakeNodePathFromAttributes(Flatness, NULL, TRUE);
01387             ok = (pNewNode != NULL);
01388         }
01389         if (ok)
01390         {
01391             pAttrMap = NULL;
01392             ALLOC_WITH_FAIL(pAttrMap, new CCAttrMap, pUndoOp);
01393             ok = (pAttrMap != NULL);
01394         }
01395         if (ok) ok = pNodePath->FindAppliedAttributes(pAttrMap, 5000, NULL, TRUE);
01396         if (ok) ok = pNewNode->ApplyAttributes(pAttrMap);
01397         if (ok) ok = CopyInkFillColourFromLine(pNewNode);
01398         if (ok) ok = CopyInkTransparencyFromLine(pNewNode);
01399         if (ok)
01400         {
01401             if (Reason == BECOMEA_REPLACE)
01402             {
01403                 ok = InsertClippedNode(pNewNode, pNodePath, PREV, pUndoOp, bClipToKeyhole);
01404                 if (ok) pBecomeA->PassBack(pNewNode, this, pAttrMap->Copy());
01405             }
01406             else
01407                 ok = PassBackClippedNode(pNewNode, pBecomeA, bClipToKeyhole);
01408         }
01409         if (pAttrMap != NULL)
01410         {
01411             delete pAttrMap;
01412             pAttrMap = NULL;
01413         }
01414     }
01415 
01416     // if we're replacing, and things are ok, then hide the NodePath.
01417     if (ok && Reason == BECOMEA_REPLACE)
01418     {
01419         if (pUndoOp)
01420             ok = pUndoOp->DoHideNode(pNodePath, FALSE);
01421         else
01422         {
01423             pNodePath->CascadeDelete();
01424             delete pNodePath;
01425         }
01426     }
01427 
01428     return ok;
01429 }

void NodeClipViewController::MarkKeyholeInvalid  )  [inline, private]
 

Definition at line 230 of file ndclpcnt.h.

00230 { m_fKeyholeValid = FALSE; }

void NodeClipViewController::MarkKeyholeValid  )  [inline, private]
 

Definition at line 229 of file ndclpcnt.h.

00229 { m_fKeyholeValid = TRUE;  }

ChangeCode NodeClipViewController::OnChildChange ObjChangeParam pParam  )  [virtual]
 

Used to notify this node of changes to its children, so that if required it can update itself. This forms part of the AllowOp / UpdateChangedNodes mechanism.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 January 2000
Parameters:
pParam describes the change which occurred. [INPUTS]
This node may regenerate itself to accomodate the change. [OUTPUTS]
Returns:
CC_OK if we have successfully processed the change. CC_FAIL if we cannot handle this particular change and must prevent the child from continuing.

Errors: ERROR2 if pParam is NULL. See also: Node::WarnParentOfChange(), Node::AllowOp()

Reimplemented from NodeGroup.

Definition at line 2112 of file ndclpcnt.cpp.

02113 {
02114     // validate input.
02115     ERROR2IF(pParam == NULL, CC_FAIL, "NULL pParam");
02116 
02117     // we'll need pointers to our ClipView and Keyhole nodes later on.
02118     NodeClipView* pClipView = GetClipView(FALSE);
02119 
02120     // we need to deal with circumstances which may put us into an inconsistent state.
02121     // these are:
02122     //
02123     //  * No ink-children, or only a ClipView node  ==> hide ourself.
02124     //  * No keyhole nodes      =>
02125     //  * No clipped nodes      ==>     turn ourself into a group.
02126     //  * No ClipView node      =>
02127     //
02128     UndoableOperation* pUndoOp = pParam->GetOpPointer();
02129     ObjChangeType cType = pParam->GetChangeType();
02130     if (cType == OBJCHANGE_FINISHED)
02131     {
02132         // count our kids.
02133         UINT32 NumKeyhole   = 0;
02134         UINT32 NumClipped   = 0;
02135         UINT32 NumKids  = 0;
02136         BOOL fCountingKeyholes = TRUE;
02137         Node* pKid = FindFirstChild();
02138         while (pKid != NULL)
02139         {
02140             if (pKid->IsAnObject())
02141             {
02142                 if (pKid == pClipView)
02143                 {
02144                     fCountingKeyholes = FALSE;
02145                 }
02146                 else
02147                 {
02148                     if (fCountingKeyholes)
02149                         NumKeyhole ++;
02150                     else
02151                         NumClipped ++;
02152                 }
02153             }
02154             pKid = pKid->FindNext();
02155         }
02156         NumKids = NumKeyhole + NumClipped;
02157 
02158         // ok, we hide ourself if we have no ink-kids (ignoring the clipview node).
02159         if (NumKids == 0)
02160         {
02161 
02162             // we need an Op in order to do tree manipulations.
02163             BOOL ok = (pUndoOp != NULL);
02164 
02165             // hide ourself - find our parent before we do though.
02166             Node* pParent = FindParent();
02167             if (ok)
02168                 ok = pUndoOp->DoHideNode(this,TRUE);
02169 
02170             // now we're hidden, factor out all attributes on our parent.
02171             if (ok)
02172                 if (pParent != NULL && pParent->IsCompound())
02173                     ok = pUndoOp->DoFactorOutCommonChildAttributes(((NodeRenderableInk*)pParent),TRUE);
02174 
02175             // TODO: rewind any actions here?
02176             if (!ok)
02177                 return CC_FAIL;
02178         }
02179 
02180         // if we're missing any one of our three magic ingredients, we mighty-morph into a group.
02181         if (pClipView == NULL || NumKeyhole == 0 || NumClipped == 0)
02182         {
02183             // we need a valid UndoOp ptr with which to perform the conversion.
02184             if (pUndoOp != NULL)
02185                 if (BecomeAGroup(pUndoOp))
02186                     return CC_OK;
02187 
02188             return CC_FAIL;
02189         }
02190 
02191         // the last case is where we have all three ingredients, in which case we
02192         // invalidate our keyhole path and make a 'mental' note that note that it
02193         // will need invalidating again whenever the user performs an undo or redo.
02194         else if (pUndoOp != NULL)
02195         {
02196 // DEBUG
02197 /*          TRACEUSER( "Karim", _T("NCVC::OnCC;"));
02198 
02199             // direction of change.
02200             ObjChangeDirection cDirection = pParam->GetDirection();
02201             switch (cDirection)
02202             {
02203             case OBJCHANGE_CALLEDBYCHILD:
02204                 TRACEUSER( "Karim", _T(" OBJCHANGE_CALLEDBYCHILD"));
02205                 break;
02206 
02207             case OBJCHANGE_CALLEDBYPARENT:
02208                 TRACEUSER( "Karim", _T(" OBJCHANGE_CALLEDBYPARENT"));
02209                 break;
02210 
02211             case OBJCHANGE_CALLEDBYOP:
02212                 TRACEUSER( "Karim", _T(" OBJCHANGE_CALLEDBYOP"));
02213                 break;
02214 
02215             default:
02216                 break;
02217             }
02218 
02219             // type of change.
02220             TRACEUSER( "Karim", _T(" ;"));
02221             switch (cType)
02222             {
02223             case OBJCHANGE_UNDEFINED:
02224                 TRACEUSER( "Karim", _T(" OBJCHANGE_UNDEFINED"));
02225                 break;
02226 
02227             case OBJCHANGE_STARTING:
02228                 TRACEUSER( "Karim", _T(" OBJCHANGE_STARTING"));
02229                 break;
02230 
02231             case OBJCHANGE_RENDERCURRENTBLOBS:
02232                 TRACEUSER( "Karim", _T(" OBJCHANGE_RENDERCURRENTBLOBS"));
02233                 break;
02234 
02235             case OBJCHANGE_RENDERCHANGEDBLOBS:
02236                 TRACEUSER( "Karim", _T(" OBJCHANGE_RENDERCHANGEDBLOBS"));
02237                 break;
02238 
02239             case OBJCHANGE_FINISHED:
02240                 TRACEUSER( "Karim", _T(" OBJCHANGE_FINISHED"));
02241                 break;
02242 
02243             case OBJCHANGE_IGNORE:
02244                 TRACEUSER( "Karim", _T(" OBJCHANGE_IGNORE"));
02245                 break;
02246 
02247             case OBJCHANGE_FAILED:
02248                 TRACEUSER( "Karim", _T(" OBJCHANGE_FAILED"));
02249                 break;
02250 
02251             default:
02252                 break;
02253             }
02254 
02255             // set change-flags.
02256             TRACEUSER( "Karim", _T("; Flags {"));
02257             ObjChangeFlags cFlags = pParam->GetChangeFlags();
02258             if (cFlags.Attribute)
02259                 TRACEUSER( "Karim", _T(" Attribute"));
02260             if (cFlags.CopyNode)
02261                 TRACEUSER( "Karim", _T(" CopyNode"));
02262             if (cFlags.DeleteNode)
02263                 TRACEUSER( "Karim", _T(" DeleteNode"));
02264             if (cFlags.MoveNode)
02265                 TRACEUSER( "Karim", _T(" MoveNode"));
02266             if (cFlags.MultiReplaceNode)
02267                 TRACEUSER( "Karim", _T(" MultiReplaceNode"));
02268             if (cFlags.RegenerateNode)
02269                 TRACEUSER( "Karim", _T(" RegenerateNode"));
02270             if (cFlags.ReplaceNode)
02271                 TRACEUSER( "Karim", _T(" ReplaceNode"));
02272             if (cFlags.TransformNode)
02273                 TRACEUSER( "Karim", _T(" TransformNode"));
02274             TRACEUSER( "Karim", _T(" }\n"));
02275 */
02276             // mark the cached keyhole path for update.
02277             UpdateCachedKeyholePathAction::Init( pUndoOp,
02278                                                  pUndoOp->GetUndoActions(),
02279                                                  this );
02280         }
02281         else if (!pUndoOp)
02282         {
02283             Document * pDoc = Document::GetCurrent();
02284 
02285             if (pDoc)
02286             {
02287                 if (pParam->GetChangeFlags ().RegenerateNode)
02288                 {
02289                     MarkKeyholeInvalid ();      // CGS:  it is now legitimate for us to do this
02290                 }
02291                 
02292                 Spread * pSpread = (Spread *)FindParent(CC_RUNTIME_CLASS(Spread));
02293                 pDoc->ForceRedraw(pSpread, GetBoundingRect(FALSE, FALSE), FALSE, this);
02294             }
02295         }
02296     }
02297 
02298     // call the base class version for the normal group checks, which will also deal with the
02299     // case where we have no kids at all.
02300     return NodeGroup::OnChildChange(pParam);
02301 }

BOOL NodeClipViewController::OnClick DocCoord  dcClickPos,
ClickType  cType,
ClickModifiers  cMods,
Spread pSpread
[virtual]
 

Handle any click-messages passed to us from a tool, eg if we want to handle clicks on our object or tool-object blobs. Currently, you can click on an NCVC tool-object blob and either select its keyhole node, or select everything *except* its keyhole node. At some point in future, you will also be able to directly drag everything except the keyhole node (instead of clicking once to select, _then_ dragging).

Reimplemented from NodeGroup.

Definition at line 760 of file ndclpcnt.cpp.

00762 {
00763 // DEBUG
00764 //  TRACEUSER( "Karim", _T("NCVC::OnClick\n"), (DWORD)cType);
00765 
00766     // determine what to do with the click.
00767     // note that we can't do anything unless we have valid pointers to view and blob manager.
00768     BlobManager* pBlobMgr = GetApplication()->GetBlobManager();
00769     DocView* pDocView = DocView::GetSelected();
00770     if (pBlobMgr == NULL || pDocView == NULL)
00771         return FALSE;
00772 
00773     // currently we only specifically handle ToolObject blobs.
00774     BlobStyle bsCurrentInterest = pBlobMgr->GetCurrentInterest();
00775     if (bsCurrentInterest.ToolObject)
00776     {
00777         // get bounds rects for the appropriate blobs.
00778         DocRect drKeyholeBlobRect;
00779         DocRect drContentsBlobRect;
00780         DocRect drBounds = GetBoundingRect();
00781         pBlobMgr->GetBlobRect(DocCoord(drBounds.lo.x, drBounds.hi.y), &drKeyholeBlobRect,
00782                                                                         FALSE, BT_CLIPVIEW);
00783         pBlobMgr->GetBlobRect(drBounds.Centre(), &drContentsBlobRect, FALSE, BT_CLIPVIEW);
00784 
00785         // inflate the rects, so the user doesn't need to be pin-point accurate.
00786         MILLIPOINT nNearRadius = OSRenderRegion::GetHitTestRadius(pDocView);
00787         drKeyholeBlobRect.Inflate(nNearRadius);
00788         drContentsBlobRect.Inflate(nNearRadius);
00789 
00790         // ok, lets test!
00791         if (drKeyholeBlobRect.ContainsCoord(dcClickPos))
00792         {
00793             if (HandleKeyholeBlobClick(cType))
00794                 return TRUE;
00795         }
00796         else if (drContentsBlobRect.ContainsCoord(dcClickPos))
00797         {
00798             if (HandleContentsBlobClick(cType))
00799                 return TRUE;
00800         }
00801     }
00802 
00803     // if we haven't handled the click and we're displaying object blobs,
00804     // hand over to our base implementation.
00805     if (bsCurrentInterest.Object)
00806         return NodeGroup::OnClick(dcClickPos, cType, cMods, pSpread);
00807 
00808     // we couldn't handle the click.
00809     return FALSE;
00810 }

BOOL NodeClipViewController::OwnsAsKeyholeNode const Node pTestNode  ) 
 

Test whether the given node is a keyhole node for this NCVC.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/05/2000
Parameters:
pTestNode the possible keyhole node. [INPUTS]
Returns:
TRUE if pTestNode is a keyhole node for us, FALSE otherwise.

Errors: In debug, ERROR3 if pTestNode is NULL. In release, just return with FALSE. See also:

Definition at line 316 of file ndclpcnt.cpp.

00317 {
00318     // input validation.
00319     if (pTestNode == NULL)
00320     {
00321         ERROR3("NCVC::OwnsAsKeyholeNode; NULL entry parameter!");
00322         return FALSE;
00323     }
00324 
00325     // Ensure keyhole path is valid (helps hit-detection)
00326     UpdateKeyholePath();
00327 
00328     // ok, any ink-node to the left of our NodeClipView is a keyhole node.
00329     Node* pKeyhole  = NULL;
00330     Node* pClipView = GetClipView();
00331     BOOL bFoundKeyhole = FALSE;
00332     if (pClipView != NULL)
00333     {
00334         pKeyhole = pClipView->FindPrevious();
00335         while (!bFoundKeyhole && pKeyhole != NULL)
00336         {
00337             bFoundKeyhole = (pKeyhole->IsAnObject() && pTestNode == pKeyhole);
00338             pKeyhole = pKeyhole->FindPrevious();
00339         }
00340     }
00341 
00342     return bFoundKeyhole;
00343 }

BOOL NodeClipViewController::PassBackClippedNode NodePath pNewNode,
BecomeA pBecomeA,
BOOL  bClipToKeyhole
[private]
 

Returns:
Errors: ERROR3 returning FALSE if invalid parameters. See also:

Definition at line 1533 of file ndclpcnt.cpp.

01536 {
01537     // validate inputs.
01538     if (pNewNode == NULL || pBecomeA == NULL)
01539     {
01540         ERROR3("NCVC::PassBackClippedNode; NULL parameters");
01541         return FALSE;
01542     }
01543 
01544     // local variables.
01545     BOOL        clipok          = TRUE;
01546     BOOL        ok              = TRUE;
01547     CCAttrMap*  pAttrMap        = NULL;
01548     CCAttrMap*  pCopiedAttrs    = NULL;
01549 
01550     // remove line width, copy its attribute map, try to clip to the keyhole
01551     // node and then pass back the path.
01552     // NB   although we usually abort if anything goes wrong, we do *not* abort
01553     //      if we failed to clip to the keyhole path - we just don't pass it back.
01554     if (ok) ok = RemoveInkLineWidth(pNewNode);
01555     if (ok)
01556     {
01557         pAttrMap = new CCAttrMap();
01558         ok = (pAttrMap != NULL);
01559     }
01560     if (ok) ok = pNewNode->FindAppliedAttributes(pAttrMap);
01561     if (ok)
01562     {
01563         pCopiedAttrs = pAttrMap->Copy();
01564         ok = (pCopiedAttrs != NULL);
01565     }
01566     if (ok)
01567     {
01568         pNewNode->CascadeDelete();
01569         if (bClipToKeyhole)
01570         {
01571             Path* pWorkPath = &(pNewNode->InkPath);
01572             m_KeyholePath.ClipPathToPath(*pWorkPath, pWorkPath, 2,  CLIPVIEW_TOLERANCE,
01573                                                                     CLIPVIEW_SOURCEFLATNESS,
01574                                                                     CLIPVIEW_CLIPFLATNESS);
01575             if (pWorkPath->GetNumCoords() < 2)
01576                 clipok = FALSE;
01577             else
01578                 pWorkPath->InitialiseFlags();
01579         }
01580         if (clipok)
01581             ok = pBecomeA->PassBack(pNewNode, this, pCopiedAttrs);
01582     }
01583 
01584     // tidy up if everything didn't go according to plan.
01585     if (!ok || !clipok)
01586     {
01587         if (pNewNode != NULL)
01588         {
01589             pNewNode->CascadeDelete();
01590             delete pNewNode;
01591         }
01592         if (pCopiedAttrs != NULL)
01593         {
01594             pCopiedAttrs->DeleteAttributes();
01595             delete pCopiedAttrs;
01596         }
01597     }
01598     if (pAttrMap != NULL)
01599         delete pAttrMap;
01600 
01601     return ok;
01602 }

void NodeClipViewController::PolyCopyNodeContents NodeRenderable pNodeCopy  )  [virtual]
 

Polymorphically copies the contents of this node to another.

Author:
Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/12/2003
Parameters:
- [OUTPUTS]
Returns:
Errors: An assertion failure will occur if NodeCopy is NULL Scope: protected

Reimplemented from NodeGroup.

Definition at line 2517 of file ndclpcnt.cpp.

02518 {
02519     ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
02520     ENSURE(IS_A(pNodeCopy, NodeClipViewController), "PolyCopyNodeContents given wrong dest node type");
02521 
02522     if (IS_A(pNodeCopy, NodeClipViewController))
02523         CopyNodeContents((NodeClipViewController*)pNodeCopy);
02524 }

BOOL NodeClipViewController::PostImport void   )  [virtual]
 

Performs any necessary post-processing once the object has been read in from a file.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
31 January 2000
Returns:
TRUE if success, FALSE if unsuccessful.

Errors: See also:

Reimplemented from Node.

Definition at line 2454 of file ndclpcnt.cpp.

02455 {
02456     return UpdateKeyholePath();
02457 }

void NodeClipViewController::PreExportRender RenderRegion pRegion  )  [virtual]
 

Starts exporting a clipview group - basically writes a 'q' token out.

Author:
Chris_Gallimore (Xara Group Ltd) <camelotdev@xara.com>
Date:
8th November 2000
Parameters:
pRegion - the RenderRegion we're exporting to. [INPUTS]
Returns:
Errors: See also: Node::PreExportRender()

Reimplemented from NodeGroup.

Definition at line 2541 of file ndclpcnt.cpp.

02542 {
02543 #ifdef DO_EXPORT
02544     if (pRegion->IsKindOf(CC_RUNTIME_CLASS(EPSRenderRegion)))
02545     {
02546         // Output "start group" token
02547         EPSExportDC *pDC = (EPSExportDC *) pRegion->GetRenderDC();
02548         pDC->OutputToken(_T("q"));
02549         pDC->OutputNewLine();
02550     }
02551 PORTNOTE("cmx", "Removed use of CMXRenderRegion")
02552 #ifndef EXCLUDE_FROM_XARALX
02553     else if(pRegion->IsKindOf(CC_RUNTIME_CLASS(CMXRenderRegion)))
02554     {
02555         // mark start of a group...
02556         CMXExportDC *pDC = (CMXExportDC *) pRegion->GetRenderDC();
02557         DocRect BBox = GetBoundingRect();
02558         pDC->StartGroup(&BBox);
02559     }
02560 #endif
02561 #endif
02562 }

BOOL NodeClipViewController::RemoveInkLineWidth NodeRenderableInk pInk  )  [private]
 

Make the outline of the given node transparent and set its line width to 0.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
09 March 2000
Parameters:
pInk pointer to the NodeRenderableInk to work on. [INPUTS]
pInk's line colour should become transparent. [OUTPUTS]
Returns:
TRUE if successful, FALSE otherwise.
NOTE: This method does *not* record undo information, and it expects attributes to have been localised beforehand.
Returns:
Errors: ERROR3 and returns FALSE if pInk is NULL. See also:

Definition at line 1655 of file ndclpcnt.cpp.

01656 {
01657     if (pInk == NULL)
01658     {
01659         ERROR3("NCVC::RemoveInkLineWidth; NULL parameter(s)");
01660         return FALSE;
01661     }
01662 
01663     NodeAttribute*      pAppliedAttr = NULL;
01664     DocColour*          pLineColour  = NULL;
01665     LineWidthAttribute* pLineWidth   = NULL;
01666 
01667     pInk->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeColour), &pAppliedAttr);
01668     if (pAppliedAttr != NULL)
01669         pLineColour = ((AttrStrokeColour*)pAppliedAttr)->GetStartColour();
01670 
01671     pAppliedAttr = NULL;
01672     pInk->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrLineWidth), &pAppliedAttr);
01673     if (pAppliedAttr != NULL)
01674         pLineWidth = (LineWidthAttribute*)pAppliedAttr->GetAttributeValue();
01675 
01676     if (pLineColour != NULL && pLineWidth != NULL)
01677     {
01678         *pLineColour = DocColour(COLOUR_TRANS);
01679         pLineWidth->LineWidth = 0;
01680         return TRUE;
01681     }
01682     
01683     return FALSE;
01684 }

void NodeClipViewController::RenderClipViewBlobs RenderRegion pRender  )  [protected, virtual]
 

Render the blobs specifically used by ClipView groups. These are currently as follows: 1. A keyhole-selection blob, which is rendered at the top-left of our bounding rectangle. 2. A select-contained-objects blob, which is rendered in the centre of the group's bounding rectangle.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
23 March 2000
Parameters:
pRender the region to render to. [INPUTS]
Returns:
Errors: See also:

Definition at line 710 of file ndclpcnt.cpp.

00711 {
00712     // quit immediately unless the current tool is the selector tool.
00713     Tool* pTool = Tool::GetCurrent();
00714     if (pTool == NULL || pTool->GetID() != TOOLID_SELECTOR)
00715         return;
00716 
00717     // get the blob manager and set the colours we'll be using.
00718 //  BlobManager* pBlobManager = GetApplication()->GetBlobManager();
00719     pRender->SetLineColour(COLOUR_NONE);
00720     pRender->SetFillColour(COLOUR_UNSELECTEDBLOB);
00721 
00722     // plot the keyhole blob at the top-left of our bounding rectangle.
00723     DocRect drBounds = GetBoundingRect();
00724     DocCoord dcKeyhole(drBounds.lo.x, drBounds.hi.y);
00725     pRender->DrawBitmapBlob(dcKeyhole, _R(IDBMP_KEYHOLE));
00726 
00727     // plot the select-inside blob at the centre of our bounding rectangle.
00728     pRender->DrawBitmapBlob(drBounds.Centre(), _R(IDBMP_CLIPVIEW_SELECT_CONTENTS));
00729 
00730     // BODGE CODE!
00731     // some of the ClipView blobs are rendered in the same position as our tiny blobs.
00732     // we don't want the tiny blobs to interfere with these blobs, so we double-render
00733     // them off the picture (double XOR = 0) whenever these blobs are rendered.
00734     // this relies on Tiny blobs always being rendered whenever these blobs
00735     // are rendered (which they have always been up till 06/04/2000)
00736     RenderTinyBlobs(pRender);
00737 }

void NodeClipViewController::RenderEorDrag RenderRegion pRender  )  [virtual]
 

Render this node as eor-blobs into the given render region.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
28 January 2000
Parameters:
pRender pointer to the render region to render into. [INPUTS]
What we probably want to do is clip the outlines of all our children, and render those outlines into the given render region, however for now we'll just render our keyhole node's outline.
Returns:
Errors: See also: See Render() for info.

Reimplemented from NodeRenderableInk.

Definition at line 548 of file ndclpcnt.cpp.

00549 {
00550     // <RANT>
00551     // unfortunately, if we opt to do eor-drag-rendering for our kids (and we do),
00552     // then as well as getting to render for them when we're dragged around, we also
00553     // get lumbered with rendering for them when *they* get dragged around.
00554     // this is annoying and the solution should *not* be to do their rendering
00555     // for them if we're not selected, but that's what we're gonna do.
00556     // </RANT>
00557 
00558     // determine whether myself or one of my ancestors is selected.
00559     BOOL fMeOrMyAncestorIsSelected = IsSelected();
00560     Node* pParent = FindParent();
00561     while (!fMeOrMyAncestorIsSelected && pParent != NULL)
00562     {
00563         fMeOrMyAncestorIsSelected = pParent->IsSelected();
00564         pParent = pParent->FindParent();
00565     }
00566 
00567     // do normal eor-drag-rendering for myself (eor-rendering our keyhole path.)
00568     if (fMeOrMyAncestorIsSelected)
00569     {
00570         UpdateKeyholePath();
00571         pRender->DrawPath(&m_KeyholePath);
00572     }
00573 
00574     // do eor-drag-rendering for those of my lazy children which are selected.
00575     RenderEorDragSelectedChildren(this, pRender);
00576 }

void NodeClipViewController::RenderEorDragSelectedChildren Node pParent,
RenderRegion pRender
[virtual]
 

Notes: I get the feeling this vfn should really live in NodeRenderableInk, so if things work out then I'll put it there.

Returns:
Errors: See also: RenderEorDragChildren() for something similar...

Definition at line 599 of file ndclpcnt.cpp.

00601 {
00602     NodeRenderableInk* pInkKid = NULL;
00603     Node* pKid = pParent->FindFirstChild();
00604     while (pKid != NULL)
00605     {
00606         if (pKid->IsAnObject())
00607         {
00608             pInkKid = (NodeRenderableInk*)pKid;
00609 
00610             // ok, is it selected? if so, render its drag blobs, taking account of bossy
00611             // controller nodes who want to render their children themselves.
00612             if (pInkKid->IsSelected())
00613             {
00614                 pInkKid->RenderEorDrag(pRender);
00615                 if (!pInkKid->ChildrenAreEorDragRenderedByMe())
00616                     pInkKid->RenderEorDragChildren(pRender);
00617             }
00618 
00619             // nope, not selected - recurse down into it if possible.
00620             else
00621             {
00622                 RenderEorDragSelectedChildren(pInkKid, pRender);
00623             }
00624         }
00625         pKid = pKid->FindNext();
00626     }
00627 }

SubtreeRenderState NodeClipViewController::RenderSubtree RenderRegion pRender,
Node **  ppNextNode = NULL,
BOOL  bClip = TRUE
[virtual]
 

Called by the main rendering loop before this node's children are rendered, usually to allow us to muck around with how we want our children to render.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
15 February 2000
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:
PRE_RENDER_CHILDREN.
It is used here to clear up any debris left over from an unfinished hit-test render-loop.
Returns:
Errors: See also:

Reimplemented from NodeGroup.

Definition at line 513 of file ndclpcnt.cpp.

00514 {
00515     if (pRender && !pRender->IsPrinting())
00516     {
00517         // ensure our cached keyhole path is up to date.
00518         UpdateKeyholePath();
00519 
00520 //      return SUBTREE_ROOTANDCHILDREN;
00521         return NodeGroup::RenderSubtree(pRender, ppNextNode, bClip);
00522     }
00523     else
00524 //      return SUBTREE_ROOTANDCHILDREN;
00525         return NodeGroup::RenderSubtree(pRender, ppNextNode, bClip);
00526 
00527 //  return SUBTREE_ROOTANDCHILDREN;
00528 }

void NodeClipViewController::RenderTinyBlobs RenderRegion pRender  )  [virtual]
 

Render our tiny-blob. This consists of a solitary blob at the top-left of our bounding rect.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
06 April 2000
Parameters:
pRender the render-region to render into. [INPUTS]

Reimplemented from NodeGroup.

Definition at line 664 of file ndclpcnt.cpp.

00665 {
00666     // Get our bounding rect, and from it the position of our tiny blob.
00667     DocRect drBounds = GetBoundingRect();
00668     DocCoord dcTinyPos = DocCoord(drBounds.lo.x, drBounds.hi.y);
00669 
00670     // Set our blob's colours and render it.
00671     pRender->SetFillColour(COLOUR_UNSELECTEDBLOB);
00672     pRender->SetLineColour(COLOUR_NONE);
00673     pRender->DrawBlob(dcTinyPos, BT_UNSELECTED);
00674 }

void NodeClipViewController::RenderToolObjectBlobs RenderRegion pRender  )  [virtual]
 

Render our tool-object blobs.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
23 March 2000
Parameters:
pRender ptr to the region to render into. [INPUTS]

Reimplemented from NodeRenderable.

Definition at line 686 of file ndclpcnt.cpp.

00687 {
00688     RenderClipViewBlobs(pRender);
00689 }

Node * NodeClipViewController::SimpleCopy void   )  [protected, virtual]
 

Copy this node.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
09 February 2000
Returns:
A copy of this node, or NULL if unsuccessful.

Errors: ERROR1 returning NULL if we couldn't allocate memory for the new node. See also: Node::SimpleCopy()

Reimplemented from NodeGroup.

Definition at line 2474 of file ndclpcnt.cpp.

02475 {
02476     NodeClipViewController* pNodeCopy = new NodeClipViewController;;
02477     ERROR1IF(pNodeCopy == NULL, NULL, _R(IDE_NOMORE_MEMORY));
02478     CopyNodeContents(pNodeCopy);
02479 
02480     return pNodeCopy;
02481 }

void NodeClipViewController::Transform TransformBase Trans  )  [virtual]
 

Perform a transformation on this node.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
31 January 2000
Parameters:
Trans non-const reference to a description of the transformation. [INPUTS]
This node will be transformed appropriately. [OUTPUTS]
Returns:
Errors: See also:

Reimplemented from NodeGroup.

Definition at line 2361 of file ndclpcnt.cpp.

02362 {
02363     // required because certain processes which transform nodes do not fire off my
02364     // OnChildChange method (haven't investigated why)
02365     MarkKeyholeInvalid();
02366 
02367     // ClipViews can't just transform their cached data - they have to
02368     // also transform their children because clipview's GetBoundingRect
02369     // always calculates - never returns cached rectangle.
02370     Trans.bTransformYourChildren = TRUE;
02371 
02372     // ClipViews can't just transform their cached data - they have to
02373     // also transform their children because clipview's GetBoundingRect
02374     // always calculates - never returns cached rectangle.
02375     Trans.bTransformYourChildren = TRUE;
02376 
02377     // ClipViews can't just transform their cached data - they have to
02378     // also transform their children because clipview's GetBoundingRect
02379     // always calculates - never returns cached rectangle.
02380     Trans.bTransformYourChildren = TRUE;
02381 
02382     // transform our children etc, in the same way a normal group would.
02383     NodeGroup::Transform(Trans);
02384 }

BOOL NodeClipViewController::UpdateKeyholePath  )  [private]
 

Update our cached outline for our keyhole node. Note that this method only tries to update the keyhole path if it is marked as invalid. If it is already valid, you just get TRUE back. It will also only re-mark the keyhole as valid if it successfully updates the keyhole cache.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
13 March 2000
Parameters:
[INPUTS] 
[OUTPUTS] 
Returns:

Errors: See also: InvalidateKeyhole().

Definition at line 1938 of file ndclpcnt.cpp.

01939 {
01940 // DEBUG
01941 //  TRACEUSER( "Karim", _T("NCVC::UpdateKeyholePath; %s.\n"),
01942 //              IsKeyholeValid() ? "valid" : "invalid");
01943 
01944     if (IsKeyholeValid())
01945         return TRUE;
01946 
01947     NodeClipView* pClipView = GetClipView();
01948     if (pClipView == NULL)
01949         return FALSE;
01950 
01951     // DoBecomeA on all our keyhole nodes (nodes to the left of our clipview node), and
01952     // add the resulting paths up to get one big keyhole-path.
01953     // in the interests of accuracy, and because most of the time we expect only to have
01954     // one keyhole path, we're going to do as little clip-path-to-path'ing as possible.
01955     BOOL bAddedFirstPath = FALSE;
01956     Node* pKeyhole = pClipView->FindPrevious();
01957     while (!bAddedFirstPath && pKeyhole != NULL)
01958     {
01959         if (pKeyhole->IsAnObject())
01960         {
01961             m_KeyholePath.ClearPath();
01962             PathBecomeA baInfo(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath), NULL, FALSE,
01963                                 &m_KeyholePath, PathBecomeA::STRIP_OUTLINES );
01964             baInfo.SetPathsOnly();
01965             if (pKeyhole->DoBecomeA(&baInfo))
01966                 bAddedFirstPath = TRUE;
01967         }
01968         pKeyhole = pKeyhole->FindPrevious();
01969     }
01970 
01971     // ok, now add any other keyholes which are kicking around.
01972     BOOL ok = TRUE;
01973     if (pKeyhole != NULL)
01974     {
01975         INT32 Flatness = EstimatePathFlatness();
01976         Path m_WorkPath;
01977         m_WorkPath.Initialise();
01978         while (ok && pKeyhole != NULL)
01979         {
01980             if (pKeyhole->IsAnObject())
01981             {
01982                 m_WorkPath.ClearPath();
01983                 PathBecomeA baInfo(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath), NULL, FALSE,
01984                                     &m_WorkPath, PathBecomeA::STRIP_OUTLINES);
01985                 baInfo.SetPathsOnly();
01986                 if (ok && pKeyhole->DoBecomeA(&baInfo))
01987                     ok = (m_KeyholePath.ClipPathToPath( m_WorkPath, &m_KeyholePath, 7,
01988                                                         CLIPVIEW_TOLERANCE,
01989                                                         Flatness,
01990                                                         Flatness) != -1);
01991             }
01992             pKeyhole = pKeyhole->FindPrevious();
01993         }
01994     }
01995 
01996     // if our keyhole path is empty, then we need to hide everything which we're clipping.
01997     // we'll do this by building an empty keyhole path out of our bounding rect.
01998     if (m_KeyholePath.GetNumCoords() == 0)
01999     {
02000         DocRect drBounds = GetBoundingRect();
02001         DocCoord drLeft(drBounds.lo.x, (drBounds.lo.y + drBounds.hi.y) / 2);
02002         DocCoord drRight(drBounds.hi.x, (drBounds.lo.y + drBounds.hi.y) / 2);
02003 
02004         m_KeyholePath.Initialise(3);
02005         m_KeyholePath.AddMoveTo(drLeft);
02006         m_KeyholePath.AddLineTo(drRight);
02007         m_KeyholePath.AddLineTo(drLeft);
02008         m_KeyholePath.IsFilled = TRUE;
02009     }
02010 
02011     // ok, setup with the new keyhole path.
02012     pClipView->SetClipPath(&m_KeyholePath);
02013     if (ok)
02014         MarkKeyholeValid();
02015 
02016     return ok;
02017 }

BOOL NodeClipViewController::WritePreChildrenNative BaseCamelotFilter pFilter  )  [virtual]
 

Writes this node out to a camelot document.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
31 January 2000
Parameters:
pFilter pointer to a camelot file filter. [INPUTS]
Returns:
TRUE if successful, FALSE otherwise.

Errors: See also:

Reimplemented from NodeGroup.

Definition at line 2433 of file ndclpcnt.cpp.

02434 {
02435     return WritePreChildrenWeb(pFilter);
02436 }

BOOL NodeClipViewController::WritePreChildrenWeb BaseCamelotFilter pFilter  )  [virtual]
 

Writes this node out to a camelot document.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
31 January 2000
Parameters:
pFilter pointer to a camelot file filter. [INPUTS]
Returns:
TRUE if successful, FALSE otherwise.

Errors: ERROR2 if pFilter is NULL. See also:

Reimplemented from NodeGroup.

Definition at line 2403 of file ndclpcnt.cpp.

02404 {
02405     // validate input.
02406     ERROR2IF(pFilter == NULL, FALSE, "NULL parameter");
02407     
02408     CXaraFileRecord Rec(TAG_CLIPVIEWCONTROLLER, TAG_CLIPVIEW_CONTROLLER_SIZE);
02409 
02410     BOOL    ok = Rec.Init();
02411     if (ok) ok = (pFilter->Write(&Rec) != 0);
02412 
02413     return ok;
02414 }


Friends And Related Function Documentation

friend class NodeClipView [friend]
 

Definition at line 152 of file ndclpcnt.h.

void OpApplyClipView::Do OpDescriptor pOpDesc  )  [friend]
 

friend class UpdateCachedKeyholePathAction [friend]
 

Definition at line 154 of file ndclpcnt.h.


Member Data Documentation

const INT32 NodeClipViewController::CLIPVIEW_CLIPFLATNESS = 50 [static]
 

Definition at line 276 of file ndclpcnt.h.

const INT32 NodeClipViewController::CLIPVIEW_SOURCEFLATNESS [static]
 

Definition at line 275 of file ndclpcnt.h.

const INT32 NodeClipViewController::CLIPVIEW_TOLERANCE [static]
 

Definition at line 274 of file ndclpcnt.h.

DocRect NodeClipViewController::m_drContentsBlobRect [private]
 

Definition at line 299 of file ndclpcnt.h.

DocRect NodeClipViewController::m_drKeyholeBlobRect [private]
 

Definition at line 298 of file ndclpcnt.h.

BOOL NodeClipViewController::m_fKeyholeValid [private]
 

Definition at line 295 of file ndclpcnt.h.

Path NodeClipViewController::m_KeyholePath [private]
 

Definition at line 294 of file ndclpcnt.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:56:47 2007 for Camelot by  doxygen 1.4.4