OpCreateContour Class Reference

Creates contours on the selection. More...

#include <opcntr.h>

Inheritance diagram for OpCreateContour:

SelOperation UndoableOperation Operation MessageHandler ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 OpCreateContour ()
 Constructor.
 ~OpCreateContour ()
 Destructor.
virtual void Do (OpDescriptor *pOpDesc)
 The do function. Applys a Bevel to the selection in the current document.
virtual void DoWithParam (OpDescriptor *pOp, OpParam *pParam)
 Applys a Bevel to the selected node after a mouse click.
virtual BOOL MayChangeNodeBounds () const

Static Public Member Functions

static BOOL Declare ()
 Adds the operation to the list of all known operations.
static OpState GetState (String_256 *Description, OpDescriptor *)
 Find out the state of the new regular shape at the specific time.

Detailed Description

Creates contours on the selection.

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/8/99

Definition at line 169 of file opcntr.h.


Constructor & Destructor Documentation

OpCreateContour::OpCreateContour  ) 
 

Constructor.

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/8/99

Definition at line 180 of file opcntr.cpp.

00181 {
00182     //TRACEUSER( "MarkH", _T("Just Made a OpCreateContour Class!\n"));
00183 }

OpCreateContour::~OpCreateContour  ) 
 

Destructor.

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/8/99

Definition at line 194 of file opcntr.cpp.

00195 {
00196     //TRACEUSER( "MarkH", _T("Just Killed OpCreateContour Class!!!\n"));
00197 }


Member Function Documentation

BOOL OpCreateContour::Declare  )  [static]
 

Adds the operation to the list of all known operations.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/11/94
Returns:
TRUE if all went OK, False otherwise

Definition at line 665 of file opcntr.cpp.

00666 {
00667     return (RegisterOpDescriptor(
00668                                 0, 
00669                                 _R(IDS_CREATECONTOUROP),
00670                                 CC_RUNTIME_CLASS(OpCreateContour), 
00671                                 OPTOKEN_CREATECONTOUR,
00672                                 OpCreateContour::GetState));
00673 
00674 }

void OpCreateContour::Do OpDescriptor pOpDesc  )  [virtual]
 

The do function. Applys a Bevel to the selection in the current document.

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/8/99
Parameters:
pOpDesc - OpDescriptor - unused [INPUTS]
- [OUTPUTS]
Returns:
-

Reimplemented from Operation.

Definition at line 211 of file opcntr.cpp.

00212 {
00213     End();
00214 }

void OpCreateContour::DoWithParam OpDescriptor pOp,
OpParam pParam
[virtual]
 

Applys a Bevel to the selected node after a mouse click.

