OpEditBlendEndObject Class Reference

The operation to edit the position of the end objects of a blend on a path. More...

#include <blndtool.h>

Inheritance diagram for OpEditBlendEndObject:

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

Public Member Functions

 OpEditBlendEndObject ()
 OpEditBlendEndObject (BlendTool *pBlendTool)
 default constructor
 ~OpEditBlendEndObject ()
 destructor, deletes pointers to dynamically created objects
virtual 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.
virtual void DragPointerMove (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL bSolidDrag)
 Pure virtual function which tells the operation that the mouse has moved.
virtual void DragFinished (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL Success, BOOL bSolidDrag)
 Ends the drag and recalculates the blend.
virtual void DragPointerIdle (DocCoord, ClickModifiers, Spread *, BOOL bSolidDrag)
 Pure virtual function which tells the operation that nothing is going on so that it has time to do background jobs.
void RenderDragBlobs (Spread *pSpread, DocCoord CentrePosition, BOOL On)
 Calls the XOR outline function and draws an 'X' in the position specified.
void RenderSelectedObjectBlobs (Spread *pSpread)
 To render the object blobs of the objects that were in the selection during the drag op. To dig myself out of the hole that I dug for myself in the implementaion of the drag op. Basically if you read the comments in DoDrag() you will be aware that we've had to temporarily change the selection for the purposes of this drag. However this means that all the objects that should really be selected lose their object blob. in order to restore them we must go through the stored selection by hand and render them individually. Awful, sorry. See also: SelState.h/.cpp DoDrag().
BOOL DoDrag (DocCoord PointerPos, Spread *pSpread)
 This starts a drag to change the position of one of the end objects of a blend The DragFinished() method will do the hard work of recalculating the blend etc.
NodeBlendPathGetNodeBlendPath ()

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 operation at the specific time.

Protected Member Functions

BOOL RecalculateBlend (DocCoord PointerPos)
 To recalculate the number of steps in the blend or distance between steps following the change of position of one of the end objects. Having done this it then creates the actions to perform the change.
BOOL GetClosestPointOnPath (DocCoord PointerPos, DocCoord *ClosestPoint)
 To find the closest point on the nodeblend path to the point clicked or dragged on by the user. The function gets the closest point on all the paths and takes the closest. However this part is only done once as the nodeblendpath is then cached.
NodeBlenderGetBlenderAndPosition (Node *pNode, BOOL *First)
 To find the NodeBlender on a curve that uses pNode as either its first or last node, and which position.
BOOL InsertChangeEndActions (double NewPathProportion, DocCoord NewPosition, Node *pNodeToEdit)
 To calculate and perform the actions necessary to transform pNode to its new PathProportion whilst maintaining a constant number of blend steps.
BOOL InsertChangeEndActions (double NewPathProportion, DocCoord NewPosition, double StepDistance, Node *pNodeToEdit)
 To calculate and perform the actions necessary to transform pNode to its new PathProportion whilst maintaining a constant distance between blend steps. This requires calculating a new position for the node that is not being edited in order to maintain the correct distance, it may also require changing the number of steps in the blend.
BOOL CalculateNewNumStepsAndPosition (UINT32 OldNumSteps, double BlendDistance, double StepDistance, double *FixedDistance, double *MoveableDistance, UINT32 *NewNumSteps)
 Works out the number of steps needed to accomodate the new step distance, as well as working out the new positions of the end objects. This is nearly identical to the function of the same name in OpChangeBlendDistance, the difference being that if the operation cannot be performed without moving the fixed node then it will inform the user.
BOOL InsertChangeProportion (double NewProp, BOOL FirstNode, NodeBlender *pEditBlender)
 inserts an action setting the proportion along the path variable to its new value

Protected Attributes

Matrixm_pTransMatrix
DocCoord m_StartCoord
DocCoord m_LastCoord
Rangem_pRange
Rangem_pCopyRange
NodeBlendm_pNodeBlend
SelectionStatem_pSelState
NodeBlendPathm_pNodeBlendPath
BlendToolm_pBlendTool

Private Member Functions

 CC_DECLARE_DYNCREATE (OpEditBlendEndObject)

Detailed Description

The operation to edit the position of the end objects of a blend on a path.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> yamanaka
Date:
6/9/99

Definition at line 919 of file blndtool.h.


Constructor & Destructor Documentation

OpEditBlendEndObject::OpEditBlendEndObject  )  [inline]
 

Definition at line 924 of file blndtool.h.

00924 {}

OpEditBlendEndObject::OpEditBlendEndObject BlendTool pBlendTool  ) 
 

default constructor

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/9/99
Returns:

Definition at line 8802 of file blndtool.cpp.

08803 {
08804     if (pBlendTool == NULL)
08805     {
08806         ERROR3("No blend tool");
08807         return;
08808     }
08809     m_pTransMatrix = NULL;
08810     m_pNodeBlend = NULL;
08811     m_pRange = NULL;
08812     m_pNodeBlendPath = NULL;
08813     m_pBlendTool = pBlendTool;
08814 }

OpEditBlendEndObject::~OpEditBlendEndObject  ) 
 

destructor, deletes pointers to dynamically created objects

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/9/99
Returns:

Definition at line 8829 of file blndtool.cpp.

08830 {
08831     delete m_pTransMatrix;
08832     delete m_pSelState;
08833 }


Member Function Documentation

BOOL OpEditBlendEndObject::CalculateNewNumStepsAndPosition UINT32  OldNumSteps,
double  BlendDistance,
double  StepDistance,
double *  FixedDistance,
double *  MoveableDistance,
UINT32 NewNumSteps
[protected]
 

Works out the number of steps needed to accomodate the new step distance, as well as working out the new positions of the end objects. This is nearly identical to the function of the same name in OpChangeBlendDistance, the difference being that if the operation cannot be performed without moving the fixed node then it will inform the user.

Parameters:
NewNumSteps - the new number of steps required [OUTPUTS] MoveableDistance - the new position of the end that we don't care about FixedDistance - in some rare instances we may have adjust the fixed position in order to accomodate the desired step distance is the last object. returns: TRUE if all went well, FALSE if the step distance gives and invalid number of steps.
See Also:

Definition at line 9806 of file blndtool.cpp.

