OpNodePathAddEndpoint Class Reference

This operation is started by the bezier editing tool when it wants to add a point to the start or end of a particular path. It uses the normal dragging of the base operation, but the action when the operation finishes is different. This class is derived from OpNodePathEditBlob which drags the normal selected points around. More...

#include <pathedit.h>

Inheritance diagram for OpNodePathAddEndpoint:

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

Public Member Functions

 OpNodePathAddEndpoint ()
void DoStartDragEdit (NodePath *, DocCoord Anchor, Spread *pSpread, ClickModifiers Mods, INT32 PathIndex, BOOL CurveOrLine, BOOL CloseThePath=FALSE, BOOL SmoothOrCusp=TRUE)
 This is called when a Drag operation has been started when the user wants to add a line or curve element to the start or end of an open subpath. Anchor is the point we are adding (that's where the user clicked) and PathIndex tells us the nearest endpoint in the path. The flag CloseThePath tells the operation if it should close the path and select both the start and endpoints to drag around.
virtual void DragFinished (DocCoord Pos, ClickModifiers Mods, Spread *pSpread, BOOL Success, BOOL bSolidDrag)
 This routine handles the end of the drag operation when adding an element to the end of a path. It will insert an element into the nodepath, then copy the contents of the temporary path into the nodepath.

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 (DocCoord NewPoint)
 Builds a copy of the path that we can edit, without destroying the original data. This version has to add an extra element which we will be dragging around. It will look at the member variable IsPathClosing to see if the path should be made to close.
BOOL InsertElement (DocCoord NewPoint, Path *DestPath, INT32 InsPos, INT32 *NewPosition, BOOL RecordUndo=FALSE, NodePath *UndoPath=NULL)
 Inserts a new element (either line or curve, depending in internal flags) into the given path. It will set the selected bit in the element.
BOOL Complete (DocCoord AddElementPoint)
 This routine does all the actions, with undo, for appending the additional endpoint onto the line, including the preparaty and concluding actions.
BOOL CompleteThisPath (DocCoord AddElementPoint)
 This routine does all the actions, with undo, for appending the additional endpoint onto the line.
virtual void SetStatusLineHelp ()
 Updates the status line message to reflect the current situation.
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.

Protected Attributes

INT32 NewPointIndex
INT32 InsertPosition
BOOL IsPathClosing
BOOL AddCurveFlag
BOOL AddSmoothFlag

Detailed Description

This operation is started by the bezier editing tool when it wants to add a point to the start or end of a particular path. It uses the normal dragging of the base operation, but the action when the operation finishes is different. This class is derived from OpNodePathEditBlob which drags the normal selected points around.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/6/94

Definition at line 318 of file pathedit.h.


Constructor & Destructor Documentation

OpNodePathAddEndpoint::OpNodePathAddEndpoint  )  [inline]
 

Definition at line 325 of file pathedit.h.

00325 : OpNodePathEditBlob() {};


Member Function Documentation

BOOL OpNodePathAddEndpoint::BuildEditPath DocCoord  NewPoint  )  [protected]
 

Builds a copy of the path that we can edit, without destroying the original data. This version has to add an extra element which we will be dragging around. It will look at the member variable IsPathClosing to see if the path should be made to close.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/6/94 Input: NewPoint is the point that's being inserted
Returns:
TRUE if it managed to build the path, FALSE if it failed

Errors: If it runs out of memory then it will return FALSE

Definition at line 4322 of file pathedit.cpp.