Author:
David_McClarnon (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/8/99
Parameters:
[INPUTS] 
- [OUTPUTS]
Returns:
-

Reimplemented from Operation.

Definition at line 228 of file opcntr.cpp.

00229 {
00230     DoStartSelOp(TRUE, TRUE);
00231     ObjChangeFlags cFlags;
00232     cFlags.RegenerateNode = TRUE;
00233     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
00234 
00235     String_64 StatusString;
00236     StatusString.Load(_R(IDS_CONTOUR_CREATE_STATUS_STRING));
00237 
00238     BeginSlowJob(-1, TRUE, &StatusString);
00239 
00240     String_256 s(StatusString);
00241     GetApplication()->UpdateStatusBarText(&s, FALSE);
00242 
00243     CreateContourParam * pCCP = (CreateContourParam *)pParam;
00244 
00245     List * pNodeList = pCCP->m_pNodeList;
00246 
00247     // first, remove all contours from the list
00248     List ContourList;
00249 
00250     NodeListItem * pItem = (NodeListItem *)pNodeList->GetHead();
00251     NodeListItem * pContourItem = NULL;
00252 
00253     BOOL ok = TRUE;
00254 
00255     NodeHidden * pHidden = NULL;
00256 
00257     while (pItem)
00258     {
00259         BevelTools::GetAllNodesUnderNode(pItem->pNode, &ContourList, CC_RUNTIME_CLASS(NodeContourController));
00260         
00261         if (!ContourList.IsEmpty())
00262         {
00263             TRACEUSER( "DavidM", _T("Found non-empty contour list\n"));
00264             pContourItem = (NodeListItem *)ContourList.GetHead();
00265             
00266             while (pContourItem)
00267             {
00268                 // remove the contour node, and promote all children
00269                 // invalidate the node
00270                 if (ok)
00271                     ok = DoInvalidateNodeRegion((NodeRenderableInk *)pContourItem->pNode, TRUE);
00272 
00273                 // factor out the child attributes
00274                 if (ok)
00275                     ok = DoLocaliseCommonAttributes((NodeRenderableInk *)pContourItem->pNode, TRUE);
00276                 
00277                 // now, move all child nodes upwards (except for the 'needs parent' nodes)
00278                 Node * pChild = pContourItem->pNode->FindFirstChild();
00279                 Node * pNextChild = NULL;
00280                 
00281                 while (pChild)
00282                 {
00283                     pNextChild = pChild->FindNext();
00284                     if (ok && !pChild->NeedsParent(pContourItem->pNode) && !pChild->IsAnAttribute())
00285                         ok = DoMoveNode(pChild, pContourItem->pNode, PREV);
00286                     
00287                     pChild = pNextChild;
00288                 }
00289                 
00290                 
00291                 // hide the original node
00292                 if (ok)
00293                     ok = DoHideNode(pContourItem->pNode, TRUE, &pHidden, FALSE);
00294                 
00295                 // move on
00296                 pContourItem = (NodeListItem *)ContourList.GetNext(pContourItem);
00297             }
00298             
00299             ContourList.DeleteAll();
00300 
00301             if (ok)
00302                 ok = DoFactorOutCommonChildAttributes((NodeRenderableInk *)pItem->pNode);
00303         }
00304         
00305         pItem = (NodeListItem *)pNodeList->GetNext(pItem);
00306     }
00307 
00308     pItem = (NodeListItem *)pNodeList->GetHead();
00309 
00310 //  CCAttrMap * pAttrMap = NULL;
00311     AttrLineWidth * pLineWidthAttr = NULL;
00312     AttrStrokeColour * pStrokeColourAttr = NULL;
00313 //  AttrStartArrow * pAttrStartArrow = NULL;
00314 //  AttrEndArrow * pAttrEndArrow = NULL;
00315 //  FlatFillAttribute * pFillAttr = NULL;
00316 //  StrokeColourAttribute * pStrokeAttr = NULL;
00317 //  NodeAttribute * pAttr = NULL;
00318 
00319     DocColour StrokeColour;
00320     MILLIPOINT LineWidth = 0;
00321 //  INT32 Red = 0;
00322 //  INT32 Blue = 0;
00323 //  INT32 Green = 0;
00324 
00325     Path ArrowPath;
00326     ArrowPath.Initialise();
00327 
00328     while (pItem && ok)
00329     {
00330         if (pItem->pNode->IsNodePath() && pItem->pNode->AllowOp(&ObjChange))
00331         {
00332             // for all closed paths in the selection, copy their stroke attribute
00333             // colour as a fill attribute
00334             NodePath * pPathNode = (NodePath *)pItem->pNode;
00335 
00336             // find out if the path is closed
00337             if (!pPathNode->InkPath.IsSubPathClosed(0))
00338             {
00339                 // first, localise all the common attributes
00340                 if (ok)
00341                     ok = DoLocaliseForAttrChange(pPathNode, (AttrTypeSet *)NULL, (ObjectSet *)NULL);
00342                 
00343                 // get the line width & the stroke colour out of the node
00344                 pLineWidthAttr = (AttrLineWidth *)pPathNode->FindFirstChild(CC_RUNTIME_CLASS(AttrLineWidth));
00345                 pStrokeColourAttr = (AttrStrokeColour *)pPathNode->FindFirstChild(CC_RUNTIME_CLASS(AttrStrokeColour));
00346 
00347                 if (pLineWidthAttr)
00348                     LineWidth = pLineWidthAttr->Value.LineWidth;
00349 
00350                 if (pStrokeColourAttr)
00351                     StrokeColour = pStrokeColourAttr->Value.Colour;
00352 
00353                 // eliminate all fills from this node
00354                 if (ok)
00355                     ok = DoRemoveAttrTypeFromSubtree(pPathNode, CC_RUNTIME_CLASS(AttrFillGeometry));
00356 
00357                 // create a new flat fill attribute & apply it to this node
00358                 AttrFlatColourFill * pFlatFill = NULL;
00359                 ALLOC_WITH_FAIL(pFlatFill, new AttrFlatColourFill, this);
00360 
00361                 pFlatFill->SetStartColour(&StrokeColour);
00362 
00363                 if (ok)
00364                 {
00365                     // [Phil, 17-09-2005]
00366                     // NO!
00367                     // Geez, DMc, you can't cast an AttrFlatColourFill* to a NodeRenderableBounded*!
00368                     // That means that you can't call DoInsertNewNode, so we have to do the same thing
00369                     // in essence directly...
00370                     //                  ok = DoInsertNewNode((NodeRenderableBounded *)pFlatFill, pPathNode,
00371                     //                      FIRSTCHILD, FALSE, FALSE, FALSE, FALSE);
00372                     pFlatFill->AttachNode(pPathNode, FIRSTCHILD);
00373                     HideNodeAction* UndoHideNodeAction;
00374                     if (HideNodeAction::Init(this, this->GetUndoActions(), pFlatFill, TRUE, (Action**)(&UndoHideNodeAction))
00375                             == AC_FAIL)
00376                     {
00377                         pFlatFill->CascadeDelete();
00378                         delete pFlatFill;
00379                         pFlatFill = FALSE;
00380                         FailAndExecute();
00381                         End();
00382                         return;
00383                     }
00384                 }
00385 
00386                 // factor out all the attributes
00387                 if (ok)
00388                     ok = DoFactorOutAfterAttrChange(pPathNode, (AttrTypeSet *)NULL);
00389             }
00390         }
00391 
00392         pItem = (NodeListItem *)pNodeList->GetNext(pItem);
00393     }
00394 
00395     if (!ok)
00396     {
00397         FailAndExecute();
00398         End();
00399         return;
00400     }
00401 
00402     // have we any shadow nodes present ?
00403     // if so, build a new list
00404     pItem = (NodeListItem *)pNodeList->GetHead();
00405     NodeListItem * pNewItem = NULL;
00406     Node * pNode = NULL;
00407     Node * pShadowNode = NULL;
00408 
00409     List ListToContour;
00410 
00411     while (pItem)
00412     {
00413         // find out if any parents are shadow controllers
00414         pNode = pItem->pNode;
00415         pShadowNode = NULL;
00416         
00417         while (pNode)
00418         {
00419             if (pNode->IS_KIND_OF(NodeShadowController))
00420                 pShadowNode = pNode; // we've found a shadow controller node
00421 
00422             pNode = pNode->FindParent();
00423         }
00424 
00425         // do we have a shadow node ? if so, make all non-needs parent children
00426         // be contoured
00427         if (pShadowNode)
00428         {
00429             // first, localise all attributes
00430             DoLocaliseCommonAttributes((NodeShadowController *)pShadowNode, TRUE);          
00431 
00432             // add children to the contour list
00433             pNode = pShadowNode->FindFirstChild();
00434             
00435             while (pNode)
00436             {
00437                 if (!pNode->NeedsParent(pShadowNode))
00438                 {
00439                     if (pNode->IsAnObject())
00440                     {
00441                         ALLOC_WITH_FAIL(pNewItem, new NodeListItem(pNode), this);
00442                         ListToContour.AddTail(pNewItem);
00443                     }
00444                 }
00445 
00446                 pNode = pNode->FindNext();
00447             }
00448         }
00449         else
00450         {
00451             ALLOC_WITH_FAIL(pNewItem, new NodeListItem(pItem->pNode), this);
00452             ListToContour.AddTail(pNewItem);
00453         }
00454 
00455         pItem = (NodeListItem *)pNodeList->GetNext(pItem);
00456     }
00457     
00458     // create the tree factory
00459     ContourNodeTreeFactory * pFactory = NULL;
00460     ALLOC_WITH_FAIL(pFactory, new ContourNodeTreeFactory, this);
00461 
00462     pFactory->SetNumberOfSteps(pCCP->m_Steps);
00463     pFactory->SetWidth(pCCP->m_Width);
00464     pFactory->SetInsetPathFlag(pCCP->m_bInsetPath);
00465 
00466     List SingleNodeList;
00467 
00468     // handle each node individually
00469     pItem = (NodeListItem *)ListToContour.GetHead();
00470 
00471     NodeBlender * pBlender = NULL;
00472 
00473     while (pItem)
00474     {
00475         ALLOC_WITH_FAIL(pNewItem, new NodeListItem(pItem->pNode), this);
00476 
00477         SingleNodeList.AddTail(pNewItem);
00478         
00479         NodeContourController * pContourNode = (NodeContourController *)pFactory->CreateNode(&SingleNodeList, this);
00480 
00481         SingleNodeList.DeleteAll();
00482         
00483         // do we have a parent shadow node ? if so, regenerate 
00484         if (!pContourNode)
00485         {
00486             FailAndExecute();
00487             End();
00488             ListToContour.DeleteAll();
00489             
00490             return;
00491         }
00492 
00493         // check for a blend needing to be re-initialised
00494         pBlender = (NodeBlender *)pContourNode->FindNext(CC_RUNTIME_CLASS(NodeBlender));
00495 
00496         if (pBlender)
00497         {
00498             if (InitBlendAction::InitOnBlender(this, GetUndoActionList(), pBlender, TRUE, TRUE) != AC_OK)
00499                 ERROR2RAW("Couldn't Initialise blend action");
00500 
00501             pBlender->Reinit(pContourNode,  pBlender->GetNodeEnd(), FALSE);
00502         }
00503         else
00504         {
00505             pBlender = (NodeBlender *)pContourNode->FindPrevious(CC_RUNTIME_CLASS(NodeBlender));
00506 
00507             if (pBlender)
00508             {
00509                 if (InitBlendAction::InitOnBlender(this, GetUndoActionList(), pBlender, TRUE, TRUE) != AC_OK)
00510                     ERROR2RAW("Couldn't Initialise blend action");
00511                     
00512                 pBlender->Reinit(pBlender->GetNodeStart(),  pContourNode, FALSE);
00513             }
00514         }
00515 
00516         if (pBlender)
00517         {
00518             NodeBlend* ptrBlend = (NodeBlend*) pBlender->FindParent ();
00519 
00520             ERROR3IF (!IS_A (ptrBlend, NodeBlend), "NodeBlend is not a NodeBlend!");
00521 
00522             BOOL done = FALSE;
00523             NodeBlender* ptrNode = ptrBlend->FindFirstBlender ();
00524 
00525             while (!done)
00526             {
00527                 if (ptrNode != pBlender)
00528                 {
00529                     if (ptrNode->GetNodeStart () == pItem->pNode)
00530                     {
00531                         if (InitBlendAction::InitOnBlender(this, GetUndoActionList(), ptrNode, TRUE, TRUE) != AC_OK)
00532                             ERROR2RAW("Couldn't Initialise blend action");
00533 
00534                         if (pContourNode)
00535                             ptrNode->Reinit(pContourNode, NULL, FALSE);
00536                     }
00537                     if (ptrNode->GetNodeEnd () == pItem->pNode)
00538                     {
00539                         if (InitBlendAction::InitOnBlender(this, GetUndoActionList(),  ptrNode, TRUE, TRUE) != AC_OK)
00540                             ERROR2RAW("Couldn't Initialise blend action");
00541 
00542                         if (pContourNode)
00543                             ptrNode->Reinit(NULL, pContourNode, FALSE);
00544                     }
00545                 }
00546 
00547                 ptrNode = ptrBlend->FindNextBlender (ptrNode);
00548 
00549                 if (!ptrNode)
00550                     done = TRUE;
00551             }
00552         }
00553         
00554         pNode = pContourNode->FindParent();
00555         
00556         while (pNode)
00557         {
00558             pNode->AllowOp(&ObjChange);
00559             pNode = pNode->FindParent();
00560         }
00561 
00562         // deselect all nodes under the contour node, and select all original nodes
00563         if (!pCCP->m_bInsetPath)
00564         {
00565             pNode = pContourNode->FindFirstChild();
00566             pContourNode->SetSelected(FALSE);
00567             
00568             while (pNode)
00569             {
00570                 if (pNode->IsAnObject() && !pNode->NeedsParent(NULL))
00571                     pNode->SetSelected(TRUE);
00572                 
00573                 pNode = pNode->FindNext();
00574             }
00575         }
00576         else
00577         {
00578             NodeContour* pContour = pContourNode->GetContourNode();
00579             ERROR3IF(!pContour,"Failed to get the contour node from the controller node!");
00581             NodeRenderableInk* pChild = pContourNode->FindFirstChildInk();
00582             CCAttrMap AttrMap;
00583             
00584             if(pChild)
00585                 ((NodeRenderableInk *)pChild)->FindAppliedAttributes(&AttrMap);
00586 
00587             DoInvalidateNodeRegion(pContourNode,FALSE);
00588 
00589             // Create the DoBecomeA Function and call it on the controller
00590             BecomeA BecomeAReplace(BECOMEA_REPLACE, CC_RUNTIME_CLASS(NodePath), this, FALSE);
00591             pContour->DoBecomeA(&BecomeAReplace);
00592 
00593             // Now get the relavent path from the group of path nodes
00594             NodePath* pPathToCopy = NULL;
00595 
00596             if(pContourNode->IsContourAnOuterContour())
00597                 pPathToCopy = (NodePath*)pContourNode->FindFirstChild(CC_RUNTIME_CLASS(NodePath));
00598             else
00599                 pPathToCopy = (NodePath*)pContourNode->FindLastChild(CC_RUNTIME_CLASS(NodePath));
00600 
00601             // pPathToCopy may be NULL if the inset contour operation reduced the input paths
00602             // to nothingness...
00603             if (pPathToCopy)
00604             {
00605                 // Create and initialize a new NodePath to hold the inset path!
00606                 NodePath* pNewPath;
00607                 ALLOC_WITH_FAIL(pNewPath, new NodePath, this);
00608                 pNewPath->InkPath.Initialise();
00609     
00610                 pNewPath->InkPath.CloneFrom(pPathToCopy->InkPath);
00611     
00612                 // now Initialize the flag array with the new Path and insert it after the group node!
00613                 pNewPath->InkPath.InitialiseFlags(0, pNewPath->InkPath.GetNumCoords());
00614                 DoInsertNewNode(pNewPath, pContourNode, NEXT, TRUE, FALSE, TRUE, TRUE);
00615     
00616                 pNewPath->InkPath.IsFilled = TRUE;
00617     
00618                 // Make sure we have the correct attributes applied to our new path and make it selected!
00619                 AttrMap.ApplyAttributesToNode(pNewPath);
00620                 pNewPath->NormaliseAttributes();
00621                 
00622                 pNewPath->SetSelected(TRUE);
00623             }
00624             
00625             DoHideNode(pContourNode, TRUE, &pHidden, TRUE);
00627 /*
00628             pContourNode->SetSelected(FALSE);
00629             pContour->SetSelected(TRUE);
00630 
00631             // do a do become a for the contour node
00632             BecomeA BecomeAReplace(BECOMEA_REPLACE, CC_RUNTIME_CLASS(NodePath), this, FALSE);
00633             pContourNode->DoBecomeA(&BecomeAReplace);
00634 */
00635         }
00636 
00637         SliceHelper::AddNamesToController(this,pContourNode);
00638 
00639         pItem = (NodeListItem *)ListToContour.GetNext(pItem);
00640     }
00641         
00642     ListToContour.DeleteAll();
00643 
00644     delete pFactory;
00645     pFactory = NULL;
00646 
00647     ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
00648     UpdateChangedNodes(&ObjChange, Document::GetSelectedSpread());
00649 
00650     GetApplication()->UpdateSelection();
00651     
00652     End();
00653 }

OpState OpCreateContour::GetState String_256 Description,
OpDescriptor
[static]
 

Find out the state of the new regular shape at the specific time.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/11/94
Parameters:
- [OUTPUTS]
Returns:
Ungreyed, Unticked

Definition at line 689 of file opcntr.cpp.

00690 {
00691     OpState Blobby;
00692 
00693     if (Description)
00694         Description->Load(_R(IDS_CONTOUR_CREATE_STATUS_STRING));
00695     
00696     return Blobby;
00697 }

virtual BOOL OpCreateContour::MayChangeNodeBounds  )  const [inline, virtual]
 

Reimplemented from SelOperation.

Definition at line 187 of file opcntr.h.

00187 { return TRUE; }


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