09809 {
09810     // First check parameters
09811     if (OldNumSteps < 0 || StepDistance < 0)
09812     {
09813         ERROR3("Invalid parameter");
09814         return FALSE;
09815     }
09816     if (BlendDistance < (*FixedDistance + *MoveableDistance))
09817     {
09818         ERROR3("Invalid distance parameter");
09819         return FALSE;
09820     }
09821 
09822     //initialise to zero 
09823     *NewNumSteps = 0;
09824 
09825     // get the distance currently occupied by the blend
09826     double DistanceUsed = BlendDistance - (*FixedDistance + *MoveableDistance);
09827 
09828     // try to use all the space 
09829     UINT32 TempNumSteps = (UINT32)(DistanceUsed / StepDistance);
09830 
09831     if (TempNumSteps > 0)
09832     {
09833         *NewNumSteps = TempNumSteps;
09834         double NewDistance = TempNumSteps * StepDistance;
09835         *MoveableDistance = BlendDistance - (*FixedDistance + NewDistance);
09836     }
09837     // thats too long, try moving the other node all the way to the end
09838     else 
09839     {
09840 
09841         TempNumSteps = (UINT32)((BlendDistance - *FixedDistance)/ StepDistance);
09842         if (TempNumSteps > 0)
09843         {
09844             double NewDistance = TempNumSteps * StepDistance;
09845             *NewNumSteps = TempNumSteps;
09846             *MoveableDistance = BlendDistance - (*FixedDistance + NewDistance);
09847         }
09848         else
09849         {
09850             // still didn't work, just quit for now but maybe 
09851             // think about bringing up a dialog asking the user if they 
09852             // wish to go to edit steps mode.
09853             return FALSE;
09854         }
09855     }
09856 
09857     // test to see that what we have is ok.
09858     if (*NewNumSteps > 0)
09859         return TRUE;
09860     else
09861         return FALSE;
09862 }

OpEditBlendEndObject::CC_DECLARE_DYNCREATE OpEditBlendEndObject   )  [private]
 

BOOL OpEditBlendEndObject::Declare  )  [static]
 

Adds the operation to the list of all known operations.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/9/99
Returns:
TRUE if all went OK, FALSE otherwise

Definition at line 8847 of file blndtool.cpp.

08848 {
08849     return (RegisterOpDescriptor(
08850                                 0, 
08851                                 0,
08852                                 CC_RUNTIME_CLASS(OpEditBlendEndObject), 
08853                                 OPTOKEN_EDITBLENDENDOBJECT,
08854                                 OpEditBlendEndObject::GetState,
08855                                 0,          /* help ID */
08856                                 _R(IDBBL_NOOP), /* bubble ID */
08857                                 0           /* bitmap ID */
08858                                 ));
08859 }

BOOL OpEditBlendEndObject::DoDrag DocCoord  PointerPos,
Spread pSpread
 

This starts a drag to change the position of one of the end objects of a blend The DragFinished() method will do the hard work of recalculating the blend etc.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/9/99
Parameters:
Position of the pointer to start the drag from. [INPUTS] The current spread.
- [OUTPUTS]
Returns:
TRUE if successful, FALSE otherwise

Definition at line 8913 of file blndtool.cpp.

08914 {
08915     GetApplication()->RegisterIdleProcessor(IDLEPRIORITY_HIGH, this);
08916 
08917     List BlendList;
08918     Node* pNodeUnderPoint = NULL;
08919     BOOL ok = BevelTools::BuildListOfSelectedNodes(&BlendList, CC_RUNTIME_CLASS(NodeBlend), FALSE);
08920     if (ok)
08921     {
08922         NodeListItem* pListItem = (NodeListItem*)BlendList.GetHead();
08923         while (pListItem != NULL)
08924         {
08925             
08926             NodeBlend* pNodeBlend = (NodeBlend*)pListItem->pNode;
08927             
08928             ok = pNodeBlend->HitOnEndDragBlob(PointerPos, &pNodeUnderPoint);
08929             if (ok)
08930             {
08931                 ObjChangeFlags cFlags;
08932                 cFlags.TransformNode = TRUE;
08933                 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
08934                 if (pNodeBlend->AllowOp(&ObjChange, TRUE))
08935                 {
08936                     m_pNodeBlend = pNodeBlend;                      
08937                     break;
08938                 }
08939             }
08940             pListItem = (NodeListItem*)BlendList.GetNext(pListItem);
08941         }
08942     }
08943     else
08944     {
08945         // that didn't work, but it may be selected inside so try this;
08946         pNodeUnderPoint = NodeRenderableInk::FindSimpleAtPoint(pSpread, PointerPos);
08947         
08948         if (pNodeUnderPoint == NULL)
08949         {
08950             // op shouldn't have been allowed as we are not above a node, lets quit
08951             FailAndExecute();
08952             End();
08953             BlendList.DeleteAll();
08954             return FALSE;
08955         }
08956         
08957         Node* pParent = pNodeUnderPoint->FindParentOfSelected();
08958         if (pParent == NULL || (!pParent->IS_KIND_OF(NodeBlend)))
08959         {
08960             FailAndExecute();
08961             End();
08962             BlendList.DeleteAll();
08963             return FALSE;
08964         }
08965         // its ok, we can continue
08966         m_pNodeBlend = (NodeBlend*)pParent;
08967 
08968     }
08969 
08970     BlendList.DeleteAll();
08971     // see if there is a node between the blend and the simple node, if so it may be a group
08972     NodeRenderableInk* pGroupUnderPoint = NodeRenderableInk::FindInnerCompound(pNodeUnderPoint, m_pNodeBlend);
08973     
08974     Node* pNodeToEdit = NULL;
08975     
08976     if (pGroupUnderPoint != NULL)
08977     {
08978         // if the group is the same as the nodeblend
08979         if (pGroupUnderPoint == m_pNodeBlend)
08980         {
08981             pNodeToEdit = (Node*) pNodeUnderPoint;
08982         }
08983         else
08984         {
08985             pNodeToEdit = (Node*)pGroupUnderPoint;
08986         }
08987     }
08988     else
08989     {
08990         FailAndExecute();
08991         End();
08992         return FALSE;
08993     }
08994     
08995     // save the selection state for restoring at the end of the drag
08996     ALLOC_WITH_FAIL(m_pSelState, new SelectionState, this);
08997     ok = m_pSelState->Record();
08998 
08999     if (!ok)
09000     {
09001         ERROR3("Could not record selection");
09002         FailAndExecute();
09003         End();
09004         return FALSE;
09005     }   
09006 
09007 
09008     m_pRange = GetApplication()->FindSelection(); 
09009 
09010     if (m_pRange == NULL)
09011     {
09012         ERROR3("No Selection");
09013         FailAndExecute();
09014         End();
09015         return FALSE;
09016     }
09017 
09018     // the bodging continues... When the TransformNodeAction gets called as part of
09019     // the undoing of this op it changes the selection so that only the transformed node is
09020     // selected.  Hence we need to insert an action that will occur after TransformNode in the 
09021     // undo list in order to have the selection as it started....nice
09022     Action* pRestoreAction;
09023     SelectionState* pCopySelState =  NULL;
09024     ALLOC_WITH_FAIL(pCopySelState, new SelectionState, this);  // gets destroyed by RestoreSelectionsAction
09025     pCopySelState->Record();  
09026 
09027     ok = RestoreSelectionsAction::Init(this, &UndoActions, pCopySelState,
09028                                         TRUE, TRUE, FALSE, TRUE, FALSE, FALSE,
09029                                         &pRestoreAction);
09030 /*  the function proto
09031 RestoreSelectionsAction::Init(Operation* const pOp, 
09032                                          ActionList* pActionList,   
09033                                          SelectionState* SelState,
09034                                          BOOL Toggle, 
09035                                          BOOL ToggleStatus,
09036                                          BOOL SelStateShared,
09037                                          BOOL RenderStartBlobs, 
09038                                          BOOL RenderEndBlobs, 
09039                                          BOOL StartRestore,  
09040                                          Action** NewAction)       
09041 
09042 */
09043     
09044     // setting the selection so that only the node we wish to be XOR'd during the
09045     // drag is selected - ugh.
09046     if (ok)
09047     {
09048         NodeRenderableInk::DeselectAll();
09049         ((NodeRenderable*)pNodeToEdit)->Select(TRUE);
09050     
09051         // we don't want to see those object blobs whilst dragging
09052         BlobManager* BlobMgr = GetApplication()->GetBlobManager();
09053         if (BlobMgr != NULL)
09054         {
09055                 // Decide which blobs we will display
09056                 BlobStyle MyBlobs;
09057             
09058                 MyBlobs.Object = FALSE;
09059                 MyBlobs.Tiny = FALSE;
09060 
09061                 BlobMgr->ToolInterest(MyBlobs);
09062         }
09063 
09064 
09065         m_pRange->ResetXOROutlineRenderer();
09066 
09067         // work out where we need to translate to and create a matrix for it
09068         DocRect BRect = ((NodeRenderableBounded*)pNodeToEdit)->GetBoundingRect();
09069         m_StartCoord = BRect.Centre();
09070 
09071         ALLOC_WITH_FAIL(m_pTransMatrix, new Matrix, this)
09072         m_pTransMatrix->SetTranslation(PointerPos - m_StartCoord);
09073 
09074         m_pRange->RenderXOROutlinesOn(NULL, pSpread, m_pTransMatrix, pNodeUnderPoint);
09075     
09076         m_LastCoord = m_StartCoord;
09077         RenderSelectedObjectBlobs(pSpread);
09078         // And tell the Dragging system that we need drags to happen
09079         StartDrag( DRAGTYPE_AUTOSCROLL );
09080     }
09081     else
09082     {
09083         FailAndExecute();
09084         End();
09085     }
09086     return ok;
09087 }

