OpClosePathWithPath Class Reference

This op deals with a destination path being edited, and a source path which may be the result of a drag edit operation. The idea is that the op will take the components of the source path and add them in a deterministic way to the destination path, resulting in a closed destination path. The source path is assumed to have either 1 or 2 elements in it. The first element will be added to the end of the destination path and act as a closing piece. The second element of the source path will affect the first element in the destination path. If both elements match in type, ie are two curves, then the none end control handles of the source will be copied to the destination. This op as can be seen is rather specific, and is used by the pen tool to close an open path. Imagine clicking on the first control point of a path and draging out control handles. The handles will affect the previous and next elements of the path. The previous being a close element and the next being the first element of the path. Hence the need for this strange op. More...

#include <penedit.h>

Inheritance diagram for OpClosePathWithPath:

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

Public Member Functions

 OpClosePathWithPath ()
 OpClosePathWithPath constructor.
void GetOpName (String_256 *OpName)
 The GetOpName fn is overridden so that we return back a description appropriate to the type of attribute that the operation applies.
void DoClosePathWithPath (NodePath *pDestinNode, Path *pAddPath, INT32 index)
 This op takes as parameters a destination path being affected, and a source path which may be the result of a drag edit operation. The idea is that the op will take the components of the source path and add them in a deterministic way to the destination path, resulting in a closed destination path. The source path is assumed to have either 1 or 2 elements in it. The first element will be added to the end of the destination path and act as a closing piece. The second element of the source path will affect the first element in the destination path. If both elements match in type, ie are two curves, the none end control handles of the source will be copied to the destination. This op as can be seen is rather specific, and is used by the pen tool to close an open path. Imagine clicking on the first control point of a path and draging out control handles. The handles will affect the previous and next elements of the path. The previous being a close element and the next being the first element of the path. Hence the need for this strange op.

Static Public Member Functions

static BOOL Init ()
 OpClosePathWithPath initialiser method.
static OpState GetState (String_256 *, OpDescriptor *)
 For finding the OpClosePathWithPath's state.

Detailed Description

This op deals with a destination path being edited, and a source path which may be the result of a drag edit operation. The idea is that the op will take the components of the source path and add them in a deterministic way to the destination path, resulting in a closed destination path. The source path is assumed to have either 1 or 2 elements in it. The first element will be added to the end of the destination path and act as a closing piece. The second element of the source path will affect the first element in the destination path. If both elements match in type, ie are two curves, then the none end control handles of the source will be copied to the destination. This op as can be seen is rather specific, and is used by the pen tool to close an open path. Imagine clicking on the first control point of a path and draging out control handles. The handles will affect the previous and next elements of the path. The previous being a close element and the next being the first element of the path. Hence the need for this strange op.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
7/10/94

Definition at line 614 of file penedit.h.


Constructor & Destructor Documentation

OpClosePathWithPath::OpClosePathWithPath  ) 
 

OpClosePathWithPath constructor.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/10/94
See also:
-

Definition at line 2992 of file penedit.cpp.

02993 {
02994 }


Member Function Documentation

void OpClosePathWithPath::DoClosePathWithPath NodePath pDestinNode,
Path pEditPath,
INT32  index
 

This op takes as parameters a destination path being affected, and a source path which may be the result of a drag edit operation. The idea is that the op will take the components of the source path and add them in a deterministic way to the destination path, resulting in a closed destination path. The source path is assumed to have either 1 or 2 elements in it. The first element will be added to the end of the destination path and act as a closing piece. The second element of the source path will affect the first element in the destination path. If both elements match in type, ie are two curves, the none end control handles of the source will be copied to the destination. This op as can be seen is rather specific, and is used by the pen tool to close an open path. Imagine clicking on the first control point of a path and draging out control handles. The handles will affect the previous and next elements of the path. The previous being a close element and the next being the first element of the path. Hence the need for this strange op.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/10/94
Parameters:
pNode = Pointer to nodepath in document to add element to [INPUTS] pEditPath = Pointer to path element to add index = offset of subpath end in destin path. The end can either be the moveto of the subpath or the index of the final coordinate in the subpath.
- [OUTPUTS]

Definition at line 3111 of file penedit.cpp.