04323 {
04324     // Find out how long the path is
04325     INT32 NumCoords = OriginalPath->InkPath.GetNumCoords();
04326 
04327     // Ask for a path with 24 free slots in it to be going on with and fail if we do not get it
04328     if (!EditPath.Initialise(NumCoords, 24))
04329         return FALSE;
04330 
04331     // Copy the path data from the original path to the editable one
04332     if (!EditPath.CopyPathDataFrom(&(OriginalPath->InkPath)))
04333         return FALSE;
04334 
04335     INT32 LastEndPoint = 0;             // The EndPoint before this one
04336     INT32 LastLastEndPoint = 0;         // The EndPoint before the last EndPoint
04337     BOOL SetNextEndPoint = FALSE;       // TRUE if we want to set the next EndPoint to render
04338     BOOL SetNextNextEndPoint = FALSE;   // TRUE if we want the one after the next one to render
04339 
04340     // Get pointers to the arrays that we are interested in
04341     PathFlags* Flags = EditPath.GetFlagArray();
04342     DocCoord* PathCoords = EditPath.GetCoordArray();
04343     PathVerb* PathVerbs = EditPath.GetVerbArray();
04344 
04345     // Clear all the selected bits in the path because we're adding a new point
04346     INT32                   i;
04347     for ( i=0; i<NumCoords; i++)
04348     {
04349         Flags[i].IsSelected = FALSE;
04350     }
04351 
04352 
04353     // Now add the new element to the correct place in the path. This we get from the
04354     // member variable InsertPosition.
04355 
04356     if (!InsertElement(NewPoint, &EditPath, InsertPosition, &NewPointIndex))
04357         return FALSE;
04358 
04359     // Read the length of the path again
04360     NumCoords = EditPath.GetNumCoords();
04361 
04362     // Get array pointers again, because the paths have moved
04363     Flags = EditPath.GetFlagArray();
04364     PathCoords = EditPath.GetCoordArray();
04365     PathVerbs = EditPath.GetVerbArray();
04366 
04367     // Now check the IsPathClosing flag to see if we should make the path closed
04368     if (IsPathClosing)
04369     {
04370         // When closing the path, we have to snap the new endpoint to the opposite 
04371         // endpoint. Thus, we need to know if this element was added to the start or end
04372         // of the path. This we can discover by looking at the previous element to
04373         // the element at NewPointIndex. If that is a MoveTo then the new point is
04374         // at the start, and we should snap the MoveTo coordinate to the coord at
04375         // the end of the path, otherwise it's at the end, and we have to snap the
04376         // coords of the final element to be the same as the coords of the initial
04377         // moveto element.
04378 
04379         if (PathVerbs[NewPointIndex-1] == PT_MOVETO)
04380         {
04381             // Snap the MoveTo coords to the coords of the endpoint
04382             for (i = NewPointIndex; i < NumCoords && PathVerbs[i] != PT_MOVETO; i++ );
04383             // i now points one element above the endpoint of the path, so decrement
04384             i--;
04385 
04386             // Copy the coords of the endpoint to the moveto
04387             PathCoords[NewPointIndex-1] = PathCoords[i];
04388 
04389             // And set the closed bit
04390             PathVerbs[i] |= PT_CLOSEFIGURE;
04391 
04392             // And select the other endpoint so it drags as well
04393             Flags[i].IsSelected = TRUE;
04394         }
04395         else
04396         {
04397             // Snap the endpoint coords to those of the moveto at the start, but first
04398             // set the CloseFigure flag in the verb.
04399             
04400             INT32 EndCoord = NewPointIndex;
04401             
04402             if ((PathVerbs[NewPointIndex] & ~PT_CLOSEFIGURE) == PT_BEZIERTO)
04403                 EndCoord = NewPointIndex + 2;
04404 
04405             PathVerbs[EndCoord] |= PT_CLOSEFIGURE;
04406 
04407             // scan back to the start of the path
04408             i = EndCoord;
04409             do
04410             {
04411                 i--;
04412             } while (PathVerbs[i] != PT_MOVETO);
04413 
04414             PathCoords[EndCoord] = PathCoords[i];
04415 
04416             // And select the moveto as well
04417             Flags[i].IsSelected = TRUE;
04418         }
04419     }
04420     
04421     EditPath.SmoothCurve();
04422 
04423     // Go though all the coords, with scary amounts of looking back and forwards
04424     for (i=0; i<NumCoords; i++)
04425     {
04426         // Make all the flags FALSE by default
04427         Flags[i].NeedToRender = FALSE;
04428 
04429         if (Flags[i].IsEndPoint)
04430         {
04431             // if the endpoint 2 elements back was selected and the last element was smooth
04432             // then we need to mark this point for rendering
04433             if (SetNextNextEndPoint)
04434             {
04435                 Flags[i].NeedToRender = TRUE;
04436                 SetNextNextEndPoint = FALSE;
04437             }
04438 
04439             // We have found an Endpoint, do we want to mark this one as renderable
04440             if (SetNextEndPoint)
04441             {
04442                 // As the last element was selected, this element needs to render
04443                 Flags[i].NeedToRender = TRUE;
04444                 SetNextEndPoint = FALSE;
04445 
04446                 // If the smooth flag is set then the next item needs to render as well
04447                 if (Flags[i].IsSmooth)
04448                     SetNextNextEndPoint = TRUE;
04449             }
04450 
04451             // If its selected, then its renderable
04452             if (Flags[i].IsSelected)
04453             {
04454                 Flags[i].NeedToRender = TRUE;
04455                 Flags[LastEndPoint].NeedToRender = TRUE;
04456 
04457                 // If the smooth flag is set then the re-draw area goes further
04458                 if (Flags[LastEndPoint].IsSmooth)
04459                     Flags[LastLastEndPoint].NeedToRender = TRUE;
04460 
04461                 // Set the flag for the next endpoint
04462                 SetNextEndPoint = TRUE;
04463             }
04464 
04465             // Make a note of the last endpoint, incase the next one is selected
04466             LastLastEndPoint = LastEndPoint;
04467             LastEndPoint = i;
04468         }
04469     }
04470 
04471     // It worked
04472     return TRUE;
04473 }

