#include <blndtool.h>
Inheritance diagram for OpEditBlendEndObject:
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. | |
NodeBlendPath * | GetNodeBlendPath () |
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. | |
NodeBlender * | GetBlenderAndPosition (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 | |
Matrix * | m_pTransMatrix |
DocCoord | m_StartCoord |
DocCoord | m_LastCoord |
Range * | m_pRange |
Range * | m_pCopyRange |
NodeBlend * | m_pNodeBlend |
SelectionState * | m_pSelState |
NodeBlendPath * | m_pNodeBlendPath |
BlendTool * | m_pBlendTool |
Private Member Functions | |
CC_DECLARE_DYNCREATE (OpEditBlendEndObject) |
Definition at line 919 of file blndtool.h.
|
Definition at line 924 of file blndtool.h.
|
|
default constructor
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 }
|
|
destructor, deletes pointers to dynamically created objects
Definition at line 8829 of file blndtool.cpp. 08830 { 08831 delete m_pTransMatrix; 08832 delete m_pSelState; 08833 }
|
|
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.
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 }
|
|
|
|
Adds the operation to the list of all known operations.
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 }
|
|
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.
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 }
|
|
Ends the drag and recalculates the blend.
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 }
|
|
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)
Reimplemented from Operation. Definition at line 9146 of file blndtool.cpp. 09147 { 09148 09149 m_pRange->RenderXOROutlinesOn(NULL, pSpread, m_pTransMatrix, NULL); 09150 }
|
|
Pure virtual function which tells the operation that the mouse has moved. virtual void Operation::DragPointerMove( DocCoord PointerPos, ClickModifiers ClickMods, Spread *pSpread, BOOL bSolidDrag)
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 }
|
|
To find the NodeBlender on a curve that uses pNode as either its first or last node, and which position.
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 }
|
|
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.
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 }
|
|
|
|
The GetOpName fn is overridden so that we return back a description appropriate to the type of attribute that the operation applies.
Reimplemented from Operation. Definition at line 10039 of file blndtool.cpp. 10040 { 10041 String_256 test = "test string"; 10042 10043 10044 }
|
|
Find out the state of the operation at the specific time. > static OpState OpEditBlendEndObject::GetState(String_256* Description, OpDescriptor*)
Definition at line 8876 of file blndtool.cpp. 08877 { 08878 OpState State; 08879 08880 return State; 08881 }
|
|
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.
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 }
|
|
To calculate and perform the actions necessary to transform pNode to its new PathProportion whilst maintaining a constant number of 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 }
|
|
inserts an action setting the proportion along the path variable to its new value
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 }
|
|
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.
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 }
|
|
Calls the XOR outline function and draws an 'X' in the position specified.
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 }
|
|
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().
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 }
|
|
Definition at line 972 of file blndtool.h. |
|
Definition at line 978 of file blndtool.h. |
|
Definition at line 974 of file blndtool.h. |
|
Definition at line 975 of file blndtool.h. |
|
Definition at line 977 of file blndtool.h. |
|
Definition at line 973 of file blndtool.h. |
|
Definition at line 976 of file blndtool.h. |
|
Definition at line 970 of file blndtool.h. |
|
Definition at line 971 of file blndtool.h. |