void OpEditBlendEndObject::DragFinished DocCoord  PointerPos,
ClickModifiers  ClickMods,
Spread pSpread,
BOOL  Success,
BOOL  bSolidDrag
[virtual]
 

Ends the drag and recalculates the blend.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/9/99
Parameters:
PointerPos - The position of the mouse at the end of the drag [INPUTS] ClickMods - the key modifiers being pressed pSpread - The spread that the drag finished on Success - TRUE if the drag was terminated properly, FALSE if it was ended with the escape key being pressed
See also:
ClickModifiers, DoDrag() for an explanation of whats going on with the selection.

Reimplemented from Operation.

Definition at line 9171 of file blndtool.cpp.

09172 {
09173     GetApplication()->RemoveIdleProcessor(IDLEPRIORITY_HIGH, this);
09174     
09175     DocCoord PointOnLine;
09176     
09177     BOOL ValidPoint = GetClosestPointOnPath(PointerPos, &PointOnLine);
09178     if (!ValidPoint)
09179     {   
09180         EndDrag();                  // not sure this is correct, should we make some attempt to 
09181         return;       // render the xor outlines off? 
09182     }
09183 
09184     Matrix NewMatrix;
09185     NewMatrix.SetTranslation(PointOnLine - m_StartCoord);
09186     
09187     m_pRange->RenderXOROutlinesOff(NULL, pSpread, &NewMatrix);
09188     EndDrag();
09189     
09190     if (Success)
09191         Success = RecalculateBlend(PointOnLine);
09192 
09193     // bring back the object blobs
09194     // we don't want to see those object blobs whilst dragging
09195     BlobManager* BlobMgr = GetApplication()->GetBlobManager();
09196     if (BlobMgr != NULL)
09197     {
09198             // Decide which blobs we will display
09199             BlobStyle MyBlobs;
09200             
09201             MyBlobs.Object = TRUE;
09202             MyBlobs.Tiny = FALSE;
09203 
09204             BlobMgr->ToolInterest(MyBlobs);
09205     }
09206 
09207     // restore the selection - very important
09208     m_pSelState->Restore();
09209     if (Success)
09210     {   
09211         SelRange* pSel = GetApplication()->FindSelection();
09212         pSel->Update();
09213     }
09214     else
09215         FailAndExecute();
09216     
09217     // Inform all changed nodes that we have finished
09218     ObjChangeFlags cFlags;
09219     ObjChangeParam ObjChange(OBJCHANGE_FINISHED, cFlags, NULL, this);
09220     
09221     /*BOOL ok =*/ UpdateChangedNodes(&ObjChange);
09222     End();
09223     
09224     //TRACEUSER( "Diccon", _T("\nFinished dragging end object\n"));
09225 
09226 }

void OpEditBlendEndObject::DragPointerIdle DocCoord  PointerPos,
ClickModifiers  Clickmodifiers,
Spread pSpread,
BOOL  bSolidDrag
[virtual]
 

Pure virtual function which tells the operation that nothing is going on so that it has time to do background jobs.

virtual void Operation::DragPointerIdle( DocCoord PointerPos, ClickModifiers ClickMods, Spread *pSpread, BOOL bSolidDrag)

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/7/93
Parameters:
PointerPos,: Position of the mouse pointer [INPUTS] ClickMods: Click modifiers
- [OUTPUTS]
Returns:
-

Errors: -

See also:
ClickModifiers

Reimplemented from Operation.

Definition at line 9146 of file blndtool.cpp.

09147 {
09148 
09149     m_pRange->RenderXOROutlinesOn(NULL, pSpread, m_pTransMatrix, NULL);
09150 }

void OpEditBlendEndObject::DragPointerMove DocCoord  PointerPos,
ClickModifiers  ClickMods,
Spread pSpread,
BOOL  bSolidDrag
[virtual]
 

Pure virtual function which tells the operation that the mouse has moved.

virtual void Operation::DragPointerMove( DocCoord PointerPos, ClickModifiers ClickMods, Spread *pSpread, BOOL bSolidDrag)

Author:
Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/7/93
Parameters:
PointerPos,: Position of the mouse pointer [INPUTS] ClickMods: Click modifiers
- [OUTPUTS]
Returns:
-

Errors: -

See also:
ClickModifiers

Reimplemented from Operation.

Definition at line 9109 of file blndtool.cpp.

09110 {
09111     // get rid of existing blobs
09112     RenderDragBlobs(pSpread, m_LastCoord, FALSE);
09113     if (m_pBlendTool != NULL)
09114         m_pBlendTool->DisplayStatusBarHelp(_R(IDS_BLENDSTATUS_MOVEEND));
09115     DocCoord PointOnLine;
09116     BOOL ValidPoint = GetClosestPointOnPath(PointerPos, &PointOnLine);
09117     if (!ValidPoint)
09118     {   
09119         EndDrag();  // not sure this is correct, should we make some attempt to 
09120         return;       // render the xor outlines off? 
09121     }
09122     // draw new blobs
09123     RenderDragBlobs(pSpread, PointOnLine, TRUE);
09124     //RenderAllBlobs(pSpread);
09125     
09126     m_LastCoord = PointOnLine;
09127 
09128 
09129 
09130 }