BOOL OpNodePathAddEndpoint::Complete DocCoord  AddElementPoint  )  [protected]
 

This routine does all the actions, with undo, for appending the additional endpoint onto the line, including the preparaty and concluding actions.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> - From Jim code
Date:
2/6/95
Parameters:
AddElementPoint - the point at which the mouse finished [INPUTS]
- [OUTPUTS]
Returns:
TRUE/FALSE for success/failure

Errors: -

See also:
OpNodePathAddEndpoint::CompleteThisPath

Definition at line 4539 of file pathedit.cpp.

04540 {
04541     BeginSlowJob();
04542     BOOL ok = TRUE;
04543     
04544     // Start the sel operation, removes blobs at start and end
04545     if (ok)
04546         ok = DoStartSelOp(TRUE,TRUE);
04547 
04548     // Create and send a change message about this path edit so parents can refuse
04549     ObjChangeFlags cFlags;
04550     cFlags.TransformNode = TRUE;
04551     ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,OriginalPath,this);
04552     if (ok)
04553     {
04554         if (!OriginalPath->AllowOp(&ObjChange, TRUE))
04555         {
04556             FailAndExecute();
04557             return TRUE;
04558         }
04559     }
04560 
04561     // Do all the work involved in closing the path
04562     if (ok)
04563         ok = CompleteThisPath(AddElementPoint);
04564 
04565     // Inform all the parents of this node that it has been changed.
04566     if (ok)
04567     {
04568         ObjChange.Define(OBJCHANGE_FINISHED,ObjChangeFlags(),OriginalPath,this);
04569         ok = UpdateChangedNodes(&ObjChange);
04570     }
04571 
04572     return ok;
04573 }

BOOL OpNodePathAddEndpoint::CompleteThisPath DocCoord  AddElementPoint  )  [protected]
 

This routine does all the actions, with undo, for appending the additional endpoint onto the line.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> - From Jim code
Date:
19/12/95
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
TRUE/FALSE for success/failure

Errors: FailAndExecute will have been called in the event of a failure

See also:
OpNodePathAddEndpoint::Complete

Definition at line 4590 of file pathedit.cpp.