03112 {
03113 #ifndef STANDALONE
03114 
03115     BeginSlowJob();
03116 
03117     DoStartSelOp(TRUE,TRUE);
03118     
03119     DocView* pDocView = DocView::GetSelected();
03120     ERROR2IF( pDocView == NULL, (void)0, "There was no selected doc view when closing a path" );
03121 
03122     // Save the bounds of the path for undo/redo
03123     if (RecalcBoundsAction::DoRecalc(this, &UndoActions, pDestinNode) == AC_FAIL)
03124     {
03125         FailAndExecute();
03126         End();
03127         return;
03128     }
03129 
03130     // go and count the number of elements given to us in the edit path
03131     INT32 ind = 0;
03132     INT32 i;
03133     for (i=0; pEditPath->FindNext(&ind); i++);
03134     ENSURE(i<3, "There are two many elements in the edit path when closing a path" );
03135 
03136     if (i<1 || i>2)
03137     {
03138         FailAndExecute();
03139         End();
03140         return;
03141     }
03142 
03143     // get a pointer to the destination path
03144     Path* pDestinPath = &(pDestinNode->InkPath);
03145 
03146     // Get the arrays for these paths
03147     PathFlags* SFlags  = pEditPath->GetFlagArray();
03148     PathVerb*  SVerbs  = pEditPath->GetVerbArray();
03149     PathVerb*  DVerbs  = pDestinPath->GetVerbArray();
03150 
03151     BOOL OnMove = (DVerbs[index] == PT_MOVETO);
03152 
03153     INT32 SEnd = 0;
03154     pEditPath->FindEndOfSubPath(&SEnd);
03155     
03156     if (i==2)
03157     {
03158         // if we have two elements in the path, go and affect the first element in
03159         // the destin path with the data held in the second element of the edit path
03160         // Er, this could be the other way around so watch out!
03161 
03162         INT32 First = index;
03163         INT32 Second;
03164 
03165         if (OnMove)
03166         {
03167             First++;
03168             Second = First+1;
03169         }
03170         else
03171         {
03172             First--;
03173             Second = First-1;
03174         }
03175 
03176         // If the elements match in type, affect the destination
03177         if ((SVerbs[SEnd] == DVerbs[First]) && (DVerbs[First] == PT_BEZIERTO))
03178         {
03179             
03180             DocCoord*  SCoords = pEditPath->GetCoordArray();
03181             DocCoord*  DCoords = pDestinPath->GetCoordArray();
03182             PathFlags* DFlags  = pDestinPath->GetFlagArray();
03183 
03184             ModifyElementAction* UnAction;
03185             ActionCode Act;
03186 
03187             // Alter the moveto's flags
03188             Act = ModifyElementAction::Init(this, 
03189                                             &UndoActions,
03190                                             DVerbs[index],
03191                                             DFlags[index],
03192                                             DCoords[index],
03193                                             index,
03194                                             pDestinNode,
03195                                             (Action**)&UnAction);
03196             if (Act == AC_FAIL)
03197             {   
03198                 FailAndExecute();
03199                 End();
03200                 return;
03201             }
03202             DFlags[index].IsRotate = TRUE;
03203 
03204             // Move the first control point
03205             Act = ModifyElementAction::Init(this, 
03206                                             &UndoActions,
03207                                             DVerbs[First],
03208                                             DFlags[First],
03209                                             DCoords[First],
03210                                             First,
03211                                             pDestinNode,
03212                                             (Action**)&UnAction);
03213             if (Act == AC_FAIL)
03214             {   
03215                 FailAndExecute();
03216                 End();
03217                 return;
03218             }
03219             DCoords[First] = SCoords[SEnd];
03220             DFlags[First].IsRotate = TRUE;
03221 
03222             // Move the second control point
03223             Act = ModifyElementAction::Init(this, 
03224                                             &UndoActions,
03225                                             DVerbs[Second],
03226                                             DFlags[Second],
03227                                             DCoords[Second],
03228                                             Second,
03229                                             pDestinNode,
03230                                             (Action**)&UnAction);
03231             if (Act == AC_FAIL)
03232             {   
03233                 FailAndExecute();
03234                 End();
03235                 return;
03236             }
03237             DCoords[Second] = SCoords[SEnd+1];
03238             DFlags[Second].IsRotate = TRUE;
03239         }
03240 
03241         // now bin the last element of the path
03242         pEditPath->DeleteFromElement(SEnd);
03243     }
03244 
03245     INT32 DStart = index;
03246     INT32 DEnd = index;
03247     pDestinPath->FindStartOfSubPath(&DStart);
03248     pDestinPath->FindEndElOfSubPath(&DEnd);
03249 
03250     if (!OnMove)
03251     {
03252         // if OnMove is false ie someone is closing a curve from the
03253         // selected moveto backwards, then we need to deselect the moveto
03254         // element and reverse the path.
03255 
03256         ActionCode Act = DeselectHandle(pDestinNode, DStart);
03257         if (Act == AC_FAIL)
03258         {   
03259             FailAndExecute();
03260             End();
03261             return;
03262         }
03263         pEditPath->Reverse();
03264     }
03265 
03266     // set a close figure on the element we're about to add and bin any selection
03267     SEnd = (pEditPath->GetNumCoords())-1;
03268     SVerbs[SEnd] = SVerbs[SEnd] | PT_CLOSEFIGURE;
03269     SFlags[SEnd].IsSelected = FALSE;
03270     
03271     // now set the filled bit on the path to make sure it really does
03272     // get filled once closed.
03273     ModifyFilledAction* pAction;
03274 
03275     if (ModifyFilledAction::Init(this, &UndoActions, TRUE, FALSE, pDestinNode, (Action**)(&pAction))== AC_FAIL)
03276     {   
03277         FailAndExecute();
03278         End();
03279         return;
03280     }
03281 
03282     pDestinNode->InkPath.IsFilled = TRUE;
03283 
03284     // Go and copy the edited path to the end of the original
03285     ExecuteType Exe = AugmentPathWithPath(pEditPath, pDestinNode, DEnd);
03286     if (Exe != ExeNone)
03287     {
03288         InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
03289         if (Exe == ExeInclusive)
03290             FailAndExecute();
03291         if (Exe == ExeExclusive)
03292             FailAndExecuteAllButLast();
03293         End();
03294         return;
03295     }   
03296 
03297     // Recalculate the path's bounding box
03298     pDestinNode->InvalidateBoundingRect();
03299     
03300     // tell the world that something in the selection has changed 
03301     // so that selection bounds are updated
03302     GetApplication()->FindSelection()->Update(TRUE);
03303 
03304     // record new bounds action undo/redo
03305     if (RecordBoundsAction::DoRecord(this, &UndoActions, pDestinNode) == AC_FAIL)
03306     {
03307         FailAndExecute();
03308         End();
03309         return;
03310     }
03311 
03312 #endif
03313 
03314     End();
03315 }