NodeBlender * OpEditBlendEndObject::GetBlenderAndPosition Node pEditNode,
BOOL *  pFirst
[protected]
 

To find the NodeBlender on a curve that uses pNode as either its first or last node, and which position.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/9/99
Parameters:
pNode - the blend object that is being edited [INPUTS]
pFirst - TRUE if pNode is the first object of the blender, FALSE if it [OUTPUTS] is the last object. returns: pointer to the nodeblender responsible for the blend being edited, or NULL if invalid.

Definition at line 9887 of file blndtool.cpp.

09888 {
09889     if (pEditNode == NULL)
09890     {
09891         ERROR3("Node is NULL");
09892         return NULL;
09893     }
09894 
09895     if (m_pNodeBlend == NULL)
09896     {
09897         ERROR3("m_pNodeBlend is NULL");
09898         return NULL;
09899     }
09900 
09901     NodeBlender* pBlender = m_pNodeBlend->FindFirstBlender();
09902     while (pBlender != NULL)
09903     {
09904         if (pBlender->IsBlendedOnCurve())
09905         {
09906             if (pBlender->GetNodeStart() == pEditNode)
09907             {
09908                 *pFirst = TRUE;
09909                 return pBlender;
09910             }
09911             else if (pBlender->GetNodeEnd() == pEditNode)
09912             {
09913                 *pFirst = FALSE;
09914                 return pBlender;
09915             }
09916             else
09917             {
09918                 // also need to check for compound nodes ....
09919 
09920                 if (pBlender->GetNodeStart ()->IsNodeInSubtree (pEditNode))
09921                 {
09922                     *pFirst = TRUE;
09923                     return pBlender;
09924                 }
09925                 else    // check the end node
09926                 {
09927                     if (pBlender->GetNodeEnd ()->IsNodeInSubtree (pEditNode))
09928                     {
09929                         *pFirst = FALSE;
09930                         return pBlender;
09931                     }
09932                 }
09933             }
09934         }
09935         pBlender = m_pNodeBlend->FindNextBlender(pBlender);
09936     }
09937 
09938     // we didn't find a nodeblender
09939     ERROR3("Couldn't find a nodeblender");
09940     return NULL;
09941 
09942 
09943 }

BOOL OpEditBlendEndObject::GetClosestPointOnPath DocCoord  PointerPos,
DocCoord ClosestPoint
[protected]
 

To find the closest point on the nodeblend path to the point clicked or dragged on by the user. The function gets the closest point on all the paths and takes the closest. However this part is only done once as the nodeblendpath is then cached.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/9/99
Parameters:
PointerPos - The current position of the mouse in Doc Coords [INPUTS]
ClosestPoint - the closest point on the nodeblendpath to pointerpos [OUTPUTS] returns: TRUE if successful , FALSE otherwise

Definition at line 9962 of file blndtool.cpp.

09963 {
09964     if (m_pNodeBlend == NULL)
09965     {
09966         ERROR3("There is no NodeBlend");
09967         return FALSE;
09968     }
09969     if (m_pNodeBlendPath == NULL)
09970     {
09971         UINT32 NBPCounter = 0;
09972         NodeBlendPath* pNodeBlendPath = m_pNodeBlend->GetNodeBlendPath(NBPCounter);
09973     
09974         if (pNodeBlendPath == NULL)
09975         {
09976             ERROR3("This blend has no nodeblendpath");
09977             return FALSE;
09978         }
09979     
09980         UINT32 ClosestIndex = 0;
09981         double ClosestDistance = 999999999999.;
09982         INT32 ClosestPath=0;
09983         double ClosestMu=0;
09984         while (pNodeBlendPath != NULL)
09985         {
09986             INT32 Index;
09987             double Mu;
09988             double SqrDistance = pNodeBlendPath->InkPath.SqrDistanceToPoint(PointerPos, &Index, &Mu);
09989             if (SqrDistance < ClosestDistance)
09990             {
09991                 ClosestDistance = SqrDistance;
09992                 ClosestPath = NBPCounter;
09993                 ClosestIndex = Index;
09994                 ClosestMu = Mu;
09995             }
09996             pNodeBlendPath = m_pNodeBlend->GetNodeBlendPath(++NBPCounter);
09997         }
09998         pNodeBlendPath = m_pNodeBlend->GetNodeBlendPath(ClosestPath);
09999         DocCoord PointOnLine = pNodeBlendPath->InkPath.ClosestPointTo(ClosestMu, ClosestIndex);
10000         // assign the point
10001         *ClosestPoint = PointOnLine;
10002         // assign the path to the member variable
10003         m_pNodeBlendPath = pNodeBlendPath; 
10004     }
10005     else
10006     {   // if we have already cached the nodeblendpath
10007         INT32 Index=0;
10008         double Mu=0;
10009         /*double SqrDistance = */m_pNodeBlendPath->InkPath.SqrDistanceToPoint(PointerPos, &Index, &Mu);
10010         DocCoord PointOnLine = m_pNodeBlendPath->InkPath.ClosestPointTo(Mu, Index);
10011         *ClosestPoint = PointOnLine;
10012     }
10013 
10014     return TRUE;
10015 
10016 
10017 
10018 }

NodeBlendPath* OpEditBlendEndObject::GetNodeBlendPath  ) 
 

void OpEditBlendEndObject::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:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/9/99
Parameters:
OpName = ptr to str to place op name in [INPUTS]
The undo string for the operation [OUTPUTS]
Returns:

Errors: -

See also:
-

Reimplemented from Operation.

Definition at line 10039 of file blndtool.cpp.

10040 {
10041     String_256 test = "test string";
10042 
10043 
10044 }

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

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

> static OpState OpEditBlendEndObject::GetState(String_256* Description, OpDescriptor*)

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

Definition at line 8876 of file blndtool.cpp.

08877 {
08878     OpState State;
08879 
08880     return State;
08881 }

BOOL OpEditBlendEndObject::InsertChangeEndActions double  NewPathProp,
DocCoord  NewPosition,
double  StepDistance,
Node pNodeToEdit
[protected]
 

To calculate and perform the actions necessary to transform pNode to its new PathProportion whilst maintaining a constant distance between blend steps. This requires calculating a new position for the node that is not being edited in order to maintain the correct distance, it may also require changing the number of steps in the blend.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/9/99
Parameters:
PathProportion - the new proportion along the path to move the end object to [INPUTS] pNode - the blend object that is being edited NewPosition - the new position as a coordinate
pNodeToEdit - some members are altered by these actions [OUTPUTS] returns: TRUE if all actions were correctly carried out, else FALSE
See Also: Overridden version of this function for use with constant number of blend steps

Definition at line 9489 of file blndtool.cpp.

