#include <blndtool.h>
Inheritance diagram for OpChangeBlendDistance:
Public Member Functions | |
OpChangeBlendDistance () | |
~OpChangeBlendDistance () | |
virtual void | DoWithParam (OpDescriptor *, OpParam *pOpParam) |
To change the distance between steps in the selected blends to that given in OpParam->Param1. The method differs depending on whether or not the blend is on a curve. If the blend is on a curve then it is necessary to recalculate the number of steps that can fit on the curve with the new length. If there is not an exact fit then the last object must be moved along the curve to ensure correct distance is maintained. If the blend is not on a curve the it is necessary to calculate the direction of the blend and move the last object forwards or backwards to maintain the correct distance. | |
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. | |
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 | InsertChangeStepsAction (NodeBlend *pNodeBlend, double StepDistance, UINT32 *NewNumSteps, double *NewDistances) |
When the distance between blend steps is changed and the blend is on a curve it is necessary to recalculate how many blend steps we can now fit on the curve. This function performs that operation and inserts a new action. | |
BOOL | InsertChangePathProportion (NodeBlend *pNodeBlend, double StartDistance, double EndDistance) |
To work out the proportion of the nodeblendpath that we need to use to set the given number of steps and step distance. Once this is known we find the point on the path corresponding to that proportion and transform the end node to that point. | |
BOOL | InsertChangeLinearBlendActions (NodeBlend *pNodeBlend, Operation *pOp, double NewStepDistance) |
Calculates the actions necessary to change a linear blend when the distance between blend steps is edited. This involves calculating the new length of the blend, transforming the last blend object accordingly and telling each blender to regenerate itself. | |
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. | |
BOOL | InsertTransformNodesAction (NodeBlend *pNodeBlend, double StartDistance, double EndDistance) |
Determines the point along the nodeblendpath to which the end objects must be moved, then creates the actions. |
Definition at line 1202 of file blndtool.h.
|
Definition at line 1208 of file blndtool.h.
|
|
Definition at line 1209 of file blndtool.h.
|
|
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.
Definition at line 6749 of file blndtool.cpp. 06752 { 06753 // First check parameters 06754 if (OldNumSteps < 0 || StepDistance < 0) 06755 { 06756 ERROR3("Invalid parameter"); 06757 return FALSE; 06758 } 06759 if (BlendDistance < (*FixedDistance + *MoveableDistance)) 06760 { 06761 ERROR3("Invalid distance parameter"); 06762 return FALSE; 06763 } 06764 06765 //initialise locals to zero 06766 *NewNumSteps = 0; 06767 06768 // get the distance currently occupied by the blend 06769 double DistanceUsed = BlendDistance - (*FixedDistance + *MoveableDistance); 06770 06771 // ideally we'd like to blend distance to be as close as possible to 06772 // what it was before editing 06773 UINT32 TempNumSteps = (UINT32)(DistanceUsed / StepDistance); 06774 06775 // if this gives us a positive number of steps then we'll take it 06776 if (TempNumSteps > 0) 06777 { 06778 double NewDistance = TempNumSteps * StepDistance; 06779 *MoveableDistance = BlendDistance - (*FixedDistance + NewDistance); 06780 *NewNumSteps = TempNumSteps; 06781 //NewFixedDistance = *FixedDistance; 06782 } 06783 // if not then we'll try to use the whole length of the blend 06784 else 06785 { 06786 TempNumSteps = (UINT32)(BlendDistance / StepDistance); 06787 if (TempNumSteps > 0) 06788 { 06789 double NewDistance = TempNumSteps * StepDistance; 06790 *MoveableDistance = BlendDistance - NewDistance; 06791 *FixedDistance = 0.0; 06792 *NewNumSteps = TempNumSteps; 06793 } 06794 else 06795 { 06796 // we've been passed a step distance that is too long, this should never happen due to the 06797 // checks in the UI 06798 ERROR3("Step distance is too long"); 06799 return FALSE; 06800 } 06801 } 06802 06803 06804 06805 // test to see that what we have is ok. 06806 if (*NewNumSteps != 0) 06807 return TRUE; 06808 else 06809 return FALSE; 06810 }
|
|
Adds the operation to the list of all known operations.
Definition at line 6825 of file blndtool.cpp. 06826 { 06827 return (RegisterOpDescriptor( 06828 0, 06829 0, 06830 CC_RUNTIME_CLASS(OpChangeBlendDistance), 06831 OPTOKEN_CHANGEBLENDDISTANCE, 06832 OpChangeBlendDistance::GetState, 06833 0, /* help ID */ 06834 0, /* bubble ID */ 06835 0 /* bitmap ID */ 06836 )); 06837 }
|
|
To change the distance between steps in the selected blends to that given in OpParam->Param1. The method differs depending on whether or not the blend is on a curve. If the blend is on a curve then it is necessary to recalculate the number of steps that can fit on the curve with the new length. If there is not an exact fit then the last object must be moved along the curve to ensure correct distance is maintained. If the blend is not on a curve the it is necessary to calculate the direction of the blend and move the last object forwards or backwards to maintain the correct distance.
Reimplemented from Operation. Definition at line 6205 of file blndtool.cpp. 06206 { 06207 ERROR3IF(pOpParam == NULL,"NULL OpParam ptr"); 06208 if (pOpParam == NULL) return; 06209 06210 SelRange* pSel = GetApplication()->FindSelection(); 06211 06212 RangeControl rg; 06213 06214 if (pSel) 06215 { 06216 rg = pSel->GetRangeControlFlags(); 06217 rg.PromoteToParent = TRUE; 06218 pSel->Range::SetRangeControl(rg); 06219 } 06220 06221 BOOL ok = (pSel != NULL); 06222 06223 if (ok) ok = DoStartSelOp(FALSE,FALSE); 06224 06225 if (ok) 06226 { 06227 List BlendList; 06228 // The new distance is in pOpParam->Param1 06229 double NewStepDistance = double(pOpParam->Param1); 06230 ok = BevelTools::BuildListOfSelectedNodes(&BlendList, CC_RUNTIME_CLASS(NodeBlend), FALSE); 06231 if (ok) 06232 { 06233 NodeListItem* pListItem = (NodeListItem*)BlendList.GetHead(); 06234 while (pListItem != NULL) 06235 { 06236 NodeBlend* pNodeBlend = (NodeBlend*)pListItem->pNode; 06237 06238 // We now have a selected blend node so: 06239 // - Invalidate the node's region 06240 // - Store the current number of blend steps in an undo actiom 06241 // - Calculate the new number of blend steps and apply 06242 // - Get the nodeblender child of the blend 06243 // - Calculate the proportion along the path we have to set in order to 06244 // achieve the correct number of steps at the exact distance entered. 06245 06246 NodeRenderableInk * pInk = (NodeRenderableInk *)pNodeBlend; 06247 06248 // Ask the node if it's ok to do the op 06249 ObjChangeFlags cFlags; 06250 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this); 06251 ok = pInk->AllowOp(&ObjChange); 06252 06253 if (ok) ok = DoInvalidateNodeRegion(pInk,TRUE,FALSE); 06254 if (ok) ok = (InvalidateBoundsAction::Init(this,&UndoActions,pInk,TRUE) != AC_FAIL); 06255 06256 if (ok) 06257 { 06258 06259 // NodeBlend* pCopyBlend = pNodeBlend; 06260 BOOL OnCurve = pNodeBlend->IsOnACurve(); 06261 06262 if (OnCurve) 06263 { 06264 // NewNumSteps calculated in InsertChangeStepsAction and passed back 06265 UINT32 NewNumSteps = 0; 06266 // NewDistances is used to store the new distances along the path for the start and end objects 06267 double NewDistances[2] = { 1.0, 0.0 }; 06268 06269 // calculate and perform the actions 06270 ok = InsertChangeStepsAction(pNodeBlend, NewStepDistance, &NewNumSteps, NewDistances); 06271 if (ok) ok = InsertTransformNodesAction(pNodeBlend, NewDistances[0], NewDistances[1]); 06272 if (ok) ok = InsertChangePathProportion(pNodeBlend, NewDistances[0], NewDistances[1]); 06273 if (ok) 06274 { 06275 // set the member variables in the nodeblend 06276 pNodeBlend->SetNumBlendSteps(NewNumSteps); 06277 pNodeBlend->UpdateStepDistance(); 06278 pNodeBlend->SetDistanceEntered(NewStepDistance); 06279 } 06280 } 06281 else 06282 { 06283 ok = InsertChangeLinearBlendActions(pNodeBlend,this, NewStepDistance); 06284 } 06285 pListItem = (NodeListItem*)BlendList.GetNext(pListItem); 06286 06287 } // end if ok 06288 06289 if (ok) ok = DoInvalidateNodeRegion(pInk,TRUE,FALSE); 06290 if (ok) ok = (InvalidateBoundsAction::Init(this,&UndoActions,pInk,TRUE) != AC_FAIL); 06291 } 06292 } 06293 BlendList.DeleteAll(); 06294 } 06295 06296 rg.PromoteToParent = FALSE; 06297 pSel->Range::SetRangeControl(rg); 06298 06299 if (ok) 06300 { 06301 pSel->Update(); 06302 06303 // Inform the effected parents of the change 06304 ObjChangeFlags cFlags; 06305 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,cFlags,NULL,this); 06306 UpdateChangedNodes(&ObjChange); 06307 } 06308 else 06309 FailAndExecute(); 06310 06311 End(); 06312 06313 }
|
|
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 6917 of file blndtool.cpp. 06918 { 06919 *OpName = String_256(_R(IDS_STEPDISTANCEUNDO)); 06920 }
|
|
Find out the state of the operation at the specific time.
Definition at line 6854 of file blndtool.cpp. 06855 { 06856 OpState State(FALSE,TRUE); // It's not ticked, but it is greyed by default 06857 06858 SelRange* pSel = GetApplication()->FindSelection(); 06859 06860 RangeControl rg = pSel->GetRangeControlFlags(); 06861 rg.PromoteToParent = TRUE; 06862 pSel->Range::SetRangeControl(rg); 06863 if (pSel != NULL) 06864 { 06865 Node* pNode = pSel->FindFirst(); 06866 while (pNode != NULL && State.Greyed) 06867 { 06868 State.Greyed = !(pNode->IS_KIND_OF(NodeBlend)); 06869 pNode = pSel->FindNext(pNode); 06870 } 06871 } 06872 // if that fails then try this, which will catch any blends that are 06873 // inside bevels or contours - DY 06874 if (State.Greyed) 06875 { 06876 List BlendList; 06877 BOOL ok = BevelTools::BuildListOfSelectedNodes(&BlendList, CC_RUNTIME_CLASS(NodeBlend), FALSE); 06878 State.Greyed = !ok; 06879 BlendList.DeleteAll(); 06880 } 06881 06882 // DY awful hack to allow us to call this op from the bezier tool 06883 // when we wish to edit the path of a blend on a path. 06884 Node* pNode = pSel->FindFirst(); 06885 if (pNode->IS_KIND_OF(NodeBlendPath)) 06886 { 06887 State.Greyed = FALSE; 06888 } 06889 06890 rg.PromoteToParent = FALSE; 06891 pSel->Range::SetRangeControl(rg); 06892 06893 06894 if (State.Greyed) 06895 *Description = String_256(_R(IDS_REMOVEBLEND_GREYED)); 06896 else 06897 *Description = String_256(_R(IDS_BLENDDISTANCEEDITVALUE)); 06898 return State; 06899 }
|
|
Calculates the actions necessary to change a linear blend when the distance between blend steps is edited. This involves calculating the new length of the blend, transforming the last blend object accordingly and telling each blender to regenerate itself.
Definition at line 6659 of file blndtool.cpp. 06662 { 06663 if (pNodeBlend->IsOnACurve()) 06664 { 06665 ERROR3("Trying to perform linear blend actions to blend on a curve"); 06666 return FALSE; 06667 } 06668 06669 NodeBlender* pBlender = pNodeBlend->FindFirstBlender(); 06670 const UINT32 NumSteps = pNodeBlend->GetNumBlendSteps(); 06671 BOOL ok = TRUE; 06672 while (pBlender != NULL) 06673 { 06674 double OldDistance = pBlender->GetLinearDistance(); 06675 double NewDistance = StepDistance * NumSteps; 06676 double DistanceRatio = NewDistance / OldDistance; 06677 DocCoord Start; 06678 DocCoord End; 06679 06680 ok = pBlender->GetBlendObjectCentres(&Start, &End); 06681 if (ok) 06682 { 06683 // bit of a hack this, when it comes to undoing we need to have the blender 06684 // regenerate itself AFTER it transforms the end node. So when first performing 06685 // this action it doesn't really do anything, but it has to be there for the Undo 06686 06687 ChangeBlenderOpParam BlenderParam; 06688 BlenderParam.m_ChangeType = CHANGEBLENDER_REGEN; 06689 ok = ChangeBlenderAction::Init(pOp, &UndoActions, pBlender, BlenderParam); 06690 06691 DocCoord NewPosition = DocCoord::PositionPointFromRatio(Start, End, DistanceRatio); 06692 06693 // we need to cast to noderenderable ink in order to use in the 06694 // transform function 06695 NodeRenderableInk* pEnd = (NodeRenderableInk*)(pBlender->GetNodeEnd()); 06696 06697 if (pEnd != NULL) 06698 { 06699 UndoableOperation* pUndoOp = (UndoableOperation*)pOp; 06700 ok = pNodeBlend->TransformNodeToPoint(pEnd, &NewPosition, pUndoOp, 0.0); 06701 06702 // tell the blender that it needs to recalculate itself 06703 pBlender->SetUninitialised(); 06704 06705 } 06706 } 06707 pBlender = pNodeBlend->FindNextBlender(pBlender); 06708 } 06709 06710 return ok; 06711 06712 }
|
|
To work out the proportion of the nodeblendpath that we need to use to set the given number of steps and step distance. Once this is known we find the point on the path corresponding to that proportion and transform the end node to that point.
Definition at line 6437 of file blndtool.cpp. 06440 { 06441 if (pNodeBlend == NULL) 06442 { 06443 ERROR3("NodeBlend is NULL"); 06444 return FALSE; 06445 } 06446 06447 NodeBlender* pNodeBlender = pNodeBlend->FindFirstBlender(); 06448 06449 if (pNodeBlender == NULL) 06450 { 06451 ERROR3("This blend has no nodeblenders"); 06452 return FALSE; 06453 } 06454 06455 // this will require changing when we implement blending from a 06456 // blend on a curve to other objects 06457 double BlendDistance = 0.0; 06458 BOOL ok = pNodeBlend->GetBlendDistance(TRUE, &BlendDistance); 06459 06460 if (ok) 06461 { 06462 double OldStartProp = 0.0; 06463 double OldEndProp = 0.0; 06464 06465 ok = pNodeBlend->GetStartAndEndProportions(&OldStartProp, &OldEndProp); 06466 if (ok) 06467 { 06468 // check to see if the proportions have changed 06469 double OldStartDist = BlendDistance * OldStartProp; 06470 if (OldStartDist != StartDistance) 06471 { 06472 double NewPathProportion = StartDistance / BlendDistance; 06473 ChangeBlenderOpParam BlenderParam; 06474 BlenderParam.m_ChangeType = CHANGEBLENDER_PATHSTART; 06475 BlenderParam.m_NewPathStart = NewPathProportion; 06476 ok = ChangeBlenderAction::Init(this, &UndoActions, pNodeBlender, BlenderParam); 06477 } 06478 06479 double OldEndDist = BlendDistance - (BlendDistance * OldEndProp); 06480 06481 if (OldEndDist != EndDistance) 06482 { 06483 double NewPathProportion = 1 - (EndDistance / BlendDistance); 06484 ChangeBlenderOpParam BlenderParam; 06485 BlenderParam.m_ChangeType = CHANGEBLENDER_PATHEND; 06486 BlenderParam.m_NewPathEnd = NewPathProportion; 06487 ok = ChangeBlenderAction::Init(this, &UndoActions, pNodeBlender, BlenderParam); 06488 } 06489 } 06490 } 06491 return ok; 06492 }
|
|
When the distance between blend steps is changed and the blend is on a curve it is necessary to recalculate how many blend steps we can now fit on the curve. This function performs that operation and inserts a new action.
Definition at line 6336 of file blndtool.cpp. 06338 { 06339 UINT32 OldNumSteps = 0; 06340 double BlendDistance = 0.0; 06341 06342 OldNumSteps = pNodeBlend->GetNumBlendSteps(); 06343 UINT32 TempNumSteps = OldNumSteps; 06344 BOOL ok = pNodeBlend->GetBlendDistance(TRUE, &BlendDistance); 06345 06346 06347 double StartProportion = 0.0; 06348 double EndProportion = 0.0; 06349 double StartDistance = 0.0; 06350 double EndDistance = 0.0; 06351 06352 if (ok) 06353 { 06354 // find out if the user has edited the end position 06355 switch (pNodeBlend->GetLastEdited()) 06356 { 06357 case NONE: 06358 TempNumSteps = (UINT32)(BlendDistance / StepDistance); 06359 EndDistance = BlendDistance - (TempNumSteps * StepDistance); 06360 StartDistance = 0.0; 06361 06362 break; 06363 case FIRST: 06364 ok = pNodeBlend->GetStartAndEndProportions(&StartProportion, &EndProportion); 06365 if (ok) 06366 { 06367 StartDistance = StartProportion * BlendDistance; 06368 EndDistance = BlendDistance - (EndProportion * BlendDistance); 06369 ok = CalculateNewNumStepsAndPosition(OldNumSteps, BlendDistance, StepDistance, 06370 &StartDistance, &EndDistance, &TempNumSteps); 06371 } 06372 06373 break; 06374 case LAST: 06375 06376 StartProportion = 0.0; 06377 EndProportion = 0.0; 06378 06379 ok = pNodeBlend->GetStartAndEndProportions(&StartProportion, &EndProportion); 06380 if (ok) 06381 { 06382 StartDistance = StartProportion * BlendDistance; 06383 EndDistance = BlendDistance - (EndProportion * BlendDistance); 06384 ok = CalculateNewNumStepsAndPosition(OldNumSteps, BlendDistance, StepDistance, 06385 &EndDistance, &StartDistance, &TempNumSteps); 06386 } 06387 break; 06388 default: 06389 break; 06390 06391 06392 } 06393 if ((TempNumSteps != OldNumSteps) && ok) 06394 { 06395 double DistanceEntered = pNodeBlend->GetDistanceEntered(); 06396 ChangeBlendStepsAction* pStepAction; 06397 NodeRenderableInk * pInk = (NodeRenderableInk *)pNodeBlend; 06398 ok = ChangeBlendStepsAction::Init(this,&UndoActions,pInk,OldNumSteps,DistanceEntered, &pStepAction) != AC_FAIL; 06399 } 06400 } 06401 06402 if (ok) 06403 { 06404 *NewNumSteps = TempNumSteps; 06405 NewDistances[0] = StartDistance; 06406 NewDistances[1] = EndDistance; 06407 } 06408 else 06409 *NewNumSteps = OldNumSteps; // restore the original number 06410 // if something went wrong. 06411 06412 return ok; 06413 }
|
|
Determines the point along the nodeblendpath to which the end objects must be moved, then creates the actions.
Definition at line 6563 of file blndtool.cpp. 06565 { 06566 if (pNodeBlend == NULL) 06567 { 06568 ERROR3("NodeBlend is NULL"); 06569 return FALSE; 06570 } 06571 06572 NodeBlender* pNodeBlender = pNodeBlend->FindFirstBlender(); 06573 06574 if (pNodeBlender == NULL) 06575 { 06576 ERROR3("This blend has no nodeblenders"); 06577 return FALSE; 06578 } 06579 06580 // this will require changing when we implement blending from a 06581 // blend on a curve to other objects 06582 double BlendDistance = 0.0; 06583 BOOL ok = pNodeBlend->GetBlendDistance(TRUE, &BlendDistance); 06584 06585 if (ok) 06586 { 06587 double OldStartProp = 0.0; 06588 double OldEndProp = 0.0; 06589 06590 ok = pNodeBlend->GetStartAndEndProportions(&OldStartProp, &OldEndProp); 06591 if (ok) 06592 { 06593 // check to see if the proportions have changed 06594 double OldStartDist = BlendDistance * OldStartProp; 06595 if (OldStartDist != StartDistance) 06596 { 06597 // locate the point on the line corresponding to the new distance 06598 DocCoord NewPoint; 06599 double ExtraParam = 0.0; //passed to the function but not used afterwards 06600 06601 ok = pNodeBlender->GetPointFromDistance(StartDistance, &NewPoint, &ExtraParam); 06602 if (ok) 06603 { 06604 NodeRenderableInk* pEnd = pNodeBlender->GetNodeStart(); 06605 ok = ((pEnd != NULL) && (pNodeBlend != NULL)); 06606 if (ok) 06607 ok = pNodeBlend->TransformNodeToPoint(pEnd,&NewPoint,this,ExtraParam); 06608 } 06609 } 06610 06611 double OldEndDist = BlendDistance - (BlendDistance * OldEndProp); 06612 06613 if (OldEndDist != EndDistance) 06614 { 06615 // locate the point on the line corresponding to the new distance 06616 DocCoord NewPoint; 06617 double ExtraParam = 0.0; //passed to the function but not used afterwards 06618 double DistanceFromStart = BlendDistance - EndDistance; 06619 pNodeBlender = pNodeBlend->FindLastBlender(); 06620 if (pNodeBlender != NULL) 06621 { 06622 ok = pNodeBlender->GetPointFromDistance(DistanceFromStart, &NewPoint, &ExtraParam); 06623 06624 if (ok) 06625 { 06626 NodeRenderableInk* pEnd = pNodeBlender->GetNodeEnd(); 06627 ok = ((pEnd != NULL) && (pNodeBlend != NULL)); 06628 if (ok) 06629 ok = pNodeBlend->TransformNodeToPoint(pEnd,&NewPoint,this,ExtraParam); 06630 } 06631 } 06632 } 06633 } 06634 } 06635 return ok; 06636 }
|