04591 {
04592     BOOL ok = TRUE;
04593 
04594     // Force a re-draw of the place where the path used to be
04595     if (ok)
04596         ok = (RecalcBoundsAction::DoRecalc(this, &UndoActions, OriginalPath) != AC_FAIL);
04597 
04598 //  // Store the paths sub-selection state
04599 //  if (ok)
04600 //      ok = (StorePathSubSelStateAction::DoRecord(this, &UndoActions, &OriginalPath->InkPath) != AC_FAIL);
04601 
04602     // Snap the endpoint that we are dragging with the other end of the sub-path
04603     if (ok && EndSnapped)
04604         SnapEndsTogether();
04605 
04606     // First thing to do is add a point into the path at the same place we added it
04607     // for the temporary path.
04608     if (ok)
04609         ok = InsertElement(AddElementPoint, &(OriginalPath->InkPath), InsertPosition, &NewPointIndex, TRUE, OriginalPath);
04610 
04611     // Copy the edited path back over the original path
04612     if (ok)
04613         ok = CopyEditedPathBack();
04614 
04615     if (IsPathClosing)
04616         EndSnapped = TRUE;
04617         
04618     // If the ends snapped, set the filled bit on the path
04619     if (ok)
04620         ok = FillPathIfEndsSnapped() && JoinWithOtherPath() ;
04621 
04622     if (ok)
04623     {
04624         // Update the bounding rectangle
04625         OriginalPath->InvalidateBoundingRect();
04626 
04627         // Announce this bounds change to the world
04628         GetApplication()->FindSelection()->UpdateBounds();
04629 
04630         // Force a redraw of the place where the path is now.
04631         ok = (RecordBoundsAction::DoRecord(this, &UndoActions, OriginalPath) != AC_FAIL);
04632     }
04633 
04634     // DY 9/99 are we editing a blend on a curve? If so we may wish to change the number of
04635     // steps in the blend
04636     NodeGroup* pParent = GetGroupParentOfCurve();
04637     
04638     if (pParent != NULL)
04639     {
04640         if (pParent->IS_KIND_OF(NodeBlend))
04641         {
04642             if (ok)
04643                 InsertChangeBlendStepsAction((NodeBlend*)pParent);               
04644         }
04645     
04646     }
04647     ObjChangeFlags cFlags(FALSE,TRUE);
04648     ObjChangeParam ObjChange(OBJCHANGE_FINISHED,cFlags,NULL,this);
04649     ok = UpdateChangedNodes(&ObjChange);
04650     
04651     return ok;
04652 }

void OpNodePathAddEndpoint::DoStartDragEdit NodePath OrigPath,
DocCoord  Anchor,
Spread pSpread,
ClickModifiers  Mods,
INT32  PathIndex,
BOOL  CurveOrLine,
BOOL  CloseThePath = FALSE,
BOOL  SmoothOrCusp = TRUE
 