09491 {
09492     // couple of quick checks
09493     if (pNodeToEdit == NULL)
09494     {
09495         ERROR3("Node to edit is NULL");
09496         return FALSE;
09497     }
09498     if (NewPathProp < 0.0 || NewPathProp > 1.0)
09499     {
09500         ERROR3("Invalid path proportion");
09501         return FALSE;
09502     }
09503     if (m_pNodeBlend == NULL)
09504     {
09505         ERROR3("m_pNodeBlend is NULL");
09506         return FALSE;
09507     }
09508     // find out if this node is the first or last node of the blend
09509     BOOL NodeIsFirst;
09510     NodeBlender* pNodeBlender = GetBlenderAndPosition(pNodeToEdit, &NodeIsFirst);   
09511     if (pNodeBlender == NULL)
09512     {
09513         ERROR3("No NodeBlender");
09514         return FALSE;
09515     }
09516     // get the variables that we need to pass to CalculateNewNumSteps()
09517     double OtherDistance = 0.0;
09518     double ThisDistance = 0.0;
09519     double StartProp = 0.0;
09520     double EndProp = 1.0;
09521     UINT32 CurrentSteps = m_pNodeBlend->GetNumBlendSteps();
09522     UINT32 NewNumSteps = CurrentSteps;
09523     double BlendDistance = 0.0;
09524     
09525     BOOL Valid = m_pNodeBlend->GetBlendDistance(TRUE, &BlendDistance);
09526     if (Valid)
09527     {
09528         Valid = m_pNodeBlend->GetStartAndEndProportions(&StartProp, &EndProp);
09529         if (Valid)
09530         {
09531             // we must pass the distance of each object from their respective ends,
09532             // i.e. the distance of the end object is the distance from the object to
09533             // the end of the path.
09534             if (NodeIsFirst)
09535             {
09536                 // have we reversed the order? If so then do it as an action
09537                 if (NewPathProp >= EndProp)
09538                 {   
09539                     // Swap the ends
09540                     Valid = InsertChangeProportion(NewPathProp, NodeIsFirst, pNodeBlender);
09541                     // get the new proportions
09542                     if (Valid) Valid = m_pNodeBlend->GetStartAndEndProportions(&StartProp, &EndProp);
09543                     // work out the distances from the closest end to each object
09544                     OtherDistance = BlendDistance * StartProp;
09545                     ThisDistance = BlendDistance * (1-NewPathProp);
09546                     // we have swapped ends
09547                     NodeIsFirst = FALSE;
09548                 }
09549                 else
09550                 {
09551                     OtherDistance = BlendDistance * (1-EndProp);
09552                     ThisDistance = BlendDistance * NewPathProp;
09553                 }
09554             }
09555             else
09556             {
09557                 if (NewPathProp <= StartProp)
09558                 {
09559                     Valid = InsertChangeProportion(NewPathProp, NodeIsFirst, pNodeBlender);
09560                     if (Valid) Valid = m_pNodeBlend->GetStartAndEndProportions(&StartProp, &EndProp);   
09561                     OtherDistance = BlendDistance * (1-EndProp);
09562                     ThisDistance = BlendDistance * NewPathProp;
09563                     NodeIsFirst = TRUE;
09564                 }
09565                 else
09566                 {
09567                     OtherDistance = BlendDistance * StartProp;
09568                     ThisDistance = BlendDistance * (1-NewPathProp);
09569                 }
09570             }
09571             Valid = CalculateNewNumStepsAndPosition(CurrentSteps, BlendDistance, 
09572                                                     StepDistance, &ThisDistance, 
09573                                                     &OtherDistance, &NewNumSteps);
09574 
09575             if (Valid)
09576             {
09577                 double NewOtherProp = 0.0;
09578                 
09579                 // if we are editing the start node make the other distance go from the
09580                 // start of the path
09581                 if (NodeIsFirst)
09582                     OtherDistance = BlendDistance - OtherDistance;
09583                     
09584                 NewOtherProp = OtherDistance / BlendDistance;
09585 
09586                 Valid = DoInvalidateNodeRegion((NodeRenderableInk*)m_pNodeBlend,TRUE,FALSE);
09587                 if (Valid)  Valid = (InvalidateBoundsAction::Init(this,&UndoActions,m_pNodeBlend,TRUE) != AC_FAIL);
09588                 if (Valid)
09589                 {
09590 //                  NodeBlender* pThisBlender = NULL;
09591                     NodeBlender* pOtherBlender = NULL;
09592                     Node* pOtherNode = NULL;
09593                     if (NodeIsFirst)
09594                     {
09595                         pOtherBlender = m_pNodeBlend->FindLastBlender();
09596                         if (pOtherBlender ==  NULL)
09597                         {
09598                             ERROR3("Couldn't find blender");
09599                             return FALSE;
09600                         }
09601                         pOtherNode = pOtherBlender->GetNodeEnd();
09602                     }
09603                     else
09604                     {
09605                         pOtherBlender = m_pNodeBlend->FindFirstBlender();
09606                         if (pOtherBlender ==  NULL)
09607                         {
09608                             ERROR3("Couldn't find blender");
09609                             return FALSE;
09610                         }
09611                         pOtherNode = pOtherBlender->GetNodeStart();
09612                     }
09613 
09614                     if (pOtherNode == NULL)
09615                     {
09616                         ERROR3("Couldn't find other blend node");
09617                         return FALSE;
09618                     }
09619                     // insert a change steps action if we need one
09620                     if (NewNumSteps != CurrentSteps)
09621                     {
09622                         double DistanceEntered = m_pNodeBlend->GetDistanceEntered();
09623                         ChangeBlendStepsAction* pStepAction;
09624                         NodeRenderableInk * pInk = (NodeRenderableInk *)m_pNodeBlend;       
09625                         Valid = ChangeBlendStepsAction::Init(this,&UndoActions,pInk,CurrentSteps,DistanceEntered, &pStepAction) != AC_FAIL;
09626                         m_pNodeBlend->SetNumBlendSteps(NewNumSteps);
09627                     }
09628                     // insert change proportion for the node we edited
09629                     Valid = InsertChangeProportion(NewPathProp, NodeIsFirst, pNodeBlender);
09630                     
09631                     // insert change for the node that was moved in order to retain constant step distance
09632                     if (Valid) Valid = InsertChangeProportion(NewOtherProp, (!NodeIsFirst), pOtherBlender);
09633                     
09634                     // transform the edited node to its new position
09635                     if (Valid) Valid = m_pNodeBlend->TransformNodeToPoint((NodeRenderableInk*)pNodeToEdit,&NewPosition,this,0.0);
09636                     
09637                     // transform the other node to its new position
09638                     if (Valid)
09639                     {   
09640                         DocCoord NewPoint;
09641                         double VoidParam;
09642                         Valid = pOtherBlender->GetPointFromDistance(OtherDistance, &NewPoint, &VoidParam);
09643                         if (Valid) Valid = m_pNodeBlend->TransformNodeToPoint((NodeRenderableInk*)pOtherNode, &NewPoint, this, 0.0);
09644                     
09645                         // find out if we are part of a bevel, shadow or contour, if so then we must regenerate
09646                         Node* pController = m_pNodeBlend->GetParentController();
09647                         if (pController != NULL)
09648                             pController->RegenerateNode(this);
09649 
09650                         if (Valid) Valid = DoInvalidateNodeRegion((NodeRenderableInk*)m_pNodeBlend,TRUE,FALSE);
09651                         if (Valid) Valid = (InvalidateBoundsAction::Init(this,&UndoActions,m_pNodeBlend,TRUE) != AC_FAIL);
09652                     
09653                     }
09654                         
09655                 }
09656             }
09657         }
09658     }
09659 
09660     
09661     return Valid;
09662 
09663 
09664 }

