nodebrsh.cpp

Go to the documentation of this file.
00001 // $Id: nodebrsh.cpp 1282 2006-06-09 09:46:49Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 // implementation of the NodeBrush class
00100 #include "camtypes.h"
00101 #include "nodebrsh.h"
00102 //#include "group.h"
00103 //#include "rndrgn.h"
00104 //#include "document.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00105 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00106 #include "blobs.h"
00107 //#include "nodershp.h"
00108 #include "ndbrshpt.h"
00109 #include "ndbrshmk.h"
00110 //#include "progress.h"
00111 //#include "objchge.h"
00112 //#include "markn.h"
00113 //#include "opdrbrsh.h"
00114 #include "opshadow.h"
00115 //#include "opbevel.h"
00116 #include "objchge.h"
00117 
00118 class BlendRef;
00119 
00120 CC_IMPLEMENT_DYNCREATE(NodeBrush, NodeGroup);
00121 // Declare smart memory handling in Debug builds
00122 #define new CAM_DEBUG_NEW
00123 #define BRUSH_MIN_SPACING 100
00124 #define BRUSH_MAX_SPACING 10000000
00125 #define BRUSH_DEFAULT_SPACING 10000
00126 
00127 
00128 /*********************************************************************************************
00129 
00130 >    NodeBrush::NodeBrush() 
00131 
00132      Author:    Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00133      Created:   6/10/99
00134      Inputs:    
00135      Outputs:   
00136      Returns:   
00137      Purpose:   This constructor creates a NodeBrush linked to no other
00138      Errors:    
00139 
00140 **********************************************************************************************/
00141  
00142 NodeBrush::NodeBrush(): NodeGroup()
00143 {
00144     
00145 }
00146     
00147 /***********************************************************************************************
00148 
00149 >   void NodeBrush::NodeBrush
00150     (
00151         Node* ContextNode,  
00152         AttachNodeDirection Direction,  
00153         BOOL Locked = FALSE, 
00154         BOOL Mangled = FALSE,  
00155         BOOL Marked = FALSE, 
00156         BOOL Selected = FALSE, 
00157     )
00158 
00159     Author:  Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00160     Created:    6/10/99
00161     Inputs: ContextNode: Pointer to a node which this node is to be attached to.     
00162     
00163             Direction: 
00164             
00165                 Specifies the direction in which this node is to be attached to the 
00166                 ContextNode. The values this variable can take are as follows: 
00167                                   
00168                 PREV      : Attach node as a previous sibling of the context node
00169                 NEXT      : Attach node as a next sibling of the context node
00170                 FIRSTCHILD: Attach node as the first child of the context node
00171                 LASTCHILD : Attach node as a last child of the context node                               
00172                           
00173             The remaining inputs specify the status of the node: 
00174             
00175             Locked:     Is node locked ?
00176             Mangled:    Is node mangled ?
00177             Marked:     Is node marked ?
00178             Selected:   Is node selected ?
00179             
00180     Outputs:   -
00181     Returns:   - 
00182     Purpose: This method initialises the node and links it to ContextNode in the
00183              direction specified by Direction. All necessary tree links are
00184              updated.     
00185              
00186     Errors:  An assertion error will occur if ContextNode is NULL
00187 
00188 
00189 ***********************************************************************************************/
00190 
00191 NodeBrush::NodeBrush(Node* ContextNode,  
00192                      AttachNodeDirection Direction,  
00193                      BOOL Locked, 
00194                      BOOL Mangled,  
00195                      BOOL Marked, 
00196                      BOOL Selected   
00197                ):NodeGroup(ContextNode, Direction, Locked, Mangled, Marked, 
00198                 Selected) 
00199 { 
00200 
00201 
00202 } 
00203 
00204 
00205 /*********************************************************************************************
00206 
00207 >    NodeBrush::~NodeBrush() 
00208 
00209      Author:    Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00210      Created:   6/10/99
00211      Inputs:    
00212      Outputs:   
00213      Returns:   
00214      Purpose:   Destructor
00215      Errors:    
00216 
00217 **********************************************************************************************/
00218 
00219 
00220 NodeBrush::~NodeBrush()
00221 {
00222     
00223 
00224 }
00225 
00226 /********************************************************************************************
00227 
00228 >   DocRect NodeBrush::GetBlobBoundingRect()
00229 
00230     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00231     Created:    7/10/99
00232     Returns:    DocRect - The bounding rect of the node and its blobs
00233     Purpose:    This calls the base classes GetBlobBoundingRect(), and inflates the result by the width
00234                 of a blob
00235 
00236 ********************************************************************************************/
00237 
00238 DocRect NodeBrush::GetBlobBoundingRect()
00239 {
00240     
00241 #if !defined(EXCLUDE_FROM_RALPH)
00242     // Find the base class blob bounding rectangle
00243     DocRect Rect = NodeGroup::GetBlobBoundingRect();
00244 
00245     // inflate it by the width of a blob (plus a bit)
00246     DocRect TempRect;
00247     GetApplication()->GetBlobManager()->GetBlobRect(Rect.lo,&TempRect);
00248     INT32 Delta = ((TempRect.hi.x - TempRect.lo.x)*1)/1;
00249     Rect.Inflate(Delta);
00250 
00251     return Rect;
00252 #else
00253     return DocRect(0,0,0,0);
00254 #endif
00255 
00256 }
00257 
00258 /********************************************************************************************
00259 
00260 >   DocRect NodeBrusher::GetBoundingRect(BOOL DontUseAttrs=FALSE, BOOL HitTest=FALSE)
00261 
00262     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00263     Created:    11/10/94
00264     Inputs:     DontUseAttrs - TRUE if we should ignore the nodes attributes.
00265                 Defaults to FALSE
00266                 HitTest      - TRUE if being called during HitTest
00267     Returns:    The nodes bounding rect
00268     Purpose:    if the bounding rect is valid it is returned, if not, it is recalculated
00269                 and then returned.
00270     SeeAlso:    NodeBrusher::GetBlobBoundingRect
00271 
00272 ********************************************************************************************/
00273 
00274 
00275 DocRect NodeBrush::GetBoundingRect(BOOL DontUseAttrs, BOOL HitTest)
00276 {
00277     /*
00278     // first get the bounding rect of the path
00279     DocRect Rect =  m_pNodeBrushPath->GetBoundingRect();
00280     
00281     // inflate by half the size of the brush ink object.
00282 
00283     NodeRenderableInk* pInk = m_pNodeBrushMaker->GetInkNode();
00284     
00285     if (pInk != NULL)
00286     {
00287         DocRect InkRect = pInk->GetBoundingRect();
00288 
00289         INT32 dx = InkRect.Width() / 2;
00290         INT32 dy = InkRect.Height() / 2;
00291 
00292         Rect.Inflate(dx, dy);
00293     }
00294 
00295     return Rect;
00296     */
00297     // default docrect constructor makes empty rect
00298     DocRect Rect;
00299     if (m_pNodeBrushMaker != NULL)
00300         Rect =  m_pNodeBrushMaker->GetBoundingRect();
00301     
00302     return Rect;
00303 }
00304 
00305 
00306 
00307 /********************************************************************************************
00308 
00309 >   void NodeBrush::Render (RenderRegion* pRender)
00310 
00311     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00312     Created:    7/10/99
00313     Inputs:     pRender - The region to draw the blobs in
00314     Purpose:    Renders the nodebrushpath, if selected, otherwise nothing.  The main 
00315                 rendering is performed by the nodebrushmaker
00316 
00317 ********************************************************************************************/
00318 
00319 void NodeBrush::Render(RenderRegion* pRender)
00320 {
00321     if (this->IsSelected())
00322     {
00323         if (m_pNodeBrushPath != NULL)
00324             m_pNodeBrushPath->RenderObjectBlobs(pRender);
00325     }
00326     if (m_pNodeBrushMaker != NULL)
00327         m_pNodeBrushMaker->Render(pRender);
00328 }
00329 
00330 
00331 /********************************************************************************************
00332 >   virtual SubtreeRenderState NodeBrush::RenderSubtree(RenderRegion* pRender, Node** ppNextNode, BOOL bClip = TRUE)
00333 
00334     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00335     Created:    22/06/2004
00336     Inputs:     A Render Region to Render into.
00337     Returns:    PRE_FAILED for something went wrong,
00338                 PRE_RENDER_CHILDREN for continue to render children,
00339                 PRE_NO_RENDER_CHILDREN for DO NOT Render any of my children!!!!
00340 
00341     Purpose:    Enables Nodes to be able to Do Pre Print time alterations or even take over
00342                 the control of the current Printing of their children.
00343 
00344 ********************************************************************************************/
00345 SubtreeRenderState NodeBrush::RenderSubtree(RenderRegion* pRender, Node** ppNextNode, BOOL bClip)
00346 {
00347     return SUBTREE_ROOTONLY;
00348 }
00349 
00350 
00351 
00352 
00353 /********************************************************************************************
00354 
00355 >   void NodeBrush::RenderObjectBlobs(RenderRegion* pRender)
00356 
00357     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00358     Created:    7/10/99
00359     Inputs:     pRender - The region to draw the blobs in
00360     Purpose:    Renders the object blobs
00361 
00362 ********************************************************************************************/
00363 
00364 void NodeBrush::RenderObjectBlobs(RenderRegion* pRegion)
00365 { 
00366 #if !defined(EXCLUDE_FROM_RALPH)
00367     // Find out about the groups bounding rect
00368     DocRect BoundingRect = GetBoundingRect();
00369 
00370     // Inflate the bounds by the width of a blob
00371     DocRect TempRect;
00372     GetApplication()->GetBlobManager()->GetBlobRect(BoundingRect.lo,&TempRect);
00373     INT32 Delta = ((TempRect.hi.x - TempRect.lo.x)*3)/4;
00374     BoundingRect.Inflate(Delta);
00375 
00376     // Find out where to draw the blobs
00377     DocCoord Low  = BoundingRect.LowCorner();
00378     DocCoord High = BoundingRect.HighCorner();
00379 
00380     // Set the colours of the blobs
00381     pRegion->SetFillColour(COLOUR_UNSELECTEDBLOB);
00382     pRegion->SetLineColour(COLOUR_NONE);
00383 
00384     // Draw all the blobs
00385     pRegion->DrawBlob(Low, BT_UNSELECTED);  
00386     pRegion->DrawBlob(High, BT_UNSELECTED); 
00387     pRegion->DrawBlob(DocCoord(Low.x, High.y), BT_UNSELECTED); 
00388     pRegion->DrawBlob(DocCoord(High.x, Low.y), BT_UNSELECTED); 
00389 
00390     // for some reason the NBP is never called, there is probably a 
00391     // proper fix for this but I don't have time right now, so render
00392     // the nodeblend path here
00393     m_pNodeBrushPath->RenderObjectBlobs(pRegion);
00394 
00395 
00396 #endif 
00397 }
00398 
00399 
00400 /********************************************************************************************
00401 
00402 >   void NodeBrush::RenderTinyBlobs(RenderRegion* pRender)
00403 
00404     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00405     Created:    7/10/99
00406     Inputs:     pRender - The region to draw the blobs in
00407     Purpose:    Renders the object blobs
00408 
00409 ********************************************************************************************/
00410 
00411 void NodeBrush::RenderTinyBlobs(RenderRegion* pRegion)
00412 {
00413     // for some reason the NBP is never called, there is probably a 
00414     // proper fix for this but I don't have time right now, so render
00415     // the nodeblend path here
00416     m_pNodeBrushPath->RenderTinyBlobs(pRegion);
00417 
00418 }
00419 
00420 
00421 /********************************************************************************************
00422 
00423 >   void NodeBrush::Transform(TransformBase& Trans)
00424 
00425     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00426     Created:    7/10/99
00427     Inputs:     Trans - the transformation to perform
00428     Purpose:    transforms the brush
00429 
00430 ********************************************************************************************/
00431 
00432 void NodeBrush::Transform(TransformBase& Trans)
00433 {
00434     // The groups bounding rect is no longer valid
00435     InvalidateBoundingRect();
00436 
00437     // Transform all the children
00438     // See GroupCanTransformCached()
00439     NodeGroup::Transform(Trans);
00440 
00441 }
00442 
00443 
00444 
00445 /********************************************************************************************
00446 
00447   > virtual BOOL NodeBrush::WritePreChildrenWeb(BaseCamelotFilter* pFilter)
00448 
00449     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 
00450     Created:    7/20/99
00451     Inputs:     pFilter = ptr to the filter
00452     Returns:    TRUE if record is written, FALSE if not
00453     Purpose:    Writes the brush record to the filter
00454                 
00455     SeeAlso:    -
00456 
00457 ********************************************************************************************/
00458 
00459 BOOL NodeBrush::WritePreChildrenWeb(BaseCamelotFilter* pFilter)
00460 {
00461     return TRUE;
00462 }
00463 
00464 
00465 /********************************************************************************************
00466 
00467   > virtual BOOL NodeBrush::WritePreChildrenNative(BaseCamelotFilter* pFilter)
00468 
00469     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 
00470     Created:    7/20/99
00471     Inputs:     pFilter = ptr to the filter
00472     Returns:    TRUE if record is written, FALSE if not
00473     Purpose:    Writes the brush record to the filter
00474                 
00475     SeeAlso:    -
00476 
00477 ********************************************************************************************/
00478 
00479 BOOL NodeBrush::WritePreChildrenNative(BaseCamelotFilter* pFilter)
00480 {
00481     return TRUE;
00482 }
00483 
00484 
00485 
00486 /***********************************************************************************************
00487 
00488 > Node* NodeBrush::SimpleCopy()  
00489 
00490     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00491     Created:    6/10/99
00492     Inputs:     -  
00493     Outputs:    -
00494     Returns:    A copy of the node, or NULL if memory has run out 
00495          
00496     Purpose:    This method returns a shallow copy of the node with all Node pointers NULL. 
00497                 The function is virtual, and must be defined for all derived classes.  
00498                 
00499     Errors:     If memory runs out when trying to copy, then ERROR is called with an out of memory
00500                 error and the function returns NULL.                                                                      
00501                                                                                  
00502 **********************************************************************************************/
00503 
00504 Node* NodeBrush::SimpleCopy()
00505 {
00506     NodeBrush* pCopyOfNode = new NodeBrush();
00507     if (pCopyOfNode != NULL)
00508         CopyNodeContents(pCopyOfNode);
00509     return (pCopyOfNode);
00510 }   
00511 
00512 /***********************************************************************************************
00513 
00514 >   void NodeBrush::CopyNodeContents(Node* pCopyOfNode)
00515 
00516     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00517     Created:    6/10/99
00518     Inputs:     pCopyOfNode - The node to copy data to
00519     Outputs:    -
00520     Returns:    -
00521     Purpose:    Copies the data from this node to pCopyOfNode by first calling the base class to get it to
00522                 copy its stuff, and then copying its own stuff
00523     Scope:      protected
00524     SeeAlso:    NodeGroup::CopyNodeContents
00525 
00526 ***********************************************************************************************/
00527 
00528 void NodeBrush::CopyNodeContents(NodeBrush* pCopyOfNode)
00529 {
00530     NodeGroup::CopyNodeContents(pCopyOfNode);
00531 
00532     // Copy member vars here
00533 
00534 }
00535    
00536 
00537 
00538 /***********************************************************************************************
00539 >   void NodeBrush::PolyCopyNodeContents(NodeRenderable* pNodeCopy)
00540 
00541     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00542     Created:    18/12/2003
00543     Outputs:    -
00544     Purpose:    Polymorphically copies the contents of this node to another
00545     Errors:     An assertion failure will occur if NodeCopy is NULL
00546     Scope:      protected
00547                                      
00548 ***********************************************************************************************/
00549 
00550 void NodeBrush::PolyCopyNodeContents(NodeRenderable* pNodeCopy)
00551 {
00552     ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
00553     ENSURE(IS_A(pNodeCopy, NodeBrush), "PolyCopyNodeContents given wrong dest node type");
00554 
00555     if (IS_A(pNodeCopy, NodeBrush))
00556         CopyNodeContents((NodeBrush*)pNodeCopy);
00557 }
00558 
00559 
00560 
00561 /********************************************************************************************
00562 
00563 >   virtual String NodeBrush::Describe(BOOL Plural, BOOL Verbose = TRUE)
00564 
00565     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00566     Created:    6/10/99
00567     Inputs:     Plural: Flag indicating if the string description should be plural or
00568                         singular. 
00569     Outputs:    -
00570     Retuns:     Description of the blend node 
00571     Purpose:    To return a description of the Brush object in either the singular or the 
00572                 plural. This method is called by the DescribeRange method.
00573                 
00574                 The description will always begin with a lower case letter.   
00575                 
00576     Errors:     -
00577     SeeAlso:    -
00578 
00579 ********************************************************************************************/
00580 
00581 String NodeBrush::Describe(BOOL Plural, BOOL Verbose) 
00582 {     
00583     return m_BrushName;
00584 }
00585 
00586 
00587 /*********************************************************************************************
00588 
00589 >    NodeBrushPath* NodeBrush::GetNodeBtushPath() 
00590 
00591      Author:    Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00592      Created:   6/10/99
00593      Inputs:    
00594      Outputs:   
00595      Returns:   the nodebrushpath used by this brush
00596      Purpose:   as above
00597 **********************************************************************************************/
00598 
00599 NodeBrushPath* NodeBrush::GetNodeBrushPath()
00600 {
00601     return m_pNodeBrushPath;
00602 }
00603 
00604 
00605 
00606 /*********************************************************************************************
00607 
00608 >    void NodeBrush: SetNodeBrushPath() 
00609 
00610      Author:    Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00611      Created:   6/10/99
00612      Inputs:    
00613      Outputs:   
00614      Returns:   the nodebrushpath used by this brush
00615      Purpose:   as above
00616 **********************************************************************************************/
00617 
00618 void NodeBrush::SetNodeBrushPath(NodeBrushPath* pPath)
00619 {
00620     m_pNodeBrushPath = pPath;
00621 
00622 }
00623 
00624 
00625 
00626 /*********************************************************************************************
00627 
00628 >    NodeBrushMaker* NodeBrush::GetNodeBtushMaker() 
00629 
00630      Author:    Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00631      Created:   6/10/99
00632      Inputs:    
00633      Outputs:   
00634      Returns:   the nodebrushMaker used by this brush
00635      Purpose:   as above
00636 **********************************************************************************************/
00637 
00638 NodeBrushMaker* NodeBrush::GetNodeBrushMaker()
00639 {
00640     return m_pNodeBrushMaker;
00641 }
00642 
00643 
00644 
00645 /*********************************************************************************************
00646 
00647 >    void NodeBrush: SetNodeBrushMaker() 
00648 
00649      Author:    Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00650      Created:   6/10/99
00651      Inputs:    
00652      Outputs:   
00653      Returns:   the nodebrushMaker used by this brush
00654      Purpose:   as above
00655 **********************************************************************************************/
00656 
00657 void NodeBrush::SetNodeBrushMaker(NodeBrushMaker* pMaker)
00658 {
00659     m_pNodeBrushMaker = pMaker;
00660 
00661 }
00662 
00663 /*********************************************************************************************
00664 
00665 >    MILLIPOINT NodeBrush: GetBrushSpacing() 
00666 
00667      Author:    Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00668      Created:   19/11/99
00669      Inputs:    
00670      Outputs:   
00671      Returns:   the spacing between objects of this brush
00672      Purpose:   as above
00673 **********************************************************************************************/
00674 
00675 MILLIPOINT NodeBrush::GetBrushSpacing()
00676 {
00677     if (m_pNodeBrushMaker != NULL)
00678         return m_pNodeBrushMaker->GetBrushSpacing();
00679     else
00680     {
00681         ERROR3("NodeBrushMaker is NULL");
00682         return 0;
00683     }
00684 }
00685 
00686 /*********************************************************************************************
00687 
00688 >    void NodeBrush: SetBrushSpacing(MILLIPOINT Spacing) 
00689 
00690      Author:    Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00691      Created:   18/11/99
00692      Inputs:    Spacing to set
00693      Outputs:   
00694      Returns:   -
00695      Purpose:   Sets the distance between brush objects used buy the nodebrushmaker
00696 **********************************************************************************************/
00697 
00698 void NodeBrush::SetBrushSpacing(MILLIPOINT Spacing)
00699 {
00700     if (Spacing >= BRUSH_MIN_SPACING && Spacing >= BRUSH_MAX_SPACING)
00701     {
00702         ERROR3("Invalid spacing got passed to NodeBrush::SetBrushSpacing");     
00703         Spacing = BRUSH_DEFAULT_SPACING;
00704     }
00705             
00706     if (m_pNodeBrushMaker != NULL)
00707     {
00708         m_pNodeBrushMaker->SetBrushSpacing(Spacing);
00709     }
00710     else
00711         ERROR3("NodeBrushMaker is NULL");
00712 
00713 }
00714 
00715 /********************************************************************************************
00716 
00717 >   BOOL NodeBrush::ResetBrushPath() 
00718 
00719     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00720     Created:    6/10/99
00721     Inputs:     -
00722     Outputs:    -
00723     Returns:    TRUE if successful, FALSE otherwise 
00724     Purpose:    Asks the nodebrushmaker to recalculate its number of steps, for use when 
00725                 the nodebrushpath has been edited
00726                 
00727 ********************************************************************************************/
00728 
00729 BOOL NodeBrush::ResetBrushPath()
00730 {
00731     // get the brushmaker to recalculate how many steps it needs
00732     if (m_pNodeBrushMaker != NULL)
00733     {
00734         m_pNodeBrushMaker->RecalculateMaxStep();
00735         m_pNodeBrushMaker->ClearListOfPointsToRender();
00736     }
00737     else
00738     {
00739         ERROR3("NodeBrushMaker is NULL");
00740         return FALSE;
00741     }
00742     return TRUE;
00743 
00744 }
00745 
00746 /********************************************************************************************
00747 
00748 >   BOOL NodeBrush::ReInitialiseInk() 
00749 
00750     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00751     Created:    6/10/99
00752     Inputs:     -
00753     Outputs:    -
00754     Returns:    TRUE if successful, FALSE otherwise 
00755     Purpose:    Asks the nodebrushmaker to reinitialise itself, for use when the ink node has
00756                 been altered, e.g. attribute changes.  Note that this must be called AFTER the
00757                 attribute change in order to work.
00758             
00759 ********************************************************************************************/
00760 
00761 BOOL NodeBrush::ReInitialiseInk()
00762 {
00763     if (m_pNodeBrushMaker!= NULL)
00764     {
00765         NodeRenderableInk* pInk = m_pNodeBrushMaker->GetInkNode();
00766         if (pInk != NULL)
00767         {   
00768             //if (!m_pNodeBrushMaker->InitialiseInk(pInk))
00769             //  return FALSE;
00770             //else
00771             {
00772                 // clear the cache in case we have any points left to render
00773                 m_pNodeBrushMaker->ClearListOfPointsToRender();
00774                 return TRUE;
00775             }
00776         }
00777 
00778     }
00779     ERROR3("NodeBrushMaker is NULL");
00780     return FALSE;
00781 
00782 }
00783 
00784 /********************************************************************************************
00785 
00786 >   void NodeBrush::ChangeNodeBrushPath(NodeBrushPath * pNewPath) 
00787 
00788     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00789     Created:    6/10/99
00790     Inputs:     pNewPath - the new path to set
00791     Outputs:    -
00792     Returns:    TRUE if successful, FALSE otherwise 
00793     Purpose:    Changes the nodebrushpath used by the brush
00794 
00795 ********************************************************************************************/
00796 
00797 /* IMPLEMENTATION NOTE:
00798 This function was written for use when the path was modified using the freehand or bezier tool.
00799 These operations take care of hiding the old nodebrushpath for you, so it is not performed here.
00800 If you wish to use this function for some other purpose then make sure you do something with 
00801 the original nodebrushpath before swapping in a new one
00802 */
00803 
00804 BOOL NodeBrush::ChangeNodeBrushPath(NodeBrushPath* pNewPath)
00805 {
00806     if (pNewPath == NULL)
00807     {
00808         ERROR3("NodeBrushPath is NULL");
00809         return FALSE;;
00810     }
00811 
00812     m_pNodeBrushPath = pNewPath;
00813     if (m_pNodeBrushMaker != NULL)
00814         m_pNodeBrushMaker->InitialisePath(pNewPath);
00815     else
00816     {
00817         ERROR3("NodeBrushMaker is NULL");
00818         return FALSE;;
00819     }
00820     return TRUE;
00821 }
00822 
00823 
00824 /*********************************************************************************************
00825 
00826 >   Node* NodeBrush::HasEditableChild(CCRuntimeClass* ChildClass, Node* pPreviousChild)
00827 
00828      Author:    Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00829      Created:   19/11/99
00830      Inputs:    ChildClass      = the runtime class of the editable object
00831                 pPreviousChild  = a pointer to the previous editable child 
00832                                   returned by 'this' node, NULL if this is the first
00833                                   call to this node.
00834      Outputs:   -
00835      Returns:   A node pointer, to an object which forms part of the editable surface of
00836                 its parent (this node).
00837      Purpose:   This function returns our edit node (the NodeBrushPath)
00838 
00839 **********************************************************************************************/
00840 
00841 Node* NodeBrush::HasEditableChild(CCRuntimeClass* ChildClass, Node* pPreviousChild)
00842 {
00843     if (ChildClass != CC_RUNTIME_CLASS(NodePath))
00844         return NULL;
00845 
00846     NodeBrushPath* pNodeBrushPath = GetNodeBrushPath();
00847     // check to see if this has already been asked for once
00848     if (((Node*)pNodeBrushPath) == pPreviousChild)
00849         return NULL;
00850 
00851     return pNodeBrushPath;
00852 }
00853 
00854 
00855 /*********************************************************************************************
00856 
00857 >    NodeRenderableInk* NodeBrush: GetInkNode() 
00858 
00859      Author:    Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00860      Created:   19/11/99
00861      Inputs:    
00862      Outputs:   
00863      Returns:   the ink node used by the nodebrushmaker to generate the blendpaths
00864      Purpose:   as above
00865 **********************************************************************************************/
00866 
00867 NodeRenderableInk* NodeBrush::GetInkNode()
00868 {
00869     if (m_pNodeBrushMaker != NULL)
00870     {
00871         return m_pNodeBrushMaker->GetInkNode();
00872     }
00873     return NULL;
00874 }
00875 
00876 
00877 
00878 /********************************************************************************************
00879 
00880 >   virtual BOOL NodeBrush::AllowOp(ObjChangeParam* pParam,BOOL SetOpPermissionState = TRUE)
00881 
00882     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00883     Created:    6/12/99
00884     Inputs:     pParam               = describes the way an op wants to change the node
00885                 SetOpPermissionState = if TRUE the Op permission state of this node will be set according to
00886                                         the outcome of the call
00887     Outputs:    -
00888     Returns:    TRUE means the node and all its parents are happy with this op, FALSE means don't do it
00889     Purpose:    In this instance, the func gives the brush a chance to stop an op from happening to one
00890                 of its children.
00891                 Currently the only permitted ops on children are those that change their appearance, .eg.
00892                 change fill, line width etc.
00893                         
00894                 This must be called *before* the op is performed.
00895     SeeAlso:    Node::AllowOp(),GetOpPermission(),SetOpPermission();
00896 
00897 ********************************************************************************************/
00898 
00899 BOOL NodeBrush::AllowOp(ObjChangeParam* pParam, BOOL SetOpPermissionState)
00900 {
00901     ERROR2IF(pParam==NULL,FALSE,"NodeBlend::AllowOp() - pParam==NULL");
00902 
00903     // clean out the calling-child ptr, so it doesn't get passed around unintentionally.
00904     pParam->SetCallingChild(NULL);
00905 
00906     // decide if we allow it ... (and if we'll still exist after the op)
00907     BOOL allowed=TRUE;
00908     ObjChangeFlags Flags=pParam->GetChangeFlags();
00909     if (pParam->GetDirection()==OBJCHANGE_CALLEDBYCHILD)
00910     {
00911         if  (Flags.DeleteNode || Flags.MultiReplaceNode || Flags.MoveNode)
00912         {
00913             pParam->SetReasonForDenial(_R(IDS_BLEND_CANT_OP_ON_CHILDREN));
00914             allowed=FALSE;
00915         }
00916     }
00917 
00918     // if we allow it, (and our parents weren't calling us) see if our parents do ...
00919     if (allowed && pParam->GetDirection()!=OBJCHANGE_CALLEDBYPARENT && Parent!=NULL)
00920     {
00921         ObjChangeDirection OldDirection=pParam->GetDirection();
00922         pParam->SetCallingChild(this);
00923         pParam->SetDirection(OBJCHANGE_CALLEDBYCHILD);
00924         allowed=Parent->AllowOp(pParam,SetOpPermissionState);
00925         pParam->SetDirection(OldDirection);
00926     }
00927 
00928     if (allowed && pParam->GetDirection() == OBJCHANGE_CALLEDBYCHILD)
00929     {
00930         if (pParam->GetOpPointer())
00931         {
00932             if (pParam->GetOpPointer()->IS_KIND_OF(OpApplyShadow))
00933             {
00934                 allowed = FALSE;
00935             }
00936 
00937 PORTNOTE("other", "Removed use of OpCreateBevel from NodeBrush::AllowOp")
00938 #if !defined(EXCLUDE_FROM_XARALX)
00939             if (pParam->GetOpPointer()->IS_KIND_OF(OpCreateBevel))
00940             {
00941                 allowed = FALSE;
00942             }
00943 #endif
00944         }
00945     }
00946 
00947     // if setting permisions ... (and possibly cause post-op code to be called)
00948     if (SetOpPermissionState)
00949     {
00950         if (allowed)
00951         {
00952             if (Parent!=NULL)
00953                 Parent->SetOpPermission(PERMISSION_ALLOWED);
00954 
00955             // if post process required, ensure our OnChildChange is called (by setting permission on ourself),
00956             // insert an inverse action in the undo
00957             if (pParam->GetDirection()==OBJCHANGE_CALLEDBYCHILD || Flags.Attribute)
00958             {
00959                 SetOpPermission(PERMISSION_ALLOWED);
00960 PORTNOTE("other", "Removed use of ChangeBrushOpParam from NodeBrush::AllowOp")
00961 #if !defined(EXCLUDE_FROM_XARALX)
00962                 UndoableOperation* pOp=pParam->GetOpPointer();
00963                 if (pOp!=NULL)
00964                 {
00965                     ChangeBrushOpParam BrushParam;
00966                     BrushParam.ChangeType = CHANGEBRUSH_REGEN;
00967                     ChangeBrushAction* pNewAction;
00968                     if (allowed) allowed=(ChangeBrushAction::Init(pOp, pOp->GetUndoActionList(), this, 
00969                                            &BrushParam, &pNewAction) != AC_FAIL);
00970                     if (allowed) allowed=pOp->DoInvalidateNodeRegion(this,TRUE);
00971                 }
00972 #endif
00973             }
00974         }
00975         else
00976             SetOpPermission(PERMISSION_DENIED,TRUE);
00977     }
00978 
00979     // if the op was allowed, inform our children by calling their AllowOp()s
00980     // this must be done after we've inserted our undo actions so that any child undo actions will be undone first!
00981     if (allowed && pParam->GetDirection()!=OBJCHANGE_CALLEDBYCHILD)
00982         AllowOp_AccountForCompound(pParam, SetOpPermissionState);
00983 
00984 
00985     // return result (directly, or indirectly via a child AllowOp()) to op
00986     return allowed;
00987 }
00988 
00989 
00990 /********************************************************************************************
00991 
00992 >   virtual ChangeCode NodeBlend::OnChildChange(ObjChangeParam* pParam)
00993 
00994     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00995     Created:    6/12/99
00996     Inputs:     pParam  = pointer to a object change parameter class
00997     Returns:    CC_OK       if we have successfully processed the change.
00998                 CC_FAIL     if we cannot handle this particular change and must prevent the
00999                             child from continuing
01000     Purpose:    This function should be overridden in derived object classes.
01001                 Composite objects can use this function to respond to one of their children
01002                 undergoing a change. They should return CC_FAIL whenever they are unable to
01003                 cope with the change.
01004 
01005                 Brushes simply regenerate themselves at the moment.
01006 
01007     SeeAlso:    WarnParentOfChange(),AllowOp();
01008 
01009 ********************************************************************************************/
01010 
01011 ChangeCode NodeBrush::OnChildChange(ObjChangeParam* pParam)
01012 {
01013 PORTNOTE("other","NodeBrush::OnChildChange - ChangeBrushAction ChangeBrushOpParam")
01014 #ifndef EXCLUDE_FROM_XARALX
01015     ERROR2IF(pParam == NULL,CC_FAIL,"pParam == NULL");
01016 
01017     ObjChangeType cType  = pParam->GetChangeType();
01018     ObjChangeFlags Flags = pParam->GetChangeFlags();
01019 
01020     if (cType == OBJCHANGE_FINISHED)
01021     {
01022         UndoableOperation* pUndoOp = pParam->GetOpPointer();
01023 
01024         if (pUndoOp == NULL)
01025         {
01026             ERROR3("Couldn't get undo op");
01027             return CC_FAIL;
01028         }
01029 
01030         ChangeBrushAction* pAction;
01031         ChangeBrushOpParam OpParam;
01032         OpParam.ChangeType = CHANGEBRUSH_REGEN;
01033         
01034         BOOL ok = (ChangeBrushAction::Init(pUndoOp, pUndoOp->GetUndoActionList(), 
01035             this, &OpParam, &pAction) != AC_FAIL);
01036     
01037         if (ok) ok = pUndoOp->DoInvalidateNodeRegion(this,TRUE);
01038 
01039         if (ok)
01040             return CC_OK;
01041         else
01042             return CC_FAIL;
01043     }
01044 #endif
01045     return CC_OK;
01046 }

Generated on Sat Nov 10 03:45:59 2007 for Camelot by  doxygen 1.4.4