This is called when a Drag operation has been started when the user wants to add a line or curve element to the start or end of an open subpath. Anchor is the point we are adding (that's where the user clicked) and PathIndex tells us the nearest endpoint in the path. The flag CloseThePath tells the operation if it should close the path and select both the start and endpoints to drag around.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com> (via Rik)
Date:
17/6/94
Parameters:
OrigPath - Pointer to the path we are about to edit [INPUTS] Anchor - The position of the mouse at the start of the Drag pSpread - The spread that the path is on PathIndex is the index into the path of the element to which we're adding CurveOrLine is TRUE if we're adding a curve segment, FALSE for a line CloseThePath is true if this click is to close the path SmoothOrCusp is TRUE if the new point is smooth, FALSE if it is a cusp.

Definition at line 4213 of file pathedit.cpp.

04221 {
04222     // Remember the index of the point to which we're adding this element
04223     InsertPosition = PathIndex;
04224     OriginalPath = OrigPath;
04225 
04226     // We had better take a note of the starting point of the drag
04227     StartMousePos = Anchor;
04228     LastMousePos = Anchor;
04229     StartSpread  = pSpread;
04230     IsPathClosing = CloseThePath;
04231     AddCurveFlag = CurveOrLine;
04232     AddSmoothFlag = SmoothOrCusp;
04233     
04234     // Now work out the position to constrain to.
04235     PathFlags*  Flags = OrigPath->InkPath.GetFlagArray();
04236     PathVerb*   Verbs = OrigPath->InkPath.GetVerbArray();
04237     DocCoord*   Coords = OrigPath->InkPath.GetCoordArray();
04238     if (Verbs[InsertPosition] == PT_MOVETO)
04239         ConstrainPoint = Coords[InsertPosition];
04240     else
04241     {
04242         INT32 Temp = InsertPosition;
04243         while (!Flags[Temp].IsEndPoint && (Temp < OrigPath->InkPath.GetNumCoords()))
04244             Temp++;
04245         ConstrainPoint = Coords[Temp];
04246     }
04247     ConstrainPrevPoint = ConstrainPoint;
04248     ConstrainNextPoint = ConstrainPoint;
04249 
04250     // Constrain the anchor and snap it to the grid
04251     ERROR3IF(ConstrainPoint == DocCoord(-1,-1),"DragConstrainPoint wasn't set");
04252     if (Mods.Constrain)
04253         DocView::ConstrainToAngle(ConstrainPoint, &LastMousePos);
04254     DocView::SnapCurrent(pSpread, &LastMousePos);
04255 
04256     BOOL ok = TRUE;
04257     
04258     // We also need to make a version of the path that we can change
04259     if (ok)
04260         ok = BuildEditPath(LastMousePos);
04261     UpdatePoint = DragPoint;
04262 
04263     // If the path is closing we don't want to start a drag as it leads to complications with snapping to ourselves
04264     if (CloseThePath)
04265     {
04266         if (ok)
04267             ok = Complete(StartMousePos);
04268     
04269         if (!ok)
04270         {
04271             InformError();
04272             FailAndExecute();
04273         }
04274 
04275         End();
04276         return;
04277     }
04278     else
04279     {
04280         // Create the drag cursors
04281         if (ok)
04282             ok = CreateCursors();
04283 
04284         // Render the bits of the path that are different
04285         if (ok)
04286         {
04287             DocRect EditPathBBox = EditPath.GetBoundingRect();
04288 //          RenderPathEditBlobs(EditPathBBox, pSpread);
04289 
04290             // And tell the Dragging system that we need drags to happen
04291             ok = StartDrag(DRAGTYPE_AUTOSCROLL, &EditPathBBox, &LastMousePos);
04292         }
04293 
04294         if (ok)
04295             ChangeCursor(pCrossHairCursor);
04296     }
04297 
04298     if (!ok)
04299     {
04300         InformError();
04301         FailAndExecute();
04302         End();
04303     }
04304 }

void OpNodePathAddEndpoint::DragFinished DocCoord  Pos,
ClickModifiers  Mods,
Spread pSpread,
BOOL  Success,
BOOL  bSolidDrag
[virtual]
 

This routine handles the end of the drag operation when adding an element to the end of a path. It will insert an element into the nodepath, then copy the contents of the temporary path into the nodepath.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/6/94
Parameters:
Pos = mouse position at end of drag [INPUTS] Mods = click modifiers (Adjust, etc.) pSpread points at the spread the drag finished in Success indicates whether the drag was aborted with Escape
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Reimplemented from OpNodePathEditBlob.

Definition at line 4499 of file pathedit.cpp.

04504 {
04505     RenderPathEditBlobs( EditPath.GetBoundingRect(), StartSpread );
04506     EndDrag();
04507     DestroyCursors();
04508     if ( Success )
04509     {
04510         if (!Complete(Pos))
04511         {
04512             InformError();
04513             FailAndExecute();
04514         }
04515     }
04516     else
04517         FailAndExecute();
04518 
04519     End();  
04520     
04521 
04522 }

BOOL OpNodePathAddEndpoint::EditBrushAttribute INT32  FirstIndex,
INT32  LastIndex,
AttrBrushType pAttrBrush
[protected, virtual]
 

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.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/6/2000 inputs : FirstIndex - first changed index of the path LastIndex - the last changed index pAttrBrush - the attribute to change outputs: - returns: TRUE if all went well
Notes: Derived version does not do the remove points (as we are only adding here). Instead it makes itself some new data and inserts it at the insert point.

Reimplemented from OpNodePathEditBlob.

Definition at line 4676 of file pathedit.cpp.

04677 {
04678     if (FirstIndex < 0 || LastIndex < 0 || LastIndex <= FirstIndex || pAttrBrush == NULL)
04679     {
04680         //ERROR3("Invalid inputs to OpNodePathEditBlob::EditBrushAttribute");
04681         return FALSE;
04682     }
04683     
04684     // currently we only have pressure implemented, and if this attribute does not use
04685     // pressure then theres nothing for us to do
04686     CDistanceSampler* pDistSamp = pAttrBrush->GetPressureCache();
04687     if (pDistSamp == NULL)
04688         return TRUE;  // not an error 
04689     
04690     // what we basically want to do here is to make a new section of data and insert ot
04691     // either at the beginning or the end
04692 
04693     MILLIPOINT SectionLength = GetLengthOfPathSection(&EditPath, FirstIndex, LastIndex);
04694     if (SectionLength == -1) // something went wrong
04695         return FALSE;
04696     // work out how many items we need
04697     INT32 NumItems = SectionLength / MIN_BRUSH_SPACING;
04698 
04699     // make a new CDistanceSampler
04700     CDistanceSampler* pNewSampler = new CDistanceSampler;
04701     if (pNewSampler == NULL)
04702         return FALSE;
04703 
04704     if (!pNewSampler->InitialiseData(NumItems))  // initialise the array 
04705     {
04706         delete pNewSampler;
04707         return FALSE;
04708     }
04709 
04710     // we are inserting either at the beginning or the end
04711     INT32 InsertIndex = 0;
04712     if (FirstIndex != 0)
04713         InsertIndex = LastIndex;
04714 
04715     // Get the distance to the insert index
04716     DocCoord* pCoord = EditPath.GetCoordArray();
04717     if (pCoord == NULL)
04718     {
04719         delete pNewSampler;
04720         return FALSE;
04721     }
04722     DocCoord InsertCoord = pCoord[InsertIndex];
04723     
04724     MILLIPOINT InsertDistance = -1;
04725     if (!EditPath.GetDistanceToPoint(InsertCoord, &InsertDistance))
04726     {
04727         delete pNewSampler;
04728         return FALSE;
04729     }
04730 
04731     // we want to get the pressure at this distance
04732     UINT32 InternalIndex = pDistSamp->GetInternalIndexFromDistance(InsertDistance);
04733     
04734     if (InternalIndex == (UINT32)-1) // we're over the end!
04735         InternalIndex = UINT32(pDistSamp->GetNumItems() - 1);
04736 
04737     pDistSamp->SetRetrievalSampleRate(1.0);
04738     CSampleItem TheItem;
04739 
04740     if (!pDistSamp->GetAt(InternalIndex, &TheItem))
04741     {
04742         ERROR3("Unable to retrieve pressure item in OpNodePathAddEndpoint::EditBrushAttribute"); 
04743         delete pNewSampler;
04744         return FALSE;
04745     }
04746 
04747     // whew, now we just have to fill up our new sampler with that item
04748     BOOL ok = pNewSampler->SetAt(0, TheItem);
04749     while (ok)
04750     {
04751         ok = pNewSampler->SetNext(TheItem);
04752         TRACEUSER( "Diccon", _T("Adding item pressure = %d\n"), TheItem.m_Pressure);
04753     }
04754 
04755     // now insert our new points into the attribute
04756     AddPressurePointsAction* pAddAction;
04757 
04758     // find out how many points we're inserting
04759     size_t NumAddPoints = pNewSampler->GetNumItems() + 1;
04760     
04761     if (AddPressurePointsAction::Init(this, &UndoActions, pAttrBrush, pNewSampler, InternalIndex, NumAddPoints,  &pAddAction) == AC_FAIL)
04762     {
04763         delete pNewSampler;
04764         return FALSE;
04765     }
04766  
04767     return TRUE;
04768 }

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

Find out the state of the operation at the specific time.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/6/94
Parameters:
Description - GetState fills this string with an approriate description [OUTPUTS] of the current state of the selector tool
Returns:
The state of the operation, so that menu items (ticks and greying can be done properly

Reimplemented from OpNodePathEditBlob.

Reimplemented in OpCloseNodePaths.

Definition at line 4151 of file pathedit.cpp.

04152 {
04153     OpState Blobby;
04154     
04155     return Blobby;
04156 }

BOOL OpNodePathAddEndpoint::Init void   )  [static]
 

Adds the operation to the list of all known operations.

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

Reimplemented from OpNodePathEditBlob.

Reimplemented in OpCloseNodePaths.

Definition at line 4124 of file pathedit.cpp.

04125 {
04126     return (RegisterOpDescriptor(   0, 
04127                                     _R(IDS_NODEPATH_ADDENDPOINT),
04128                                     CC_RUNTIME_CLASS(OpNodePathAddEndpoint), 
04129                                     OPTOKEN_ADDENDPOINT,
04130                                     OpNodePathAddEndpoint::GetState,
04131                                     0,                                      // help ID
04132                                     _R(IDBBL_NODEPATHOP),
04133                                     0 ) );                                  // bitmap ID
04134 }

BOOL OpNodePathAddEndpoint::InsertElement DocCoord  NewPoint,
Path DestPath,
INT32  InsPos,
INT32 *  NewPosition,
BOOL  RecordUndo = FALSE,
NodePath UndoPath = NULL
[protected]
 

Inserts a new element (either line or curve, depending in internal flags) into the given path. It will set the selected bit in the element.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/6/94
Parameters:
NewPoint is the point that should be added [INPUTS] DestPath is the path to which the element should be added InsPos is the index of the element which we're adding to (the first or last element in the path). RecordUndo is a flag telling the routine to build undo information (default FALSE) UndoPath is the path that's being operated on, for the undo recording
NewPosition is the index of the element [OUTPUTS] Also sets DragPoint
Returns:
BOOL indicating success or failure
NOTE: This routine will move the path data around so any pointers to the arrays in the path should be re-read after any call to this routine.

Returns:
Errors: If no memory available to insert the point
See also:
-

Definition at line 4966 of file pathedit.cpp.

04972 {
04973 
04974     Action* UnAction;       // pointer to action that might be created
04975     ActionCode Act;         // Action code that might be used
04976 
04977     // There are two possibilities here - that we're at the start of a path, or at the
04978     // end. The end case is easier - we just add an element after the end element. For a
04979     // point added to the start, we have to change the MoveToCoordinates to be the point
04980     // clicked, and add an element which goes from there to the original MoveTo position.
04981     // If we add a CurveTo element, we have to smooth the coordinates before the drag starts.
04982 
04983     DestPath->SetPathPosition(InsPos);
04984 
04985     if (DestPath->GetVerb() == PT_MOVETO)
04986     {
04987         DocCoord tempcoord = DestPath->GetEndPoint();       // Get coord of moveto
04988         DestPath->FindNext();                               // Skip to after the MoveTo
04989         *NewPosition = DestPath->GetPathPosition();         // remember index of point we're inserting
04990 
04991         // If we're undoing, create an action for this insert
04992         if (RecordUndo)
04993         {
04994             if (AddCurveFlag)
04995                 Act = RemovePathElementAction::Init(this, &UndoActions, 3,*NewPosition, (Action**)(&UnAction));
04996             else
04997                 Act = RemovePathElementAction::Init(this, &UndoActions, 1,*NewPosition, (Action**)(&UnAction));
04998             if (Act == AC_FAIL)
04999                 return FALSE;
05000 
05001             ((RemovePathElementAction*)UnAction)->RecordPath(UndoPath);
05002         }
05003 
05004         PathFlags tempflags;
05005 
05006         if (AddSmoothFlag)
05007         {
05008             tempflags.IsSmooth = TRUE;
05009             tempflags.IsRotate = TRUE;
05010         }
05011         else
05012         {
05013             tempflags.IsSmooth = TRUE;
05014             tempflags.IsRotate = FALSE;
05015         }
05016         
05017         if (AddCurveFlag)
05018         {
05019             // We insert a curve element with all three coords the same, since 
05020             // they will get smoothed
05021             if (!DestPath->InsertCurveTo(tempcoord,tempcoord,tempcoord,&tempflags))
05022                 return FALSE;
05023         }
05024         else
05025         {
05026             if (!DestPath->InsertLineTo(tempcoord, &tempflags))
05027                 return FALSE;
05028         }       
05029 
05030         // Read the pointers to the arrays.
05031         PathFlags* Flags = DestPath->GetFlagArray();
05032         DocCoord* PathCoords = DestPath->GetCoordArray();
05033         PathVerb* PathVerbs = DestPath->GetVerbArray();
05034 
05035         // Set the selected bit on the point we have to move (the MoveTo)
05036         if (RecordUndo)
05037         {
05038             DoChangeSelection(UndoPath, InsPos, TRUE);
05039             if (AddCurveFlag)
05040                 DoChangeSelection(UndoPath, InsPos+1, TRUE);
05041         }
05042         else
05043         {
05044             Flags[InsPos].IsSelected = TRUE;    
05045             if (AddCurveFlag)
05046                 Flags[InsPos+1].IsSelected = TRUE;
05047         }
05048 
05049         // Now to adjust the MoveTo coordinate, recording undo info if necessary
05050 
05051         if (RecordUndo)
05052         {
05053             Act = ModifyElementAction::Init(this, 
05054                                             &UndoActions,
05055                                             PathVerbs[InsPos],
05056                                             Flags[InsPos],
05057                                             PathCoords[InsPos],
05058                                             InsPos,
05059                                             UndoPath,
05060                                             (Action**)&UnAction);
05061         }
05062 
05063         PathCoords[InsPos] = NewPoint;
05064 
05065         // Make it smooth/rotate
05066         Flags[InsPos].IsSmooth = TRUE;
05067         Flags[InsPos].IsRotate = TRUE;
05068 
05069         DragPoint = InsPos;
05070 
05071         // Now smooth the path
05072 //      DestPath->SmoothCurve();
05073     }
05074     else
05075     {
05076         // Adding to the end of a path is easier - insert an element after this one
05077         DestPath->FindNext();
05078         *NewPosition = DestPath->GetPathPosition();
05079 
05080         // If we're undoing, create an action for this insert
05081         if (RecordUndo)
05082         {
05083             if (AddCurveFlag)
05084                 Act = RemovePathElementAction::Init(this, &UndoActions, 3,*NewPosition, (Action**)(&UnAction));
05085             else
05086                 Act = RemovePathElementAction::Init(this, &UndoActions, 1,*NewPosition, (Action**)(&UnAction));
05087             if (Act == AC_FAIL)
05088                 return FALSE;
05089 
05090             ((RemovePathElementAction*)UnAction)->RecordPath(UndoPath);
05091         }
05092 
05093         PathFlags tempflags;
05094         if (AddSmoothFlag)
05095         {
05096             tempflags.IsSmooth = TRUE;
05097             tempflags.IsRotate = TRUE;
05098         }
05099         else
05100         {
05101             tempflags.IsSmooth = TRUE;
05102             tempflags.IsRotate = FALSE;
05103         }
05104         if (AddCurveFlag)
05105         {
05106             if (!DestPath->InsertCurveTo(NewPoint,NewPoint,NewPoint,&tempflags))
05107                 return FALSE;
05108         }
05109         else
05110         {
05111             if (!DestPath->InsertLineTo(NewPoint,&tempflags))
05112                 return FALSE;
05113         }
05114 
05115         // Re-read the pointers to the arrays, in case they've changed
05116         PathFlags* Flags = DestPath->GetFlagArray();
05117 //      DocCoord* PathCoords = DestPath->GetCoordArray();
05118 //      PathVerb* PathVerbs = DestPath->GetVerbArray();
05119 
05120         if (AddCurveFlag)
05121         {
05122             if (RecordUndo)
05123             {
05124                 DoChangeSelection(UndoPath,(*NewPosition)+2, TRUE);     // Select the endpoint
05125                 DoChangeSelection(UndoPath, (*NewPosition)+1, TRUE);    // Select the control point as well
05126             }
05127             else
05128             {
05129                 Flags[(*NewPosition)+2].IsSelected = TRUE;
05130                 Flags[(*NewPosition)+1].IsSelected = TRUE;
05131             }
05132             DragPoint = (*NewPosition)+2;
05133     //      DestPath->SmoothCurve();
05134         }
05135         else
05136         {
05137             if (RecordUndo)
05138                 DoChangeSelection(UndoPath,(*NewPosition), TRUE);
05139             else
05140                 Flags[(*NewPosition)].IsSelected = TRUE;
05141             DragPoint = *NewPosition;
05142         }
05143     }
05144 
05145     return TRUE;
05146 }

void OpNodePathAddEndpoint::SetStatusLineHelp  )  [protected, virtual]
 