BOOL OpEditBlendEndObject::InsertChangeEndActions double  NewPathProp,
DocCoord  NewPosition,
Node pNodeToEdit
[protected]
 

To calculate and perform the actions necessary to transform pNode to its new PathProportion whilst maintaining a constant number of blend steps.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/9/99
Parameters:
PathProportion - the new proportion along the path to move the end object to [INPUTS] pNodeToEdit - the blend object that is being edited NewPosition - the new position as a coordinate
pNodeToEdit - some members are altered by these actions [OUTPUTS] returns: TRUE if all actions were correctly carried out, else FALSE
See Also: Overridden version of this function for use with constant distance between blend steps

NodeIsFirst);

Definition at line 9320 of file blndtool.cpp.

09322 {
09323     // couple of quick checks
09324     if (pNodeToEdit == NULL)
09325     {
09326         ERROR3("Node to edit is NULL");
09327         return FALSE;
09328     }
09329 
09330     if (NewPathProp < 0.0 || NewPathProp > 1.0)
09331     {
09332         ERROR3("Invalid path proportion");
09333         return FALSE;
09334     }
09335 
09336     // find out if this node is the first or last node of the blender on a curve
09337     BOOL NodeIsFirst;
09338     NodeBlender* pNodeBlender = GetBlenderAndPosition(pNodeToEdit, &NodeIsFirst);
09339     BOOL Valid = FALSE;     
09340     if (pNodeBlender == NULL)
09341     {
09342         ERROR3("No NodeBlender");
09343         return FALSE;
09344     }
09345     else
09346     {   
09347         Valid = DoInvalidateNodeRegion((NodeRenderableInk*)m_pNodeBlend,TRUE,FALSE);
09348         if (Valid)  Valid = (InvalidateBoundsAction::Init(this,&UndoActions,m_pNodeBlend,TRUE) != AC_FAIL);
09349 
09350         // change the proportion along the path to the new value
09351         if (Valid)
09352             Valid = InsertChangeProportion(NewPathProp, NodeIsFirst, pNodeBlender);
09353         
09354         double AngleChange = 0.0;
09355         // if we are rotated along the curve then calculate the new angle
09356         if (m_pNodeBlend->IsTangential() && Valid)
09357         {
09358             
09359             NodeBlendPath* pNodeBlendPath = pNodeBlender->GetNodeBlendPath();
09360             if (pNodeBlendPath != NULL)
09361             {
09362                 double NewAngle = 0.0;
09363                 double OldAngle = 0.0;
09364                 double BlendRatio = 0.0;
09365                 ChangeBlenderOpParam ChangeParam;
09366                 if (NodeIsFirst)
09367                 {
09368                     OldAngle = pNodeBlender->GetAngleStart();
09369                     ChangeParam.m_ChangeType = CHANGEBLENDER_ANGLESTART;
09370                     BlendRatio = 0.0;
09371                 }
09372                 else
09373                 {
09374                     OldAngle = pNodeBlender->GetAngleEnd();
09375                     ChangeParam.m_ChangeType = CHANGEBLENDER_ANGLEEND;
09376                     BlendRatio = 1.0;
09377                 }
09378 //              MILLIPOINT PathDistance = (MILLIPOINT)(pNodeBlendPath->GetPathLength());
09379 //              MILLIPOINT PointDistance = (MILLIPOINT)(NewPathProp * PathDistance);
09380                 DocCoord Point;
09381                 Valid = pNodeBlender->GetPointOnNodeBlendPath(BlendRatio, &Point, &NewAngle);
09382                 if (Valid)
09383                 {
09384                     AngleChange = NewAngle - OldAngle;
09385                     TRACEUSER( "Diccon", _T("Moved end: OldAngle: %f, NewAngle %f, Change %f\n"), OldAngle, NewAngle, AngleChange);
09386                     // make it undoable     
09387                     if (!NodeIsFirst)
09388                         ChangeParam.m_NewAngleEnd = NewAngle;
09389                     else
09390                         ChangeParam.m_NewAngleStart = NewAngle;
09391                     ActionCode Ac = ChangeBlenderAction::Init(  this, &UndoActions,
09392                                                                 pNodeBlender,ChangeParam);
09393                     Valid = (Ac !=AC_FAIL);
09394                 }
09395 
09396             }
09397         }
09398         
09399         // transform the edited node to its new location
09400         if (Valid) 
09401             Valid = m_pNodeBlend->TransformNodeToPoint((NodeRenderableInk*)pNodeToEdit,&NewPosition,this,AngleChange);
09402         
09403         // find out if this node is part of another blend, and if so then regenerate it
09404         if (Valid)
09405         {
09406             BOOL OtherEnd;
09407             NodeBlender* pOtherBlender = m_pNodeBlend->NodeIsPartOfBlender( pNodeToEdit, pNodeBlender, &OtherEnd); 
09408             if (pOtherBlender != NULL && pOtherBlender != pNodeBlender)
09409             {
09410                 // if its not on a curve just ask it to reninitialise
09411                 if (!pOtherBlender->IsBlendedOnCurve())
09412                 {
09413                     ChangeBlenderOpParam Param;
09414                     Param.m_ChangeType = CHANGEBLENDER_REGEN;
09415                     Valid = ChangeBlenderAction::Init(this, &UndoActions, pOtherBlender, Param);
09416                 }
09417                 // if it is on a curve work set the new position for the other blender
09418                 else
09419                 {
09420                     ChangeBlenderOpParam ChangeParam;
09421                     if (OtherEnd)
09422                     {
09423                         ChangeParam.m_ChangeType = CHANGEBLENDER_PATHSTART;
09424                         ChangeParam.m_NewPathStart = NewPathProp;
09425                     }
09426                     else
09427                     {
09428                         ChangeParam.m_ChangeType = CHANGEBLENDER_PATHEND;
09429                         ChangeParam.m_NewPathEnd = NewPathProp;
09430                     }
09431                     ActionCode Ac = ChangeBlenderAction::Init(  this, &UndoActions,
09432                                                                 pOtherBlender,ChangeParam);
09433                     Valid = (Ac !=AC_FAIL);
09434 
09435                 }
09436             }
09437         }
09438     }
09439     // regenerate any shadows, bevels or contours
09440     Node* pController = ((Node*)m_pNodeBlend)->FindParent(CC_RUNTIME_CLASS(NodeShadowController));
09441     if (pController != NULL)
09442         pController->RegenerateNode(this);
09443     else 
09444     {
09445         pController = ((Node*)m_pNodeBlend)->FindParent(CC_RUNTIME_CLASS(NodeBevelController));
09446         if (pController != NULL)
09447             pController->RegenerateNode(this);
09448         else
09449         {
09450             pController = ((Node*)m_pNodeBlend)->FindParent(CC_RUNTIME_CLASS(NodeContourController));
09451             if (pController != NULL)
09452                 pController->RegenerateNode(this);
09453         }
09454     }
09455 
09456         
09457     if (Valid)
09458         Valid = DoInvalidateNodeRegion((NodeRenderableInk*)m_pNodeBlend,TRUE,FALSE);
09459     if (Valid)
09460         Valid = (InvalidateBoundsAction::Init(this,&UndoActions,m_pNodeBlend,TRUE) != AC_FAIL);
09461     
09462     return Valid;
09463 }