void OpClosePathWithPath::GetOpName String_256 OpName  )  [virtual]
 

The GetOpName fn is overridden so that we return back a description appropriate to the type of attribute that the operation applies.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/10/94
Parameters:
- [INPUTS]
The undo string for the operation [OUTPUTS]
Returns:

Errors: -

See also:
-

Reimplemented from Operation.

Definition at line 3070 of file penedit.cpp.

03071 {
03072     *OpName = String_256(_R(IDS_UNDO_CLOSEPATHWITHPATHOP));
03073 }

OpState OpClosePathWithPath::GetState String_256 UIDescription,
OpDescriptor
[static]
 

For finding the OpClosePathWithPath's state.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/10/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
The state of the OpClosePathWithPath

Errors: -

See also:
-

Definition at line 3046 of file penedit.cpp.

03047 {
03048     OpState OpSt;
03049     return OpSt;   
03050 }

BOOL OpClosePathWithPath::Init void   )  [static]
 

OpClosePathWithPath initialiser method.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/10/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
TRUE if the operation could be successfully initialised FALSE if no more memory could be allocated

Errors: ERROR will be called if there was insufficient memory to allocate the operation.

See also:
-

Reimplemented from SimpleCCObject.

Definition at line 3016 of file penedit.cpp.

03017 {
03018     return (RegisterOpDescriptor(0,                                     // tool ID
03019                                 _R(IDS_CLOSEPATHWITHPATHOP),                // string resource ID
03020                                 CC_RUNTIME_CLASS(OpClosePathWithPath),  // runtime class for Op
03021                                 OPTOKEN_CLOSEPATHWITHPATH,              // Ptr to token string
03022                                 OpClosePathWithPath::GetState,          // GetState function
03023                                 0,                                      // help ID = 0
03024                                 _R(IDBBL_CLOSEPATHWITHPATHOP),              // bubble help ID = 0
03025                                 0                                       // resource ID = 0
03026                                 )); 
03027 
03028 }               


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