#include <pathedit.h>
Inheritance diagram for OpNodePathEditBlob:

Public Member Functions | |
| OpNodePathEditBlob () | |
| void | DoStartDragEdit (NodePath *, DocCoord Anchor, Spread *) |
| This is called to start a drag operation on an endpoint on a path. | |
| virtual void | DragPointerMove (DocCoord Pos, ClickModifiers Mods, Spread *pSpread, BOOL bSolidDrag) |
| This is called every time the mouse moves, during a drag. | |
| virtual void | DragFinished (DocCoord Pos, ClickModifiers Mods, Spread *pSpread, BOOL Success, BOOL bSolidDrag) |
| This is called when a drag operation finishes. | |
| virtual void | RenderDragBlobs (DocRect, Spread *, BOOL bSolidDrag) |
| Renders the new version of the path to the window. It makes use of flags in the path to determine which segments of the path need to be rendered. | |
Static Public Member Functions | |
| static BOOL | Init () |
| Adds the operation to the list of all known operations. | |
| static OpState | GetState (String_256 *Description, OpDescriptor *) |
| Find out the state of the operation at the specific time. | |
Protected Member Functions | |
| BOOL | BuildEditPath () |
| Builds a copy of the path that we can edit, without destroying the original data. Also sets the NeedToRender flags for EOR display. | |
| BOOL | BuildEditPaths () |
| Builds a copy of each path in the selection that we can edit, without destroying the original data. Also sets the NeedToRender flags for EOR display. | |
| BOOL | CopyEditedPathBack () |
| Copies the contents of the edited path back into the original path. | |
| BOOL | CopyEditedPathBack (NodePath *pOrigPath, Path *pEditPath) |
| Copies the contents of the edited path back into the original path. | |
| BOOL | CopyNeedToRenderFlags () |
| This function is used to copy the NeedToRender flags from EditPath to OriginalPath. This are then used in optimised region invalidation. | |
| BOOL | CopyNeedToRenderFlags (NodePath *pOrigPath, Path *pEditPath) |
| This function is used to copy the NeedToRender flags from EditPath to OriginalPath. This are then used in optimised region invalidation. | |
| void | RecalculatePath (DocCoord Offset, BOOL SnapEnds=FALSE, INT32 SnapIndex=0) |
| This goes through the path, moves all the selected coords by the offset and then performs some magic to smooth the rest of the path round the changes if it needs it. | |
| void | RecalculatePaths (Path *pEditPath, DocCoord Offset, BOOL SnapEnds=FALSE, INT32 SnapIndex=0) |
| This goes through the path, moves all the selected coords by the offset and then performs some magic to smooth the rest of the path round the changes if it needs it. | |
| void | SnapEndsTogether () |
| Sets the closefigure flag in the last element in the subpath. Also turns off the rotate bit in the points we're snapping together if their smoothing bits are also turned off. This prevents us creating a cusp that has rotate flags set. | |
| void | SnapEndsTogether (Path *pEditPath) |
| Sets the closefigure flag in the last element in the subpath. Also turns off the rotate bit in the points we're snapping together if their smoothing bits are also turned off. This prevents us creating a cusp that has rotate flags set. | |
| BOOL | JoinWithOtherPath () |
| Looks at the member variables dealing with snapping to another path and joins the paths together. It will always join the other path to the original path, keeping the original path's attributes intact. NOTE: This routine will alter the OriginalPath member variable if it joins paths, because it has to make a copy of the path for undo purposes. | |
| BOOL | JoinWithOtherPath (NodePath **pOrigPath) |
| Looks at the member variables dealing with snapping to another path and joins the paths together. It will always join the other path to the original path, keeping the original path's attributes intact. NOTE: This routine will alter the OriginalPath member variable if it joins paths, because it has to make a copy of the path for undo purposes. | |
| BOOL | FillPathIfEndsSnapped () |
| Will look at the EndSnapped flag and set the IsFilled bit in the OriginalPath Builds undo information. Returns FALSE if it couldn't build the Undo info. | |
| BOOL | FillPathIfEndsSnapped (NodePath *pOrigPath) |
| Will look at the EndSnapped flag and set the IsFilled bit in the OriginalPath Builds undo information. Returns FALSE if it couldn't build the Undo info. | |
| virtual void | RenderDraggingBlobs (DocRect, Spread *) |
| Call this function to render all the blobs on screen from this operation. | |
| virtual void | RenderDraggingBlobs (Path *pEditPath, Spread *) |
| Call this function to render all the blobs on screen from this operation. | |
| void | RenderPathEditBlobs (DocRect Rect, Spread *pSpread) |
| void | RenderPathEditBlobs (Path *pEditPath, Spread *pSpread) |
| Call this function to render all the blobs on screen from this operation. | |
| virtual void | SetStatusLineHelp () |
| Updates the status line message to reflect the current situation. | |
| NodeGroup * | GetGroupParentOfCurve () |
| To determine if the current selection is a blend on a curve. | |
| NodeGroup * | GetGroupParentOfCurve (NodePath *pOrigPath) |
| To determine if the current selection is a blend on a curve. | |
| BOOL | InsertChangeBlendStepsAction (NodeBlend *pNodeBlend) |
| To adjust the number of steps in a blend on a path as a result of the path being edited (which is why its here rather than in the blend code). First the number of steps is calculated from the new path distance and if different a new action is inserted. | |
| AttrBrushType * | GetAppliedBrush () |
| To get the brush attribute that is applied to the nodepath we are editing. | |
| virtual BOOL | EditBrushAttribute (INT32 FirstIndex, INT32 LastIndex, AttrBrushType *pAttrBrush) |
| If we use the shape editor to edit a nodepath with an applied brush attribute and this brush attribute makes use of sampled pressure or time information then the brush needs to resample its data. So here we will insert a few actions to make that happen. | |
| MILLIPOINT | GetLengthOfPathSection (Path *pPath, INT32 FirstIndex, INT32 LastIndex) |
| As above, if you want to know the distance between two points on the edit path then this function is for you. | |
| MILLIPOINT | GetDistanceToPathIndex (Path *pPath, INT32 Index) |
| As above,. | |
| void | ChangeCursor (Cursor *cursor) |
| Changes the mouse pointer to a new shape. | |
| BOOL | CreateCursors () |
| Creates the cursor objects for the path operations. | |
| void | DestroyCursors () |
| Deletes the path operation cursors. | |
Protected Attributes | |
| Spread * | StartSpread |
| DocCoord | StartMousePos |
| DocCoord | LastMousePos |
| DocCoord | ConstrainPoint |
| DocCoord | ConstrainPrevPoint |
| DocCoord | ConstrainNextPoint |
| NodePath * | OriginalPath |
| Path | EditPath |
| List | OriginalPaths |
| List | EditPaths |
| List | PathsDragStarted |
| BOOL | MultiplePaths |
| BOOL | EndSnapped |
| BOOL | SnapToAnother |
| NodePath * | SnapToPath |
| INT32 | SnapToIndex |
| BOOL | SnapToLineOrCurve |
| DocCoord | SnapToCoords [4] |
| Cursor * | pMoveCursor |
| Cursor * | pCloseCursor |
| Cursor * | pCrossHairCursor |
| Cursor * | MyCurrentCursor |
| INT32 | CurrentCursorID |
| ObjChangePathEdit | EditObjChange |
| List | ObjChanges |
| INT32 | DragPoint |
| INT32 | UpdatePoint |
| BOOL | DragStarted |
Definition at line 143 of file pathedit.h.
|
|
|
|
|
Builds a copy of the path that we can edit, without destroying the original data. Also sets the NeedToRender flags for EOR display.
Reimplemented in OpNodePathEditControlBlob, and OpReshapeOrAddPoint. Definition at line 2197 of file pathedit.cpp. 02198 { 02199 // Make a copy of the original path 02200 UINT32 NumCoords = OriginalPath->InkPath.GetNumCoords(); 02201 if (!EditPath.Initialise(NumCoords, 24)) 02202 return FALSE; 02203 if (!EditPath.CopyPathDataFrom(&(OriginalPath->InkPath))) 02204 return FALSE; 02205 02206 // Go though all the coords, with scary amounts of looking back and forwards 02207 UINT32 LastEndPoint = 0; // The EndPoint before this one 02208 BOOL SetNextEndPoint = FALSE; // TRUE if we want to set the next EndPoint to render 02209 BOOL SetNextNextEndPoint = FALSE; // TRUE if we want the one after the next one to render 02210 PathFlags* Flags = EditPath.GetFlagArray(); 02211 for (UINT32 i=0; i<NumCoords; i++) 02212 { 02213 // Make all the flags FALSE by default 02214 Flags[i].NeedToRender = FALSE; 02215 02216 if (Flags[i].IsEndPoint) 02217 { 02218 // if the endpoint 2 elements back was selected and the last element was smooth 02219 // then we need to mark this point for rendering 02220 if (SetNextNextEndPoint) 02221 { 02222 Flags[i].NeedToRender = TRUE; 02223 SetNextNextEndPoint = FALSE; 02224 } 02225 02226 // We have found an Endpoint, do we want to mark this one as renderable 02227 if (SetNextEndPoint) 02228 { 02229 // As the last element was selected, this element needs to render 02230 Flags[i].NeedToRender = TRUE; 02231 SetNextEndPoint = FALSE; 02232 02233 // If the smooth flag is set then the next item needs to render as well 02234 if (Flags[i].IsRotate || Flags[i].IsSmooth) 02235 SetNextNextEndPoint = TRUE; 02236 } 02237 02238 // If its selected, then its renderable 02239 if (Flags[i].IsSelected) 02240 { 02241 Flags[i].NeedToRender = TRUE; 02242 if (Flags[LastEndPoint].IsRotate || Flags[LastEndPoint].IsSmooth) 02243 Flags[LastEndPoint].NeedToRender = TRUE; 02244 02245 // Set the flag for the next endpoint 02246 SetNextEndPoint = TRUE; 02247 } 02248 02249 LastEndPoint = i; 02250 } 02251 } 02252 02253 return TRUE; 02254 }
|
|
|
Builds a copy of each path in the selection that we can edit, without destroying the original data. Also sets the NeedToRender flags for EOR display.
Definition at line 2107 of file pathedit.cpp. 02108 { 02109 NodeListItem* pCurrent = (NodeListItem*) OriginalPaths.GetHead (); 02110 02111 while (pCurrent) 02112 { 02113 NodePath* pCurrentPath = (NodePath*) (pCurrent->pNode); 02114 Path* NewEditPath = new Path (); 02115 02116 UINT32 NumCoords = pCurrentPath->InkPath.GetNumCoords(); 02117 02118 if (!NewEditPath->Initialise(NumCoords, 24)) 02119 return FALSE; 02120 if (!NewEditPath->CopyPathDataFrom(&(pCurrentPath->InkPath))) 02121 return FALSE; 02122 02123 // Go though all the coords, with scary amounts of looking back and forwards 02124 UINT32 LastEndPoint = 0; // The EndPoint before this one 02125 BOOL SetNextEndPoint = FALSE; // TRUE if we want to set the next EndPoint to render 02126 BOOL SetNextNextEndPoint = FALSE; // TRUE if we want the one after the next one to render 02127 PathFlags* Flags = NewEditPath->GetFlagArray(); 02128 02129 for (UINT32 i=0; i<NumCoords; i++) 02130 { 02131 // Make all the flags FALSE by default 02132 Flags[i].NeedToRender = FALSE; 02133 02134 if (Flags[i].IsEndPoint) 02135 { 02136 // if the endpoint 2 elements back was selected and the last element was smooth 02137 // then we need to mark this point for rendering 02138 if (SetNextNextEndPoint) 02139 { 02140 Flags[i].NeedToRender = TRUE; 02141 SetNextNextEndPoint = FALSE; 02142 } 02143 02144 // We have found an Endpoint, do we want to mark this one as renderable 02145 if (SetNextEndPoint) 02146 { 02147 // As the last element was selected, this element needs to render 02148 Flags[i].NeedToRender = TRUE; 02149 SetNextEndPoint = FALSE; 02150 02151 // If the smooth flag is set then the next item needs to render as well 02152 if (Flags[i].IsRotate || Flags[i].IsSmooth) 02153 SetNextNextEndPoint = TRUE; 02154 } 02155 02156 // If its selected, then its renderable 02157 if (Flags[i].IsSelected) 02158 { 02159 Flags[i].NeedToRender = TRUE; 02160 if (Flags[LastEndPoint].IsRotate || Flags[LastEndPoint].IsSmooth) 02161 Flags[LastEndPoint].NeedToRender = TRUE; 02162 02163 // Set the flag for the next endpoint 02164 SetNextEndPoint = TRUE; 02165 } 02166 02167 LastEndPoint = i; 02168 } 02169 } 02170 02171 NodeListItem* pInsert = new NodeListItem; 02172 pInsert->pNode = (Node*) NewEditPath; 02173 02174 EditPaths.AddTail (pInsert);//NewEditPath); 02175 02176 pCurrent = (NodeListItem*) OriginalPaths.GetNext (pCurrent); 02177 02178 //delete (pInsert); 02179 02180 // delete (NewEditPath); // cleanup that is necessary 02181 } 02182 02183 return (TRUE); 02184 }
|
|
|
Changes the mouse pointer to a new shape.
Definition at line 4787 of file pathedit.cpp. 04788 { 04789 if (cursor != MyCurrentCursor) 04790 { // only change if this cursor is different from the current cursor 04791 if (MyCurrentCursor != NULL) 04792 { // If one of our cursors is on the stack then get it off 04793 CursorStack::GPop(CurrentCursorID); 04794 } 04795 MyCurrentCursor = cursor; 04796 CurrentCursorID = CursorStack::GPush(cursor); 04797 } 04798 }
|
|
||||||||||||
|
Copies the contents of the edited path back into the original path.
Definition at line 2441 of file pathedit.cpp. 02442 { 02443 // Now to do some undo information. To do this, I have to look at each element in the path 02444 // and each element in the copy, and see which ones differ. I then have to work out how many 02445 // elements that was, and create a path to contain those elements, along with an array of indices 02446 // telling me where those elements came from 02447 INT32 NumElements = pOrigPath->InkPath.GetNumCoords(); 02448 PathVerb* SourceVerbs = pOrigPath->InkPath.GetVerbArray(); 02449 DocCoord* SourceCoords = pOrigPath->InkPath.GetCoordArray(); 02450 PathFlags* SourceFlags = pOrigPath->InkPath.GetFlagArray(); 02451 PathVerb* DestVerbs = pEditPath->GetVerbArray(); 02452 DocCoord* DestCoords = pEditPath->GetCoordArray(); 02453 PathFlags* DestFlags = pEditPath->GetFlagArray(); 02454 02455 INT32 ChangedElements = 0; 02456 INT32 i; 02457 02458 for (i=0;i<NumElements;i++) 02459 { 02460 if (SourceVerbs[i] != DestVerbs[i] || 02461 SourceCoords[i] != DestCoords[i] || 02462 SourceFlags[i] != DestFlags[i] 02463 ) 02464 ChangedElements++; 02465 } 02466 02467 // ChangedElements is the number of elements in this path that will change. 02468 // We have to create three arrays to contain the changed elements, plus one array 02469 // to tell me where the elements should go (the indices) 02470 02471 // I also have to create an action object to contain these arrays. I have to create the action 02472 // object first because that does all the work of deciding if there's enough memory in the 02473 // undo buffer to store the action, and prompting the user accordingly of there isn't 02474 02475 if (ChangedElements > 0) 02476 { 02477 ModifyPathAction* ModAction; 02478 02479 ActionCode Act; 02480 Act = ModifyPathAction::Init(this, &UndoActions, ChangedElements, (Action**)(&ModAction)); 02481 if (Act == AC_FAIL) 02482 { 02483 FailAndExecute(); 02484 End(); 02485 return FALSE; 02486 } 02487 02488 PathVerb* ChangedVerbs=NULL; 02489 DocCoord* ChangedCoords=NULL; 02490 PathFlags* ChangedFlags=NULL; 02491 INT32* ChangedIndices=NULL; 02492 02493 // If the function returned AC_NO_RECORD we shouldn't record any undo information in the action 02494 // NOTE - during unwind all actions return AC_OK with a NULL ModAction pointer!! 02495 if ((Act!=AC_NORECORD) && (ModAction!=NULL)) 02496 { 02497 // This next bit is a bit hellish. Any one of these four allocations can fail, in which case 02498 // we have to tidy up afterwards. Cue a lot of nested ifs and elses. 02499 02500 ALLOC_WITH_FAIL(ChangedVerbs,(PathVerb*) CCMalloc(ChangedElements * sizeof(PathVerb)),this); 02501 if (ChangedVerbs) 02502 { 02503 ALLOC_WITH_FAIL(ChangedCoords,(DocCoord*) CCMalloc(ChangedElements * sizeof(DocCoord)),this); 02504 if (ChangedCoords) 02505 { 02506 ALLOC_WITH_FAIL(ChangedFlags,(PathFlags*) CCMalloc(ChangedElements * sizeof(PathFlags)),this); 02507 if (ChangedFlags) 02508 { 02509 ALLOC_WITH_FAIL(ChangedIndices,(INT32*) CCMalloc(ChangedElements * sizeof(INT32)),this); 02510 if (!ChangedIndices) 02511 { 02512 CCFree( ChangedFlags ); 02513 CCFree( ChangedCoords ); 02514 CCFree( ChangedVerbs); 02515 FailAndExecute(); 02516 End(); 02517 return FALSE; 02518 } 02519 } 02520 else 02521 { 02522 CCFree( ChangedCoords ); 02523 CCFree( ChangedVerbs ); 02524 FailAndExecute(); 02525 End(); 02526 return FALSE; 02527 02528 } 02529 } 02530 else 02531 { 02532 CCFree( ChangedVerbs); 02533 FailAndExecute(); 02534 End(); 02535 return FALSE; 02536 02537 } 02538 } 02539 02540 // Now to put the undo data into the undo action 02541 INT32 index = 0; 02542 for (i=0;i<NumElements;i++) 02543 { 02544 if (SourceVerbs[i] != DestVerbs[i] || 02545 SourceCoords[i] != DestCoords[i] || 02546 SourceFlags[i] != DestFlags[i] 02547 ) 02548 { 02549 ChangedVerbs[index] = SourceVerbs[i]; 02550 ChangedFlags[index] = SourceFlags[i]; 02551 ChangedCoords[index] = SourceCoords[i]; 02552 ChangedIndices[index] = i; 02553 index++; 02554 } 02555 } 02556 02557 // Now we've allocated the arrays, let's tell the action about 'em 02558 ModAction->StoreArrays(ChangedVerbs, ChangedFlags, ChangedCoords, ChangedIndices, pOrigPath); 02559 } 02560 } 02561 02562 if (!pOrigPath->InkPath.CopyPathDataFrom(pEditPath)) 02563 return FALSE; 02564 else 02565 return TRUE; 02566 }
|
|
|
Copies the contents of the edited path back into the original path.
Definition at line 2269 of file pathedit.cpp. 02270 { 02271 // Now to do some undo information. To do this, I have to look at each element in the path 02272 // and each element in the copy, and see which ones differ. I then have to work out how many 02273 // elements that was, and create a path to contain those elements, along with an array of indices 02274 // telling me where those elements came from 02275 INT32 NumElements = OriginalPath->InkPath.GetNumCoords(); 02276 PathVerb* SourceVerbs = OriginalPath->InkPath.GetVerbArray(); 02277 DocCoord* SourceCoords = OriginalPath->InkPath.GetCoordArray(); 02278 PathFlags* SourceFlags = OriginalPath->InkPath.GetFlagArray(); 02279 PathVerb* DestVerbs = EditPath.GetVerbArray(); 02280 DocCoord* DestCoords = EditPath.GetCoordArray(); 02281 PathFlags* DestFlags = EditPath.GetFlagArray(); 02282 02283 // DY now we want to keep track of the indexes of the changed section 02284 INT32 ChangedElements = 0; 02285 INT32 FirstChanged = -1; 02286 INT32 LastChanged = -1; 02287 02288 INT32 i; 02289 for (i=0;i<NumElements;i++) 02290 { 02291 if (SourceVerbs[i] != DestVerbs[i] || SourceCoords[i] != DestCoords[i] || 02292 SourceFlags[i] != DestFlags[i] ) 02293 { 02294 ChangedElements++; 02295 02296 // if (SourceCoords[i] != DestCoords[i]) 02297 { 02298 // if we have not yet set the first changed index then set it 02299 if (FirstChanged == -1) 02300 FirstChanged = i; 02301 02302 // always set the last changed index 02303 LastChanged = i; 02304 } 02305 } 02306 02307 } 02308 02309 02310 // ChangedElements is the number of elements in this path that will change. 02311 // We have to create three arrays to contain the changed elements, plus one array 02312 // to tell me where the elements should go (the indices) 02313 02314 // I also have to create an action object to contain these arrays. I have to create the action 02315 // object first because that does all the work of deciding if there's enough memory in the 02316 // undo buffer to store the action, and prompting the user accordingly of there isn't 02317 02318 if (ChangedElements > 0) 02319 { 02320 // do the brush editing here 02321 // the following block deals with editing path blobs. For some reason I could not get a 02322 // sensible value for the distance of the edited path from the changed indexes, however 02323 // it works quite nicely by finding the contraining points. 02324 if (DragPoint != -1) 02325 { 02326 // this section only applies for editing blobs (as reshaping has no drag point) 02327 FirstChanged = DragPoint; 02328 LastChanged = DragPoint; 02329 OriginalPath->InkPath.FindPrevEndPoint(&FirstChanged); 02330 OriginalPath->InkPath.FindNextEndPoint(&LastChanged); 02331 } 02332 02333 AttrBrushType* pAttrBrush = GetAppliedBrush(); 02334 if (pAttrBrush != NULL) 02335 EditBrushAttribute(FirstChanged, LastChanged, pAttrBrush); 02336 02337 ModifyPathAction* ModAction; 02338 02339 ActionCode Act; 02340 Act = ModifyPathAction::Init(this, &UndoActions, ChangedElements, (Action**)(&ModAction)); 02341 if (Act == AC_FAIL) 02342 { 02343 FailAndExecute(); 02344 End(); 02345 return FALSE; 02346 } 02347 02348 PathVerb* ChangedVerbs=NULL; 02349 DocCoord* ChangedCoords=NULL; 02350 PathFlags* ChangedFlags=NULL; 02351 INT32* ChangedIndices=NULL; 02352 02353 // If the function returned AC_NO_RECORD we shouldn't record any undo information in the action 02354 // NOTE - during unwind all actions return AC_OK with a NULL ModAction pointer!! 02355 if ((Act!=AC_NORECORD) && (ModAction!=NULL)) 02356 { 02357 // This next bit is a bit hellish. Any one of these four allocations can fail, in which case 02358 // we have to tidy up afterwards. Cue a lot of nested ifs and elses. 02359 02360 ALLOC_WITH_FAIL(ChangedVerbs,(PathVerb*) CCMalloc(ChangedElements * sizeof(PathVerb)),this); 02361 if (ChangedVerbs) 02362 { 02363 ALLOC_WITH_FAIL(ChangedCoords,(DocCoord*) CCMalloc(ChangedElements * sizeof(DocCoord)),this); 02364 if (ChangedCoords) 02365 { 02366 ALLOC_WITH_FAIL(ChangedFlags,(PathFlags*) CCMalloc(ChangedElements * sizeof(PathFlags)),this); 02367 if (ChangedFlags) 02368 { 02369 ALLOC_WITH_FAIL(ChangedIndices,(INT32*) CCMalloc(ChangedElements * sizeof(INT32)),this); 02370 if (!ChangedIndices) 02371 { 02372 CCFree( ChangedFlags ); 02373 CCFree( ChangedCoords ); 02374 CCFree( ChangedVerbs); 02375 FailAndExecute(); 02376 End(); 02377 return FALSE; 02378 } 02379 } 02380 else 02381 { 02382 CCFree( ChangedCoords ); 02383 CCFree( ChangedVerbs ); 02384 FailAndExecute(); 02385 End(); 02386 return FALSE; 02387 02388 } 02389 } 02390 else 02391 { 02392 CCFree( ChangedVerbs); 02393 FailAndExecute(); 02394 End(); 02395 return FALSE; 02396 02397 } 02398 } 02399 02400 // Now to put the undo data into the undo action 02401 INT32 index = 0; 02402 for (i=0;i<NumElements;i++) 02403 { 02404 if (SourceVerbs[i] != DestVerbs[i] || 02405 SourceCoords[i] != DestCoords[i] || 02406 SourceFlags[i] != DestFlags[i] 02407 ) 02408 { 02409 ChangedVerbs[index] = SourceVerbs[i]; 02410 ChangedFlags[index] = SourceFlags[i]; 02411 ChangedCoords[index] = SourceCoords[i]; 02412 ChangedIndices[index] = i; 02413 index++; 02414 } 02415 } 02416 02417 // Now we've allocated the arrays, let's tell the action about 'em 02418 ModAction->StoreArrays(ChangedVerbs, ChangedFlags, ChangedCoords, ChangedIndices, OriginalPath); 02419 } 02420 } 02421 02422 if (!OriginalPath->InkPath.CopyPathDataFrom(&EditPath)) 02423 return FALSE; 02424 else 02425 return TRUE; 02426 }
|
|
||||||||||||
|
This function is used to copy the NeedToRender flags from EditPath to OriginalPath. This are then used in optimised region invalidation.
Definition at line 2618 of file pathedit.cpp. 02619 { 02620 const INT32 OrigLength = pOrigPath->InkPath.GetNumCoords(); 02621 const INT32 EditLength = pEditPath->GetNumCoords(); 02622 02623 if (EditLength != OrigLength) 02624 return FALSE; 02625 02626 PathFlags* EditFlags = pEditPath->GetFlagArray(); 02627 PathFlags* OrigFlags = pOrigPath->InkPath.GetFlagArray(); 02628 02629 for (INT32 loop = 0; loop < EditLength; loop ++) 02630 { 02631 OrigFlags[loop].NeedToRender = EditFlags[loop].NeedToRender; 02632 } 02633 02634 return TRUE; 02635 }
|
|
|
This function is used to copy the NeedToRender flags from EditPath to OriginalPath. This are then used in optimised region invalidation.
Definition at line 2583 of file pathedit.cpp. 02584 { 02585 const INT32 OrigLength = OriginalPath->InkPath.GetNumCoords(); 02586 const INT32 EditLength = EditPath.GetNumCoords(); 02587 02588 if (EditLength != OrigLength) 02589 return FALSE; 02590 02591 PathFlags* EditFlags = EditPath.GetFlagArray(); 02592 PathFlags* OrigFlags = OriginalPath->InkPath.GetFlagArray(); 02593 02594 for (INT32 loop = 0; loop < EditLength; loop ++) 02595 { 02596 OrigFlags[loop].NeedToRender = EditFlags[loop].NeedToRender; 02597 } 02598 02599 return TRUE; 02600 }
|
|
|
Creates the cursor objects for the path operations.
Definition at line 4816 of file pathedit.cpp. 04817 { 04818 if (pMoveCursor == NULL) 04819 { // If already created then don't create a new set. 04820 MyCurrentCursor = NULL; 04821 pMoveCursor = new Cursor(TOOLID_BEZTOOL, _R(IDC_MOVEBEZIERCURSOR)); 04822 pCloseCursor = new Cursor(TOOLID_BEZTOOL, _R(IDC_CLOSEPATHCURSOR)); 04823 pCrossHairCursor = new Cursor(TOOLID_BEZTOOL, _R(IDC_CROSSHAIRCURSOR)); 04824 // See if any of them failed 04825 if ((!pMoveCursor || !pMoveCursor->IsValid()) 04826 || (!pCloseCursor || !pCloseCursor->IsValid()) 04827 || (!pCrossHairCursor || !pCrossHairCursor->IsValid())) 04828 { 04829 // They did fail, so clean up 04830 TRACE( _T("Cursors not created in OpNodePathEditBlob::CreateCursors\n")); 04831 delete pMoveCursor; 04832 delete pCloseCursor; 04833 delete pCrossHairCursor; 04834 pMoveCursor = NULL; 04835 return FALSE; 04836 } 04837 } 04838 return TRUE; 04839 }
|
|
|
Deletes the path operation cursors.
Definition at line 4858 of file pathedit.cpp. 04859 { 04860 if (pMoveCursor != NULL) 04861 { // If one is NULL then the rest don't exist 04862 if (MyCurrentCursor != NULL) 04863 { 04864 CursorStack::GPop(CurrentCursorID); 04865 } 04866 delete pMoveCursor; 04867 delete pCloseCursor; 04868 delete pCrossHairCursor; 04869 pMoveCursor = NULL; 04870 MyCurrentCursor = NULL; 04871 CurrentCursorID = 0; 04872 } 04873 }
|
|
||||||||||||||||
|
This is called to start a drag operation on an endpoint on a path.
Definition at line 227 of file pathedit.cpp. 00228 { 00229 BOOL Success = TRUE; 00230 00231 // We had better take a note of the starting point of the drag 00232 LastMousePos = Anchor; 00233 StartMousePos = Anchor; 00234 StartSpread = pSpread; 00235 00236 SelRange* theSelection = GetApplication ()->FindSelection (); 00237 00238 BOOL selectionContainsMoulds = FALSE; 00239 00240 if (theSelection) 00241 { 00242 // we need to do some special processing to handle moulds .... 00243 00244 Node* pCurrentNode = (Node*) theSelection->FindFirst (); 00245 00246 while (pCurrentNode) 00247 { 00248 if (IS_A (pCurrentNode, NodeMould)) 00249 { 00250 selectionContainsMoulds = TRUE; 00251 pCurrentNode = NULL; 00252 } 00253 else 00254 { 00255 pCurrentNode = (Node*) theSelection->FindNext (pCurrentNode); 00256 } 00257 } 00258 } 00259 00260 if (!selectionContainsMoulds) 00261 { 00262 BevelTools::BuildListOfSelectedNodes(&OriginalPaths, CC_RUNTIME_CLASS(NodePath)); 00263 } 00264 else 00265 { 00266 // now go and get those moulds baby ! 00267 BevelTools::BuildListOfSelectedNodes(&OriginalPaths, CC_RUNTIME_CLASS(NodeMouldPath)); 00268 00269 // now, we also have to rescan the selection (again!) BUT this time without 00270 // the moulds 00271 00272 Node* pCurrentNode = (Node*) theSelection->FindFirst (); 00273 00274 while (pCurrentNode) 00275 { 00276 if (IS_A (pCurrentNode, NodeMould)) 00277 { 00278 pCurrentNode = (Node*) theSelection->FindNext (pCurrentNode); 00279 } 00280 else 00281 { 00282 if (IS_A (pCurrentNode, NodePath)) 00283 { 00284 NodeListItem* pInsert = new NodeListItem (); 00285 00286 if (pInsert) // and insert into the paths list .... 00287 { 00288 pInsert->pNode = pCurrentNode; 00289 OriginalPaths.AddHead (pInsert); 00290 } 00291 } 00292 00293 pCurrentNode = (Node*) theSelection->FindNext (pCurrentNode); 00294 } 00295 } 00296 } 00297 00298 if (OriginalPaths.GetCount () == 1) 00299 //if (TRUE) 00300 { 00301 MultiplePaths = FALSE; 00302 00303 OriginalPath = OrigPath; 00304 00305 // Now calculate DragPoint and UpdatePoint 00306 if (Success) 00307 { 00308 PathFlags* Flags = OriginalPath->InkPath.GetFlagArray(); 00309 PathVerb* Verbs = OriginalPath->InkPath.GetVerbArray(); 00310 INT32 NumCoords = OriginalPath->InkPath.GetNumCoords(); 00311 00312 for (INT32 i=0;i<NumCoords;i++) 00313 { 00314 if (Flags[i].IsEndPoint && Flags[i].IsSelected 00315 && !(OriginalPath->InkPath.IsSubPathClosed(i) && (Verbs[i] == PT_MOVETO)) ) 00316 { 00317 // If you are dragging a closepoint then you are actually dragging two points 00318 // but we need to update the line tool as the user thinks they are dragging one. 00319 // If we are on the opening moveto then just skip the tests. 00320 if (DragPoint != -1) 00321 { 00322 UpdatePoint = -1; 00323 DragPoint = -1; 00324 break; 00325 } 00326 else 00327 { 00328 UpdatePoint = i; 00329 DragPoint = i; 00330 } 00331 } 00332 } 00333 // On exit from that loop, DragPoint = -1 if there are multiple selected endpoints, 00334 // otherwise DragPoint is the index to the selected endpoint. UpdatePoint is the 00335 // index of the point displaied in the Line tool 00336 } 00337 00338 // Set the constrain point 00339 if (DragPoint != -1) 00340 { 00341 ConstrainPoint = OriginalPath->InkPath.GetCoordArray()[DragPoint]; 00342 00343 // Get the previous endpoint 00344 INT32 OtherEndpoint = DragPoint; 00345 if (OriginalPath->InkPath.FindPrevEndPoint(&OtherEndpoint)) 00346 ConstrainPrevPoint = OriginalPath->InkPath.GetCoordArray()[OtherEndpoint]; 00347 else 00348 ConstrainPrevPoint = ConstrainPoint; 00349 00350 // Get the next endpoint 00351 OtherEndpoint = DragPoint; 00352 if (OriginalPath->InkPath.FindNextEndPoint(&OtherEndpoint)) 00353 ConstrainNextPoint = OriginalPath->InkPath.GetCoordArray()[OtherEndpoint]; 00354 else 00355 ConstrainNextPoint = ConstrainPoint; 00356 } 00357 else 00358 { 00359 ConstrainPoint = Anchor; 00360 ConstrainPrevPoint = Anchor; 00361 ConstrainNextPoint = Anchor; 00362 } 00363 00364 // We also need to make a version of the path that we can change 00365 Success = BuildEditPath(); 00366 00367 // Create and send a change message about this path edit 00368 // This one is handled by moulds in their OnChildChange() function 00369 if (Success) 00370 Success = (EditObjChange.ObjChangeStarting(OrigPath,this,&EditPath,StartSpread,TRUE) == CC_OK); 00371 00372 // Create and display the cursors for this operation 00373 if (Success) 00374 Success = CreateCursors(); 00375 if (Success) 00376 ChangeCursor(pCrossHairCursor); 00377 00378 // // Render the bits of the path that are different 00379 DocRect EditPathBBox = EditPath.GetBoundingRect(); 00380 // if (Success) 00381 // RenderPathEditBlobs(EditPathBBox, pSpread); 00382 00383 // Tell the Dragging system that we need drags to happen 00384 if (Success) 00385 Success = StartDrag(DRAGTYPE_AUTOSCROLL, &EditPathBBox, &LastMousePos); 00386 00387 if (!Success) 00388 { 00389 InformError(); 00390 FailAndExecute(); 00391 End(); 00392 } 00393 } 00394 else 00395 { 00396 // lets try and keep things the same for the blobs parent as in the one selection case 00397 // BUT lets also try and do our extra stuff .... I expect time MUCK UPS to occur !!!! 00398 00399 MultiplePaths = TRUE; 00400 00401 OriginalPath = OrigPath; 00402 00403 // we need to make OrigPath the first one in our linked list .... 00404 00405 NodeListItem* pCurrentOrig = (NodeListItem*) OriginalPaths.GetHead (); 00406 00407 while (pCurrentOrig) 00408 { 00409 NodePath* pOrigPath = (NodePath*) (pCurrentOrig->pNode); 00410 00411 if (pOrigPath == OrigPath) 00412 { 00413 NodeListItem* newHead = (NodeListItem*) OriginalPaths.RemoveItem (pCurrentOrig); 00414 00415 OriginalPaths.AddHead (newHead); 00416 00417 pCurrentOrig = NULL; 00418 } 00419 else 00420 { 00421 pCurrentOrig = (NodeListItem*) OriginalPaths.GetNext (pCurrentOrig); 00422 } 00423 } 00424 00425 // Now calculate DragPoint and UpdatePoint 00426 if (Success) 00427 { 00428 NodeListItem* pCurrentOrig = (NodeListItem*) OriginalPaths.GetHead (); 00429 00430 // CGS: while loop taken out since we can only be 'drag sensitive' to the point 00431 // that is actually being dragged 00432 00433 //while (pCurrentOrig) 00434 { 00435 NodePath* pOrigPath = (NodePath*) (pCurrentOrig->pNode); 00436 00437 PathFlags* Flags = pOrigPath->InkPath.GetFlagArray(); 00438 PathVerb* Verbs = pOrigPath->InkPath.GetVerbArray(); 00439 INT32 NumCoords = pOrigPath->InkPath.GetNumCoords(); 00440 00441 for (INT32 i=0;i<NumCoords;i++) 00442 { 00443 if (Flags[i].IsEndPoint && Flags[i].IsSelected 00444 && !(pOrigPath->InkPath.IsSubPathClosed(i) && (Verbs[i] == PT_MOVETO)) ) 00445 { 00446 // If you are dragging a closepoint then you are actually dragging two points 00447 // but we need to update the line tool as the user thinks they are dragging one. 00448 // If we are on the opening moveto then just skip the tests. 00449 if (DragPoint != -1) 00450 { 00451 UpdatePoint = -1; 00452 DragPoint = -1; 00453 break; 00454 } 00455 else 00456 { 00457 UpdatePoint = i; 00458 DragPoint = i; 00459 } 00460 } 00461 } 00462 00463 // pCurrentOrig = (NodeListItem*) OriginalPaths.GetNext (pCurrentOrig); 00464 } 00465 // On exit from that loop, DragPoint = -1 if there are multiple selected endpoints, 00466 // otherwise DragPoint is the index to the selected endpoint. UpdatePoint is the 00467 // index of the point displaied in the Line tool 00468 } 00469 00470 // Set the constrain point - do this only for the path that was clicked on |