BOOL OpEditBlendEndObject::InsertChangeProportion double  NewProp,
BOOL  FirstNode,
NodeBlender pEditBlender
[protected]
 

inserts an action setting the proportion along the path variable to its new value

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/9/99
Parameters:
PathProportion - the new proportion along the path to move the end object to [INPUTS] pNode - the blend object that is being edited
pNodeToEdit - some members are altered by these actions [OUTPUTS] returns: TRUE if all actions were correctly carried out, else FALSE

Definition at line 9683 of file blndtool.cpp.

09685 {
09686     // insert the change blender action
09687     ChangeBlenderOpParam BlenderParam;
09688     ChangeBlendOpParam   BlendParam;
09689 
09690     BOOL Valid;
09691     // lets see if we need to swap the ends
09692     if (FirstNode)
09693     {
09694         // if the new proportion of path is past the other end then 
09695         // we need to swap ends.
09696         if (NewProp > pEditBlender->GetProportionOfPathDistEnd())
09697         {
09698             BlenderParam.m_ChangeType = CHANGEBLENDER_SWAPENDS;
09699             Valid = ChangeBlenderAction::Init(this, &UndoActions, pEditBlender, BlenderParam);
09700             
09701             if (Valid)
09702             {
09703                 // set the new start proportion to the old end proportion
09704                 BlenderParam.m_ChangeType = CHANGEBLENDER_PATHSTART;
09705                 BlenderParam.m_NewPathStart = pEditBlender->GetProportionOfPathDistEnd();
09706                 BlendParam.NewEndObject  = FIRST;
09707                 Valid = ChangeBlenderAction::Init(this, &UndoActions, pEditBlender, BlenderParam);
09708                 
09709                 if (Valid)
09710                 {
09711                     BlenderParam.m_ChangeType = CHANGEBLENDER_PATHEND;
09712                     BlenderParam.m_NewPathEnd = NewProp;
09713                     BlendParam.NewEndObject  = LAST;
09714                     Valid = ChangeBlenderAction::Init(this, &UndoActions, pEditBlender, BlenderParam);
09715                 }
09716             }           
09717 
09718         }
09719         else
09720         {
09721             // just a regular end edit
09722             BlenderParam.m_ChangeType = CHANGEBLENDER_PATHSTART;
09723             BlenderParam.m_NewPathStart = NewProp;
09724             BlendParam.NewEndObject  = FIRST;
09725             Valid = ChangeBlenderAction::Init(this, &UndoActions, pEditBlender, BlenderParam);
09726         }
09727     }
09728     else 
09729     {
09730         if (NewProp < pEditBlender->GetProportionOfPathDistStart())
09731         {
09732             BlenderParam.m_ChangeType = CHANGEBLENDER_SWAPENDS;
09733             Valid = ChangeBlenderAction::Init(this, &UndoActions, pEditBlender, BlenderParam);  
09734         
09735             if (Valid)
09736             {
09737                 // set the new end proportion to the old start proportion
09738                 BlenderParam.m_ChangeType = CHANGEBLENDER_PATHEND;
09739                 BlenderParam.m_NewPathEnd = pEditBlender->GetProportionOfPathDistStart();
09740                 BlendParam.NewEndObject  = LAST;
09741                 Valid = ChangeBlenderAction::Init(this, &UndoActions, pEditBlender, BlenderParam);
09742                 
09743                 if (Valid)
09744                 {
09745                     BlenderParam.m_ChangeType = CHANGEBLENDER_PATHSTART;
09746                     BlenderParam.m_NewPathStart = NewProp;
09747                     BlendParam.NewEndObject  = FIRST;
09748                     Valid = ChangeBlenderAction::Init(this, &UndoActions, pEditBlender, BlenderParam);
09749                 }
09750             }           
09751 
09752         }
09753         else
09754         {
09755             // just a regular end edit
09756             BlenderParam.m_ChangeType = CHANGEBLENDER_PATHEND;
09757             BlenderParam.m_NewPathEnd = NewProp;
09758             BlendParam.NewEndObject  = LAST;
09759             Valid = ChangeBlenderAction::Init(this, &UndoActions, pEditBlender, BlenderParam);
09760         }
09761     }
09762 
09763     return Valid;
09764 }

BOOL OpEditBlendEndObject::RecalculateBlend DocCoord  EndPosition  )  [protected]
 

To recalculate the number of steps in the blend or distance between steps following the change of position of one of the end objects. Having done this it then creates the actions to perform the change.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/9/99
Parameters:
PointerPos - The position to move the end object to [INPUTS]
[OUTPUTS] returns: TRUE if successful , FALSE otherwise

Definition at line 9244 of file blndtool.cpp.

09245 {
09246     // check the inputs
09247     if (m_pNodeBlend == NULL) 
09248     {
09249         ERROR3("NodeBlend is not initialised");
09250         return FALSE;
09251     }
09252     // get a pointer to the path
09253     
09254     if (m_pNodeBlendPath == NULL)
09255     {
09256         ERROR3("NodeBlend is not on a path");
09257         return FALSE;
09258     }
09259     // find out how far the point is along the path
09260     double PathLength = m_pNodeBlendPath->GetPathLength();
09261     INT32 DistanceAlongPath = 0;
09262     BOOL Valid = m_pNodeBlendPath->InkPath.GetDistanceToPoint(EndPosition, &DistanceAlongPath);
09263     
09264     // Range::FindFirst() always returns NULL for some reason so I'm forced
09265     // to use FindLast(), given that there is only one this seems ok.
09266     Node* pNode = m_pRange->FindLast();
09267     NodeRenderableInk* pNodeToEdit= NULL;
09268     if (pNode == NULL)
09269     {
09270         ERROR3("Range is empty");
09271         Valid = FALSE;
09272     }
09273     else
09274          pNodeToEdit = (NodeRenderableInk*)pNode;
09275 
09276     if (Valid)
09277     {
09278         // depending on which Edit mode the blend is in try to keep either
09279         // number of steps or distance between steps constant.
09280         double NewPathProportion = DistanceAlongPath / PathLength;
09281         if (m_pNodeBlend->GetEditState() == EDIT_STEPS)
09282         {   
09283             Valid = InsertChangeEndActions(NewPathProportion, EndPosition, pNode);
09284         }
09285         else
09286         {
09287             double StepDistance = m_pNodeBlend->GetDistanceEntered();
09288             Valid = InsertChangeEndActions(NewPathProportion, EndPosition, StepDistance, pNode);
09289         }
09290 
09291     }
09292     
09293 
09294     return Valid;
09295 
09296 }