Updates the status line message to reflect the current situation.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/1/95

Reimplemented from OpNodePathEditBlob.

Definition at line 4167 of file pathedit.cpp.

04168 {
04169     String_256 HelpString;
04170     if (EndSnapped)
04171         HelpString = String_256(_R(IDS_PATHDRAGCREATESHAPE));
04172     else
04173     {
04174         if (SnapToAnother)
04175             HelpString = String_256(_R(IDS_PATHDRAGJOINPATHS));
04176         else
04177             HelpString = String_256(_R(IDS_PATHDRAGADDSEGMENT));
04178     }
04179 
04180     GetApplication()->UpdateStatusBarText(&HelpString, FALSE);
04181 }


Member Data Documentation

BOOL OpNodePathAddEndpoint::AddCurveFlag [protected]
 

Definition at line 360 of file pathedit.h.

BOOL OpNodePathAddEndpoint::AddSmoothFlag [protected]
 

Definition at line 361 of file pathedit.h.

INT32 OpNodePathAddEndpoint::InsertPosition [protected]
 

Definition at line 358 of file pathedit.h.

BOOL OpNodePathAddEndpoint::IsPathClosing [protected]
 

Definition at line 359 of file pathedit.h.

INT32 OpNodePathAddEndpoint::NewPointIndex [protected]
 

Definition at line 357 of file pathedit.h.


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