void OpEditBlendEndObject::RenderDragBlobs Spread pSpread,
DocCoord  CentrePosition,
BOOL  On
 

Calls the XOR outline function and draws an 'X' in the position specified.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/9/99
Parameters:
CentrePosition - the centre of the 'X' to be drawn [INPUTS] pSpread - The spread that the drawing will happen on On - are we rendering the blobs on or off?

Definition at line 10061 of file blndtool.cpp.

10062 {
10063     if (pSpread == NULL)
10064     {
10065         ERROR3("No Spread");
10066         return;
10067     }
10068     if (m_pRange == NULL || m_pTransMatrix == NULL)
10069     {
10070         ERROR3("Null member variables");
10071         return;
10072     }
10073 
10074     Matrix NewMatrix;
10075     NewMatrix.SetTranslation(CentrePosition - m_StartCoord);
10076     
10077     if (On == FALSE)
10078         m_pRange->RenderXOROutlinesOff(NULL, pSpread, m_pTransMatrix);
10079     else
10080     {
10081         m_pRange->RenderXOROutlinesOn(NULL, pSpread, &NewMatrix, NULL);
10082         m_pTransMatrix->SetTranslation(CentrePosition - m_StartCoord);
10083     }
10084     
10085     //we'll render the 'X' directly so we need a render region
10086     
10087     RenderRegion* pRegion = DocView::RenderOnTop(NULL, pSpread, UnclippedEOR);
10088     while ( pRegion != NULL )
10089     {
10090         pRegion->SetLineColour(COLOUR_UNSELECTEDBLOB);
10091         pRegion->SetFillColour(COLOUR_UNSELECTEDBLOB);
10092     
10093                     
10094         // Draw a blob at the centre point
10095         DocRect BlobSize;
10096         BlobManager* pBlobMgr = GetApplication()->GetBlobManager();
10097         if (pBlobMgr != NULL)
10098         {   
10099             pBlobMgr->GetBlobRect(CentrePosition, &BlobSize);
10100     
10101             pRegion->DrawLine(DocCoord(BlobSize.hi.x, BlobSize.hi.y), DocCoord(BlobSize.lo.x, BlobSize.lo.y));
10102             pRegion->DrawLine(DocCoord(BlobSize.lo.x, BlobSize.hi.y), DocCoord(BlobSize.hi.x, BlobSize.lo.y));
10103             pRegion->DrawPixel(DocCoord(BlobSize.hi.x, BlobSize.lo.y));
10104             pRegion->DrawPixel(DocCoord(BlobSize.lo.x, BlobSize.lo.y));
10105         }
10106         pRegion = DocView::GetNextOnTop(NULL);
10107     }
10108             
10109 }

void OpEditBlendEndObject::RenderSelectedObjectBlobs Spread pSpread  ) 
 

To render the object blobs of the objects that were in the selection during the drag op. To dig myself out of the hole that I dug for myself in the implementaion of the drag op. Basically if you read the comments in DoDrag() you will be aware that we've had to temporarily change the selection for the purposes of this drag. However this means that all the objects that should really be selected lose their object blob. in order to restore them we must go through the stored selection by hand and render them individually. Awful, sorry. See also: SelState.h/.cpp DoDrag().

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/9/99
Parameters:
pSpread - The spread that the drawing will happen on [INPUTS]

Definition at line 10131 of file blndtool.cpp.

10132 {
10133     // variables we want so long as the selection state member is ok
10134     Node** pSelectionNodes = NULL;
10135     UINT32 NumNodes = 0; 
10136     SelNdRng* pSelectedRanges = NULL;
10137     UINT32 NumRanges = 0;
10138 
10139     // check out the member
10140     if (m_pSelState == NULL)
10141     {
10142         ERROR3("m_pSelState is NULL");
10143         return;
10144     }
10145     else
10146     {
10147         pSelectionNodes = m_pSelState->GetNodeList();
10148         NumNodes = m_pSelState->GetNumNodes();
10149         pSelectedRanges = m_pSelState->GetSelectionList();
10150         NumRanges = m_pSelState->GetNumRanges();
10151     }
10152 
10153     if ((NumNodes == 0 || pSelectionNodes[0] == NULL) && 
10154         (NumRanges == 0 || pSelectedRanges[0].FirstNode == NULL))
10155     {
10156         ERROR3("No selection nodes");
10157         EndDrag();
10158         return;
10159     }
10160 
10161     UINT32 i;
10162     for ( i = 0; i < NumRanges; i++)
10163     {   
10164         NodeRenderable* pNode = (NodeRenderable*)pSelectedRanges[i].FirstNode;
10165         for (UINT32 j = 0; j < pSelectedRanges[i].NumSelected; j++)
10166         {
10167             if (pNode == NULL)
10168             {
10169                 ERROR3("Node is null");
10170                 break;
10171             }
10172 
10173             RenderRegion* pOnTopRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR);
10174             while (pOnTopRegion)
10175             {
10176                 pNode->RenderObjectBlobs(pOnTopRegion);
10177 
10178                 // Go find the next region
10179                 pOnTopRegion = DocView::GetNextOnTop(NULL);
10180             }
10181             pNode = (NodeRenderable*)pNode->FindNext(CC_RUNTIME_CLASS(NodeRenderableInk));
10182         }
10183     }
10184 
10185 
10186     for ( i = 0; i < NumNodes; i++)
10187     {   
10188         NodeRenderable* pNode = (NodeRenderable*)pSelectionNodes[i];
10189         RenderRegion* pOnTopRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR);
10190         while (pOnTopRegion)
10191         {
10192             pNode->RenderObjectBlobs(pOnTopRegion);
10193 
10194             // Go find the next region
10195             pOnTopRegion = DocView::GetNextOnTop(NULL);
10196         }
10197     }
10198 
10199     
10200 }


Member Data Documentation

DocCoord OpEditBlendEndObject::m_LastCoord [protected]
 

Definition at line 972 of file blndtool.h.

BlendTool* OpEditBlendEndObject::m_pBlendTool [protected]
 

Definition at line 978 of file blndtool.h.

Range* OpEditBlendEndObject::m_pCopyRange [protected]
 

Definition at line 974 of file blndtool.h.

NodeBlend* OpEditBlendEndObject::m_pNodeBlend [protected]
 

Definition at line 975 of file blndtool.h.

NodeBlendPath* OpEditBlendEndObject::m_pNodeBlendPath [protected]
 

Definition at line 977 of file blndtool.h.

Range* OpEditBlendEndObject::m_pRange [protected]
 

Definition at line 973 of file blndtool.h.

SelectionState* OpEditBlendEndObject::m_pSelState [protected]
 

Definition at line 976 of file blndtool.h.

Matrix* OpEditBlendEndObject::m_pTransMatrix [protected]
 

Definition at line 970 of file blndtool.h.

DocCoord OpEditBlendEndObject::m_StartCoord [protected]
 

Definition at line 971 of file blndtool.h.


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