00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 #include "camtypes.h"
00104
00105
00106
00107 #include "csrstack.h"
00108
00109
00110 #include "nodepath.h"
00111 #include "progress.h"
00112 #include "nodeblnd.h"
00113 #include "nodebldr.h"
00114
00115 #include "blobs.h"
00116
00117
00118 #include "objchge.h"
00119
00120
00121 #include "filltool.h"
00122 #include "bubbleid.h"
00123
00124 #include "attrmap.h"
00125 #include "ndbldpth.h"
00126 #include "pathedit.h"
00127 #include "keypress.h"
00128 #include "vkextra.h"
00129
00130 #include "blndtool.h"
00131
00132 #include "opbevel.h"
00133
00134
00135 #include "biasgdgt.h"
00136 #include "opcntr.h"
00137
00138 #include "shapeops.h"
00139 #include "biasdlg.h"
00140
00141
00142
00143
00144
00145 #include "nbevcont.h"
00146 #include "nodecont.h"
00147
00148 #include "nodecntr.h"
00149 #include "ncntrcnt.h"
00150 #include "opbevel.h"
00151 #include "layer.h"
00152 #include "ophist.h"
00153
00154 DECLARE_SOURCE( "$Revision: 1401 $" );
00155
00156 CC_IMPLEMENT_MEMDUMP(BlendTool,Tool_v1)
00157 CC_IMPLEMENT_DYNCREATE(BlendInfoBarOp,InformationBarOp)
00158 CC_IMPLEMENT_MEMDUMP(BlendToolRef,CC_CLASS_MEMDUMP)
00159 CC_IMPLEMENT_DYNCREATE(OpBlendNodes,SelOperation)
00160 CC_IMPLEMENT_DYNCREATE(OpRemoveBlend,SelOperation)
00161 CC_IMPLEMENT_DYNCREATE(OpAddBlendPath,SelOperation)
00162 CC_IMPLEMENT_DYNCREATE(OpDetachBlendPath,SelOperation)
00163 CC_IMPLEMENT_DYNCREATE(OpChangeBlend,SelOperation)
00164 CC_IMPLEMENT_DYNCREATE(OpBlendOneToOne,OpChangeBlend)
00165 CC_IMPLEMENT_DYNCREATE(OpBlendAntialias,OpChangeBlend)
00166 CC_IMPLEMENT_DYNCREATE(OpBlendTangential,OpChangeBlend)
00167 CC_IMPLEMENT_DYNCREATE(OpChangeBlendSteps,SelOperation)
00168 CC_IMPLEMENT_DYNCREATE(ChangeBlendAction,Action)
00169 CC_IMPLEMENT_DYNCREATE(ChangeBlenderAction,Action)
00170 CC_IMPLEMENT_DYNCREATE(ChangeBlendStepsAction,Action)
00171 CC_IMPLEMENT_DYNCREATE(RemapBlendAction,Action)
00172 CC_IMPLEMENT_DYNCREATE(InitBlendersAction,Action)
00173 CC_IMPLEMENT_MEMDUMP(ChangeBlendOpParam,OpParam)
00174 CC_IMPLEMENT_MEMDUMP(ChangeBlenderOpParam,OpParam)
00175 CC_IMPLEMENT_DYNCREATE(InvalidateBoundsAction,Action)
00176 CC_IMPLEMENT_DYNCREATE(OpChangeBlendDistance, SelOperation)
00177 CC_IMPLEMENT_DYNCREATE(OpEditBlendEndObject, SelOperation)
00178 CC_IMPLEMENT_MEMDUMP(BlenderInfoItem,ListItem);
00179
00180
00181
00182
00183 #define new CAM_DEBUG_NEW
00184
00185
00186 TCHAR* BlendTool::FamilyName = _T("Blend Tools");
00187 TCHAR* BlendTool::ToolName = _T("Blend Tool");
00188 TCHAR* BlendTool::Purpose = _T("Blend manipulation");
00189 TCHAR* BlendTool::Author = _T("Mark Neves");
00190
00191
00192 BlendInfoBarOp* BlendTool::pBlendInfoBarOp = NULL;
00193 BlendToolRef* BlendTool::pRefStart = NULL;
00194 BlendToolRef* BlendTool::pRefEnd = NULL;
00195 Cursor* BlendTool::pcNormalCursor = NULL;
00196 Cursor* BlendTool::pcBlendableCursor = NULL;
00197 Cursor* BlendTool::pcBlendableBlobCursor = NULL;
00198 Cursor* BlendTool::pcBlendableRemapCursor = NULL;
00199 Cursor* BlendTool::pcCurrentCursor = NULL;
00200 INT32 BlendTool::CurrentCursorID = 0;
00201 UINT32 BlendTool::StatusID = _R(IDS_BLENDSTATUS_FINDSTART);
00202
00203
00204
00205 #define SWAP(type,a,b) { type x=a; a=b; b=x; }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 BlendTool::BlendTool()
00220 {
00221 pcCurrentCursor = NULL;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 BlendTool::~BlendTool()
00235 {
00236 if (pRefStart != NULL)
00237 {
00238 delete pRefStart;
00239 pRefStart = NULL;
00240 }
00241
00242 if (pRefEnd != NULL)
00243 {
00244 delete pRefEnd;
00245 pRefEnd = NULL;
00246 }
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 BOOL BlendTool::Init()
00263 {
00264
00265
00266 BOOL ok = ( OpBlendNodes::Declare() &&
00267 OpRemoveBlend::Declare() &&
00268 OpAddBlendPath::Declare() &&
00269 OpDetachBlendPath::Declare() &&
00270 OpChangeBlend::Declare() &&
00271 OpBlendOneToOne::Declare() &&
00272 OpBlendAntialias::Declare() &&
00273 OpChangeBlendSteps::Declare());
00274
00275 if (!ok) return FALSE;
00276
00277
00278 BlendTool::pRefStart = new BlendToolRef;
00279 BlendTool::pRefEnd = new BlendToolRef;
00280
00281 ok = (BlendTool::pRefStart != NULL && BlendTool::pRefEnd != NULL);
00282
00283
00284
00285
00286 if (ok)
00287 {
00288 pBlendInfoBarOp = new BlendInfoBarOp();
00289 ok = (pBlendInfoBarOp != NULL);
00290 #if 0
00291 CCResTextFile file;
00292 BlendInfoBarOpCreate BarCreate;
00293
00294 ok = file.open(_R(IDM_BLEND_BAR), _R(IDT_INFO_BAR_RES));
00295 if (ok) ok = DialogBarOp::ReadBarsFromFile(file,BarCreate);
00296 if (ok) file.close();
00297
00298 ENSURE(ok,"Unable to load blendbar.ini from resource\n");
00299
00300 if (ok)
00301 {
00302
00303 String_32 str = String_32(_R(IDS_BLNDTOOL_INFOBARNAME));
00304 DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(str);
00305
00306 ok = (pDialogBarOp != NULL);
00307 if (ok) ok = pDialogBarOp->IsKindOf(CC_RUNTIME_CLASS(BlendInfoBarOp));
00308 if (ok) pBlendInfoBarOp = (BlendInfoBarOp*)pDialogBarOp;
00309
00310 ENSURE(ok,"Error finding the blend tool info bar");
00311 }
00312 #endif
00313 }
00314
00315 return (ok);
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 void BlendTool::Describe(void *InfoPtr)
00336 {
00337
00338 ToolInfo_v1 *Info = (ToolInfo_v1 *) InfoPtr;
00339
00340 Info->InfoVersion = 1;
00341
00342 Info->InterfaceVersion = GetToolInterfaceVersion();
00343
00344
00345 Info->Version = 1;
00346 Info->ID = GetID();
00347 Info->TextID = _R(IDS_BLEND_TOOL);
00348
00349 Info->Family = FamilyName;
00350 Info->Name = ToolName;
00351 Info->Purpose = Purpose;
00352 Info->Author = Author;
00353
00354 Info->BubbleID = _R(IDBBL_BLEND_TOOLBOX);
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 void BlendTool::SelectChange(BOOL isSelected)
00374 {
00375 if (isSelected)
00376 {
00377 if (!CreateCursors()) return;
00378 CurrentCursorID = CursorStack::GPush(pcNormalCursor, FALSE);
00379 pcCurrentCursor = pcNormalCursor;
00380
00381
00382 pBlendInfoBarOp->Create();
00383 m_EditEndObject = FALSE;
00384
00385 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00386 if (BlobMgr != NULL)
00387 {
00388
00389 BlobStyle MyBlobs;
00390
00391 MyBlobs.Object = TRUE;
00392 MyBlobs.Tiny = FALSE;
00393
00394 BlobMgr->ToolInterest(MyBlobs);
00395 }
00396
00397 Document* pDoc = Document::GetCurrent();
00398 if (pDoc != NULL)
00399 BlobMgr->RenderToolBlobsOn(this, pDoc->GetSelectedSpread(),NULL);
00400 }
00401 else
00402 {
00403
00404 if (pcCurrentCursor != NULL)
00405 {
00406 CursorStack::GPop(CurrentCursorID);
00407 pcCurrentCursor = NULL;
00408 CurrentCursorID = 0;
00409 }
00410 DestroyCursors();
00411
00412
00413 pBlendInfoBarOp->CloseProfileDialog (pBlendInfoBarOp->m_BiasGainGadgetPosition);
00414 pBlendInfoBarOp->CloseProfileDialog (pBlendInfoBarOp->m_BiasGainGadgetAttribute);
00415
00416
00417
00418
00419
00420 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00421 if (BlobMgr != NULL)
00422 {
00423 BlobStyle bsRemoves;
00424 bsRemoves.ToolObject = TRUE;
00425 BlobMgr->RemoveInterest(bsRemoves);
00426 }
00427
00428
00429 pBlendInfoBarOp->Delete();
00430
00431 Document* pDoc = Document::GetCurrent();
00432 if (pDoc != NULL)
00433 BlobMgr->RenderToolBlobsOff(this, pDoc->GetSelectedSpread(),NULL);
00434 }
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 BOOL BlendTool::CreateCursors()
00452 {
00453
00454 pcNormalCursor = new Cursor(this, _R(IDC_BLENDNORMALCURSOR));
00455 pcBlendableCursor = new Cursor(this, _R(IDC_BLENDABLECURSOR));
00456 pcBlendableBlobCursor = new Cursor(this, _R(IDC_BLENDABLEBLOBCURSOR));
00457 pcBlendableRemapCursor = new Cursor(this, _R(IDC_BLENDABLEREMAPCURSOR));
00458
00459 if ( pcNormalCursor ==NULL || !pcNormalCursor->IsValid() ||
00460 pcBlendableCursor ==NULL || !pcBlendableCursor->IsValid() ||
00461 pcBlendableBlobCursor ==NULL || !pcBlendableBlobCursor->IsValid() ||
00462 pcBlendableRemapCursor ==NULL || !pcBlendableRemapCursor->IsValid()
00463 )
00464 {
00465 DestroyCursors();
00466 return FALSE;
00467 }
00468 else
00469 return TRUE;
00470 }
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 void BlendTool::DestroyCursors()
00487 {
00488 if (pcNormalCursor != NULL) delete pcNormalCursor;
00489 if (pcBlendableCursor != NULL) delete pcBlendableCursor;
00490 if (pcBlendableBlobCursor != NULL) delete pcBlendableBlobCursor;
00491 if (pcBlendableRemapCursor != NULL) delete pcBlendableRemapCursor;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 BOOL BlendTool::OnKeyPress(KeyPress* pKeyPress)
00507 {
00508 #if defined(_DEBUG) && 0
00509 if (pKeyPress == NULL)
00510 return FALSE;
00511
00512 if (pKeyPress->IsRepeat())
00513 return FALSE;
00514
00515 if (pKeyPress->IsRelease())
00516 return FALSE;
00517
00518 AFp BiasDelta = 0.0;
00519 AFp GainDelta = 0.0;
00520 BOOL Reset = FALSE;
00521 if (*pKeyPress == KeyPress(CAMKEY(Z))) { BiasDelta = -0.1; TRACEUSER( "Markn", _T("Decrease Bias by 0.1\n"));}
00522 if (*pKeyPress == KeyPress(CAMKEY(X))) { BiasDelta = 0.1; TRACEUSER( "Markn", _T("Increase Bias by 0.1\n"));}
00523 if (*pKeyPress == KeyPress(CAMKEY(N))) { GainDelta = -0.1; TRACEUSER( "Markn", _T("Decrease Gain by 0.1\n"));}
00524 if (*pKeyPress == KeyPress(CAMKEY(M))) { GainDelta = 0.1; TRACEUSER( "Markn", _T("Increase Gain by 0.1\n"));}
00525
00526 if (*pKeyPress == KeyPress(CAMKEY(R))) { Reset = TRUE; TRACEUSER( "Markn", _T("Resetting Bias and Gain\n"));}
00527
00528 SelRange* pSelRange = GetApplication()->FindSelection();
00529 Node* pNode = pSelRange->FindFirst();
00530 while (pNode)
00531 {
00532 if (IS_A(pNode,NodeBlend))
00533 {
00534 NodeBlend* pNodeBlend = (NodeBlend*)pNode;
00535
00536
00537 CProfileBiasGain* pProfile = pNodeBlend->GetAttrProfile();
00538 if (pProfile)
00539 {
00540 AFp Bias = pProfile->GetBias() + BiasDelta;
00541 AFp Gain = pProfile->GetGain() + GainDelta;
00542 if (Reset)
00543 Bias = Gain = 0.0;
00544
00545 if (Bias < -0.9) Bias = -0.9;
00546 if (Bias > 0.9) Bias = 0.9;
00547 if (Gain < -0.9) Gain = -0.9;
00548 if (Gain > 0.9) Gain = 0.9;
00549
00550 pProfile->SetBiasGain(Bias,Gain);
00551 }
00552 }
00553
00554 pNode = pSelRange->FindNext(pNode);
00555 }
00556 #endif // _DEBUG
00557
00558 return FALSE;
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 void BlendTool::OnClick( DocCoord PointerPos, ClickType Click, ClickModifiers ClickMods,
00582 Spread* pSpread )
00583 {
00584 if (ClickMods.Menu) return;
00585
00586 ERROR3IF_PF(pSpread==NULL,("pSpread is NULL"));
00587
00588 if (Click == CLICKTYPE_DRAG)
00589 {
00590
00591 BOOL MoveEndObject = EditBlendEnd(pSpread, PointerPos);
00592
00593
00594 if (!MoveEndObject)
00595 {
00596 UpdateRef(pRefStart,pSpread,PointerPos);
00597 UpdateRef(pRefEnd ,pSpread,PointerPos);
00598 CheckNodeRemapping(pRefStart,pRefEnd);
00599 UpdateCursorAndStatus();
00600
00601 if (pRefStart->pNode != NULL)
00602 {
00603
00604 OpBlendNodes* pOpBlendNodes = new OpBlendNodes;
00605 if (pOpBlendNodes != NULL)
00606 {
00607
00608 if (!pOpBlendNodes->DoDrag(this))
00609 delete pOpBlendNodes;
00610 }
00611 }
00612 }
00613 else
00614 {
00615 OpEditBlendEndObject* pEditEnd = new OpEditBlendEndObject(this);
00616
00617 if (pEditEnd != NULL)
00618 {
00619 StatusID = _R(IDS_BLENDSTATUS_MOVEEND);
00620 DisplayStatusBarHelp(StatusID);
00621 pEditEnd->DoDrag(PointerPos, pSpread);
00622 }
00623 }
00624 }
00625
00626
00627
00628 DragTool::OnClick (PointerPos, Click, ClickMods, pSpread);
00629 }
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645 void BlendTool::OnMouseMove(DocCoord PointerPos,Spread* pSpread,ClickModifiers ClickMods)
00646 {
00647 ERROR3IF_PF(pSpread==NULL,("pSpread is NULL"));
00648
00649 pRefEnd->Reset();
00650 UpdateRef(pRefStart,pSpread,PointerPos,FALSE);
00651
00652 m_EditEndObject = EditBlendEndAndUpdateCursor(pSpread, PointerPos);
00653
00654 if (m_EditEndObject == FALSE)
00655 UpdateCursorAndStatus();
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 BOOL BlendTool::EditBlendEndAndUpdateCursor(Spread* pSpread, DocCoord PointerPos)
00676 {
00677 Cursor* pcNewCursor = pcNormalCursor;
00678
00679 List BlendList;
00680
00681 BOOL ok = BevelTools::BuildListOfSelectedNodes(&BlendList, CC_RUNTIME_CLASS(NodeBlend), FALSE);
00682 if (ok)
00683 {
00684 ok = FALSE;
00685 NodeListItem* pListItem = (NodeListItem*)BlendList.GetHead();
00686 while (pListItem != NULL)
00687 {
00688
00689 NodeBlend* pNodeBlend = (NodeBlend*)pListItem->pNode;
00690 Node* pNode = NULL;
00691
00692 ok = pNodeBlend->HitOnEndDragBlob(PointerPos, &pNode);
00693 if (ok)
00694 {
00695 pcNewCursor = pcBlendableBlobCursor;
00696 StatusID = _R(IDS_BLENDSTATUS_EDITENDS);
00697 break;
00698 }
00699 pListItem = (NodeListItem*)BlendList.GetNext(pListItem);
00700 }
00701 }
00702 BlendList.DeleteAll();
00703
00704 if (pcCurrentCursor != pcNewCursor)
00705 {
00706
00707 CursorStack::GSetTop(pcNewCursor, CurrentCursorID);
00708 pcCurrentCursor = pcNewCursor;
00709 }
00710
00711 return ok;
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731 BOOL BlendTool::EditBlendEnd(Spread* pSpread, DocCoord PointerPos)
00732 {
00733 List BlendList;
00734
00735 BOOL ok = BevelTools::BuildListOfSelectedNodes(&BlendList, CC_RUNTIME_CLASS(NodeBlend), FALSE);
00736 if (ok)
00737 {
00738 ok = FALSE;
00739 NodeListItem* pListItem = (NodeListItem*)BlendList.GetHead();
00740 while (pListItem != NULL)
00741 {
00742
00743 NodeBlend* pNodeBlend = (NodeBlend*)pListItem->pNode;
00744 Node* pNode = NULL;
00745
00746 ok = pNodeBlend->HitOnEndDragBlob(PointerPos, &pNode);
00747 if (ok)
00748 break;
00749 pListItem = (NodeListItem*)BlendList.GetNext(pListItem);
00750 }
00751 }
00752 BlendList.DeleteAll();
00753
00754 return ok;
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 void BlendTool::UpdateRef(BlendToolRef* pRef,Spread* pSpread, DocCoord PointerPos,BOOL CheckNodeUnderPoint)
00781 {
00782 ERROR3IF_PF(pRef ==NULL,("pRef is NULL"));
00783 ERROR3IF_PF(pSpread==NULL,("pSpread is NULL"));
00784
00785
00786 pRef->Reset();
00787
00788
00789
00790 if (!IsPointOverPathBlob(&PointerPos,pRef))
00791 {
00792
00793 pRef->Reset();
00794
00795
00796
00797 if (!IsPointOverBlendBlob(&PointerPos,pRef))
00798 {
00799
00800 pRef->Reset();
00801
00802 if (CheckNodeUnderPoint)
00803 {
00804
00805 NodeRenderableInk* pNodeUnderPoint = FindObject(pSpread,PointerPos);
00806
00807 if (pNodeUnderPoint != NULL)
00808 {
00809 BecomeA TestBecomeA(BECOMEA_TEST, CC_RUNTIME_CLASS(NodePath));
00810
00811 if (pNodeUnderPoint->CanBecomeA(&TestBecomeA))
00812 {
00813
00814 pRef->pNode = pNodeUnderPoint;
00815 }
00816 }
00817 }
00818 }
00819 }
00820
00821
00822 pRef->pSpread = pSpread;
00823 pRef->PointerPos = PointerPos;
00824 }
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 void BlendTool::UpdateCursorAndStatus()
00850 {
00851 ERROR3IF_PF(pRefStart==NULL,("pRefStart is NULL"));
00852 ERROR3IF_PF(pRefEnd ==NULL,("pRefEnd is NULL"));
00853
00854
00855 Cursor* pcNewCursor = pcNormalCursor;
00856 StatusID = _R(IDS_BLENDSTATUS_FINDSTART);
00857
00858 if (pRefStart->RemapRef > 0)
00859 {
00860
00861 pcNewCursor = pcBlendableBlobCursor;
00862 StatusID = _R(IDS_BLENDSTATUS_REMAPSTART);
00863
00864 if (pRefStart->RemapRef == pRefEnd->RemapRef && pRefStart->AStartNode != pRefEnd->AStartNode)
00865 {
00866
00867 StatusID = _R(IDS_BLENDSTATUS_REMAPEND);
00868 pcNewCursor = pcBlendableRemapCursor;
00869 }
00870 }
00871 else if (pRefStart->pNode != NULL)
00872 {
00873 if (pRefEnd->pSpread == NULL)
00874 {
00875 if (pRefStart->Index >= 0)
00876 {
00877
00878 pcNewCursor = pcBlendableBlobCursor;
00879 StatusID = _R(IDS_BLENDSTATUS_OVERBLOB);
00880 }
00881 else
00882 {
00883
00884 pcNewCursor = pcBlendableCursor;
00885 StatusID = _R(IDS_BLENDSTATUS_FINDEND);
00886 }
00887 }
00888 else if (pRefStart->pSpread == pRefEnd->pSpread)
00889 {
00890
00891 if (pRefStart->pNode != pRefEnd->pNode && pRefEnd->pNode != NULL)
00892 {
00893 StatusID = _R(IDS_BLENDSTATUS_OVEREND);
00894
00895 if (pRefEnd->Index >= 0 && pRefStart->Index >= 0)
00896
00897
00898 pcNewCursor = pcBlendableRemapCursor;
00899 else
00900
00901 pcNewCursor = pcBlendableCursor;
00902 }
00903 else
00904 StatusID = _R(IDS_BLENDSTATUS_FINDEND);
00905 }
00906 }
00907
00908 if (pcCurrentCursor != pcNewCursor)
00909 {
00910
00911 CursorStack::GSetTop(pcNewCursor, CurrentCursorID);
00912 pcCurrentCursor = pcNewCursor;
00913 }
00914
00915
00916 DisplayStatusBarHelp(StatusID);
00917 }
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 BOOL BlendTool::GetStatusLineText(String_256* pStr,Spread* pSpread,DocCoord DocPos,ClickModifiers ClickMods)
00938 {
00939 *pStr = String_256(StatusID);
00940 return TRUE;
00941 }
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 void BlendTool::UpdateInfobar()
00959 {
00960 pBlendInfoBarOp->UpdateInfoBarState();
00961 }
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984 BOOL BlendTool::IsPointOverPathBlob(DocCoord* pPointerPos,BlendToolRef* pRef)
00985 {
00986 if (pRef == NULL) return FALSE;
00987
00988
00989 SelRange* pSelRange = GetApplication()->FindSelection();
00990 Node* pNode = pSelRange->FindFirst();
00991
00992 BOOL BlobFound = FALSE;
00993
00994
00995 while (!BlobFound && pNode != NULL && pNode->FindParent() != NULL)
00996 {
00997
00998 if (IS_A(pNode,NodePath) && IS_A(pNode->FindParent(),Layer))
00999 {
01000 NodePath* pNodePath = (NodePath*)pNode;
01001
01002 if (pNodePath->GetUnionBlobBoundingRect().ContainsCoord(*pPointerPos))
01003 {
01004
01005 Path* pPath = &(pNodePath->InkPath);
01006
01007
01008 BlobFound = pPath->FindNearestPoint(*pPointerPos,POINTFLAG_ENDPOINTS,&(pRef->Index));
01009
01010
01011 if (BlobFound)
01012 {
01013 pRef->pNode = pNodePath;
01014 pPath->SetPathPosition(pRef->Index);
01015 *pPointerPos = pPath->GetCoord();
01016 }
01017 }
01018 }
01019
01020
01021 pNode = pSelRange->FindNext(pNode);
01022 }
01023
01024 return BlobFound;
01025 }
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045 BOOL BlendTool::IsPointOverBlendBlob(DocCoord* pPointerPos,BlendToolRef* pRef)
01046 {
01047 if (pRef == NULL) return FALSE;
01048
01049
01050 SelRange* pSelRange = GetApplication()->FindSelection();
01051 Node* pNode = pSelRange->FindFirst();
01052
01053 BOOL BlobFound = FALSE;
01054
01055
01056 while (pNode != NULL && !BlobFound)
01057 {
01058 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodeBlend))
01059 {
01060 NodeBlend* pNodeBlend = (NodeBlend*)pNode;
01061
01062 if (pNodeBlend->GetUnionBlobBoundingRect().ContainsCoord(*pPointerPos))
01063 {
01064 BlobFound = pNodeBlend->IsPointOverBlob(pPointerPos,
01065 &(pRef->pBlendPath),
01066 &(pRef->Index),
01067 &(pRef->AStartNode),
01068 &(pRef->RemapRef));
01069
01070 if (BlobFound)
01071 {
01072 pRef->pNode = pNodeBlend;
01073 pRef->pNodeBlend = pNodeBlend;
01074
01075 }
01076 }
01077 }
01078
01079
01080 pNode = pSelRange->FindNext(pNode);
01081 }
01082
01083 return BlobFound;
01084 }
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105 void BlendTool::CheckNodeRemapping(BlendToolRef* pRefStart, BlendToolRef* pRefEnd)
01106 {
01107 ERROR3IF(pRefStart == NULL,"pRefStart == NULL");
01108 ERROR3IF(pRefEnd == NULL,"pRefEnd == NULL");
01109 if (pRefStart == NULL || pRefEnd == NULL)
01110 return;
01111
01112 NodeBlend* pNodeBlend = pRefStart->pNodeBlend;
01113
01114 if (pNodeBlend == NULL || pNodeBlend != pRefEnd->pNodeBlend)
01115 return;
01116
01117 Node* pNode = pNodeBlend->FindFirstChild();
01118 while (pNode != NULL)
01119 {
01120 if (IS_A(pNode,NodeBlender))
01121 {
01122 NodeBlender* pNodeBlender = (NodeBlender*)pNode;
01123
01124 BOOL StartFound = pNodeBlender->IsPointOverBlob(&(pRefStart->PointerPos),
01125 &(pRefStart->pBlendPath),
01126 &(pRefStart->Index),
01127 &(pRefStart->AStartNode));
01128
01129 BOOL EndFound = pNodeBlender->IsPointOverBlob(&(pRefEnd ->PointerPos),
01130 &(pRefEnd ->pBlendPath),
01131 &(pRefEnd ->Index),
01132 &(pRefEnd ->AStartNode));
01133
01134 if (StartFound && EndFound && (pRefStart->AStartNode != pRefEnd->AStartNode))
01135 {
01136 pRefStart->RemapRef = pNodeBlender->GetTag();
01137 pRefEnd ->RemapRef = pNodeBlender->GetTag();
01138 return;
01139 }
01140 }
01141 pNode = pNode->FindNext();
01142 }
01143 }
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161 NodeRenderableInk* BlendTool::FindObject(Spread* pSpread, DocCoord PointerPos)
01162 {
01163 return NodeRenderableInk::FindCompoundAtPoint(pSpread,PointerPos,NULL);
01164 }
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182 void BlendTool::RenderToolBlobs(Spread* pSpread,DocRect* pDocRect)
01183 {
01184
01185 DocView* pDocView = DocView::GetCurrent();
01186
01187 if (pDocView != NULL && pSpread != NULL)
01188 {
01189 SelRange* pSel = GetApplication()->FindSelection();
01190 if (pSel == NULL) return;
01191
01192 List BlendList;
01193 BOOL ok = BevelTools::BuildListOfSelectedNodes(&BlendList, CC_RUNTIME_CLASS(NodeBlend), FALSE);
01194 if (ok)
01195 {
01196
01197 RenderRegion* pRender = pDocView->RenderOnTop(pDocRect,pSpread,UnclippedEOR);
01198
01199
01200
01201
01202 while (pRender != NULL)
01203 {
01204 NodeListItem* pListItem = (NodeListItem*)BlendList.GetHead();
01205
01206 while (pListItem != NULL)
01207 {
01208 NodeBlend* pNodeBlend = (NodeBlend*)pListItem->pNode;
01209 pNodeBlend->RenderBlendBlobs(pRender);
01210 pListItem = (NodeListItem*)BlendList.GetNext(pListItem);
01211 }
01212
01213 Node *pNode = pSel->FindFirst();
01214 while (pNode != NULL)
01215 {
01216 Node* pParent = pNode->FindParentOfSelected();
01217
01218 if ((pParent != NULL) && (IS_A(pParent, NodeBlend)))
01219 {
01220 RenderSelectInsideBlobs(pRender, (NodeRenderableInk*)pNode);
01221 }
01222
01223 pNode = pSel->FindNext(pNode);
01224 }
01225
01226 pRender = pDocView->GetNextOnTop(pDocRect);
01227 }
01228 }
01229 BlendList.DeleteAll();
01230 }
01231 }
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251 BOOL BlendTool::RenderSelectInsideBlobs(RenderRegion* pRender, NodeRenderableInk* pNode)
01252 {
01253
01254 if (pRender == NULL)
01255 {
01256 ERROR3("No render region");
01257 return FALSE;
01258 }
01259
01260 if (pNode == NULL)
01261 {
01262 ERROR3("node is NULL");
01263 return FALSE;
01264 }
01265
01266
01267
01268 if (pNode->IsABaseTextClass())
01269 {
01270 pRender->SetLineColour(COLOUR_BEZIERBLOB);
01271 pRender->SetFillColour(COLOUR_BEZIERBLOB);
01272 }
01273 else
01274 {
01275 pRender->SetLineColour(COLOUR_UNSELECTEDBLOB);
01276 pRender->SetFillColour(COLOUR_UNSELECTEDBLOB);
01277 }
01278
01279
01280 DocRect BlobSize;
01281 BlobManager* pBlobMgr = GetApplication()->GetBlobManager();
01282 if (pBlobMgr != NULL)
01283 {
01284 DocRect BoundingRect = ((NodeRenderableBounded*)pNode)->GetBoundingRect();
01285 DocCoord Point = BoundingRect.Centre();
01286 pBlobMgr->GetBlobRect(Point, &BlobSize);
01287
01288 if (pNode->IsABaseTextClass())
01289 {
01290 pRender->DrawBlob(Point, BT_UNSELECTED);
01291 }
01292 else
01293 {
01294 pRender->DrawLine(DocCoord(BlobSize.hi.x, BlobSize.hi.y), DocCoord(BlobSize.lo.x, BlobSize.lo.y));
01295 pRender->DrawLine(DocCoord(BlobSize.lo.x, BlobSize.hi.y), DocCoord(BlobSize.hi.x, BlobSize.lo.y));
01296 pRender->DrawPixel(DocCoord(BlobSize.hi.x, BlobSize.lo.y));
01297 pRender->DrawPixel(DocCoord(BlobSize.lo.x, BlobSize.lo.y));
01298 }
01299 return TRUE;
01300 }
01301
01302 ERROR3("Couldn't get BlobManager");
01303 return FALSE;
01304 }
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323 void BlendTool::DisplayStatusBarHelp(UINT32 StatusID)
01324 {
01325 String_256 StatusMsg("");
01326 StatusMsg.Load(StatusID);
01327 GetApplication()->UpdateStatusBarText(&StatusMsg);
01328 }
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344 BOOL BlendTool::IsCurrent()
01345 {
01346 return (Tool::GetCurrentID() == TOOLID_BLEND);
01347 }
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365 BOOL BlendTool::SelectedBlendIsOnCurve()
01366 {
01367 List BlendList;
01368
01369 BOOL ok = BevelTools::BuildListOfSelectedNodes(&BlendList, CC_RUNTIME_CLASS(NodeBlend), FALSE);
01370 if (ok)
01371 {
01372 NodeListItem* pListItem = (NodeListItem*)BlendList.GetHead();
01373 while (pListItem != NULL)
01374 {
01375 NodeBlend* pNodeBlend = (NodeBlend*)pListItem->pNode;
01376
01377 if (pNodeBlend->IsOnACurve())
01378 {
01379 BlendList.DeleteAll();
01380 return TRUE;
01381 }
01382
01383 pListItem = (NodeListItem*)BlendList.GetNext(pListItem);
01384 }
01385 }
01386 BlendList.DeleteAll();
01387 return FALSE;
01388 }
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412 MsgResult BlendInfoBarOp::Message(Msg* Message)
01413 {
01414 if (IS_OUR_DIALOG_MSG(Message))
01415 {
01416 DialogMsg* Msg = (DialogMsg*)Message;
01417
01418
01419 switch (Msg->DlgMsg)
01420 {
01421
01422
01423 case DIM_CANCEL:
01424
01425 Close();
01426 break;
01427
01428 case DIM_CREATE:
01429 {
01430
01431
01432
01433
01434
01435 m_BiasGainGadgetPosition.Init(this, _R(IDC_BLENDOBJECTBIASGAIN), _R(IDBBL_BLENDOBJECTBIASGAIN), _R(IDS_BLENDOBJECTBIASGAIN));
01436 m_BiasGainGadgetAttribute.Init(this, _R(IDC_BLENDATTRBIASGAIN), _R(IDBBL_BLENDATTRBIASGAIN), _R(IDS_BLENDATTRBIASGAIN));
01437 m_BiasGainGadgetAttribute.ToggleFillProfile ();
01438
01439 SetGadgetHelp(_R(IDC_BTN_BLENDSTEPS), _R(IDBBL_BLENDSTEPSEDIT), _R(IDS_BLENDSTEPSEDIT));
01440
01441
01442
01443 SetBitmapButtonIndexes(_R(IDC_ADDREMOVEBLENDPATH), 79, 80);
01444 SetBitmapButtonIndexes(_R(IDC_TANGENTIAL), 81, 84);
01445
01446
01447 CheckSelectionAndSet();
01448
01449
01450 if (GetBlendOnCurve() != NULL)
01451 m_BlendedOnCurve = TRUE;
01452 else
01453 m_BlendedOnCurve = FALSE;
01454
01455
01456 NodeBlend* pNodeBlend = GetNodeBlend();
01457 if (pNodeBlend != NULL)
01458 {
01459 if (pNodeBlend->GetEditState() == EDIT_STEPS)
01460 {
01461 m_EditBlendSteps = TRUE;
01462 SetLongGadgetValue(_R(IDC_BTN_BLENDDISTANCE), FALSE);
01463 }
01464 else
01465 {
01466 m_EditBlendSteps = FALSE;
01467 SetLongGadgetValue(_R(IDC_BTN_BLENDDISTANCE), FALSE);
01468 }
01469 }
01470
01471 UpdateInfoBarState();
01472 }
01473 break;
01474
01475 case DIM_LFT_BN_CLICKED:
01476 {
01477 if (FALSE) {}
01478 else if (Msg->GadgetID == _R(IDC_ADDREMOVEBLENDPATH))
01479 {
01480
01481 BOOL OnPath = (GetBlendOnCurve() != NULL);
01482 m_BlendedOnCurve = OnPath;
01483 ChangeBitmapButtonState(_R(IDC_ADDREMOVEBLENDPATH), &m_BlendedOnCurve);
01484
01485 OpDescriptor* pOpDesc = NULL;
01486
01487 if (!m_BlendedOnCurve)
01488 pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_DETACHBLENDPATH);
01489 else
01490 pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_ADDBLENDPATH);
01491
01492 if (pOpDesc != NULL)
01493 pOpDesc->Invoke();
01494 }
01495 else if (Msg->GadgetID ==_R(IDC_REMOVEBLEND))
01496 {
01497 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_REMOVEBLEND);
01498 if (pOpDesc != NULL)
01499 pOpDesc->Invoke();
01500
01501 m_BlendedOnCurve = FALSE;
01502
01503 }
01504 else if (Msg->GadgetID == _R(IDC_BLENDOBJECTBIASGAIN))
01505 HandleProfileButtonClick (m_BiasGainGadgetPosition, _R(IDC_BLENDOBJECTBIASGAIN));
01506 else if (Msg->GadgetID == _R(IDC_BLENDATTRBIASGAIN))
01507 HandleProfileButtonClick (m_BiasGainGadgetAttribute, _R(IDC_BLENDATTRBIASGAIN));
01508 else if (Msg->GadgetID == _R(IDC_BTN_ONETOONE))
01509 {
01510
01511 ChangeBitmapButtonState(_R(IDC_BTN_ONETOONE), &m_OneToOne);
01512
01513 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_CHANGEBLEND);
01514 if (pOpDesc != NULL)
01515 {
01516 ChangeBlendOpParam Param;
01517 Param.ChangeType = CHANGEBLEND_ONETOONE;
01518 Param.NewOneToOne = GetBoolGadgetSelected(_R(IDC_BTN_ONETOONE));
01519 pOpDesc->Invoke(&Param);
01520 }
01521 }
01522 else if (Msg->GadgetID == _R(IDC_BTN_BLENDANTIALIAS))
01523 {
01524
01525 ChangeBitmapButtonState(_R(IDC_BTN_BLENDANTIALIAS), &m_BlendAntiAlias);
01526
01527 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_CHANGEBLEND);
01528 if (pOpDesc != NULL)
01529 {
01530 ChangeBlendOpParam Param;
01531 Param.ChangeType = CHANGEBLEND_ANTIALIAS;
01532 Param.NewAntiAlias = GetBoolGadgetSelected(_R(IDC_BTN_BLENDANTIALIAS));
01533 pOpDesc->Invoke(&Param);
01534 }
01535 }
01536 else if (Msg->GadgetID == _R(IDC_TANGENTIAL))
01537 {
01538
01539 ChangeBitmapButtonState(_R(IDC_TANGENTIAL), &m_Tangential);
01540
01541 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_CHANGEBLEND);
01542 if (pOpDesc != NULL)
01543 {
01544 ChangeBlendOpParam Param;
01545 Param.ChangeType = CHANGEBLEND_TANGENTIAL;
01546 Param.NewTangential = GetBoolGadgetSelected(_R(IDC_TANGENTIAL));
01547 pOpDesc->Invoke(&Param);
01548 }
01549 }
01550
01551
01552 else if (Msg->GadgetID == _R(IDC_BTN_BLENDDISTANCE))
01553 {
01554
01555 SetLongGadgetValue(_R(IDC_BTN_BLENDSTEPS), FALSE);
01556 m_EditBlendSteps = FALSE;
01557 SetBlendEditState(EDIT_DISTANCE);
01558 UpdateInfoBarState();
01559
01560 }
01561 else if (Msg->GadgetID == _R(IDC_BTN_BLENDSTEPS))
01562 {
01563
01564 SetLongGadgetValue(_R(IDC_BTN_BLENDDISTANCE), FALSE);
01565 m_EditBlendSteps = TRUE;
01566 SetBlendEditState(EDIT_STEPS);
01567 UpdateInfoBarState();
01568 }
01569
01570 }
01571 break;
01572
01573 case DIM_SELECTION_CHANGED:
01574 {
01575 if (FALSE) {}
01576 else if (Msg->GadgetID == _R(IDC_BLENDSTEPS))
01577 {
01578 BOOL Valid = FALSE;
01579 INT32 NumSteps = 0;
01580
01581
01582
01583 if (m_EditBlendSteps)
01584 {
01585 Valid = GetNumSteps(1, 999, &NumSteps);
01586 if (Valid)
01587 {
01588 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_CHANGEBLENDSTEPS);
01589 if (pOpDesc != NULL)
01590 {
01591 OpParam Param(NumSteps,0);
01592 pOpDesc->Invoke(&Param);
01593 }
01594 }
01595 UpdateInfoBarState();
01596 }
01597 else
01598 {
01599 double Distance = 0.0;
01600 Valid = GetDistanceEntered( &Distance);
01601 if (Valid)
01602 {
01603
01604 Valid = IsStepDistanceValid(1, 999, Distance);
01605 if (Valid)
01606 {
01607 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_CHANGEBLENDDISTANCE);
01608 if (pOpDesc != NULL)
01609 {
01610 OpParam Param((INT32)Distance, 0);
01611 pOpDesc->Invoke(&Param);
01612 }
01613 }
01614 }
01615 UpdateInfoBarState();
01616 }
01617
01618 }
01619 else if (Msg->GadgetID == _R(IDC_EFFECT))
01620 {
01621 WORD Index;
01622 GetValueIndex(_R(IDC_EFFECT),&Index);
01623 ColourBlendType ColBlendType = (ColourBlendType)Index;
01624
01625 if (ColBlendType <= COLOURBLEND_ALTRAINBOW)
01626 {
01627 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_CHANGEBLEND);
01628 if (pOpDesc != NULL)
01629 {
01630 ChangeBlendOpParam Param;
01631 Param.ChangeType = CHANGEBLEND_COLOURBLENDTYPE;
01632 Param.NewColBlendType = ColBlendType;
01633 pOpDesc->Invoke(&Param);
01634 }
01635 }
01636 }
01637 }
01638 break;
01639
01640 default:
01641 break;
01642 }
01643
01644
01645 if (( Msg->GadgetID == _R(IDC_BLENDOBJECTBIASGAIN)) || (Msg->GadgetID == _R(IDC_BLENDATTRBIASGAIN)))
01646 {
01647 ProfileSelectionChange( Msg, Msg->GadgetID );
01648 }
01649
01650 }
01651
01652 if (MESSAGE_IS_A(Message, SelChangingMsg))
01653 {
01654 UpdateInfoBarState();
01655
01656 if (this != NULL && this->HasWindow())
01657 {
01658 if (BlendTool::IsCurrent())
01659 {
01660 HandleProfileSelChangingMsg (m_BiasGainGadgetPosition, _R(IDC_BLENDOBJECTBIASGAIN));
01661 HandleProfileSelChangingMsg (m_BiasGainGadgetAttribute, _R(IDC_BLENDATTRBIASGAIN));
01662 }
01663 }
01664 }
01665
01666
01667 return (InformationBarOp::Message(Message));
01668 }
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681 void BlendInfoBarOp::ChangeProfile(CProfileBiasGain* Profile, CGadgetID GadgetID)
01682 {
01683
01684 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_CHANGEBLEND);
01685 if (pOpDesc != NULL)
01686 {
01687 BOOL FireOp = TRUE;
01688
01689
01690
01691
01692
01693 Operation* pLastOp = NULL;
01694
01695 if (Profile->GetGeneratesInfiniteUndo ())
01696 {
01697 pLastOp = Document::GetSelected()->GetOpHistory().FindLastOp();
01698 }
01699
01700 ChangeBlendOpParam Param;
01701
01702 if (GadgetID == _R(IDC_BLENDOBJECTBIASGAIN))
01703 {
01704 if (pLastOp)
01705 {
01706 if (pLastOp->GetRuntimeClass() == CC_RUNTIME_CLASS(OpChangeBlend))
01707 {
01708 OpChangeBlend* pLastBlendOp = (OpChangeBlend*) pLastOp;
01709
01710 if (pLastBlendOp->GetChangeType () == CHANGEBLEND_OBJECTPROFILE)
01711 {
01712 if (Profile->GetGeneratesInfiniteUndo ())
01713 {
01714 FireOp = FALSE;
01715 }
01716 }
01717 }
01718 }
01719
01720 if (FireOp == TRUE)
01721 {
01722 Param.ChangeType = CHANGEBLEND_OBJECTPROFILE;
01723 Param.NewObjectProfile = *Profile;
01724 }
01725 else
01726 {
01727
01728
01729 ChangeBlendAction Action;
01730 Action.ChangeObjectProfileWithNoUndo (*Profile);
01731 }
01732 }
01733 else if (GadgetID == _R(IDC_BLENDATTRBIASGAIN))
01734 {
01735 if (pLastOp)
01736 {
01737 if (pLastOp->GetRuntimeClass() == CC_RUNTIME_CLASS(OpChangeBlend))
01738 {
01739 OpChangeBlend* pLastBlendOp = (OpChangeBlend*) pLastOp;
01740
01741 if (pLastBlendOp->GetChangeType () == CHANGEBLEND_ATTRPROFILE)
01742 {
01743 FireOp = FALSE;
01744 }
01745 }
01746 }
01747
01748 if (FireOp == TRUE)
01749 {
01750 Param.ChangeType = CHANGEBLEND_ATTRPROFILE;
01751 Param.NewAttrProfile = *Profile;
01752 }
01753 else
01754 {
01755
01756
01757 ChangeBlendAction Action;
01758 Action.ChangeAttributeProfileWithNoUndo (*Profile);
01759 }
01760 }
01761 else
01762 return;
01763
01764 if (FireOp == TRUE)
01765 {
01766 pOpDesc->Invoke(&Param);
01767 }
01768 }
01769 }
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782 void BlendInfoBarOp::ChangeProfileOnIdle(CProfileBiasGain* Profile, CGadgetID GadgetID)
01783 {
01784 if (GadgetID == _R(IDC_BLENDOBJECTBIASGAIN))
01785 {
01786
01787
01788 ChangeBlendAction Action;
01789 Action.ChangeObjectProfileWithNoUndo (*Profile, TRUE);
01790 }
01791
01792
01793
01794 }
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812 BOOL BlendInfoBarOp::GetNumSteps( UINT32 MinValue, UINT32 MaxValue, INT32 *NumSteps)
01813 {
01814 BOOL Valid = TRUE;
01815
01816 String_256 StrNumSteps = GetStringGadgetValue(_R(IDC_BLENDSTEPS), &Valid);
01817
01818
01819 if (Valid)
01820 {
01821 INT32 Position = 0;
01822 double DNumSteps = 0.0;
01823
01824
01825 Valid = Convert::ReadNumber(StrNumSteps, &Position, &DNumSteps);
01826
01827 if (Valid)
01828 {
01829
01830 if (DNumSteps < MinValue || DNumSteps > MaxValue)
01831 {
01832 InformWarning(_R(IDS_BLENDSTEPS_INVALID));
01833 Valid = FALSE;
01834 }
01835 else
01836 {
01837 *NumSteps = (INT32)DNumSteps;
01838 return Valid;
01839 }
01840 }
01841 }
01842
01843
01844 NumSteps = 0;
01845 return Valid;
01846
01847 }
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863 BOOL BlendInfoBarOp::GetDistanceEntered(double* Distance)
01864
01865 {
01866
01867 SelRange* pSel = GetApplication()->FindSelection();
01868 BOOL Valid = FALSE;
01869 if (pSel != NULL)
01870 {
01871 Node* pNode = pSel->FindFirst();
01872
01873 double UnitValue = 0.0;
01874 UnitType TheUnit;
01875 Valid = GetDoubleAndUnitGadgetValue(Distance, &UnitValue, &TheUnit, _R(IDC_BLENDSTEPS), pNode);
01876 if (!Valid)
01877 InformWarning(_R(IDS_INVALIDDISTANCE));
01878 }
01879 return Valid;
01880 }
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902 BOOL BlendInfoBarOp::GetNumStepsFromDistance(UINT32 MinValue, UINT32 MaxValue, INT32* NumSteps)
01903 {
01904
01905 SelRange* pSel = GetApplication()->FindSelection();
01906 BOOL Valid = FALSE;
01907 if (pSel != NULL)
01908 {
01909 Node* pNode = pSel->FindFirst();
01910 double MPValue = 0.0;
01911 double UnitValue = 0.0;
01912 UnitType TheUnit;
01913 Valid = GetDoubleAndUnitGadgetValue(&MPValue, &UnitValue, &TheUnit, _R(IDC_BLENDSTEPS), pNode);
01914
01915 if (Valid)
01916 {
01917
01918 if (pNode->IS_KIND_OF(NodeBlend))
01919 {
01920 double Distance = 0.0;
01921 Valid = ((NodeBlend*)pNode)->GetBlendDistance(FALSE, &Distance);
01922 if (Valid)
01923 {
01924 UINT32 TempNumSteps = (UINT32)(Distance/MPValue);
01925 if (TempNumSteps < MinValue)
01926 {
01927 InformWarning(_R(IDS_BLENDDISTANCE_TOOBIG));
01928 Valid = FALSE;
01929 }
01930 else if (TempNumSteps > MaxValue)
01931 {
01932 InformWarning(_R(IDS_BLENDDISTANCE_TOOSMALL));
01933 Valid = FALSE;
01934 }
01935 else
01936 {
01937 *NumSteps = TempNumSteps;
01938 }
01939 }
01940 else
01941 InformWarning(_R(IDS_BLENDDISTANCE_INVALID));
01942 }
01943 else
01944 InformWarning(_R(IDS_BLENDDISTANCE_INVALID));
01945 }
01946 }
01947 return Valid;
01948 }
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037 void BlendInfoBarOp::UpdateState()
02038 {
02039
02040
02041
02042 }
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055 void BlendInfoBarOp::UpdateInfoBarState()
02056 {
02057 if(this== NULL)
02058 return;
02059 if(!this->HasWindow())
02060 return ;
02061
02062 if (!BlendTool::IsCurrent()) return;
02063
02064 DialogBarOp::UpdateState();
02065
02066 BOOL OneToOne = FALSE;
02067 BOOL Antialias = NodeBlend::GetDefaultAntialias();
02068 INT32 NumSteps = 0;
02069 UINT32 NumSelBlends = 0;
02070 ColourBlendType ColBlendType = COLOURBLEND_FADE;
02071
02072 BOOL OnlyBlendsSelected = TRUE;
02073 BOOL AllSelectedBlendsAreOnCurve= TRUE;
02074
02075 BOOL Tangential = FALSE;
02076 BOOL EditSteps = TRUE;
02077 UINT32 NumBlendsOnCurve = 0;
02078 BOOL NonLinearProfile = FALSE;
02079 BOOL MultiStageBlendOnCurve = FALSE;
02080 List BlendList;
02081
02082 BOOL ok = BevelTools::BuildListOfSelectedNodes(&BlendList, CC_RUNTIME_CLASS(NodeBlend), FALSE);
02083 if (!ok)
02084 {
02085 OnlyBlendsSelected = FALSE;
02086 AllSelectedBlendsAreOnCurve = FALSE;
02087 }
02088 else
02089 {
02090 NodeListItem* pListItem = (NodeListItem*)BlendList.GetHead();
02091
02092 while (pListItem != NULL)
02093 {
02094 NodeBlend* pNodeBlend = (NodeBlend*)pListItem->pNode;
02095
02096
02097 if (!pNodeBlend->IsChildOfGroup())
02098 {
02099 NumSelBlends++;
02100
02101 if (pNodeBlend->GetEditState() == EDIT_DISTANCE)
02102 EditSteps = FALSE;
02103
02104 UINT32 ThisNumSteps = pNodeBlend->GetNumBlendSteps();
02105 ColourBlendType ThisColBlendType= pNodeBlend->GetColourBlendType();
02106
02107 if (NumSelBlends == 1)
02108 {
02109 NumSteps = ThisNumSteps;
02110 ColBlendType = ThisColBlendType;
02111 }
02112 else
02113 {
02114 if (NumSteps >= 0 && NumSteps != INT32(ThisNumSteps))
02115 NumSteps = -1;
02116 if (ColBlendType != ThisColBlendType)
02117 ColBlendType = COLOURBLEND_NONE;
02118 }
02119
02120 if (!OneToOne && pNodeBlend->IsOneToOne())
02121 OneToOne = TRUE;
02122
02123 if (Antialias && pNodeBlend->IsNotAntialiased())
02124 Antialias = FALSE;
02125
02126 if (!Tangential && pNodeBlend->IsTangential())
02127 Tangential = TRUE;
02128
02129 if (pNodeBlend->GetNodeBlendPath(0) != NULL)
02130 NumBlendsOnCurve++;
02131 else
02132 AllSelectedBlendsAreOnCurve = FALSE;
02133
02134 if (pNodeBlend->NonLinearObjectProfile())
02135 NonLinearProfile = TRUE;
02136
02137 if (pNodeBlend->GetNumNodeBlendPaths() > 1)
02138 MultiStageBlendOnCurve = TRUE;
02139 }
02140
02141 pListItem = (NodeListItem*)BlendList.GetNext(pListItem);
02142
02143 }
02144 }
02145 BlendList.DeleteAll();
02146
02147 OnlyBlendsSelected = !NonBlendsSelected();
02148
02149 EnableBlendSelectedGadgets(NumSelBlends > 0);
02150
02151
02152
02153
02154
02155
02156
02157 if (NonLinearProfile == TRUE || MultiStageBlendOnCurve == TRUE || NumBlendsOnCurve == 0)
02158 {
02159 EnableGadget(_R(IDC_BTN_BLENDDISTANCE), FALSE);
02160
02161 if (m_EditBlendSteps == FALSE)
02162 BROADCAST_TO_CLASS( DialogMsg(NULL, DIM_LFT_BN_CLICKED, _R(IDC_BTN_BLENDSTEPS), 0, 0 ), DialogOp);
02163 }
02164 else
02165 EnableGadget(_R(IDC_BTN_BLENDDISTANCE), TRUE);
02166
02167 EnableGadget(_R(IDC_BTN_BLENDSTEPS), TRUE);
02168 EnableGadget(_R(IDC_ADDREMOVEBLENDPATH), !(NumSelBlends == 0 || (OnlyBlendsSelected && NumBlendsOnCurve==0)));
02169 EnableGadget(_R(IDC_TANGENTIAL), (NumSelBlends > 0) && (NumBlendsOnCurve > 0));
02170
02171 SetBoolGadgetSelected(_R(IDC_BTN_ONETOONE),OneToOne);
02172 SetBoolGadgetSelected(_R(IDC_BTN_BLENDANTIALIAS),Antialias);
02173 SetBoolGadgetSelected(_R(IDC_TANGENTIAL), Tangential);
02174
02175 LoadStringsIntoEffectCombo();
02176
02177 if (m_EditBlendSteps != EditSteps)
02178 {
02179 if (EditSteps)
02180 {
02181 SetLongGadgetValue(_R(IDC_BTN_BLENDDISTANCE), FALSE);
02182 }
02183 else
02184 {
02185 SetLongGadgetValue(_R(IDC_BTN_BLENDSTEPS), FALSE);
02186 }
02187 }
02188
02189 if (NumSelBlends != GetApplication()->FindSelection()->Count())
02190 {
02191 EnableGadget (_R(IDC_BLENDOBJECTBIASGAIN), FALSE);
02192 EnableGadget (_R(IDC_BLENDATTRBIASGAIN), FALSE);
02193 }
02194
02195 if (NumSelBlends == 0)
02196 {
02197
02198 String_64 Str;
02199 Str = _T("");
02200 SetStringGadgetValue(_R(IDC_BLENDSTEPS),Str);
02201 SetStringGadgetValue(_R(IDC_EFFECT),Str, FALSE, -1);
02202 }
02203 else
02204 {
02205 ShowEffectComboString(ColBlendType);
02206
02207
02208 if (NumSelBlends == 1)
02209 {
02210 if (m_EditBlendSteps)
02211 SetBlendStepsEditText((INT32)NumSteps);
02212 else
02213 SetBlendDistanceEditText((INT32)NumSteps);
02214 }
02215
02216 else if (NumSelBlends > 1)
02217 {
02218 if (m_EditBlendSteps)
02219 {
02220 if (AllBlendsHaveSameNumSteps())
02221 SetBlendStepsEditText((INT32)NumSteps);
02222 else
02223 SetStringGadgetValue(_R(IDC_BLENDSTEPS),_R(IDS_MANY));
02224 }
02225 else
02226 {
02227 if (AllBlendsHaveSameDistance())
02228 SetBlendDistanceEditText((INT32)NumSteps);
02229 else
02230 SetStringGadgetValue(_R(IDC_BLENDSTEPS),_R(IDS_MANY));
02231 }
02232 }
02233 }
02234
02235
02236
02237
02238 if (NumSelBlends > 0)
02239 {
02240 if (NumBlendsOnCurve > 0)
02241 {
02242 SetLongGadgetValue(_R(IDC_ADDREMOVEBLENDPATH), TRUE);
02243 if (Tangential)
02244 {
02245 SetLongGadgetValue(_R(IDC_TANGENTIAL), TRUE);
02246 }
02247 }
02248
02249 }
02250
02251
02252
02253
02254 if (m_EditBlendSteps == TRUE)
02255 {
02256 SetLongGadgetValue(_R(IDC_BTN_BLENDSTEPS), TRUE);
02257 SetGadgetHelp(_R(IDC_BLENDSTEPS), _R(IDBBL_BLENDSTEPSEDITVALUE), _R(IDS_BLENDSTEPSEDITVALUE));
02258 }
02259 else
02260 {
02261 SetLongGadgetValue(_R(IDC_BTN_BLENDDISTANCE), TRUE);
02262 SetGadgetHelp(_R(IDC_BLENDSTEPS), _R(IDBBL_BLENDDISTANCEEDITVALUE), _R(IDS_BLENDDISTANCEEDITVALUE));
02263 }
02264 }
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277 void BlendInfoBarOp::ShowEffectComboString(ColourBlendType Type)
02278 {
02279 String_64 Str;
02280 switch (Type)
02281 {
02282 case COLOURBLEND_FADE: Str.Load(_R(IDS_FILLTOOL_FADE)); break;
02283 case COLOURBLEND_RAINBOW: Str.Load(_R(IDS_FILLTOOL_RAINBOW)); break;
02284 case COLOURBLEND_ALTRAINBOW: Str.Load(_R(IDS_FILLTOOL_ALTRAINBOW)); break;
02285 case COLOURBLEND_NONE: Str.Load(_R(IDS_MANY)); break;
02286
02287 default:ERROR3("Unknown colour blend type"); Str.Load(_R(IDS_FILLTOOL_FADE)); break;
02288 }
02289 SetStringGadgetValue(_R(IDC_EFFECT),Str, FALSE, -1);
02290 }
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303 void BlendInfoBarOp::LoadStringsIntoEffectCombo()
02304 {
02305 String_64 Str;
02306 DeleteAllValues(_R(IDC_EFFECT));
02307 Str.Load(_R(IDS_FILLTOOL_FADE));
02308 SetStringGadgetValue(_R(IDC_EFFECT),Str,FALSE, FEMENU_FADE);
02309 Str.Load(_R(IDS_FILLTOOL_RAINBOW));
02310 SetStringGadgetValue(_R(IDC_EFFECT),Str,FALSE, FEMENU_RAINBOW);
02311 Str.Load(_R(IDS_FILLTOOL_ALTRAINBOW));
02312 SetStringGadgetValue(_R(IDC_EFFECT),Str,TRUE, FEMENU_ALTRAINBOW);
02313
02314 SetComboListLength(_R(IDC_EFFECT));
02315 }
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329 void BlendInfoBarOp::EnableBlendSelectedGadgets(BOOL Enable)
02330 {
02331 EnableGadget(_R(IDC_BLENDOBJECTBIASGAIN), Enable);
02332 EnableGadget(_R(IDC_BLENDATTRBIASGAIN), Enable);
02333 EnableGadget(_R(IDC_BLENDSTEPS), Enable);
02334 EnableGadget(_R(IDC_BTN_ONETOONE), Enable);
02335 EnableGadget(_R(IDC_BTN_BLENDANTIALIAS),Enable);
02336 EnableGadget(_R(IDC_EFFECT), Enable);
02337 }
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351 void BlendInfoBarOp::ChangeBitmapButtonState(CGadgetID GadgetID, BOOL* CurrentState)
02352 {
02353 GetBoolGadgetSelected(GadgetID);
02354 if (*CurrentState == FALSE)
02355 {
02356 *CurrentState = TRUE;
02357 }
02358 else
02359 {
02360 *CurrentState = FALSE;
02361 SetLongGadgetValue(GadgetID, FALSE);
02362 }
02363
02364 }
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377 void BlendInfoBarOp::SetBlendStepsEditText(INT32 NumSteps)
02378 {
02379 String_256 StepString(_R(IDS_BLENDSTEPS_POSTFIX));
02380 String_256 StrNumSteps = _T("");
02381 Convert::LongToString(NumSteps, &StrNumSteps);
02382 StrNumSteps += StepString;
02383
02384 SetStringGadgetValue(_R(IDC_BLENDSTEPS), StrNumSteps);
02385
02386 }
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400 void BlendInfoBarOp::SetBlendDistanceEditText(INT32 NumSteps)
02401 {
02402 double Distance = 0.0;
02403
02404 BOOL Valid = GetMeanBlendDistance(&Distance);
02405
02406 if (!Valid)
02407 return;
02408
02409 double DistanceBetweenSteps = Distance/NumSteps;
02410
02411
02412 SelRange* pSel = GetApplication()->FindSelection();
02413 if (pSel == NULL)
02414 return;
02415 Spread* pCurrentSpread = pSel->FindFirst()->FindParentSpread();
02416
02417 if (pCurrentSpread != NULL)
02418 {
02419
02420 DimScale* pDimScale = DimScale::GetPtrDimScale((Node*)pCurrentSpread);
02421 if (pDimScale == NULL)
02422 return;
02423
02424 String_256 Str;
02425 pDimScale->ConvertToUnits(DistanceBetweenSteps, &Str, TRUE, 4);
02426
02427 SetStringGadgetValue(_R(IDC_BLENDSTEPS), Str);
02428 }
02429
02430 return;
02431 }
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447 BOOL BlendInfoBarOp::GetMeanBlendDistance(double* Distance)
02448 {
02449 BOOL Valid = FALSE;
02450 *Distance = 0.0;
02451 NodeBlend* pNodeBlend = GetNodeBlend();
02452
02453 if (pNodeBlend == NULL)
02454 return FALSE;
02455
02456 UINT32 NumBlenders = pNodeBlend->GetNumBlenders();
02457 if (NumBlenders == 0)
02458 {
02459 ERROR3("This blend has zero blenders");
02460 return FALSE;
02461 }
02462 double TempDistance = 0.0;
02463
02464 Valid = pNodeBlend->GetBlendDistance(FALSE, &TempDistance);
02465 if (Valid)
02466 {
02467 TempDistance = TempDistance / NumBlenders;
02468 *Distance = TempDistance;
02469 }
02470
02471 return Valid;
02472 }
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485
02486
02487
02488 BOOL BlendInfoBarOp::AllBlendsHaveSameNumSteps()
02489 {
02490 UINT32 NumSteps = 0;
02491 BOOL FoundFirst = FALSE;
02492 BOOL SameNumber = FALSE;
02493 SelRange* pSel = GetApplication()->FindSelection();
02494 if (pSel != NULL)
02495 {
02496 Node* pNode = pSel->FindFirst();
02497 while (pNode != NULL)
02498 {
02499 if (pNode->IS_KIND_OF(NodeBlend))
02500 if (!FoundFirst)
02501 {
02502 NumSteps = ((NodeBlend*)pNode)->GetNumBlendSteps();
02503 FoundFirst = TRUE;
02504 SameNumber = TRUE;
02505 }
02506 else
02507 {
02508 if (((NodeBlend*)pNode)->GetNumBlendSteps() != NumSteps)
02509 return FALSE;
02510 }
02511 pNode = pSel->FindNext(pNode);
02512 }
02513 }
02514 return SameNumber;
02515 }
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531 BOOL BlendInfoBarOp::AllBlendsHaveSameDistance()
02532 {
02533 double FirstDistance = 0.0;
02534 double FirstStepDistance = 0.0;
02535
02536 BOOL FoundFirst = FALSE;
02537 BOOL SameNumber = FALSE;
02538 SelRange* pSel = GetApplication()->FindSelection();
02539 if (pSel != NULL)
02540 {
02541 Node* pNode = pSel->FindFirst();
02542 while (pNode != NULL)
02543 {
02544 if (pNode->IS_KIND_OF(NodeBlend))
02545 if (!FoundFirst)
02546 {
02547 if (!((NodeBlend*)pNode)->GetBlendDistance(FALSE, &FirstDistance))
02548 return FALSE;
02549 UINT32 NumSteps = ((NodeBlend*)pNode)->GetNumBlendSteps();
02550 FirstStepDistance = FirstDistance/NumSteps;
02551 FoundFirst = TRUE;
02552 SameNumber = TRUE;
02553 }
02554 else
02555 {
02556 double NextDistance;
02557 if (!((NodeBlend*)pNode)->GetBlendDistance(FALSE, &NextDistance))
02558 return FALSE;
02559
02560 UINT32 NumSteps = ((NodeBlend*)pNode)->GetNumBlendSteps();
02561 double ThisStepDistance = FirstDistance/NumSteps;
02562
02563 if (ThisStepDistance != FirstStepDistance)
02564 return FALSE;
02565 }
02566 pNode = pSel->FindNext(pNode);
02567 }
02568 }
02569 return SameNumber;
02570 }
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585 NodeBlender* BlendInfoBarOp::GetBlender()
02586 {
02587
02588 SelRange Sel(*( GetApplication()->FindSelection()));
02589 NodeBlend* pNodeBlend = NULL;
02590
02591
02592 if (!Sel.IsEmpty())
02593 {
02594 Node* pNode = Sel.FindFirst();
02595 while (pNode != NULL)
02596 {
02597 if (pNode->IS_KIND_OF(NodeBlend))
02598 {
02599 pNodeBlend = (NodeBlend*)pNode;
02600 break;
02601 }
02602 pNode = Sel.FindNext(pNode);
02603 }
02604 }
02605
02606 if (pNodeBlend == NULL)
02607 return NULL;
02608
02609
02610 NodeBlender* pBlender = NULL;
02611
02612 Node* pNode = pNodeBlend->FindFirstChild();
02613 while (pNode != NULL)
02614 {
02615 if (pNode->IS_KIND_OF(NodeBlender))
02616 {
02617 pBlender = (NodeBlender*)pNode;
02618 break;
02619 }
02620 pNode = pNode->FindNext();
02621 }
02622
02623 return pBlender;
02624 }
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639 NodeBlend* BlendInfoBarOp::GetNodeBlend()
02640 {
02641 SelRange* pSel = GetApplication()->FindSelection();
02642 NodeBlend* pNodeBlend = NULL;
02643
02644 if (pSel != NULL)
02645 {
02646 Node* pNode = pSel->FindFirst();
02647
02648 while (pNode != NULL)
02649 {
02650 if (pNode->IS_KIND_OF(NodeBlend))
02651 {
02652 pNodeBlend = (NodeBlend*)pNode;
02653 return pNodeBlend;
02654 }
02655 pNode = pSel->FindNext(pNode);
02656 }
02657 }
02658 return pNodeBlend;
02659 }
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675 NodeBlend* BlendInfoBarOp::GetBlendOnCurve()
02676 {
02677
02678 SelRange Sel(*( GetApplication()->FindSelection()));
02679 NodeBlend* pNodeBlend = NULL;
02680
02681
02682 if (!Sel.IsEmpty())
02683 {
02684 Node* pNode = Sel.FindFirst();
02685 while (pNode != NULL)
02686 {
02687 if (pNode->IS_KIND_OF(NodeBlend))
02688 {
02689 pNodeBlend = (NodeBlend*)pNode;
02690 break;
02691 }
02692 pNode = Sel.FindNext(pNode);
02693 }
02694 }
02695
02696 if (pNodeBlend == NULL)
02697 return NULL;
02698
02699 if (pNodeBlend->IsOnACurve())
02700 return pNodeBlend;
02701 else
02702 return NULL;
02703
02704 }
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718 void BlendInfoBarOp::SetBlendEditState(EditState State)
02719 {
02720
02721 SelRange Sel(*( GetApplication()->FindSelection()));
02722
02723
02724
02725 if (!Sel.IsEmpty())
02726 {
02727 Node* pNode = Sel.FindFirst();
02728 while (pNode != NULL)
02729 {
02730 if (pNode->IS_KIND_OF(NodeBlend))
02731 {
02732 ((NodeBlend*)pNode)->SetEditState(State);
02733 }
02734 pNode = Sel.FindNext(pNode);
02735 }
02736 }
02737 }
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754 BOOL BlendInfoBarOp::IsStepDistanceValid(UINT32 MinValue, UINT32 MaxValue, double Distance)
02755 {
02756
02757 SelRange Sel(*( GetApplication()->FindSelection()));
02758
02759
02760 if (Distance <= 0)
02761 {
02762 InformWarning(_R(IDS_BLENDDISTANCE_TOOSMALL));
02763 return FALSE;
02764 }
02765
02766 if (!Sel.IsEmpty())
02767 {
02768 Node* pNode = Sel.FindFirst();
02769 while (pNode != NULL)
02770 {
02771 if (pNode->IS_KIND_OF(NodeBlend))
02772 {
02773
02774
02775 UINT32 NumSteps = 0;
02776 BOOL Valid = ((NodeBlend*)pNode)->GetNumStepsFromDistance(Distance, &NumSteps);
02777 if (Valid)
02778 {
02779 if (NumSteps < MinValue)
02780 {
02781 InformWarning(_R(IDS_BLENDDISTANCE_TOOBIG));
02782 return FALSE;
02783 }
02784 else if (NumSteps > MaxValue)
02785 {
02786 InformWarning(_R(IDS_BLENDDISTANCE_TOOSMALL));
02787 return FALSE;
02788 }
02789 }
02790 else
02791 return FALSE;
02792 }
02793 pNode = Sel.FindNext(pNode);
02794 }
02795 }
02796 return TRUE;
02797 }
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815 CProfileBiasGain* BlendInfoBarOp::GetProfileFromSelection(CGadgetID GadgetID, BOOL* bMany, BOOL* bAllSameType)
02816 {
02817 BOOL ok = ((GadgetID == _R(IDC_BLENDOBJECTBIASGAIN)) || (GadgetID == _R(IDC_BLENDATTRBIASGAIN)));
02818
02819 ERROR2IF(ok==FALSE, FALSE, "Invalid gadgetID passed");
02820
02821
02822
02823
02824
02825
02826 SelRange Sel(*( GetApplication()->FindSelection()));
02827
02828 NodeBlend* pFirstNodeBlend = NULL;
02829 CProfileBiasGain* pFirstProfile = NULL;
02830
02831
02832 if (!Sel.IsEmpty())
02833 {
02834 Node* pNode = Sel.FindFirst();
02835 while (pNode != NULL)
02836 {
02837 if (pNode->IS_KIND_OF(NodeBlend))
02838 {
02839 if (pFirstNodeBlend == NULL)
02840 {
02841 pFirstNodeBlend = (NodeBlend*) pNode;
02842
02843 if (GadgetID == _R(IDC_BLENDOBJECTBIASGAIN))
02844 {
02845 pFirstProfile = pFirstNodeBlend->GetObjectProfile();
02846 }
02847 else if (GadgetID == _R(IDC_BLENDATTRBIASGAIN))
02848 {
02849 pFirstProfile = pFirstNodeBlend->GetAttrProfile();
02850 }
02851 }
02852 else
02853 {
02854
02855
02856
02857
02858 if (GadgetID == _R(IDC_BLENDOBJECTBIASGAIN))
02859 {
02860 if (*pFirstProfile == *((NodeBlend*) pNode)->GetObjectProfile())
02861 {
02862
02863 }
02864 else
02865 {
02866 *bMany = TRUE;
02867 }
02868 }
02869 else if (GadgetID == _R(IDC_BLENDATTRBIASGAIN))
02870 {
02871 if (*pFirstProfile == *((NodeBlend*) pNode)->GetAttrProfile())
02872 {
02873
02874 }
02875 else
02876 {
02877 *bMany = TRUE;
02878 }
02879 }
02880 }
02881 }
02882 else
02883 {
02884 *bAllSameType = FALSE;
02885 return (NULL);
02886 }
02887 pNode = Sel.FindNext(pNode);
02888 }
02889 }
02890
02891 if (*bMany == TRUE)
02892 {
02893 return (NULL);
02894 }
02895 else
02896 {
02897 return (pFirstProfile);
02898 }
02899 }
02900
02901
02902
02903 INT32 BlendInfoBarOp::AttributeIndexModifier(INT32 CurrentIndex)
02904 {
02905 INT32 retval = 1;
02906
02907 switch (CurrentIndex)
02908 {
02909 case 1:
02910 retval = 1;
02911 break;
02912 case 2:
02913 retval= 3;
02914 break;
02915 case 3:
02916 retval = 2;
02917 break;
02918 case 4:
02919 retval= 5;
02920 break;
02921 case 5:
02922 retval = 4;
02923 break;
02924 case 6:
02925 retval = 6;
02926 break;
02927 }
02928 return retval;
02929 }
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944 NodeBlend* BlendInfoBarOp::GetCurrentNodeBlend()
02945 {
02946
02947 SelRange Sel(*( GetApplication()->FindSelection()));
02948 NodeBlend* pNodeBlend = NULL;
02949
02950
02951 if (!Sel.IsEmpty())
02952 {
02953 Node* pNode = Sel.FindFirst();
02954 while (pNode != NULL)
02955 {
02956 if (pNode->IS_KIND_OF(NodeBlend))
02957 {
02958 pNodeBlend = (NodeBlend*)pNode;
02959 break;
02960 }
02961 pNode = Sel.FindNext(pNode);
02962 }
02963 }
02964
02965 return pNodeBlend;
02966 }
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986 BOOL BlendInfoBarOp::CheckSelectionAndSet()
02987 {
02988 SelRange* pSel = GetApplication()->FindSelection();
02989
02990 if (pSel == NULL)
02991 return FALSE;
02992
02993 Node* pNode = pSel->FindFirst();
02994
02995 if (pNode != NULL)
02996 {
02997 if (pNode->IS_KIND_OF(NodeBlendPath))
02998 {
02999 Node* pParent = pNode->FindParent();
03000
03001 if (pParent->IS_KIND_OF(NodeBlend))
03002 {
03003 NodeRenderableInk::DeselectAll();
03004 ((NodeRenderable*)pParent)->Select(TRUE);
03005 pSel->Update();
03006
03007 return TRUE;
03008 }
03009 }
03010 }
03011 return FALSE;
03012
03013 }
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026 BOOL BlendInfoBarOp::NonBlendsSelected()
03027 {
03028 SelRange* pSel = GetApplication()->FindSelection();
03029
03030 if (pSel == NULL)
03031 return FALSE;
03032
03033 Node* pNode = pSel->FindFirst();
03034 while (pNode != NULL)
03035 {
03036 if (pNode->IsAnObject())
03037 {
03038
03039 if (pNode->IsCompound())
03040 {
03041 if (!pNode->IS_KIND_OF(NodeBlend))
03042 {
03043
03044 if (pNode->IS_KIND_OF(NodeBevelController) ||
03045 pNode->IS_KIND_OF(NodeShadowController) ||
03046 pNode->IS_KIND_OF(NodeContourController))
03047 {
03048 Node* pChild = pNode->FindFirstChild(CC_RUNTIME_CLASS(NodeBlend));
03049 if (pChild == NULL)
03050 return TRUE;
03051 }
03052 }
03053 }
03054 else
03055 return TRUE;
03056 }
03057 pNode = pSel->FindNext(pNode);
03058 }
03059 return FALSE;
03060
03061 }
03062
03063
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081 OpBlendNodes::OpBlendNodes()
03082 {
03083 pRefStart = NULL;
03084 pRefEnd = NULL;
03085 OpType = BLENDOPTYPE_NONE;
03086
03087 pNodeBlend = NULL;
03088 pNodeBlendStart = NULL;
03089 pNodeBlendEnd = NULL;
03090 }
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102 OpBlendNodes::~OpBlendNodes()
03103 {
03104 }
03105
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121 BOOL OpBlendNodes::DoDrag(BlendTool* pBlendTool)
03122 {
03123
03124
03125 if (Tool::GetCurrent()->GetID() == TOOLID_BLEND)
03126 {
03127 pRefStart = BlendTool::GetPtrRefStart();
03128 pRefEnd = BlendTool::GetPtrRefEnd();
03129 }
03130
03131 ERROR2IF_PF(pRefStart == NULL || pRefEnd == NULL,FALSE,("Blend tool refs are NULL"));
03132
03133 pRefEnd->PointerPos = pRefStart->PointerPos;
03134 RenderMyDragBlobs();
03135 m_pBlendTool = pBlendTool;
03136
03137
03138 StartDrag( DRAGTYPE_AUTOSCROLL );
03139
03140 return TRUE;
03141 }
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161 void OpBlendNodes::DragPointerMove( DocCoord PointerPos, ClickModifiers ClickMods,
03162 Spread* pSpread, BOOL bSolidDrag)
03163 {
03164
03165 RenderMyDragBlobs();
03166
03167
03168 if (pSpread != pRefStart->pSpread)
03169 PointerPos = MakeRelativeToSpread(pRefStart->pSpread, pSpread, PointerPos);
03170
03171
03172
03173 if (Tool::GetCurrent()->GetID() == TOOLID_BLEND)
03174 {
03175 BlendTool::UpdateRef(pRefEnd,pRefStart->pSpread,PointerPos,FALSE);
03176 BlendTool::CheckNodeRemapping(pRefStart,pRefEnd);
03177 BlendTool::UpdateCursorAndStatus();
03178 }
03179
03180
03181 RenderMyDragBlobs();
03182 }
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206 void OpBlendNodes::DragFinished( DocCoord PointerPos, ClickModifiers ClickMods,
03207 Spread* pSpread, BOOL Success, BOOL bSolidDrag)
03208 {
03209 ERROR3IF(pRefStart == NULL,"pRefStart is NULL");
03210 ERROR3IF(pRefEnd == NULL,"pRefEnd is NULL");
03211 if ((pRefStart == NULL) || (pRefEnd == NULL)) return;
03212
03213
03214 RenderMyDragBlobs();
03215
03216 if (Success)
03217 {
03218
03219 if (pSpread != pRefStart->pSpread)
03220 PointerPos = MakeRelativeToSpread(pRefStart->pSpread, pSpread, PointerPos);
03221
03222 if (Tool::GetCurrent()->GetID() == TOOLID_BLEND)
03223 {
03224 BlendTool::UpdateRef(pRefEnd,pRefStart->pSpread,PointerPos);
03225 BlendTool::CheckNodeRemapping(pRefStart,pRefEnd);
03226 }
03227 else
03228 {
03229 FailAndExecute();
03230 EndDrag();
03231 delete this;
03232 return;
03233 }
03234
03235 String_32 ProgString = _T("Calculating blend, please wait..");
03236 Progress Hourglass(&ProgString, -1, FALSE);
03237 Node* pNodeStart = pRefStart->pNode;
03238 Node* pNodeEnd = pRefEnd ->pNode;
03239
03240
03241 while (pNodeStart)
03242 {
03243 if (!pNodeStart->PromoteHitTestOnChildrenToMe() && pNodeStart->IsAnObject())
03244 {
03245 pRefStart->pNode = (NodeRenderableInk *)pNodeStart;
03246 }
03247
03248 pNodeStart = pNodeStart->FindParent();
03249 }
03250
03251 while (pNodeEnd)
03252 {
03253 if (!pNodeEnd->PromoteHitTestOnChildrenToMe() && pNodeEnd->IsAnObject())
03254 {
03255 pRefEnd->pNode = (NodeRenderableInk *)pNodeEnd;
03256 }
03257
03258 pNodeEnd = pNodeEnd->FindParent();
03259 }
03260
03261
03262 BOOL ok = FALSE;
03263
03264 if (pRefStart->pNode == NULL || pRefEnd->pNode == NULL)
03265 {
03266
03267 FailAndExecute();
03268 EndDrag();
03269 delete this;
03270 return;
03271 }
03272 else if (pRefStart->pNode == pRefEnd->pNode)
03273 {
03274 if (pRefStart->RemapRef == pRefEnd->RemapRef && pRefStart->RemapRef > 0)
03275 {
03276
03277
03278 if (pRefStart->AStartNode != pRefEnd->AStartNode)
03279
03280 ok = DoRemapBlend();
03281 }
03282 else
03283 {
03284
03285 FailAndExecute();
03286 EndDrag();
03287 delete this;
03288 return;
03289 }
03290 }
03291 else if (IS_A(pRefStart->pNode,NodeBlend) &&
03292 IS_A(pRefEnd ->pNode,NodeBlend))
03293 {
03294
03295 ok = DoBlendBlendAndBlend();
03296 }
03297 else if (IS_A(pRefStart->pNode,NodeBlend) ||
03298 IS_A(pRefEnd ->pNode,NodeBlend))
03299 {
03300
03301 ok = DoBlendBlendAndObject();
03302 }
03303 else
03304 {
03305 ok = DoBlendObjects();
03306 }
03307
03308 if (!ok)
03309 FailAndExecute();
03310
03311
03312 if (Tool::GetCurrent()->GetID() == TOOLID_BLEND)
03313 {
03314 BlendTool::UpdateCursorAndStatus();
03315 }
03316 else
03317 {
03318
03319 }
03320 }
03321 else
03322 FailAndExecute();
03323
03324
03325
03326 EndDrag();
03327 End();
03328 }
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342 BOOL OpBlendNodes::DoContourNode(Node * pNode, DocCoord PointerPos, UINT32 Steps)
03343 {
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480 return TRUE;
03481
03482 }
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498 BOOL OpBlendNodes::DoBlendBlendAndBlend()
03499 {
03500
03501 pNodeBlendStart = (NodeBlend*)pRefStart->pNode;
03502 pNodeBlendEnd = (NodeBlend*)pRefEnd ->pNode;
03503
03504
03505 if (pNodeBlendStart->IsOnACurve() || pNodeBlendEnd->IsOnACurve())
03506 {
03507 OpType = BLENDOPTYPE_BLENDBLENDONPATH;
03508 pNodeBlendStart->SetBlendedOnCurve(TRUE);
03509 }
03510 else
03511 OpType = BLENDOPTYPE_BLENDANDBLEND;
03512
03513
03514 if (pNodeBlendStart == NULL || pNodeBlendEnd == NULL || pNodeBlendStart == pNodeBlendEnd) return FALSE;
03515
03516 ERROR3IF(!IS_A(pNodeBlendStart,NodeBlend) || !IS_A(pNodeBlendEnd,NodeBlend),"Either start or end is not a NodeBlend");
03517 if (!IS_A(pNodeBlendStart,NodeBlend) || !IS_A(pNodeBlendEnd,NodeBlend)) return FALSE;
03518
03519
03520 List BlenderListStart,BlenderListEnd;
03521 if (!RecordBlenderInfo(BlenderListStart,pNodeBlendStart) || !RecordBlenderInfo(BlenderListEnd,pNodeBlendEnd))
03522 {
03523
03524 BlenderListStart.DeleteAll();
03525 BlenderListEnd .DeleteAll();
03526 return FALSE;
03527 }
03528
03529
03530
03531 NodeRenderableInk* pNodeStart = NULL;
03532 NodeRenderableInk* pNodeEnd = NULL;
03533
03534 BOOL ok = GetNodeClosestToPoint(&pNodeStart, TRUE);
03535 if (ok) ok = GetNodeClosestToPoint(&pNodeEnd, FALSE);
03536 ERROR3IF(pNodeStart == NULL,"The start node ptr is NULL");
03537 ERROR3IF(pNodeEnd == NULL,"The end node ptr is NULL");
03538 if (pNodeStart == NULL || pNodeEnd == NULL) return FALSE;
03539
03540 BlobManager* pBlobManager = GetApplication()->GetBlobManager();
03541 ENSURE(pBlobManager, "Can't get BlobManager");
03542
03543 ok = DeterminBlendObjectsProcessorHit ();
03544
03545
03546
03547
03548 if (ok) ok = DoStartSelOp(TRUE,TRUE);
03549
03550 if (ok) ok = (Tool::GetCurrent() != NULL);
03551 if (ok) pBlobManager->RenderToolBlobsOff(Tool::GetCurrent(), pRefStart->pSpread,NULL);
03552 if (ok) NodeRenderableInk::DeselectAll(FALSE);
03553
03554
03555 if (ok) pNodeBlendStart->SetSelected(TRUE);
03556
03557
03558 if (ok) ok = DoDeinitBlenders(BlenderListEnd);
03559
03560
03561 if (ok) ok = DoLocaliseCommonAttributes(pNodeBlendStart);
03562
03563
03564 if (ok) ok = DoLocaliseCommonAttributes(pNodeBlendEnd);
03565
03566
03567 NodeHidden* pNodeHidden;
03568 if (ok) ok = DoHideNode(pNodeBlendEnd,TRUE,&pNodeHidden);
03569
03570 if (ok)
03571 {
03572
03573
03574 INT32 FirstBlendNumPaths = pNodeBlendStart->GetNumNodeBlendPaths();
03575 NodeBlender* pBlender = pNodeBlendEnd->FindFirstBlender();
03576 while (pBlender != NULL)
03577 {
03578 INT32 CurrentIndex = pBlender->GetNodeBlendPathIndex();
03579 if (CurrentIndex > -1)
03580 {
03581 ChangeBlenderOpParam Param;
03582 Param.m_NewNodeBlendPathIndex = (CurrentIndex + FirstBlendNumPaths);
03583 Param.m_ChangeType = CHANGEBLENDER_NBPINDEX;
03584 ok = ChangeBlenderAction::Init(this, &UndoActions, pBlender, Param);
03585 }
03586 pBlender = pNodeBlendEnd->FindNextBlender(pBlender);
03587 }
03588 }
03589
03590
03591 if (ok)
03592 {
03593 Node* pNode = pNodeBlendEnd->FindFirstChild();
03594 while (pNode != NULL && ok)
03595 {
03596 Node* pNext = pNode->FindNext();
03597 if (!pNode->IS_KIND_OF(NodeHidden))
03598 ok = DoMoveNode(pNode,pNodeBlendStart,LASTCHILD);
03599
03600
03601
03602
03603 pNode = pNext;
03604 }
03605 }
03606
03607
03608 if (ok) ok = DoCreateBlender(pNodeStart,-1,pNodeEnd,-1,pNodeStart,NEXT);
03609
03610
03611 if (ok) ok = DoReinitBlenders(BlenderListEnd);
03612
03613
03614 if (ok) ok = DoFactorOutCommonChildAttributes(pNodeBlendStart);
03615
03616
03617 if (ok) ok = DoInvalidateNodeRegion(pNodeBlendStart,TRUE);
03618
03619
03620 BlenderListStart.DeleteAll();
03621 BlenderListEnd .DeleteAll();
03622
03623
03624 GetApplication()->UpdateSelection();
03625
03626 return (ok);
03627 }
03628
03629
03630
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649 BOOL OpBlendNodes::DoBlendBlendAndObject()
03650 {
03651 ERROR3IF(!IS_A(pRefStart->pNode,NodeBlend) && !IS_A(pRefEnd->pNode,NodeBlend),"Neither start or end are NodeBlends");
03652 if (!IS_A(pRefStart->pNode,NodeBlend) && !IS_A(pRefEnd->pNode,NodeBlend)) return FALSE;
03653
03654 OpType = BLENDOPTYPE_BLENDANDOBJECT;
03655
03656 BOOL BlendIsStart = IS_A(pRefStart->pNode,NodeBlend);
03657
03658
03659 pNodeBlend = NULL;
03660 if (BlendIsStart)
03661 pNodeBlend = (NodeBlend*)pRefStart->pNode;
03662 else
03663 pNodeBlend = (NodeBlend*)pRefEnd->pNode;
03664
03665 if (pNodeBlend == NULL) return FALSE;
03666
03667
03668 List BlenderList;
03669 if (!RecordBlenderInfo(BlenderList,pNodeBlend))
03670 return FALSE;
03671
03672 NodeRenderableInk* pNodeStart = NULL;
03673 NodeRenderableInk* pNodeEnd = NULL;
03674 Node* pContextNode;
03675 AttachNodeDirection AttachDir;
03676 BOOL ok = FALSE;
03677 if (BlendIsStart)
03678 {
03679
03680 pNodeBlendStart = pNodeBlend;
03681 ok = GetNodeClosestToPoint(&pNodeStart, TRUE);
03682 pNodeEnd = pRefEnd->pNode;
03683 pContextNode = pNodeEnd;
03684 AttachDir = PREV;
03685 }
03686 else
03687 {
03688
03689 pNodeStart = pRefStart->pNode;
03690 pNodeBlendEnd = pNodeBlend;
03691 ok = GetNodeClosestToPoint(&pNodeEnd, FALSE);
03692 pContextNode = pNodeStart;
03693 AttachDir = NEXT;
03694 }
03695
03696 ERROR3IF(pNodeBlend == NULL,"Neither start or end are NodeBlends");
03697 ERROR3IF(pNodeStart == NULL,"The start node ptr is NULL");
03698 ERROR3IF(pNodeEnd == NULL,"The end node ptr is NULL");
03699 if (pNodeBlend == NULL || pNodeStart == NULL || pNodeEnd == NULL)
03700 return FALSE;
03701
03702 BlobManager* pBlobManager = GetApplication()->GetBlobManager();
03703 ENSURE(pBlobManager, "Can't get BlobManager");
03704
03705 ok = DeterminBlendObjectsProcessorHit ();
03706
03707
03708 if (ok) ok = DoStartSelOp(TRUE,TRUE);
03709
03710 if (ok) ok = (Tool::GetCurrent() != NULL);
03711 if (ok) pBlobManager->RenderToolBlobsOff(Tool::GetCurrent(), pRefStart->pSpread,NULL);
03712 if (ok) NodeRenderableInk::DeselectAll(FALSE);
03713
03714
03715 if (ok) pNodeBlend->SetSelected(TRUE);
03716
03717
03718 if (ok) ok = DoDeinitBlenders(BlenderList);
03719
03720
03721 if (ok) ok = DoLocaliseCommonAttributes(pNodeBlend);
03722
03723
03724
03725 if (ok && !BlendIsStart) ok = DoMoveNode(pNodeStart,pNodeBlend,FIRSTCHILD);
03726 if (ok && !BlendIsStart) ok = DoDeselectNode(pNodeStart);
03727
03728
03729
03730 if (ok && BlendIsStart) ok = DoMoveNode(pNodeEnd,pNodeBlend,LASTCHILD);
03731 if (ok && BlendIsStart) ok = DoDeselectNode(pNodeEnd);
03732
03733
03734 if (ok) ok = DoCreateBlender(pNodeStart,-1,pNodeEnd,-1,pContextNode,AttachDir);
03735
03736
03737 if (ok) ok = DoFactorOutCommonChildAttributes(pNodeBlend);
03738
03739
03740 if (ok) ok = DoInvalidateNodeRegion(pNodeBlend,TRUE);
03741
03742
03743 if (ok) ok = DoReinitBlenders(BlenderList);
03744
03745
03746 BlenderList.DeleteAll();
03747
03748
03749 GetApplication()->UpdateSelection();
03750
03751 return (ok);
03752 }
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767
03768 BOOL OpBlendNodes::DoDeinitBlenders(List& BlenderList)
03769 {
03770 InitBlendersAction* pAction;
03771 BOOL ok = (InitBlendersAction::Init(this,&UndoActions,&BlenderList,TRUE,&pAction) != AC_FAIL);
03772
03773 if (ok) DeinitBlenders(BlenderList);
03774
03775 return (ok);
03776 }
03777
03778
03779
03780
03781
03782
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792 BOOL OpBlendNodes::DoReinitBlenders(List& BlenderList)
03793 {
03794 InitBlendersAction* pAction;
03795 BOOL ok = (InitBlendersAction::Init(this,&UndoActions,&BlenderList,FALSE,&pAction) != AC_FAIL);
03796
03797 if (ok)
03798 {
03799 ok = ReinitBlenders(BlenderList);
03800 if (!ok) FailAndExecuteAllButLast();
03801 }
03802
03803 return ok;
03804 }
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819 void OpBlendNodes::DeinitBlenders(List& BlenderList)
03820 {
03821 BlenderInfoItem* pItem = (BlenderInfoItem*) BlenderList.GetHead();
03822
03823 while (pItem != NULL)
03824 {
03825 pItem->pNodeBlender->Deinit();
03826 pItem = (BlenderInfoItem*) BlenderList.GetNext(pItem);
03827 }
03828 }
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845 BOOL OpBlendNodes::ReinitBlenders(List& BlenderList)
03846 {
03847 BOOL ok = TRUE;
03848 BlenderInfoItem* pItem = (BlenderInfoItem*) BlenderList.GetHead();
03849
03850 while (pItem != NULL && ok)
03851 {
03852 ok = pItem->pNodeBlender->Reinit(pItem->pNodeStart,pItem->pNodeEnd);
03853 pItem = (BlenderInfoItem*) BlenderList.GetNext(pItem);
03854 }
03855
03856 return (ok);
03857 }
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874 BOOL OpBlendNodes::RecordBlenderInfo(List& BlenderList,NodeBlend* pNodeBlend)
03875 {
03876 ERROR3IF(pNodeBlend == NULL,"pNodeBlend == NULL");
03877 if (pNodeBlend == NULL) return FALSE;
03878
03879 BOOL ok = TRUE;
03880
03881 Node* pNode = pNodeBlend->FindFirstChild();
03882 while (pNode != NULL && ok)
03883 {
03884 if (IS_A(pNode,NodeBlender))
03885 {
03886 NodeBlender* pNodeBlender = (NodeBlender*)pNode;
03887 BlenderInfoItem* pItem = new BlenderInfoItem;
03888 ok = (pItem != NULL);
03889
03890 if (ok)
03891 {
03892 pItem->pNodeBlender = pNodeBlender;
03893 pItem->pNodeStart = pNodeBlender->GetNodeStart();
03894 pItem->pNodeEnd = pNodeBlender->GetNodeEnd();
03895
03896 ok = (pItem->pNodeStart != NULL && pItem->pNodeEnd != NULL);
03897 }
03898
03899 if (ok) BlenderList.AddTail(pItem);
03900 }
03901 pNode = pNode->FindNext();
03902 }
03903
03904 return ok;
03905 }
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920
03921
03922 BOOL OpBlendNodes::DoRemapBlend()
03923 {
03924
03925 OpType = BLENDOPTYPE_REMAP;
03926
03927
03928 ERROR3IF(pRefStart == NULL,"pRefStart == NULL");
03929 ERROR3IF(pRefEnd == NULL,"pRefEnd == NULL");
03930 ERROR3IF(pRefStart->pNode == NULL,"pRefStart->pNode == NULL");
03931 ERROR3IF(pRefEnd ->pNode == NULL,"pRefEnd->pNode == NULL");
03932 ERROR3IF(pRefStart->pNodeBlend == NULL,"pRefStart->pNodeBlend == NULL");
03933 ERROR3IF(pRefEnd ->pNodeBlend == NULL,"pRefEnd->pNodeBlend == NULL");
03934 ERROR3IF(pRefStart->pNodeBlend != pRefEnd->pNodeBlend,"Start and end blend nodes not equal");
03935 ERROR3IF(pRefStart->RemapRef != pRefEnd->RemapRef,"Start and end remap refs not equal");
03936 ERROR3IF(pRefStart->AStartNode == pRefEnd->AStartNode,"Start and end AStartNode vals equal");
03937
03938 BOOL ok = TRUE;
03939 RemapBlendAction* pAction;
03940 NodeBlend* pNodeBlend = pRefStart->pNodeBlend;
03941 UINT32 RemapRef = pRefStart->RemapRef;
03942
03943 DocCoord PosStart = pRefStart->PointerPos;
03944 DocCoord PosEnd = pRefEnd ->PointerPos;
03945
03946 if (!pRefStart->AStartNode)
03947 {
03948
03949 DocCoord Temp = PosStart;
03950 PosStart = PosEnd;
03951 PosEnd = Temp;
03952 }
03953
03954 ObjChangeFlags cFlags;
03955 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,pNodeBlend,this);
03956 ok = pNodeBlend->AllowOp(&ObjChange);
03957
03958 if (ok) ok = DoInvalidateNodeRegion(pRefStart->pNodeBlend,TRUE);
03959
03960 if (ok) ok = RemapBlendAction::Init(this,&UndoActions,
03961 pNodeBlend,RemapRef,PosStart,PosEnd,
03962 &pAction) != AC_FAIL;
03963
03964 if (ok)
03965 {
03966 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,pNodeBlend,this);
03967 UpdateChangedNodes(&ObjChange);
03968 }
03969
03970 return (ok);
03971 }
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985 BOOL OpBlendNodes::RemoveCompoundNodes(CompoundNodeTreeFactoryList * pList)
03986 {
03987
03988
03989
03990
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008 return TRUE;
04009 }
04010
04011
04012
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022
04023
04024
04025
04026
04027 BOOL OpBlendNodes::RemoveCompoundNodesFromNode(Node * pNode, Node ** pRetnNode,
04028 CompoundNodeTreeFactoryList * pList)
04029 {
04030
04031
04032
04033
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044
04045
04046
04047
04048
04049
04050
04051
04052
04053
04054
04055
04056
04057
04058
04059
04060
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106
04107
04108
04109
04110
04111
04112
04113
04114
04115
04116
04117
04118
04119
04120
04121
04122
04123
04124
04125
04126
04127
04128
04129
04130
04131
04132
04133
04134
04135
04136
04137
04138
04139
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168
04169
04170
04171
04172
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184
04185
04186
04187
04188
04189
04190
04191
04192
04193
04194
04195
04196
04197
04198
04199
04200
04201
04202
04203
04204
04205
04206
04207
04208 return TRUE;
04209 }
04210
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230 BOOL OpBlendNodes::DoBlendObjects()
04231 {
04232
04233
04234
04235
04236
04237 OpType = BLENDOPTYPE_NEW;
04238
04239
04240 ERROR3IF_PF(pRefStart == NULL,("pRefStart == NULL"));
04241 ERROR3IF_PF(pRefEnd == NULL,("pRefEnd == NULL"));
04242 ERROR3IF_PF(pRefStart->pNode == NULL,("pRefStart->pNode == NULL"));
04243 ERROR3IF_PF(pRefEnd ->pNode == NULL,("pRefEnd->pNode == NULL"));
04244
04245 BOOL ok = DeterminBlendObjectsProcessorHit ();
04246
04247 if (!ok)
04248 {
04249 return (FALSE);
04250 }
04251
04252 ok = DoStartSelOp(TRUE,TRUE);
04253
04254 CompoundNodeTreeFactoryList CFList;
04255
04256 RemoveCompoundNodes(&CFList);
04257
04258 NodeBlend* pNodeBlend;
04259
04260
04261
04262 Node * pParent = pRefStart->pNode;
04263
04264 while (pParent)
04265 {
04266 if (!pParent->PromoteHitTestOnChildrenToMe() && pParent->IsAnObject())
04267 {
04268 pRefStart->pNode = (NodeRenderableInk *)pParent;
04269 }
04270
04271 pParent = pParent->FindParent();
04272 }
04273
04274 pParent = pRefEnd->pNode;
04275
04276 while (pParent)
04277 {
04278 if (!pParent->PromoteHitTestOnChildrenToMe() && pParent->IsAnObject())
04279 {
04280 pRefEnd->pNode = (NodeRenderableInk *)pParent;
04281 }
04282
04283 pParent = pParent->FindParent();
04284 }
04285
04286 BlobManager* pBlobManager = GetApplication()->GetBlobManager();
04287 ENSURE(pBlobManager, "Can't get BlobManager");
04288
04289 if (ok) ok = (Tool::GetCurrent() != NULL);
04290 if (ok) pBlobManager->RenderToolBlobsOff(Tool::GetCurrent(), pRefStart->pSpread,NULL);
04291 if (ok) NodeRenderableInk::DeselectAll(FALSE,FALSE);
04292
04293 if (ok) ALLOC_WITH_FAIL(pNodeBlend,new NodeBlend,this);
04294 if (ok) ok = (pNodeBlend != NULL);
04295
04296 if (ok) pRefStart->pNode->SetSelected(FALSE);
04297 if (ok) pRefEnd ->pNode->SetSelected(FALSE);
04298
04299 if (ok) ok = DoInsertNewNode(pNodeBlend,pRefEnd->pNode,NEXT,FALSE,FALSE,FALSE,FALSE);
04300 if (ok) ok = DoMoveNode(pRefStart->pNode,pNodeBlend,LASTCHILD);
04301 if (ok) ok = DoMoveNode(pRefEnd ->pNode,pNodeBlend,LASTCHILD);
04302 if (ok) ok = DoCreateBlender(pRefStart->pNode,pRefStart->Index,pRefEnd->pNode,pRefEnd->Index,pRefStart->pNode,NEXT);
04303 if (ok) ok = DoInvalidateNodeRegion(pNodeBlend,TRUE);
04304
04305
04306 if (ok) ok = DoFactorOutCommonChildAttributes(pNodeBlend);
04307
04308
04309 if (ok)
04310 pNodeBlend->SetSelected(TRUE);
04311
04312
04313 GetApplication()->UpdateSelection();
04314
04315 return (ok);
04316 }
04317
04318
04319
04320
04321
04322
04323
04324
04325
04326
04327
04328
04329
04330
04331
04332
04333
04334
04335
04336
04337
04338 BOOL OpBlendNodes::DeterminBlendObjectsProcessorHit ()
04339 {
04340 Node* pStart = pRefStart->pNode;
04341 Node* pEnd = pRefEnd->pNode;
04342
04343 INT32 complexityEstimate1 = pStart->EstimateNodeComplexity (NULL);
04344 INT32 complexityEstimate2 = pEnd->EstimateNodeComplexity (NULL);
04345
04346 INT32 generatedPathsEstimate = 3*complexityEstimate1 + 2*complexityEstimate2;
04347
04348 static BOOL foundCPU = FALSE;
04349 static INT32 pathsBeforeAsk = 0;
04350
04351 if (!foundCPU)
04352 {
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366
04367
04368
04369 {
04370
04371 pathsBeforeAsk = 24000;
04372 }
04373 foundCPU = TRUE;
04374 }
04375
04376 if (generatedPathsEstimate > pathsBeforeAsk)
04377 {
04378
04379 String_256 QueryString(_R(IDS_ASKLONGJOB));
04380
04381
04382 Error::SetError(0, QueryString, 0);
04383 INT32 DlgResult = InformMessage(0, _R(IDS_YES), _R(IDS_NO));
04384 Error::ClearError();
04385
04386 switch (DlgResult)
04387 {
04388 case 1:
04389 return (TRUE);
04390 break;
04391 case 2:
04392 return (FALSE);
04393 }
04394 }
04395
04396 return (TRUE);
04397 }
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421 BOOL OpBlendNodes::DoCreateBlender( NodeRenderableInk* pNodeStart,INT32 PathIndexStart,
04422 NodeRenderableInk* pNodeEnd, INT32 PathIndexEnd,
04423 Node* pContextNode, AttachNodeDirection AttachDir)
04424 {
04425 ERROR2IF(pNodeStart == NULL,FALSE,"pNodeStart is NULL");
04426 ERROR2IF(pNodeEnd == NULL,FALSE,"pNodeEnd is NULL");
04427
04428
04429
04430 BecomeA TestStart(BECOMEA_TEST, CC_RUNTIME_CLASS(NodePath));
04431 BecomeA TestEnd(BECOMEA_TEST, CC_RUNTIME_CLASS(NodePath));
04432 TestStart.ResetCount();
04433 TestEnd.ResetCount();
04434 pNodeStart->CanBecomeA(&TestStart);
04435 pNodeEnd ->CanBecomeA(&TestEnd);
04436
04437
04438 Progress Hourglass(_R(IDS_BLENDING), INT32(TestStart.GetCount() + TestEnd.GetCount()) );
04439
04440 BOOL ok = FALSE;
04441 NodeBlender* pNodeBlender;
04442
04443 ALLOC_WITH_FAIL(pNodeBlender,new NodeBlender,this);
04444 ok = (pNodeBlender != NULL);
04445
04446
04447 if (PathIndexStart < 0 || PathIndexEnd < 0)
04448 PathIndexStart = PathIndexEnd = -1;
04449
04450 if (ok) ok = DoInsertNewNode(pNodeBlender,pContextNode,AttachDir,FALSE,FALSE,FALSE,FALSE);
04451 if (ok) ok = pNodeBlender->Initialise(pNodeStart,pNodeEnd,PathIndexStart,PathIndexEnd,this,&Hourglass,FALSE);
04452
04453 pRefStart->pNode = pNodeStart;
04454 pRefEnd->pNode = pNodeEnd;
04455 return (ok);
04456 }
04457
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468
04469
04470
04471
04472
04473
04474 void OpBlendNodes::RenderMyDragBlobs()
04475 {
04476 INT32 x0 = pRefStart->PointerPos.x;
04477 INT32 y0 = pRefStart->PointerPos.y;
04478 INT32 x1 = pRefEnd ->PointerPos.x;
04479 INT32 y1 = pRefEnd ->PointerPos.y;
04480
04481 DocRect Rect = DocRect( min(x0,x1),min(y0,y1),max(x0,x1),max(y0,y1));
04482
04483 RenderDragBlobs(Rect, pRefStart->pSpread, FALSE);
04484 }
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500 void OpBlendNodes::RenderDragBlobs(DocRect Rect,Spread* pSpread, BOOL bSolidDrag)
04501 {
04502 if (pRefStart->PointerPos == pRefEnd->PointerPos)
04503 return;
04504
04505
04506 FIXED16 ScaledPixelWidth,
04507 ScaledPixelHeight;
04508 GetWorkingView()->GetScaledPixelSize(&ScaledPixelWidth, &ScaledPixelHeight);
04509
04510 MILLIPOINT LineWidth = ScaledPixelWidth.MakeLong()*2;
04511 StockColour Colour = COLOUR_BLACK;
04512
04513 if (pRefStart->RemapRef == pRefEnd->RemapRef && pRefStart->RemapRef > 0 &&
04514 pRefStart->AStartNode != pRefEnd->AStartNode)
04515 {
04516 Colour = COLOUR_RED;
04517 LineWidth += LineWidth;
04518 }
04519 else if ((pRefStart->pNode != NULL) &&
04520 (pRefEnd ->pNode != NULL) &&
04521 (pRefStart->pNode != pRefEnd->pNode) &&
04522 (pRefStart->Index >= 0) &&
04523 (pRefEnd ->Index >= 0))
04524 {
04525 Colour = COLOUR_RED;
04526 LineWidth += LineWidth;
04527 }
04528
04529
04530 Rect.Inflate(LineWidth);
04531
04532 RenderRegion* pRegion = DocView::RenderOnTop( &Rect, pSpread, UnclippedEOR );
04533
04534 while ( pRegion != NULL )
04535 {
04536
04537 pRegion->SetLineColour(Colour);
04538
04539
04540 pRegion->SetLineWidth(LineWidth);
04541 pRegion->DrawLine(pRefStart->PointerPos,pRefEnd->PointerPos);
04542
04543
04544 pRegion = DocView::GetNextOnTop( &Rect );
04545 }
04546 }
04547
04548
04549
04550
04551
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561 BOOL OpBlendNodes::Declare()
04562 {
04563 return (RegisterOpDescriptor(
04564 0,
04565 _R(IDS_BLEND_TOOL),
04566 CC_RUNTIME_CLASS(OpBlendNodes),
04567 OPTOKEN_BLENDNODES,
04568 OpBlendNodes::GetState,
04569 0,
04570 _R(IDBBL_NOOP),
04571 0
04572 ));
04573 }
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583
04584
04585
04586
04587
04588
04589
04590 OpState OpBlendNodes::GetState(String_256* Description, OpDescriptor*)
04591 {
04592 OpState State;
04593
04594 return State;
04595 }
04596
04597
04598
04599
04600
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610
04611
04612
04613 void OpBlendNodes::GetOpName(String_256* OpName)
04614 {
04615 switch (OpType)
04616 {
04617 case BLENDOPTYPE_NEW:
04618 case BLENDOPTYPE_BLENDANDOBJECT:
04619 case BLENDOPTYPE_BLENDANDBLEND:
04620 *OpName = String_256(_R(IDS_BLEND_UNDO));
04621 break;
04622
04623 case BLENDOPTYPE_REMAP:
04624 *OpName = String_256(_R(IDS_REMAP_UNDO));
04625 break;
04626
04627 default:
04628 break;
04629 }
04630 }
04631
04632
04633
04634
04635
04636
04637
04638
04639
04640
04641
04642
04643
04644
04645
04646
04647 BOOL OpBlendNodes::Undo()
04648 {
04649
04650 switch (OpType)
04651 {
04652 case BLENDOPTYPE_NEW:
04653 case BLENDOPTYPE_BLENDANDBLEND:
04654 case BLENDOPTYPE_REMAP:
04655 case BLENDOPTYPE_BLENDANDOBJECT:
04656 case BLENDOPTYPE_BLENDBLENDONPATH:
04657 break;
04658 default:
04659 ERROR3_PF(("Unknown blend OpType (%d)",OpType));
04660 break;
04661 }
04662
04663
04664 SelOperation::Undo();
04665
04666
04667 switch (OpType)
04668 {
04669 case BLENDOPTYPE_NEW:
04670 case BLENDOPTYPE_REMAP:
04671 break;
04672
04673 case BLENDOPTYPE_BLENDANDBLEND:
04674
04675
04676
04677
04678
04679
04680
04681
04682 break;
04683
04684 case BLENDOPTYPE_BLENDANDOBJECT:
04685
04686
04687
04688
04689
04690
04691 break;
04692
04693 default:
04694 break;
04695 }
04696
04697 return TRUE;
04698 }
04699
04700
04701
04702
04703
04704
04705
04706
04707
04708
04709
04710
04711
04712
04713
04714
04715 BOOL OpBlendNodes::Redo()
04716 {
04717
04718 switch (OpType)
04719 {
04720 case BLENDOPTYPE_NEW:
04721 case BLENDOPTYPE_BLENDANDBLEND:
04722 case BLENDOPTYPE_REMAP:
04723 case BLENDOPTYPE_BLENDANDOBJECT:
04724 case BLENDOPTYPE_BLENDBLENDONPATH:
04725 break;
04726 default:
04727 ERROR3_PF(("Unknown blend OpType (%d)",OpType));
04728 break;
04729 }
04730 SelRange* pSel = GetApplication()->FindSelection();
04731 pSel->FindFirst();
04732
04733
04734 SelOperation::Redo();
04735
04736
04737 switch (OpType)
04738 {
04739 case BLENDOPTYPE_NEW:
04740 case BLENDOPTYPE_REMAP:
04741 break;
04742
04743 case BLENDOPTYPE_BLENDANDBLEND:
04744
04745
04746
04747
04748
04749
04750 break;
04751
04752 case BLENDOPTYPE_BLENDANDOBJECT:
04753
04754
04755
04756
04757
04758
04759 break;
04760
04761 default:
04762 break;
04763 }
04764
04765 return TRUE;
04766 }
04767
04768
04769
04770
04771
04772
04773
04774
04775
04776
04777
04778
04779
04780
04781
04782
04783 BOOL OpBlendNodes::GetNodeClosestToPoint(NodeRenderableInk** ppInk, BOOL StartBlend)
04784 {
04785
04786
04787
04788 DocCoord Point;
04789
04790
04791
04792 NodeBlend* pBlend = NULL;
04793
04794 if (StartBlend)
04795 {
04796 Point = pRefStart->PointerPos;
04797
04798 pBlend = pNodeBlendStart;
04799 }
04800 else
04801 {
04802 Point = pRefEnd->PointerPos;
04803
04804 pBlend = pNodeBlendEnd;
04805 }
04806
04807
04808 double ClosestDistance = 9999999999999.9;
04809 Node* pClosestNode = NULL;
04810 Node* pNode = pBlend->FindFirstChild();
04811 while (pNode != NULL)
04812 {
04813
04814
04815 if (pNode->IS_KIND_OF(NodeRenderableInk) &&
04816 (!pNode->IS_KIND_OF(NodeBlender)) &&
04817 (!pNode->IS_KIND_OF(NodeBlendPath)))
04818 {
04819 DocRect Rect = ((NodeRenderableInk*)pNode)->GetBoundingRect();
04820 Coord Centre = (Coord)(Rect.Centre());
04821 double Distance = Point.Distance(Centre);
04822
04823 if (Distance < ClosestDistance)
04824 {
04825 pClosestNode = pNode;
04826 ClosestDistance = Distance;
04827 }
04828 }
04829 pNode = pNode->FindNext();
04830 }
04831 if (pClosestNode != NULL)
04832 {
04833 *ppInk = (NodeRenderableInk*)pClosestNode;
04834 return TRUE;
04835 }
04836 else
04837 {
04838 ERROR3("Couldn't find a node close to point");
04839 return FALSE;
04840 }
04841 }
04842
04843
04844
04845
04846
04847
04848
04849
04850
04851
04852
04853
04854
04855
04856
04857
04858
04859
04860
04861
04862
04863
04864
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878 class BlendPathBecomeA : public BecomeA
04879 {
04880 public:
04881 BlendPathBecomeA(UndoableOperation* pOp) : BecomeA(BECOMEA_PASSBACK,CC_RUNTIME_CLASS(NodePath),pOp)
04882 {
04883 m_pNodePath = NULL;
04884 m_pAttrMap = NULL;
04885 }
04886
04887 ~BlendPathBecomeA()
04888 {
04889 if (m_pNodePath != NULL)
04890 delete m_pNodePath;
04891
04892 if (m_pAttrMap != NULL)
04893 {
04894 m_pAttrMap->DeleteAttributes();
04895 delete m_pAttrMap;
04896 }
04897 }
04898
04899 virtual BOOL PassBack(NodeRenderableInk* pNewNode,NodeRenderableInk* pCreatedByNode,CCAttrMap* pAttrMap=NULL)
04900 {
04901 ERROR2IF(pCreatedByNode == NULL,FALSE,"pCreatedByNode == NULL");
04902 ERROR2IF(pNewNode == NULL,FALSE,"pNewNode == NULL");
04903 ERROR2IF(!pNewNode->IsKindOf(CC_RUNTIME_CLASS(NodePath)),FALSE,"pNewNode not a kind of NodePath");
04904
04905 BOOL ok = FALSE;
04906 if (m_pNodePath == NULL)
04907 {
04908 m_pNodePath = new NodePath;
04909 if (m_pNodePath)
04910 {
04911 if (!m_pNodePath->SetUpPath())
04912 {
04913 delete m_pNodePath;
04914 m_pNodePath = NULL;
04915 }
04916
04917 }
04918 }
04919
04920 if (m_pNodePath)
04921 {
04922 Path& PassedPath = ((NodePath*)pNewNode)->InkPath;
04923 INT32 Len = PassedPath.GetNumCoords();
04924
04925 ok = m_pNodePath->InkPath.MakeSpaceInPath(Len);
04926 if (ok) ok = m_pNodePath->InkPath.MergeTwoPaths(PassedPath);
04927 }
04928
04929 if (m_pAttrMap == NULL)
04930 {
04931 if (pAttrMap == NULL)
04932 {
04933 CCAttrMap* pTempAttrMap = CCAttrMap::MakeAppliedAttrMap(pCreatedByNode);
04934 if (pTempAttrMap)
04935 {
04936 m_pAttrMap = pTempAttrMap->Copy();
04937 delete pTempAttrMap;
04938 }
04939 }
04940 else
04941 m_pAttrMap = pAttrMap;
04942 }
04943 else
04944 {
04945 if (pAttrMap != NULL)
04946 {
04947 pAttrMap->DeleteAttributes();
04948 delete pAttrMap;
04949 pAttrMap = NULL;
04950 }
04951 }
04952
04953 if (pNewNode)
04954 {
04955 pNewNode->CascadeDelete();
04956 delete pNewNode;
04957 pNewNode = NULL;
04958 }
04959
04960 return ok;
04961 }
04962
04963 NodePath* GetNodePath() { return m_pNodePath; }
04964 CCAttrMap* GetAttrMap() { return m_pAttrMap; }
04965
04966 private:
04967 NodePath* m_pNodePath;
04968 CCAttrMap* m_pAttrMap;
04969 };
04970
04971
04973
04974
04975
04976
04977
04978
04979
04980
04981
04982
04983
04984
04985
04986
04987
04988
04989
04990
04991 void OpAddBlendPath::Do(OpDescriptor*)
04992 {
04993 SelRange* pSel = GetApplication()->FindSelection();
04994
04995 BOOL ok = (pSel != NULL);
04996
04997
04998 if (ok) ok = DoStartSelOp(FALSE,FALSE);
04999
05000
05001
05002
05003 BOOL BlendPathOnTop = FALSE;
05004 if (ok)
05005 BlendPathOnTop = IsBlendPathOnTopOfBlend(pSel);
05006
05007 if (ok)
05008 {
05009
05010
05011 ObjChangeFlags cFlags;
05012 cFlags.DeleteNode = TRUE;
05013 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
05014
05015 BlendPathBecomeA BPBecomeA(this);
05016 BecomeA TestPathBecomeA(BECOMEA_TEST, CC_RUNTIME_CLASS(NodePath));
05017
05018 Node* pSelNode = pSel->FindFirst();
05019 while (pSelNode != NULL && ok)
05020 {
05021 Node* pNode = pSelNode;
05022 pSelNode = pSel->FindNext(pSelNode);
05023
05024 if (!pNode->IS_KIND_OF(NodeBlend) && pNode->IsAnObject() && pNode->CanBecomeA(&TestPathBecomeA))
05025 {
05026
05027 ok = pNode->AllowOp(&ObjChange);
05028 if (ok) ok = pNode->DoBecomeA(&BPBecomeA);
05029 if (ok) ok = DoInvalidateNodeRegion((NodeRenderableInk*)pNode,TRUE,FALSE);
05030 if (ok) ok = DoHideNode(pNode,TRUE);
05031 }
05032 }
05033
05034
05035
05036 ObjChangeFlags cBlendFlags;
05037 cBlendFlags.Attribute = TRUE;
05038 ObjChangeParam BlendChange(OBJCHANGE_STARTING,cBlendFlags,NULL,this);
05039
05040 NodePath* pBlendPath = BPBecomeA.GetNodePath();
05041 CCAttrMap* pAttrMap = BPBecomeA.GetAttrMap();
05042
05043 if (ok) ok = (pBlendPath != NULL);
05044
05045 pSelNode = pSel->FindFirst();
05046 while (pSelNode != NULL && ok)
05047 {
05048 Node* pNode = pSelNode;
05049 pSelNode = pSel->FindNext(pSelNode);
05050
05051 if (pNode->IS_KIND_OF(NodeBlend))
05052 {
05053 NodeBlend* pNodeBlend = (NodeBlend*)pNode;
05054
05055
05056 ok = pNodeBlend->AllowOp(&BlendChange);
05057 if (ok) ok = pNodeBlend->BlendAlongThisPath(pBlendPath,pAttrMap,this, BlendPathOnTop);
05058 if (ok) ok = DoInvalidateNodeRegion(pNodeBlend,TRUE);
05059 if (ok)
05060 {
05061
05062 ChangeBlendAction* pAction;
05063 ChangeBlendOpParam ChangeParam;
05064 ChangeParam.ChangeType = CHANGEBLEND_BLENDONPATH;
05065 ChangeParam.NewBlendedOnCurve = TRUE;
05066 ok = ChangeBlendAction::Init(this,&UndoActions,pNodeBlend,&ChangeParam,&pAction) != AC_FAIL;
05067 }
05068
05069 pNodeBlend->UpdateStepDistance();
05070 }
05071 }
05072
05073 if (ok)
05074 {
05075
05076 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
05077 UpdateChangedNodes(&ObjChange);
05078 }
05079 }
05080
05081 if (ok)
05082 {
05083 pSel->Update();
05084
05085 }
05086 else
05087 FailAndExecute();
05088
05089 End();
05090 }
05091
05092
05093
05094
05095
05096
05097
05098
05099
05100
05101
05102
05103 BOOL OpAddBlendPath::Declare()
05104 {
05105 return (RegisterOpDescriptor(
05106 0,
05107 _R(IDS_ADDBLENDPATH),
05108 CC_RUNTIME_CLASS(OpAddBlendPath),
05109 OPTOKEN_ADDBLENDPATH,
05110 OpAddBlendPath::GetState,
05111 0,
05112 _R(IDBBL_ADDBLENDPATH),
05113 0
05114 ));
05115 }
05116
05117
05118
05119
05120
05121
05122
05123
05124
05125
05126
05127
05128
05129
05130
05131
05132 OpState OpAddBlendPath::GetState(String_256* Description, OpDescriptor*)
05133 {
05134 OpState State(FALSE,TRUE);
05135
05136
05137
05138 ObjChangeFlags cFlags;
05139 cFlags.MultiReplaceNode = TRUE;
05140 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL);
05141
05142 BOOL Denied = FALSE;
05143 SelRange* pSel = GetApplication()->FindSelection();
05144
05145 if (pSel != NULL)
05146 {
05147 Node* pNode = pSel->FindFirst();
05148 while (pNode != NULL && State.Greyed)
05149 {
05150 if (IS_A(pNode,NodeBlend))
05151 {
05152
05153 if (pNode->AllowOp(&ObjChange,FALSE))
05154 State.Greyed = FALSE;
05155 else
05156 Denied = TRUE;
05157 }
05158 pNode = pSel->FindNext(pNode);
05159 }
05160 }
05161
05162 UINT32 IDS = 0;
05163 if (State.Greyed)
05164 {
05165
05166 if (Denied)
05167 IDS = ObjChange.GetReasonForDenial();
05168 else
05169 IDS = _R(IDS_ADDBLENDPATH_GREYED);
05170 }
05171
05172
05173 if (IDS == 0)
05174 IDS = _R(IDS_ADDBLENDPATH);
05175
05176 *Description = String_256(IDS);
05177
05178 return State;
05179 }
05180
05181
05182
05183
05184
05185
05186
05187
05188
05189
05190
05191
05192
05193
05194
05195
05196
05197 void OpAddBlendPath::GetOpName(String_256* OpName)
05198 {
05199 *OpName = String_256(_R(IDS_ADDBLENDPATH_UNDO));
05200 }
05201
05202
05203
05204
05205
05206
05207
05208
05209 void OpDetachBlendPath::Do(OpDescriptor*)
05210 {
05211 SelRange* pSel = GetApplication()->FindSelection();
05212
05213 BOOL ok = (pSel != NULL);
05214
05215 if (ok) ok = DoStartSelOp(FALSE,FALSE);
05216
05217 if (ok)
05218 {
05219
05220
05221 ObjChangeFlags cBlendFlags;
05222 cBlendFlags.Attribute = TRUE;
05223 ObjChangeParam BlendChange(OBJCHANGE_STARTING,cBlendFlags,NULL,this);
05224
05225 Node* pSelNode = pSel->FindFirst();
05226 while (pSelNode != NULL && ok)
05227 {
05228 if (pSelNode->IS_KIND_OF(NodeBlend))
05229 {
05230 NodeBlend* pNodeBlend = (NodeBlend*)pSelNode;
05231
05232 ok = pNodeBlend->AllowOp(&BlendChange);
05233 if (ok) ok = pNodeBlend->DetachNodeBlendPath(pNodeBlend,NEXT,this);
05234 if (ok) ok = DoInvalidateNodeRegion(pNodeBlend,TRUE);
05235 if (ok) ok = pNodeBlend->RotateBlendEndObjectsBack(this);
05236 if (ok)
05237 {
05238
05239 ChangeBlendAction* pAction;
05240 ChangeBlendOpParam ChangeParam;
05241 ChangeParam.ChangeType = CHANGEBLEND_BLENDONPATH;
05242 ChangeParam.NewBlendedOnCurve = FALSE;
05243 ok = ChangeBlendAction::Init(this,&UndoActions,pNodeBlend,&ChangeParam,&pAction) != AC_FAIL;
05244 }
05245 if (ok) ok = DoInvalidateNodeRegion(pNodeBlend,TRUE);
05246 }
05247 pSelNode = pSel->FindNext(pSelNode);
05248 }
05249
05250 if (ok)
05251 {
05252
05253 BlendChange.Define(OBJCHANGE_FINISHED,cBlendFlags,NULL,this);
05254 UpdateChangedNodes(&BlendChange);
05255 }
05256 }
05257
05258 if (ok)
05259 {
05260 pSel->Update();
05261
05262 GetApplication()->GetBlobManager();
05263 }
05264 else
05265 FailAndExecute();
05266
05267 End();
05268 }
05269
05270
05271
05272
05273
05274
05275
05276
05277
05278
05279
05280 BOOL OpAddBlendPath::IsBlendPathOnTopOfBlend(SelRange* pSel)
05281 {
05282 Node* pNode = pSel->FindFirst();
05283
05284 while (pNode != NULL)
05285 {
05286 if (pNode->IS_KIND_OF(NodeBlend))
05287 return TRUE;
05288 else if (pNode->IS_KIND_OF(NodePath))
05289 return FALSE;
05290
05291 pNode = pSel->FindNext(pNode);
05292 }
05293
05294
05295
05296
05297 return TRUE;
05298 }
05299
05300
05301
05302
05303
05304
05305
05306
05307
05308
05309
05310
05311
05312 BOOL OpDetachBlendPath::Declare()
05313 {
05314 return (RegisterOpDescriptor(
05315 0,
05316 _R(IDS_DETACHBLENDPATH),
05317 CC_RUNTIME_CLASS(OpDetachBlendPath),
05318 OPTOKEN_DETACHBLENDPATH,
05319 OpDetachBlendPath::GetState,
05320 0,
05321 _R(IDBBL_DETACHBLENDPATH),
05322 0
05323 ));
05324 }
05325
05326
05327
05328
05329
05330
05331
05332
05333
05334
05335
05336
05337
05338
05339
05340
05341 OpState OpDetachBlendPath::GetState(String_256* Description, OpDescriptor*)
05342 {
05343 OpState State(FALSE,TRUE);
05344
05345
05346
05347 ObjChangeFlags cFlags;
05348 cFlags.Attribute = TRUE;
05349 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL);
05350
05351 BOOL Denied = FALSE;
05352 SelRange* pSel = GetApplication()->FindSelection();
05353
05354 if (pSel != NULL)
05355 {
05356 Node* pNode = pSel->FindFirst();
05357 while (pNode != NULL && State.Greyed)
05358 {
05359 if (IS_A(pNode,NodeBlend))
05360 {
05361
05362 if (pNode->AllowOp(&ObjChange,FALSE))
05363 State.Greyed = FALSE;
05364 else
05365 Denied = TRUE;
05366 }
05367 pNode = pSel->FindNext(pNode);
05368 }
05369 }
05370
05371 UINT32 IDS = 0;
05372 if (State.Greyed)
05373 {
05374
05375 if (Denied)
05376 IDS = ObjChange.GetReasonForDenial();
05377 else
05378 IDS = _R(IDS_DETACHBLENDPATH_GREYED);
05379 }
05380
05381
05382 if (IDS == 0)
05383 IDS = _R(IDS_DETACHBLENDPATH);
05384
05385 *Description = String_256(IDS);
05386
05387 return State;
05388 }
05389
05390
05391
05392
05393
05394
05395
05396
05397
05398
05399
05400
05401
05402
05403
05404
05405
05406 void OpDetachBlendPath::GetOpName(String_256* OpName)
05407 {
05408 *OpName = String_256(_R(IDS_DETACHBLENDPATH_UNDO));
05409 }
05410
05411
05413
05414
05415
05416
05417
05418
05419
05420
05421
05422
05423
05424
05425
05426
05427
05428
05429
05430
05431
05432
05433
05434
05435
05436
05437 void OpRemoveBlend::Do(OpDescriptor*)
05438 {
05439 SelRange* pSel = GetApplication()->FindSelection();
05440
05441 BOOL ok = (pSel != NULL);
05442
05443 if (ok) ok = DoStartSelOp(FALSE,FALSE);
05444 List BlendList;
05445 if (ok) ok = BevelTools::BuildListOfSelectedNodes(&BlendList, CC_RUNTIME_CLASS(NodeBlend), FALSE);
05446
05447
05448 if (ok)
05449 {
05450
05451
05452 ObjChangeFlags cFlags;
05453 cFlags.MultiReplaceNode = TRUE;
05454 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
05455
05456 NodeListItem* pListItem = (NodeListItem*)BlendList.GetHead();
05457
05458
05459 while (pListItem != NULL)
05460 {
05461
05462 NodeBlend* pNodeBlend = (NodeBlend*)pListItem->pNode;
05463
05464
05465
05466
05467
05468
05469
05470 NodeHidden* pNodeHidden;
05471
05472
05473
05474
05475
05476 pNodeBlend->ReleaseCached(TRUE, FALSE, FALSE, TRUE);
05477
05478
05479 ok = pNodeBlend->AllowOp(&ObjChange);
05480
05481 if(!ok)
05482 {
05483 UINT32 IDS = ObjChange.GetReasonForDenial();
05484
05485 if (IDS == _R(IDS_CANT_REMOVE_BLEND_WHEN_BEVELLED) ||
05486 IDS == _R(IDS_CANT_REMOVE_BLEND_WHEN_CONTOURED) )
05487 InformWarning(IDS);
05488 }
05489
05490 DocRect BRect = pNodeBlend->GetBoundingRect();
05491 Spread* pSpread = Document::GetSelectedSpread();
05492
05493 if (ok) ok = DoInvalidateRegion(pSpread, BRect);
05494
05495 if (ok) ok = DoInvalidateNodeRegion(pNodeBlend,TRUE,FALSE);
05496
05497 if (ok) ok = pNodeBlend->RotateBlendEndObjectsBack(this);
05498
05499
05500 BRect = pNodeBlend->GetBoundingRect();
05501 if (ok) ok = DoInvalidateRegion(pSpread, BRect);
05502
05503 if (ok) ok = DoLocaliseCommonAttributes(pNodeBlend);
05504
05505
05506 if (ok) ok = DoHideNode(pNodeBlend,TRUE,&pNodeHidden,FALSE);
05507 if (ok) pNodeBlend->SetSelected(FALSE);
05508
05509 if (ok)
05510 {
05511
05512 NodeBlender* pBlender = pNodeBlend->FindFirstBlender();
05513 while (pBlender != NULL)
05514 {
05515
05516 ChangeBlenderOpParam Param;
05517 Param.m_NewNodeBlendPathIndex = (-1);
05518 Param.m_ChangeType = CHANGEBLENDER_NBPINDEX;
05519 ok = ChangeBlenderAction::Init(this, &UndoActions, pBlender, Param);
05520
05521 pBlender = pNodeBlend->FindNextBlender(pBlender);
05522 }
05523 }
05524
05525
05526 Node* pNode = pNodeBlend->FindFirstChild();
05527 while (pNode != NULL && ok)
05528 {
05529 Node* pNext = pNode->FindNext();
05530
05531 if (pNode->IsAnObject())
05532 {
05533 NodeRenderableInk* pInkNode = (NodeRenderableInk*)pNode;
05534 if (pInkNode->IS_KIND_OF(NodeBlendPath))
05535 ok = pNodeBlend->DetachNodeBlendPath(pNodeHidden,PREV,this);
05536 else if (!pInkNode->IS_KIND_OF(NodeBlender))
05537 {
05538 ok = DoMoveNode(pInkNode,pNodeHidden,PREV);
05539 if (ok) DoSelectNode(pInkNode);
05540 }
05541 }
05542 pNode = pNext;
05543 }
05544
05545 pListItem = (NodeListItem*)BlendList.GetNext(pListItem);
05546 }
05547 BlendList.DeleteAll();
05548
05549
05550 if (ok)
05551 {
05552
05553 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,NULL,this);
05554 UpdateChangedNodes(&ObjChange);
05555 }
05556
05557
05558 if (ok)
05559 pSel->Update();
05560 else
05561 FailAndExecute();
05562
05563 End();
05564 }
05565 }
05566
05567
05568
05569
05570
05571
05572
05573
05574
05575
05576
05577
05578 BOOL OpRemoveBlend::Declare()
05579 {
05580 return (RegisterOpDescriptor(
05581 0,
05582 _R(IDS_REMOVEBLEND),
05583 CC_RUNTIME_CLASS(OpRemoveBlend),
05584 OPTOKEN_REMOVEBLEND,
05585 OpRemoveBlend::GetState,
05586 0,
05587 _R(IDBBL_REMOVEBLEND),
05588 0
05589 ));
05590 }
05591
05592
05593
05594
05595
05596
05597
05598
05599
05600
05601
05602
05603
05604
05605
05606
05607 OpState OpRemoveBlend::GetState(String_256* Description, OpDescriptor*)
05608 {
05609 OpState State(FALSE,TRUE);
05610
05611
05612
05613 ObjChangeFlags cFlags;
05614 cFlags.MultiReplaceNode = TRUE;
05615 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL);
05616
05617 BOOL Denied = FALSE;
05618 List BlendList;
05619 BOOL ok = BevelTools::BuildListOfSelectedNodes(&BlendList, CC_RUNTIME_CLASS(NodeBlend), FALSE);
05620 if (ok)
05621 {
05622 NodeListItem* pListItem = (NodeListItem*)BlendList.GetHead();
05623
05624 while (pListItem != NULL)
05625 {
05626
05627 NodeBlend* pNodeBlend = (NodeBlend*)pListItem->pNode;
05628
05629 if (pNodeBlend->AllowOp(&ObjChange,FALSE))
05630 State.Greyed = FALSE;
05631 else
05632 Denied = TRUE;
05633
05634 pListItem = (NodeListItem*)BlendList.GetNext(pListItem);
05635 }
05636 }
05637
05638 BlendList.DeleteAll();
05639
05640
05641
05642
05643
05644
05645
05646
05647
05648
05649
05650
05651
05652
05653
05654
05655
05656
05657
05658
05659
05660
05661
05662
05663
05664
05665
05666
05667
05668
05669 UINT32 IDS = 0;
05670 if (State.Greyed)
05671 {
05672
05673 if (Denied)
05674 IDS = ObjChange.GetReasonForDenial();
05675 else
05676 IDS = _R(IDS_REMOVEBLEND_GREYED);
05677 }
05678
05679
05680 if (IDS == 0)
05681 IDS = _R(IDS_REMOVEBLEND);
05682
05683 *Description = String_256(IDS);
05684
05685 return State;
05686 }
05687
05688
05689
05690
05691
05692
05693
05694
05695
05696
05697
05698
05699
05700
05701
05702
05703
05704 void OpRemoveBlend::GetOpName(String_256* OpName)
05705 {
05706 *OpName = String_256(_R(IDS_REMOVEBLEND_UNDO));
05707 }
05708
05709
05710
05712
05713
05714
05715
05716
05717
05718
05719
05720
05721
05722
05723
05724
05725
05726
05727
05728 void OpChangeBlendSteps::DoWithParam(OpDescriptor*,OpParam* pOpParam)
05729 {
05730 ERROR3IF(pOpParam == NULL,"NULL OpParam ptr");
05731 if (pOpParam == NULL) return;
05732
05733 List NodeList;
05734 BevelTools::BuildListOfSelectedNodes(&NodeList, CC_RUNTIME_CLASS(NodeRenderableInk));
05735
05736 NodeListItem *pItem = NULL;
05737
05738 BOOL ok = !NodeList.IsEmpty();
05739
05740 ok = DeterminBlendObjectsProcessorHit (pOpParam, &NodeList);
05741
05742 if (ok) ok = DoStartSelOp(FALSE,FALSE);
05743
05744 if (ok)
05745 {
05746
05747 UINT32 NewNumSteps = UINT32(pOpParam->Param1);
05748 pItem = (NodeListItem *)NodeList.GetHead();
05749
05750 Node* pSelNode = NULL;
05751
05752 if (pItem)
05753 {
05754 pSelNode = pItem->pNode;
05755 }
05756
05757 while (pSelNode != NULL && ok)
05758 {
05759 Node* pNode = pSelNode;
05760
05761 pItem = (NodeListItem *)NodeList.GetNext(pItem);
05762
05763 if (pItem)
05764 {
05765 pSelNode = pItem->pNode;
05766 }
05767 else
05768 {
05769 pSelNode = NULL;
05770 }
05771
05772 if (pNode->IS_KIND_OF(NodeBlend))
05773 {
05774
05775
05776
05777
05778
05779
05780 BOOL bBlend = FALSE;
05781
05782 if (pNode->IS_KIND_OF(NodeBlend))
05783 {
05784 bBlend = TRUE;
05785 }
05786
05787
05788
05789 NodeRenderableInk * pInk = (NodeRenderableInk *)pNode;
05790
05791 UINT32 NumSteps = 0;
05792 double DistanceEntered = 0.0;
05793 if (bBlend)
05794 {
05795 NumSteps = ((NodeBlend *)pNode)->GetNumBlendSteps();
05796 DistanceEntered = ((NodeBlend *)pNode)->GetDistanceEntered();
05797 }
05798
05799 ChangeBlendStepsAction* pAction;
05800
05801
05802 ObjChangeFlags cFlags;
05803 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
05804 ok = pInk->AllowOp(&ObjChange);
05805
05806 if (ok) ok = DoInvalidateNodeRegion(pInk,TRUE,FALSE);
05807 if (ok) ok = (InvalidateBoundsAction::Init(this,&UndoActions,pInk,TRUE) != AC_FAIL);
05808 if (ok) ok = ChangeBlendStepsAction::Init(this,&UndoActions,pInk,NumSteps, DistanceEntered, &pAction) != AC_FAIL;
05809
05810
05811 if (ok)
05812 {
05813 if (bBlend)
05814 {
05815 ((NodeBlend *)pNode)->SetNumBlendSteps(NewNumSteps);
05816
05817
05818 ((NodeBlend *)pNode)->UpdateStepDistance();
05819 }
05820
05821 }
05822
05823 if (ok) ok = DoInvalidateNodeRegion(pInk,TRUE,FALSE);
05824 if (ok) ok = (InvalidateBoundsAction::Init(this,&UndoActions,pInk,TRUE) != AC_FAIL);
05825 }
05826 }
05827 }
05828
05829 NodeList.DeleteAll();
05830
05831 if (ok)
05832 {
05833
05834 ObjChangeFlags cFlags;
05835 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,cFlags,NULL,this);
05836 UpdateChangedNodes(&ObjChange);
05837 }
05838 else
05839 FailAndExecute();
05840
05841 End();
05842 }
05843
05844 BOOL OpChangeBlendSteps::DeterminBlendObjectsProcessorHit (OpParam* pOpParam, List* NodeList)
05845 {
05846 NodeListItem *pItem = NULL;
05847 INT32 total = 0;
05848
05849
05850 INT32 NewNumSteps = UINT32(pOpParam->Param1);
05851 pItem = (NodeListItem *)NodeList->GetHead();
05852
05853 OpParam pParam( NewNumSteps, INT32(0) );
05854
05855 Node* pSelNode = NULL;
05856
05857 if (pItem)
05858 {
05859 pSelNode = pItem->pNode;
05860 }
05861
05862 while (pSelNode != NULL)
05863 {
05864 Node* pNode = pSelNode;
05865
05866 pItem = (NodeListItem *)NodeList->GetNext(pItem);
05867
05868 if (pItem)
05869 {
05870 pSelNode = pItem->pNode;
05871 }
05872 else
05873 {
05874 pSelNode = NULL;
05875 }
05876
05877 if (pNode->IS_KIND_OF(NodeBlend))
05878 {
05879
05880
05881
05882 NodeBlend* pBlend = (NodeBlend*) pNode;
05883 Node* start = NULL, *end = NULL;
05884
05885 pBlend->GetStartAndEndNodes (&start, &end);
05886
05887 if ((start != NULL) && (end != NULL))
05888 {
05889 total += pNode->EstimateNodeComplexity ( &pParam );
05890 }
05891 else
05892 {
05893 return (FALSE);
05894 }
05895 }
05896 }
05897
05898 static BOOL foundCPU = FALSE;
05899 static INT32 pathsBeforeAsk = 0;
05900
05901 if (!foundCPU)
05902 {
05903
05904
05905
05906
05907
05908
05909
05910
05911
05912
05913
05914
05915
05916
05917
05918
05919 {
05920
05921 pathsBeforeAsk = 24000;
05922 }
05923 foundCPU = TRUE;
05924 }
05925
05926 if (total > pathsBeforeAsk)
05927 {
05928
05929 String_256 QueryString(_R(IDS_ASKLONGJOB));
05930
05931
05932 Error::SetError(0, QueryString, 0);
05933 INT32 DlgResult = InformMessage(0, _R(IDS_YES), _R(IDS_NO));
05934 Error::ClearError();
05935
05936 switch (DlgResult)
05937 {
05938 case 1:
05939 return (TRUE);
05940 break;
05941 case 2:
05942 return (FALSE);
05943 }
05944 }
05945
05946 return (TRUE);
05947 }
05948
05949
05950
05951
05952
05953
05954
05955
05956
05957
05958
05959
05960 BOOL OpChangeBlendSteps::Declare()
05961 {
05962 return (RegisterOpDescriptor(
05963 0,
05964 0,
05965 CC_RUNTIME_CLASS(OpChangeBlendSteps),
05966 OPTOKEN_CHANGEBLENDSTEPS,
05967 OpChangeBlendSteps::GetState,
05968 0,
05969 0,
05970 0
05971 ));
05972 }
05973
05974
05975
05976
05977
05978
05979
05980
05981
05982
05983
05984
05985
05986
05987
05988
05989 OpState OpChangeBlendSteps::GetState(String_256* Description, OpDescriptor*)
05990 {
05991 OpState State(FALSE,TRUE);
05992
05993
05994
05995 List NodeList;
05996 BevelTools::BuildListOfSelectedNodes(&NodeList, CC_RUNTIME_CLASS(NodeBlend));
05997
05998 if (!NodeList.IsEmpty())
05999 {
06000 State.Greyed = FALSE;
06001 }
06002
06003 NodeList.DeleteAll();
06004
06005
06006
06007 Range * pSel = GetApplication()->FindSelection();
06008
06009 if (pSel)
06010 {
06011 Node* pNode = pSel->FindFirst();
06012 if (pNode->IS_KIND_OF(NodeBlendPath))
06013 {
06014 State.Greyed = FALSE;
06015 }
06016 }
06017
06018 if (State.Greyed)
06019 *Description = String_256(_R(IDS_REMOVEBLEND_GREYED));
06020 else
06021 *Description = String_256(_R(IDS_BLENDSTEPS));
06022
06023 return State;
06024 }
06025
06026
06027
06028
06029
06030
06031
06032
06033
06034
06035
06036
06037
06038
06039
06040
06041
06042 void OpChangeBlendSteps::GetOpName(String_256* OpName)
06043 {
06044 *OpName = String_256(_R(IDS_BLENDSTEPS_UNDO));
06045 }
06046
06047
06048
06049
06050
06051
06052
06053
06054
06055
06056
06057
06058
06059
06060
06061
06062
06063
06064
06065
06066
06067
06068
06069 ChangeBlendStepsAction::ChangeBlendStepsAction()
06070 {
06071 pNodeBlend = NULL;
06072 OldNumSteps = 0;
06073 }
06074
06075
06076
06077
06078
06079
06080
06081
06082
06083
06084
06085
06086
06087
06088
06089
06090
06091
06092
06093
06094
06095
06096
06097
06098
06099
06100
06101
06102
06103
06104
06105
06106
06107 ActionCode ChangeBlendStepsAction::Init(Operation* pOp,
06108 ActionList* pActionList,
06109 Node* pThisNodeBlend,
06110 UINT32 NumSteps,
06111 double DistanceEntered,
06112 ChangeBlendStepsAction** ppNewAction)
06113 {
06114 UINT32 ActSize = sizeof(ChangeBlendStepsAction);
06115
06116 ActionCode Ac = Action::Init(pOp,pActionList,ActSize,CC_RUNTIME_CLASS(ChangeBlendStepsAction),(Action**)ppNewAction);
06117
06118 if (Ac != AC_FAIL)
06119 {
06120 (*ppNewAction)->pNodeBlend = pThisNodeBlend;
06121 (*ppNewAction)->OldNumSteps = NumSteps;
06122 (*ppNewAction)->OldDistanceEntered = DistanceEntered;
06123 }
06124
06125 return Ac;
06126 }
06127
06128
06129
06130
06131
06132
06133
06134
06135
06136
06137
06138
06139
06140
06141
06142
06143
06144 ActionCode ChangeBlendStepsAction::Execute()
06145 {
06146 ActionCode Act;
06147 ChangeBlendStepsAction* pAction;
06148
06149 UINT32 NumSteps = 0;
06150 double DistanceEntered = 0.0;
06151
06152 if (pNodeBlend->IsKindOf(CC_RUNTIME_CLASS(NodeBlend)))
06153 {
06154 NumSteps = ((NodeBlend *)pNodeBlend)->GetNumBlendSteps();
06155 DistanceEntered = ((NodeBlend *)pNodeBlend)->GetDistanceEntered();
06156 }
06157 Act = ChangeBlendStepsAction::Init( pOperation,
06158 pOppositeActLst,
06159 pNodeBlend,
06160 NumSteps,
06161 DistanceEntered,
06162 &pAction);
06163 if (Act != AC_FAIL)
06164 {
06165 if (pNodeBlend->IsKindOf(CC_RUNTIME_CLASS(NodeBlend)))
06166 {
06167 ((NodeBlend *)pNodeBlend)->SetNumBlendSteps(OldNumSteps);
06168 ((NodeBlend *)pNodeBlend)->SetDistanceEntered(OldDistanceEntered);
06169 }
06170
06171 }
06172
06173 return Act;
06174 }
06175
06176 ChangeBlendStepsAction::~ChangeBlendStepsAction()
06177 {
06178 }
06179
06180
06182
06183
06184
06185
06186
06187
06188
06189
06190
06191
06192
06193
06194
06195
06196
06197
06198
06199
06200
06201
06202
06203
06204
06205 void OpChangeBlendDistance::DoWithParam(OpDescriptor* pOpDesc, OpParam* pOpParam)
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
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
06239
06240
06241
06242
06243
06244
06245
06246 NodeRenderableInk * pInk = (NodeRenderableInk *)pNodeBlend;
06247
06248
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
06260 BOOL OnCurve = pNodeBlend->IsOnACurve();
06261
06262 if (OnCurve)
06263 {
06264
06265 UINT32 NewNumSteps = 0;
06266
06267 double NewDistances[2] = { 1.0, 0.0 };
06268
06269
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
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 }
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
06304 ObjChangeFlags cFlags;
06305 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,cFlags,NULL,this);
06306 UpdateChangedNodes(&ObjChange);
06307 }
06308 else
06309 FailAndExecute();
06310
06311 End();
06312
06313 }
06314
06315
06316
06317
06318
06319
06320
06321
06322
06323
06324
06325
06326
06327
06328
06329
06330
06331
06332
06333
06334
06335
06336 BOOL OpChangeBlendDistance::InsertChangeStepsAction(NodeBlend* pNodeBlend,double StepDistance,
06337 UINT32* NewNumSteps, double* NewDistances)
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
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;
06410
06411
06412 return ok;
06413 }
06414
06415
06416
06417
06418
06419
06420
06421
06422
06423
06424
06425
06426
06427
06428
06429
06430
06431
06432
06433
06434
06435
06436
06437 BOOL OpChangeBlendDistance::InsertChangePathProportion(NodeBlend* pNodeBlend,
06438 double StartDistance, double EndDistance)
06439
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
06456
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
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 }
06493
06494
06495
06496
06497
06498
06499
06500
06501
06502
06503
06504
06505
06506
06507
06508
06509
06510
06511
06512
06513
06514
06515
06516
06517
06518
06519
06520
06521
06522
06523
06524
06525
06526
06527
06528
06529
06530
06531
06532
06533
06534
06535
06536
06537
06538
06539
06540
06541
06542
06543
06544
06545
06546
06547
06548
06549
06550
06551
06552
06553
06554
06555
06556
06557
06558
06559
06560
06561
06562
06563 BOOL OpChangeBlendDistance::InsertTransformNodesAction(NodeBlend* pNodeBlend, double StartDistance,
06564 double EndDistance)
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
06581
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
06594 double OldStartDist = BlendDistance * OldStartProp;
06595 if (OldStartDist != StartDistance)
06596 {
06597
06598 DocCoord NewPoint;
06599 double ExtraParam = 0.0;
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
06616 DocCoord NewPoint;
06617 double ExtraParam = 0.0;
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 }
06637
06638
06639
06640
06641
06642
06643
06644
06645
06646
06647
06648
06649
06650
06651
06652
06653
06654
06655
06656
06657
06658
06659 BOOL OpChangeBlendDistance::InsertChangeLinearBlendActions(NodeBlend* pNodeBlend,
06660 Operation* pOp,
06661 double StepDistance)
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
06684
06685
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
06694
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
06703 pBlender->SetUninitialised();
06704
06705 }
06706 }
06707 pBlender = pNodeBlend->FindNextBlender(pBlender);
06708 }
06709
06710 return ok;
06711
06712 }
06713
06714
06715
06716
06717
06718
06719
06720
06721
06722
06723
06724
06725
06726
06727
06728
06729
06730
06731
06732
06733
06734
06735
06736
06737
06738
06739
06740
06741
06742
06743
06744
06745
06746
06747
06748
06749 BOOL OpChangeBlendDistance::CalculateNewNumStepsAndPosition(UINT32 OldNumSteps, double BlendDistance,
06750 double StepDistance, double* FixedDistance,
06751 double* MoveableDistance, UINT32* NewNumSteps)
06752 {
06753
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
06766 *NewNumSteps = 0;
06767
06768
06769 double DistanceUsed = BlendDistance - (*FixedDistance + *MoveableDistance);
06770
06771
06772
06773 UINT32 TempNumSteps = (UINT32)(DistanceUsed / StepDistance);
06774
06775
06776 if (TempNumSteps > 0)
06777 {
06778 double NewDistance = TempNumSteps * StepDistance;
06779 *MoveableDistance = BlendDistance - (*FixedDistance + NewDistance);
06780 *NewNumSteps = TempNumSteps;
06781
06782 }
06783
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
06797
06798 ERROR3("Step distance is too long");
06799 return FALSE;
06800 }
06801 }
06802
06803
06804
06805
06806 if (*NewNumSteps != 0)
06807 return TRUE;
06808 else
06809 return FALSE;
06810 }
06811
06812
06813
06814
06815
06816
06817
06818
06819
06820
06821
06822
06823
06824
06825 BOOL OpChangeBlendDistance::Declare()
06826 {
06827 return (RegisterOpDescriptor(
06828 0,
06829 0,
06830 CC_RUNTIME_CLASS(OpChangeBlendDistance),
06831 OPTOKEN_CHANGEBLENDDISTANCE,
06832 OpChangeBlendDistance::GetState,
06833 0,
06834 0,
06835 0
06836 ));
06837 }
06838
06839
06840
06841
06842
06843
06844
06845
06846
06847
06848
06849
06850
06851
06852
06853
06854 OpState OpChangeBlendDistance::GetState(String_256* Description, OpDescriptor*)
06855 {
06856 OpState State(FALSE,TRUE);
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
06873
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
06883
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 }
06900
06901
06902
06903
06904
06905
06906
06907
06908
06909
06910
06911
06912
06913
06914
06915
06916
06917 void OpChangeBlendDistance::GetOpName(String_256* OpName)
06918 {
06919 *OpName = String_256(_R(IDS_STEPDISTANCEUNDO));
06920 }
06921
06922
06923
06924
06925
06926
06927
06928
06929
06930
06931
06932
06933
06934
06935
06936
06937
06938
06939
06940
06941
06942
06943
06944
06945 RemapBlendAction::RemapBlendAction()
06946 {
06947 pNodeBlend = NULL;
06948 RemapRef = 0;
06949 }
06950
06951
06952
06953
06954
06955
06956
06957
06958
06959
06960
06961
06962
06963
06964
06965
06966
06967
06968
06969
06970
06971
06972
06973
06974
06975
06976
06977
06978
06979
06980
06981
06982
06983
06984
06985
06986
06987
06988
06989
06990 ActionCode RemapBlendAction::Init( Operation* pOp,
06991 ActionList* pActionList,
06992 NodeBlend* pNodeBlend,
06993 UINT32 RemapRef,
06994 DocCoord PosStart,
06995 DocCoord PosEnd,
06996 RemapBlendAction** ppNewAction)
06997 {
06998 UINT32 ActSize = sizeof(RemapBlendAction);
06999
07000 ActionCode Ac = Action::Init(pOp,pActionList,ActSize,CC_RUNTIME_CLASS(RemapBlendAction),(Action**)ppNewAction);
07001
07002 if (Ac != AC_FAIL)
07003 {
07004 DocCoord InvPosStart,InvPosEnd;
07005
07006 if (pNodeBlend->Remap(RemapRef,PosStart,PosEnd,&InvPosStart,&InvPosEnd))
07007 {
07008 (*ppNewAction)->pNodeBlend = pNodeBlend;
07009 (*ppNewAction)->RemapRef = RemapRef;
07010 (*ppNewAction)->InvPosStart = InvPosStart;
07011 (*ppNewAction)->InvPosEnd = InvPosEnd;
07012 }
07013 else
07014 {
07015 ERROR3("pNodeBlend->Remap() failed");
07016 Ac = AC_FAIL;
07017 }
07018 }
07019
07020 return Ac;
07021 }
07022
07023
07024
07025
07026
07027
07028
07029
07030
07031
07032
07033
07034
07035
07036
07037
07038
07039
07040 ActionCode RemapBlendAction::Execute()
07041 {
07042 ActionCode Act;
07043 RemapBlendAction* pAction;
07044 Act = RemapBlendAction::Init( pOperation,
07045 pOppositeActLst,
07046 pNodeBlend,
07047 RemapRef,
07048 InvPosStart,
07049 InvPosEnd,
07050 &pAction);
07051
07052 return Act;
07053 }
07054
07055 RemapBlendAction::~RemapBlendAction()
07056 {
07057 }
07058
07059
07060
07061
07062
07063
07064
07065
07066
07067
07068
07069
07070
07071
07072
07073
07074
07075
07076
07077
07078
07079 InitBlendersAction::InitBlendersAction()
07080 {
07081 }
07082
07083
07084
07085
07086
07087
07088
07089
07090
07091
07092
07093
07094
07095
07096
07097
07098
07099
07100
07101
07102
07103
07104
07105
07106
07107
07108
07109
07110
07111
07112
07113
07114
07115
07116
07117
07118 ActionCode InitBlendersAction::Init( OpBlendNodes* pOp,
07119 ActionList* pActionList,
07120 List* pBlenderInfoList,
07121 BOOL DeinitState,
07122 InitBlendersAction** ppNewAction)
07123 {
07124 UINT32 ActSize = sizeof(InitBlendersAction)+(pBlenderInfoList->GetCount()*sizeof(BlenderInfoItem));
07125
07126 ActionCode Ac = Action::Init(pOp,pActionList,ActSize,CC_RUNTIME_CLASS(InitBlendersAction),(Action**)ppNewAction);
07127 InitBlendersAction* pAction = *ppNewAction;
07128
07129 if (Ac != AC_FAIL)
07130 {
07131 pAction->Deinit = DeinitState;
07132
07133
07134 BlenderInfoItem *pItem = (BlenderInfoItem*)pBlenderInfoList->GetHead();
07135 while (pItem != NULL && Ac != AC_FAIL)
07136 {
07137 BlenderInfoItem* pNewItem = pItem->SimpleCopy();
07138 if (pNewItem != NULL)
07139 {
07140 pAction->BlenderInfoList.AddTail(pNewItem);
07141 pItem = (BlenderInfoItem*)pBlenderInfoList->GetNext(pItem);
07142 }
07143 else
07144 Ac = AC_FAIL;
07145 }
07146 }
07147
07148 return Ac;
07149 }
07150
07151
07152
07153
07154
07155
07156
07157
07158
07159
07160
07161
07162
07163
07164
07165
07166
07167
07168 ActionCode InitBlendersAction::Execute()
07169 {
07170 ActionCode Ac;
07171 InitBlendersAction* pAction;
07172 OpBlendNodes* pOp = (OpBlendNodes*)pOperation;
07173
07174
07175 Deinit = !Deinit;
07176
07177 Ac = InitBlendersAction::Init( pOp,
07178 pOppositeActLst,
07179 &BlenderInfoList,
07180 Deinit,
07181 &pAction);
07182
07183 if (Ac != AC_FAIL)
07184 {
07185 if (Deinit)
07186 pOp->DeinitBlenders(BlenderInfoList);
07187 else
07188 {
07189 if (!(pOp->ReinitBlenders(BlenderInfoList)))
07190 Ac = AC_FAIL;
07191 }
07192 }
07193
07194 return Ac;
07195 }
07196
07197 InitBlendersAction::~InitBlendersAction()
07198 {
07199 BlenderInfoList.DeleteAll();
07200 }
07201
07203
07204
07205
07206
07207
07208
07209
07210
07211
07212
07213
07214
07215
07216
07217
07218
07219
07220 void OpChangeBlend::DoWithParam(OpDescriptor*,OpParam* pOpParam)
07221 {
07222 ERROR3IF(pOpParam == NULL,"NULL OpParam ptr");
07223 if (pOpParam == NULL) return;
07224
07225 ChangeBlendOpParam* pChangeParam = (ChangeBlendOpParam*)pOpParam;
07226
07227 List NodeList;
07228 BevelTools::BuildListOfSelectedNodes(&NodeList, CC_RUNTIME_CLASS(NodeRenderableInk));
07229
07230 BOOL ok = !NodeList.IsEmpty();
07231 if (ok) ok = DoStartSelOp(FALSE,FALSE);
07232
07233 NodeListItem * pItem = NULL;
07234
07235 if (ok)
07236 {
07237 pItem = (NodeListItem *)NodeList.GetHead();
07238
07239 Node* pSelNode = NULL;
07240
07241 if (pItem)
07242 {
07243 pSelNode = pItem->pNode;
07244 }
07245
07246 while (pSelNode != NULL && ok)
07247 {
07248 Node* pNode = pSelNode;
07249
07250 pItem = (NodeListItem *)NodeList.GetNext(pItem);
07251
07252 if (pItem)
07253 {
07254 pSelNode = pItem->pNode;
07255 }
07256 else
07257 {
07258 pSelNode = NULL;
07259 }
07260
07261 if (pNode->IS_KIND_OF(NodeBlend))
07262 {
07263
07264
07265
07266
07267
07268 ChangeBlendAction* pAction;
07269 NodeBlend* pNodeBlend = (NodeBlend*)pNode;
07270
07271
07272 ObjChangeFlags cFlags;
07273
07274
07275 cFlags.TransformNode = TRUE;
07276 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,this);
07277 ok = pNodeBlend->AllowOp(&ObjChange);
07278
07279
07280 if (ok) ok = DoInvalidateNodeRegion(pNodeBlend,TRUE,FALSE);
07281 if (ok) ok = (InvalidateBoundsAction::Init(this,&UndoActions,pNodeBlend,TRUE) != AC_FAIL);
07282
07283
07284 if (ok) ok = ChangeBlendAction::Init(this,&UndoActions,pNodeBlend,pChangeParam,&pAction) != AC_FAIL;
07285
07286 if (ok && pChangeParam->ChangeType == CHANGEBLEND_TANGENTIAL)
07287 {
07288 ok = pNodeBlend->TransformBlendEndObjects(this);
07289
07290 if (ok) ok = DoInvalidateNodeRegion(pNodeBlend,TRUE,FALSE);
07291 if (ok) ok = (InvalidateBoundsAction::Init(this,&UndoActions,pNodeBlend,TRUE) != AC_FAIL);
07292 }
07293 }
07294
07295 }
07296 }
07297
07298
07299 NodeList.DeleteAll();
07300
07301 if (ok)
07302 {
07303
07304 ObjChangeFlags cFlags;
07305 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,cFlags,NULL,this);
07306 UpdateChangedNodes(&ObjChange);
07307
07308
07309 ChangeType = pChangeParam->ChangeType;
07310 }
07311 else
07312 FailAndExecute();
07313
07314 End();
07315 }
07316
07317
07318
07319
07320
07321
07322
07323
07324
07325
07326
07327
07328 BOOL OpChangeBlend::Declare()
07329 {
07330 return (RegisterOpDescriptor(
07331 0,
07332 0,
07333 CC_RUNTIME_CLASS(OpChangeBlend),
07334 OPTOKEN_CHANGEBLEND,
07335 OpChangeBlend::GetState,
07336 0,
07337 0,
07338 0
07339 ));
07340 }
07341
07342
07343
07344
07345
07346
07347
07348
07349
07350
07351
07352
07353
07354
07355
07356
07357 OpState OpChangeBlend::GetState(String_256* Description, OpDescriptor*)
07358 {
07359 OpState State(FALSE,TRUE);
07360
07361
07362
07363 List NodeList;
07364 BevelTools::BuildListOfSelectedNodes(&NodeList, CC_RUNTIME_CLASS(NodeBlend));
07365
07366 if (!NodeList.IsEmpty())
07367 {
07368 State.Greyed = FALSE;
07369 }
07370
07371 NodeList.DeleteAll();
07372
07373
07374
07375 Range * pSel = GetApplication()->FindSelection();
07376
07377 if (pSel)
07378 {
07379 Node* pNode = pSel->FindFirst();
07380 if (pNode->IS_KIND_OF(NodeBlendPath))
07381 {
07382 State.Greyed = FALSE;
07383 }
07384 }
07385
07386 if (State.Greyed)
07387 *Description = String_256(_R(IDS_REMOVEBLEND_GREYED));
07388 else
07389 *Description = String_256(_R(IDS_BLENDSTEPS));
07390
07391 return State;
07392
07393 }
07394
07395
07396
07397
07398
07399
07400
07401
07402
07403
07404
07405
07406
07407
07408
07409
07410
07411 void OpChangeBlend::GetOpName(String_256* OpName)
07412 {
07413 UINT32 IDS = _R(IDS_MARKN_EMPTY);
07414
07415 switch (ChangeType)
07416 {
07417 case CHANGEBLEND_ONETOONE: IDS = _R(IDS_ONETOONE_UNDO); break;
07418 case CHANGEBLEND_ANTIALIAS: IDS = _R(IDS_BLENDANTIALIAS_UNDO); break;
07419 case CHANGEBLEND_COLOURBLENDTYPE: IDS = _R(IDS_COLOURBLENDTYPE_UNDO); break;
07420 case CHANGEBLEND_TANGENTIAL: IDS = _R(IDS_TANGENTIAL_UNDO); break;
07421 case CHANGEBLEND_OBJECTPROFILE: IDS = _R(IDS_POSITIONPROFILE_UNDO); break;
07422 case CHANGEBLEND_ATTRPROFILE: IDS = _R(IDS_ATTRPROFILE_UNDO); break;
07423 default: ERROR3_PF(("Unknown flag type (%d)",ChangeType)); break;
07424 }
07425
07426 *OpName = String_256(IDS);
07427 }
07428
07429
07430
07431
07433
07434
07435
07436
07437
07438
07439
07440
07441
07442
07443
07444
07445
07446
07447
07448
07449 void OpBlendOneToOne::Do(OpDescriptor* pOpDesc)
07450 {
07451 SelRange* pSel = GetApplication()->FindSelection();
07452 if (pSel != NULL)
07453 {
07454 Node* pSelNode = pSel->FindFirst();
07455 while (pSelNode != NULL)
07456 {
07457 if (IS_A(pSelNode,NodeBlend))
07458 {
07459 NodeBlend* pNodeBlend = (NodeBlend*)pSelNode;
07460
07461 ChangeBlendOpParam Param;
07462 Param.ChangeType = CHANGEBLEND_ONETOONE;
07463 Param.NewOneToOne = !pNodeBlend->IsOneToOne();
07464 DoWithParam(pOpDesc,&Param);
07465
07466
07467
07468
07469 return;
07470 }
07471 pSelNode = pSel->FindNext(pSelNode);
07472 }
07473 }
07474 }
07475
07476
07477
07478
07479
07480
07481
07482
07483
07484
07485
07486
07487 BOOL OpBlendOneToOne::Declare()
07488 {
07489 return (RegisterOpDescriptor(
07490 0,
07491 _R(IDBBL_ONETOONE),
07492
07493 CC_RUNTIME_CLASS(OpBlendOneToOne),
07494 OPTOKEN_BLENDONETOONE,
07495 OpBlendOneToOne::GetState,
07496 0,
07497 0,
07498 0
07499 ));
07500 }
07501
07502
07503
07504
07505
07506
07507
07508
07509
07510
07511
07512
07513
07514
07515
07516
07517 OpState OpBlendOneToOne::GetState(String_256* Description, OpDescriptor*)
07518 {
07519 OpState State(FALSE,TRUE);
07520
07521 SelRange* pSel = GetApplication()->FindSelection();
07522 if (pSel != NULL)
07523 {
07524 Node* pSelNode = pSel->FindFirst();
07525 while (pSelNode != NULL && !State.Ticked)
07526 {
07527 if (IS_A(pSelNode,NodeBlend))
07528 {
07529 State.Ticked = ((NodeBlend*)pSelNode)->IsOneToOne();
07530 State.Greyed = FALSE;
07531
07532
07533
07534 return State;
07535 }
07536 pSelNode = pSel->FindNext(pSelNode);
07537 }
07538 }
07539
07540 return State;
07541 }
07542
07543
07544
07546
07547
07548
07549
07550
07551
07552
07553
07554
07555
07556
07557
07558
07559
07560
07561
07562 void OpBlendAntialias::Do(OpDescriptor* pOpDesc)
07563 {
07564 SelRange* pSel = GetApplication()->FindSelection();
07565 if (pSel != NULL)
07566 {
07567 Node* pSelNode = pSel->FindFirst();
07568 while (pSelNode != NULL)
07569 {
07570 if (IS_A(pSelNode,NodeBlend))
07571 {
07572 NodeBlend* pNodeBlend = (NodeBlend*)pSelNode;
07573
07574 ChangeBlendOpParam Param;
07575 Param.ChangeType = CHANGEBLEND_ANTIALIAS;
07576 Param.NewAntiAlias = pNodeBlend->IsNotAntialiased();
07577 DoWithParam(pOpDesc,&Param);
07578
07579
07580
07581
07582 return;
07583 }
07584 pSelNode = pSel->FindNext(pSelNode);
07585 }
07586 }
07587 }
07588
07589
07590
07591
07592
07593
07594
07595
07596
07597
07598
07599
07600 BOOL OpBlendAntialias::Declare()
07601 {
07602 return (RegisterOpDescriptor(
07603 0,
07604 _R(IDBBL_BLENDANTIALIAS),
07605
07606 CC_RUNTIME_CLASS(OpBlendAntialias),
07607 OPTOKEN_BLENDANTIALIAS,
07608 OpBlendAntialias::GetState,
07609 0,
07610 0,
07611 0
07612 ));
07613 }
07614
07615
07616
07617
07618
07619
07620
07621
07622
07623
07624
07625
07626
07627
07628
07629
07630 OpState OpBlendAntialias::GetState(String_256* Description, OpDescriptor*)
07631 {
07632 OpState State(FALSE,TRUE);
07633
07634 SelRange* pSel = GetApplication()->FindSelection();
07635 if (pSel != NULL)
07636 {
07637 Node* pSelNode = pSel->FindFirst();
07638 while (pSelNode != NULL && !State.Ticked)
07639 {
07640 if (IS_A(pSelNode,NodeBlend))
07641 {
07642 State.Ticked = !(((NodeBlend*)pSelNode)->IsNotAntialiased());
07643 State.Greyed = FALSE;
07644
07645
07646
07647 return State;
07648 }
07649 pSelNode = pSel->FindNext(pSelNode);
07650 }
07651 }
07652
07653 return State;
07654 }
07655
07656
07657
07659
07660
07661
07662
07663
07664
07665
07666
07667
07668
07669
07670
07671
07672
07673
07674
07675 void OpBlendTangential::Do(OpDescriptor* pOpDesc)
07676 {
07677 SelRange* pSel = GetApplication()->FindSelection();
07678 if (pSel != NULL)
07679 {
07680 Node* pSelNode = pSel->FindFirst();
07681 while (pSelNode != NULL)
07682 {
07683 if (IS_A(pSelNode,NodeBlend))
07684 {
07685 NodeBlend* pNodeBlend = (NodeBlend*)pSelNode;
07686
07687 ChangeBlendOpParam Param;
07688 Param.ChangeType = CHANGEBLEND_TANGENTIAL;
07689 Param.NewTangential = !pNodeBlend->IsTangential();
07690 DoWithParam(pOpDesc,&Param);
07691
07692
07693
07694
07695 return;
07696 }
07697 pSelNode = pSel->FindNext(pSelNode);
07698 }
07699 }
07700 }
07701
07702
07703
07704
07705
07706
07707
07708
07709
07710
07711
07712
07713 BOOL OpBlendTangential::Declare()
07714 {
07715 return (RegisterOpDescriptor(
07716 0,
07717 _R(IDBBL_TANGENTIAL),
07718 CC_RUNTIME_CLASS(OpBlendTangential),
07719 OPTOKEN_BLENDTANGENTIAL,
07720 OpBlendTangential::GetState,
07721 0,
07722 0,
07723 0
07724 ));
07725 }
07726
07727
07728
07729
07730
07731
07732
07733
07734
07735
07736
07737
07738
07739
07740
07741
07742 OpState OpBlendTangential::GetState(String_256* Description, OpDescriptor*)
07743 {
07744 OpState State(FALSE,TRUE);
07745
07746 SelRange* pSel = GetApplication()->FindSelection();
07747 if (pSel != NULL)
07748 {
07749 Node* pSelNode = pSel->FindFirst();
07750 while (pSelNode != NULL && !State.Ticked)
07751 {
07752 if (IS_A(pSelNode,NodeBlend))
07753 {
07754 NodeBlend* pNodeBlend = (NodeBlend*)pSelNode;
07755
07756 if (!State.Ticked)
07757 State.Ticked = pNodeBlend->IsTangential();
07758
07759 if (State.Greyed)
07760 State.Greyed = (pNodeBlend->GetNodeBlendPath(0) != NULL);
07761 }
07762 pSelNode = pSel->FindNext(pSelNode);
07763 }
07764 }
07765
07766 return State;
07767 }
07768
07769
07770
07771
07772
07773
07774
07775
07776
07777
07778
07779
07780
07781
07782
07783
07784
07785
07786
07787
07788 ChangeBlendAction::ChangeBlendAction()
07789 {
07790 pNodeBlend = NULL;
07791 }
07792
07793
07794
07795
07796
07797
07798
07799
07800
07801
07802
07803
07804
07805
07806
07807
07808
07809
07810
07811
07812
07813
07814
07815
07816
07817
07818
07819
07820
07821
07822
07823
07824
07825
07826
07827 ActionCode ChangeBlendAction::Init( Operation* pOp,
07828 ActionList* pActionList,
07829 NodeRenderableInk* pNodeBlend,
07830 ChangeBlendOpParam* pChangeParam,
07831 ChangeBlendAction** ppNewAction)
07832 {
07833 ERROR2IF(pNodeBlend == NULL,AC_FAIL,"pNodeBlend is NULL");
07834 ERROR2IF(pChangeParam == NULL,AC_FAIL,"pChangeParam is NULL");
07835
07836 UINT32 ActSize = sizeof(ChangeBlendAction);
07837
07838 ChangeBlendAction* pNewAction;
07839 ActionCode Ac = Action::Init(pOp,pActionList,ActSize,CC_RUNTIME_CLASS(ChangeBlendAction),(Action**)&pNewAction);
07840
07841 *ppNewAction = pNewAction;
07842
07843 BOOL bNodeIsContour = FALSE;
07844
07845 if (Ac != AC_FAIL && pNewAction != NULL)
07846 {
07847 if (!bNodeIsContour)
07848 {
07849 ChangeBlendType ChangeType = pChangeParam->ChangeType;
07850
07851 pNewAction->pNodeBlend = pNodeBlend;
07852 pNewAction->ChangeParam.ChangeType = ChangeType;
07853 pNewAction->ChangeParam.SetOldValues(pNodeBlend);
07854
07855 switch (ChangeType)
07856 {
07857 case CHANGEBLEND_ONETOONE: ((NodeBlend *)pNodeBlend)->SetOneToOne(pChangeParam->NewOneToOne); break;
07858 case CHANGEBLEND_ANTIALIAS: ((NodeBlend *)pNodeBlend)->SetNotAntialiased(!pChangeParam->NewAntiAlias); break;
07859 case CHANGEBLEND_COLOURBLENDTYPE: ((NodeBlend *)pNodeBlend)->SetColourBlendType(pChangeParam->NewColBlendType); break;
07860 case CHANGEBLEND_EDITEND: ((NodeBlend *)pNodeBlend)->SetLastEdited(pChangeParam->NewEndObject); break;
07861 case CHANGEBLEND_TANGENTIAL:
07862 {
07863
07864 if (((NodeBlend *)pNodeBlend)->GetNodeBlendPath(0) != NULL)
07865 ((NodeBlend *)pNodeBlend)->SetTangential(pChangeParam->NewTangential);
07866 }
07867 break;
07868
07869
07870 case CHANGEBLEND_OBJECTPROFILE:
07871 {
07872 AFp BiasValue = (pChangeParam)->NewObjectProfile.GetBias();
07873 AFp GainValue = (pChangeParam)->NewObjectProfile.GetGain();
07874 CProfileBiasGain *pProfile = ((NodeBlend *)pNodeBlend)->GetObjectProfile();
07875
07876 if (pProfile != NULL)
07877 {
07878 ((NodeBlend*) pNodeBlend)->RequestObjectProfileProcessing (TRUE);
07879 pProfile->SetBiasGain(BiasValue, GainValue);
07880 }
07881
07882 }
07883 break;
07884 case CHANGEBLEND_ATTRPROFILE:
07885 {
07886 AFp BiasValue = (pChangeParam)->NewAttrProfile.GetBias();
07887 AFp GainValue = (pChangeParam)->NewAttrProfile.GetGain();
07888 CProfileBiasGain *pProfile = ((NodeBlend *)pNodeBlend)->GetAttrProfile();
07889
07890 if (pProfile != NULL)
07891 {
07892
07893
07894 ((NodeBlend*) pNodeBlend)->RequestObjectProfileProcessing (TRUE);
07895 pProfile->SetBiasGain(BiasValue, GainValue);
07896 }
07897
07898 }
07899 break;
07900
07901 case CHANGEBLEND_BLENDONPATH:
07902 {
07903 ((NodeBlend*)pNodeBlend)->SetBlendedOnCurve(pChangeParam->NewBlendedOnCurve);
07904
07905
07906 if (pChangeParam->NewBlendedOnCurve)
07907 ((NodeBlend*)pNodeBlend)->SetNumNodeBlendPaths(TRUE);
07908 else
07909 ((NodeBlend*)pNodeBlend)->SetNumNodeBlendPaths(FALSE);
07910
07911 NodeBlender* pNodeBlender = ((NodeBlend*)pNodeBlend)->FindFirstBlender();
07912 ERROR2IF((pNodeBlender == NULL), AC_FAIL, "Couldn't get blender");
07913 while (pNodeBlender != NULL)
07914 {
07915 if (pChangeParam->NewBlendedOnCurve)
07916 pNodeBlender->SetNodeBlendPathIndex(0);
07917 else
07918 pNodeBlender->SetNodeBlendPathIndex(-1);
07919
07920 pNodeBlender = ((NodeBlend*)pNodeBlend)->FindNextBlender(pNodeBlender);
07921 }
07922
07923
07924
07925
07926
07927
07928
07929
07930
07931
07932
07933
07934
07935
07936
07937 }
07938 break;
07939
07940 default : ERROR2(AC_FAIL,"Unknown change blend type"); break;
07941
07942 }
07943 }
07944 else
07945 {
07946 ChangeBlendType ChangeType = pChangeParam->ChangeType;
07947
07948 pNewAction->pNodeBlend = pNodeBlend;
07949 pNewAction->ChangeParam.ChangeType = ChangeType;
07950 pNewAction->ChangeParam.SetOldValues(pNodeBlend);
07951
07952 switch (ChangeType)
07953 {
07954 case CHANGEBLEND_COLOURBLENDTYPE: ((NodeContourController *)pNodeBlend)->SetColourBlendType(pChangeParam->NewColBlendType); break;
07955 default : ERROR2(AC_FAIL,"Unknown change blend type"); break;
07956 }
07957 }
07958
07959
07960 pNewAction->ChangeParam.SetNewValues(pNodeBlend);
07961 }
07962
07963 return Ac;
07964 }
07965
07966
07967
07968
07969
07970
07971
07972
07973
07974
07975
07976
07977
07978
07979
07980
07981
07982
07983
07984
07985
07986 void ChangeBlendAction::ChangeObjectProfileWithNoUndo (CProfileBiasGain &Profile, BOOL regenerateParents)
07987 {
07988 List NodeList;
07989 BevelTools::BuildListOfSelectedNodes(&NodeList, CC_RUNTIME_CLASS(NodeRenderableInk));
07990
07991 BOOL ok = !NodeList.IsEmpty();
07992
07993 NodeListItem * pItem = NULL;
07994
07995 if (ok)
07996 {
07997 pItem = (NodeListItem *)NodeList.GetHead();
07998
07999 Node* pSelNode = NULL;
08000
08001 if (pItem)
08002 {
08003 pSelNode = pItem->pNode;
08004 }
08005
08006 Document * pDoc = Document::GetCurrent();
08007
08008 while (pSelNode != NULL && ok)
08009 {
08010 Node* pNode = pSelNode;
08011
08012 pItem = (NodeListItem *)NodeList.GetNext(pItem);
08013
08014 if (pItem)
08015 {
08016 pSelNode = pItem->pNode;
08017 }
08018 else
08019 {
08020 pSelNode = NULL;
08021 }
08022
08023 if (pNode->IS_KIND_OF(NodeBlend))
08024 {
08025 if (!regenerateParents)
08026 {
08027
08028
08029
08030
08031 NodeBlend* pNodeBlend = (NodeBlend*)pNode;
08032
08033 AFp BiasValue = Profile.GetBias ();
08034 AFp GainValue = Profile.GetGain ();
08035 CProfileBiasGain *pProfile = ((NodeBlend *)pNodeBlend)->GetObjectProfile();
08036
08037 if (pProfile != NULL)
08038 {
08039 pNodeBlend->RequestObjectProfileProcessing (TRUE);
08040 pProfile->SetBiasGain(BiasValue, GainValue);
08041 }
08042
08043 pDoc->ForceRedraw(pNodeBlend->FindParentSpread(),
08044 pNodeBlend->GetBoundingRect(), FALSE, pNodeBlend);
08045 }
08046 else
08047 {
08048
08049
08050
08051
08052 NodeBlend* pNodeBlend = (NodeBlend*)pNode;
08053
08054
08055 ObjChangeFlags cFlags;
08056
08057
08058 cFlags.TransformNode = TRUE;
08059 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,NULL,NULL);
08060 ok = pNodeBlend->AllowOp(&ObjChange);
08061 }
08062 }
08063 }
08064
08065 if (pDoc->GetOpHistory ().CanRedo ())
08066 {
08067
08068 pDoc->GetOpHistory ().DeleteRedoableOps ();
08069
08070
08071 DialogBarOp::SetSystemStateChanged();
08072 DialogBarOp::UpdateStateOfAllBars();
08073 }
08074 }
08075
08076
08077 NodeList.DeleteAll();
08078
08079 if (ok && regenerateParents)
08080 {
08081
08082 ObjChangeFlags cFlags;
08083 cFlags.RegenerateNode = TRUE;
08084 ObjChangeParam ObjChange(OBJCHANGE_FINISHED,cFlags,NULL,NULL);
08085
08086 UndoableOperation undoOp;
08087
08088 undoOp.UpdateChangedNodes(&ObjChange);
08089 undoOp.FailAndDiscard ();
08090
08091
08092 }
08093 }
08094
08095
08096
08097
08098
08099
08100
08101
08102
08103
08104
08105
08106
08107
08108
08109
08110
08111
08112
08113
08114 void ChangeBlendAction::ChangeAttributeProfileWithNoUndo (CProfileBiasGain &Profile)
08115 {
08116 List NodeList;
08117 BevelTools::BuildListOfSelectedNodes(&NodeList, CC_RUNTIME_CLASS(NodeRenderableInk));
08118
08119 BOOL ok = !NodeList.IsEmpty();
08120
08121 NodeListItem * pItem = NULL;
08122
08123 if (ok)
08124 {
08125 pItem = (NodeListItem *)NodeList.GetHead();
08126
08127 Node* pSelNode = NULL;
08128
08129 if (pItem)
08130 {
08131 pSelNode = pItem->pNode;
08132 }
08133
08134 Document * pDoc = Document::GetCurrent();
08135
08136 while (pSelNode != NULL && ok)
08137 {
08138 Node* pNode = pSelNode;
08139
08140 pItem = (NodeListItem *)NodeList.GetNext(pItem);
08141
08142 if (pItem)
08143 {
08144 pSelNode = pItem->pNode;
08145 }
08146 else
08147 {
08148 pSelNode = NULL;
08149 }
08150
08151 if (pNode->IS_KIND_OF(NodeBlend))
08152 {
08153
08154
08155
08156
08157 NodeBlend* pNodeBlend = (NodeBlend*)pNode;
08158
08159 AFp BiasValue = Profile.GetBias ();
08160 AFp GainValue = Profile.GetGain ();
08161 CProfileBiasGain *pProfile = ((NodeBlend *)pNodeBlend)->GetAttrProfile();
08162
08163 if (pProfile != NULL)
08164 {
08165
08166
08167
08168 pNodeBlend->RequestObjectProfileProcessing (TRUE);
08169 pProfile->SetBiasGain(BiasValue, GainValue);
08170 }
08171
08172 pDoc->ForceRedraw(pNodeBlend->FindParentSpread(),
08173 pNodeBlend->GetBoundingRect(), FALSE, pNodeBlend);
08174 }
08175 }
08176
08177 if (pDoc->GetOpHistory ().CanRedo ())
08178 {
08179
08180 pDoc->GetOpHistory ().DeleteRedoableOps ();
08181
08182
08183 DialogBarOp::SetSystemStateChanged();
08184 DialogBarOp::UpdateStateOfAllBars();
08185 }
08186 }
08187
08188
08189 NodeList.DeleteAll();
08190 }
08191
08192
08193
08194
08195
08196
08197
08198
08199
08200
08201
08202
08203
08204
08205
08206
08207
08208
08209
08210 ActionCode ChangeBlendAction::Execute()
08211 {
08212 ChangeParam.SwapOldAndNew();
08213
08214 ActionCode Act;
08215 ChangeBlendAction* pAction;
08216 Act = ChangeBlendAction::Init(pOperation,pOppositeActLst,pNodeBlend,&ChangeParam,&pAction);
08217
08218 return Act;
08219 }
08220
08221 ChangeBlendAction::~ChangeBlendAction()
08222 {
08223 }
08224
08225
08226
08227
08228
08229
08230
08231
08232
08233
08234
08235
08236
08237
08238
08239
08240
08241
08242
08243 void ChangeBlendOpParam::SetOldValues(NodeRenderableInk* pNodeBlend)
08244 {
08245
08246
08247 if (pNodeBlend->IsKindOf(CC_RUNTIME_CLASS(NodeBlend)))
08248 {
08249 OldAntiAlias = !((NodeBlend*)pNodeBlend)->IsNotAntialiased();
08250 OldOneToOne = ((NodeBlend *)pNodeBlend)->IsOneToOne();
08251 OldColBlendType = ((NodeBlend *)pNodeBlend)->GetColourBlendType();
08252 OldTangential = ((NodeBlend *)pNodeBlend)->IsTangential();
08253 OldBlendedOnCurve = ((NodeBlend *)pNodeBlend)->IsOnACurve();
08254 OldEndObject = ((NodeBlend *)pNodeBlend)->GetLastEdited();
08255
08256
08257 CProfileBiasGain* pProfile = ((NodeBlend *)pNodeBlend)->GetObjectProfile();
08258 OldObjectProfile = *pProfile;
08259 pProfile = NULL;
08260
08261 pProfile = ((NodeBlend *)pNodeBlend)->GetAttrProfile();
08262 OldAttrProfile = *pProfile;
08263 pProfile = NULL;
08264 }
08265 }
08266
08267
08268
08269
08270
08271
08272
08273
08274
08275
08276
08277
08278
08279
08280
08281 void ChangeBlendOpParam::SetNewValues(NodeRenderableInk* pNodeBlend)
08282 {
08283 if (pNodeBlend->IsKindOf(CC_RUNTIME_CLASS(NodeBlend)))
08284 {
08285 NewAntiAlias = !((NodeBlend *)pNodeBlend)->IsNotAntialiased();
08286 NewOneToOne = ((NodeBlend *)pNodeBlend)->IsOneToOne();
08287 NewColBlendType = ((NodeBlend *)pNodeBlend)->GetColourBlendType();
08288 NewTangential = ((NodeBlend *)pNodeBlend)->IsTangential();
08289 NewBlendedOnCurve = ((NodeBlend *)pNodeBlend)->IsOnACurve();
08290 NewEndObject = ((NodeBlend *)pNodeBlend)->GetLastEdited();
08291
08292
08293 CProfileBiasGain* pProfile = ((NodeBlend *)pNodeBlend)->GetObjectProfile();
08294 NewObjectProfile = *pProfile;
08295 pProfile = NULL;
08296 pProfile = ((NodeBlend *)pNodeBlend)->GetAttrProfile();
08297 NewAttrProfile = *pProfile;
08298 pProfile = NULL;
08299 }
08300 }
08301
08302
08303
08304
08305
08306
08307
08308
08309
08310
08311
08312
08313
08314
08315
08316 void ChangeBlendOpParam::SwapOldAndNew()
08317 {
08318 SWAP(BOOL, OldAntiAlias, NewAntiAlias);
08319 SWAP(BOOL, OldOneToOne, NewOneToOne);
08320 SWAP(ColourBlendType, OldColBlendType, NewColBlendType);
08321 SWAP(BOOL, OldTangential, NewTangential);
08322 SWAP(BOOL, OldBlendedOnCurve, NewBlendedOnCurve);
08323 SWAP(EndObject, OldEndObject, NewEndObject);
08324
08325 SwapProfiles(&OldObjectProfile, &NewObjectProfile);
08326 SwapProfiles(&OldAttrProfile, &NewAttrProfile);
08327 }
08328
08329
08330
08331
08332
08333
08334
08335
08336
08337
08338
08339
08340
08341
08342
08343 void ChangeBlendOpParam::SwapProfiles(CProfileBiasGain* pOldProfile,
08344 CProfileBiasGain* pNewProfile)
08345 {
08346 CProfileBiasGain TempProfile = *pOldProfile;
08347 *pOldProfile = *pNewProfile;
08348 *pNewProfile = TempProfile;
08349 }
08350
08351
08352
08353
08354
08355
08356
08357
08358
08359
08360
08361
08362
08363
08364
08365
08366
08367
08368 ChangeBlenderAction::ChangeBlenderAction()
08369 {
08370 m_pNodeBlender = NULL;
08371 }
08372
08373
08374
08375
08376
08377
08378
08379
08380
08381
08382
08383
08384
08385
08386
08387
08388
08389
08390
08391
08392
08393
08394
08395
08396
08397
08398
08399
08400
08401
08402
08403
08404
08405 ActionCode ChangeBlenderAction::Init( Operation* pOp,
08406 ActionList* pActionList,
08407 NodeBlender* pNodeBlender,
08408 ChangeBlenderOpParam& ChangeParam)
08409 {
08410 ERROR2IF(pNodeBlender == NULL,AC_FAIL,"pNodeBlender is NULL");
08411
08412 UINT32 ActSize = sizeof(ChangeBlenderAction);
08413
08414 ChangeBlenderAction* pNewAction;
08415 ActionCode Ac = Action::Init(pOp,pActionList,ActSize,CC_RUNTIME_CLASS(ChangeBlenderAction),(Action**)&pNewAction);
08416
08417 if (Ac != AC_FAIL && pNewAction != NULL)
08418 {
08419 ChangeBlenderType ChangeType = ChangeParam.m_ChangeType;
08420
08421 pNewAction->m_pNodeBlender = pNodeBlender;
08422 pNewAction->m_ChangeParam.m_ChangeType = ChangeType;
08423
08424 pNewAction->m_ChangeParam.SetOldValues(pNodeBlender);
08425 switch (ChangeType)
08426 {
08427 case CHANGEBLENDER_ANGLESTART: pNodeBlender->SetAngleStart(ChangeParam.m_NewAngleStart); break;
08428 case CHANGEBLENDER_ANGLEEND: pNodeBlender->SetAngleEnd( ChangeParam.m_NewAngleEnd); break;
08429 case CHANGEBLENDER_PATHSTART:
08430 {
08431 pNodeBlender->SetProportionOfPathDistStart(ChangeParam.m_NewPathStart);
08432 pNodeBlender->SetUninitialised();
08433 }
08434 break;
08435 case CHANGEBLENDER_PATHEND:
08436 {
08437 pNodeBlender->SetProportionOfPathDistEnd(ChangeParam.m_NewPathEnd);
08438 pNodeBlender->SetUninitialised();
08439 }
08440 break;
08441 case CHANGEBLENDER_REGEN:
08442 {
08443 pNodeBlender->SetUninitialised();
08444 }
08445 break;
08446 case CHANGEBLENDER_NBPINDEX:
08447 {
08448 pNodeBlender->SetNodeBlendPathIndex(ChangeParam.m_NewNodeBlendPathIndex);
08449 }
08450 break;
08451 case CHANGEBLENDER_BLENDONCURVE:
08452 {
08453 pNodeBlender->SetBlendedOnCurve(ChangeParam.m_NewBlendedOnCurve);
08454 }
08455 break;
08456 case CHANGEBLENDER_SWAPENDS:
08457 {
08458 pNodeBlender->ReverseEnds();
08459 pNodeBlender->SetUninitialised();
08460 }
08461 break;
08462 default : ERROR2(AC_FAIL,"Unknown change blend type"); break;
08463 }
08464 pNewAction->m_ChangeParam.SetNewValues(pNodeBlender);
08465 }
08466
08467 return Ac;
08468 }
08469
08470
08471
08472
08473
08474
08475
08476
08477
08478
08479
08480
08481
08482
08483
08484
08485 ActionCode ChangeBlenderAction::Execute()
08486 {
08487 m_ChangeParam.SwapOldAndNew();
08488
08489 ActionCode Act;
08490 Act = ChangeBlenderAction::Init(pOperation,pOppositeActLst,m_pNodeBlender,m_ChangeParam);
08491
08492 return Act;
08493 }
08494
08495 ChangeBlenderAction::~ChangeBlenderAction()
08496 {
08497 }
08498
08499
08500
08501
08502
08503
08504
08505
08506
08507
08508
08509
08510
08511
08512
08513
08514
08515
08516
08517 void ChangeBlenderOpParam::SetOldValues(NodeBlender* pNodeBlender)
08518 {
08519 m_OldAngleStart = pNodeBlender->GetAngleStart();
08520 m_OldAngleEnd = pNodeBlender->GetAngleEnd();
08521 m_OldPathStart = pNodeBlender->GetProportionOfPathDistStart();
08522 m_OldPathEnd = pNodeBlender->GetProportionOfPathDistEnd();
08523 m_OldNodeBlendPathIndex = pNodeBlender->GetNodeBlendPathIndex();
08524 m_OldBlendedOnCurve = pNodeBlender->IsBlendedOnCurve();
08525 m_OldObjIndexEnd = pNodeBlender->GetObjIndexEnd();
08526 m_OldObjIndexStart = pNodeBlender->GetObjIndexStart();
08527
08528
08529 }
08530
08531
08532
08533
08534
08535
08536
08537
08538
08539
08540
08541
08542
08543
08544
08545 void ChangeBlenderOpParam::SetNewValues(NodeBlender* pNodeBlender)
08546 {
08547 m_NewAngleStart = pNodeBlender->GetAngleStart();
08548 m_NewAngleEnd = pNodeBlender->GetAngleEnd();
08549 m_NewPathStart = pNodeBlender->GetProportionOfPathDistStart();
08550 m_NewPathEnd = pNodeBlender->GetProportionOfPathDistEnd();
08551 m_NewNodeBlendPathIndex = pNodeBlender->GetNodeBlendPathIndex();
08552 m_NewBlendedOnCurve = pNodeBlender->IsBlendedOnCurve();
08553 m_NewObjIndexEnd = pNodeBlender->GetObjIndexEnd();
08554 m_NewObjIndexStart = pNodeBlender->GetObjIndexStart();
08555 }
08556
08557
08558
08559
08560
08561
08562
08563
08564
08565
08566
08567
08568
08569
08570
08571 void ChangeBlenderOpParam::SwapOldAndNew()
08572 {
08573 SWAP(double,m_NewAngleStart,m_OldAngleStart);
08574 SWAP(double,m_NewAngleEnd ,m_OldAngleEnd);
08575 SWAP(double,m_NewPathStart, m_OldPathStart);
08576 SWAP(double,m_NewPathEnd, m_OldPathEnd);
08577 SWAP(UINT32, m_NewNodeBlendPathIndex, m_OldNodeBlendPathIndex);
08578 SWAP(BOOL, m_OldBlendedOnCurve, m_NewBlendedOnCurve);
08579 SWAP(INT32, m_OldObjIndexStart, m_NewObjIndexStart);
08580 SWAP(INT32, m_OldObjIndexEnd, m_NewObjIndexEnd);
08581 }
08582
08583
08584
08585
08586
08587
08588
08589
08590
08591
08592
08593
08594
08595
08596
08597
08598 InvalidateBoundsAction::InvalidateBoundsAction()
08599 {
08600 m_pNode = NULL;
08601 m_IncludeChildren = FALSE;
08602 }
08603
08604
08605
08606
08607
08608
08609
08610
08611
08612
08613
08614
08615
08616
08617
08618
08619
08620
08621
08622
08623
08624
08625
08626
08627
08628
08629
08630
08631
08632
08633
08634
08635 ActionCode InvalidateBoundsAction::Init(Operation* pOp,
08636 ActionList* pActionList,
08637 NodeRenderableBounded* pNode,
08638 BOOL IncludeChildren)
08639 {
08640 ERROR2IF(pNode == NULL,AC_FAIL,"pNode is NULL");
08641
08642 UINT32 ActSize = sizeof(InvalidateBoundsAction);
08643
08644 InvalidateBoundsAction* pNewAction;
08645 ActionCode Ac = Action::Init(pOp,pActionList,ActSize,CC_RUNTIME_CLASS(InvalidateBoundsAction),(Action**)&pNewAction);
08646
08647 if (Ac != AC_FAIL && pNewAction != NULL)
08648 {
08649 pNewAction->m_pNode = pNode;
08650 pNewAction->m_IncludeChildren = IncludeChildren;
08651
08652 pNode->InvalidateBoundingRect(IncludeChildren);
08653 }
08654
08655 return Ac;
08656 }
08657
08658
08659
08660
08661
08662
08663
08664
08665
08666
08667
08668
08669
08670
08671
08672
08673 ActionCode InvalidateBoundsAction::Execute()
08674 {
08675 ActionCode Act;
08676 Act = InvalidateBoundsAction::Init(pOperation,pOppositeActLst,m_pNode,m_IncludeChildren);
08677
08678 return Act;
08679 }
08680
08681 InvalidateBoundsAction::~InvalidateBoundsAction()
08682 {
08683 }
08684
08685
08686
08687
08688
08689
08690
08691
08692
08693
08694
08695
08696
08697
08698
08699
08700
08701
08702
08703
08704
08705 CompoundNodeTreeFactoryList::~CompoundNodeTreeFactoryList()
08706 {
08707 CompoundNodeTreeFactoryListItem * pItem = (CompoundNodeTreeFactoryListItem *)GetHead();
08708
08709 while (pItem)
08710 {
08711 delete pItem->pFactory;
08712 pItem->pFactory = NULL;
08713
08714 pItem = (CompoundNodeTreeFactoryListItem *)GetNext(pItem);
08715 }
08716
08717 List::DeleteAll();
08718 }
08719
08720
08721
08722
08723
08724
08725
08726
08727
08728
08729
08730
08731
08732
08733
08734
08735 void CompoundNodeTreeFactoryList::AddItem(CompoundNodeTreeFactory *pItem)
08736 {
08737
08738 BOOL bAdd = TRUE;
08739
08740 CompoundNodeTreeFactoryListItem * pListItem = (CompoundNodeTreeFactoryListItem *)GetHead();
08741
08742 while (pListItem && bAdd)
08743 {
08744 if (pListItem->pFactory->GetRuntimeClass() == pItem->GetRuntimeClass())
08745 {
08746 bAdd = FALSE;
08747 }
08748
08749 pListItem = (CompoundNodeTreeFactoryListItem *)GetNext(pListItem);
08750 }
08751
08752 if (bAdd)
08753 {
08754 pListItem = new CompoundNodeTreeFactoryListItem;
08755 pListItem->pFactory = pItem;
08756 AddTail(pListItem);
08757 }
08758 }
08759
08760
08761
08762
08763
08764
08765
08766
08767
08768
08769
08770
08771
08772
08773
08774 CompoundNodeTreeFactory * CompoundNodeTreeFactoryList::GetItem(INT32 index)
08775 {
08776 if( index >= INT32(GetCount()) )
08777 return NULL;
08778
08779 CompoundNodeTreeFactoryListItem * pItem = (CompoundNodeTreeFactoryListItem *)GetHead();
08780
08781 for (INT32 i = 0 ; i < index; i++)
08782 {
08783 pItem = (CompoundNodeTreeFactoryListItem *)GetNext(pItem);
08784 }
08785
08786 return pItem->pFactory;
08787 }
08788
08789
08790
08791
08792
08793
08794
08795
08796
08797
08798
08799
08800
08801
08802 OpEditBlendEndObject::OpEditBlendEndObject(BlendTool* pBlendTool)
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 }
08815
08816
08817
08818
08819
08820
08821
08822
08823
08824
08825
08826
08827
08828
08829 OpEditBlendEndObject::~OpEditBlendEndObject()
08830 {
08831 delete m_pTransMatrix;
08832 delete m_pSelState;
08833 }
08834
08835
08836
08837
08838
08839
08840
08841
08842
08843
08844
08845
08846
08847 BOOL OpEditBlendEndObject::Declare()
08848 {
08849 return (RegisterOpDescriptor(
08850 0,
08851 0,
08852 CC_RUNTIME_CLASS(OpEditBlendEndObject),
08853 OPTOKEN_EDITBLENDENDOBJECT,
08854 OpEditBlendEndObject::GetState,
08855 0,
08856 _R(IDBBL_NOOP),
08857 0
08858 ));
08859 }
08860
08861
08862
08863
08864
08865
08866
08867
08868
08869
08870
08871
08872
08873
08874
08875
08876 OpState OpEditBlendEndObject::GetState(String_256* Description, OpDescriptor*)
08877 {
08878 OpState State;
08879
08880 return State;
08881 }
08882
08883
08884
08885
08886
08887
08888
08889
08890
08891
08892
08893
08894
08895
08896
08897
08898
08899
08900
08901
08902
08903
08904
08905
08906
08907
08908
08909
08910
08911
08912
08913 BOOL OpEditBlendEndObject::DoDrag(DocCoord PointerPos, Spread* pSpread)
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
08946 pNodeUnderPoint = NodeRenderableInk::FindSimpleAtPoint(pSpread, PointerPos);
08947
08948 if (pNodeUnderPoint == NULL)
08949 {
08950
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
08966 m_pNodeBlend = (NodeBlend*)pParent;
08967
08968 }
08969
08970 BlendList.DeleteAll();
08971
08972 NodeRenderableInk* pGroupUnderPoint = NodeRenderableInk::FindInnerCompound(pNodeUnderPoint, m_pNodeBlend);
08973
08974 Node* pNodeToEdit = NULL;
08975
08976 if (pGroupUnderPoint != NULL)
08977 {
08978
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
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
09019
09020
09021
09022 Action* pRestoreAction;
09023 SelectionState* pCopySelState = NULL;
09024 ALLOC_WITH_FAIL(pCopySelState, new SelectionState, this);
09025 pCopySelState->Record();
09026
09027 ok = RestoreSelectionsAction::Init(this, &UndoActions, pCopySelState,
09028 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE,
09029 &pRestoreAction);
09030
09031
09032
09033
09034
09035
09036
09037
09038
09039
09040
09041
09042
09043
09044
09045
09046 if (ok)
09047 {
09048 NodeRenderableInk::DeselectAll();
09049 ((NodeRenderable*)pNodeToEdit)->Select(TRUE);
09050
09051
09052 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
09053 if (BlobMgr != NULL)
09054 {
09055
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
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
09079 StartDrag( DRAGTYPE_AUTOSCROLL );
09080 }
09081 else
09082 {
09083 FailAndExecute();
09084 End();
09085 }
09086 return ok;
09087 }
09088
09089
09090
09091
09092
09093
09094
09095
09096
09097
09098
09099
09100
09101
09102
09103
09104
09105
09106
09107
09108
09109 void OpEditBlendEndObject::DragPointerMove(DocCoord PointerPos, ClickModifiers ClickMods, Spread* pSpread, BOOL bSolidDrag)
09110 {
09111
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();
09120 return;
09121 }
09122
09123 RenderDragBlobs(pSpread, PointOnLine, TRUE);
09124
09125
09126 m_LastCoord = PointOnLine;
09127
09128
09129
09130 }
09131
09132
09133
09134
09135
09136
09137
09138
09139
09140
09141
09142
09143
09144
09145
09146 void OpEditBlendEndObject::DragPointerIdle(DocCoord PointerPos, ClickModifiers Clickmodifiers, Spread* pSpread, BOOL bSolidDrag)
09147 {
09148
09149 m_pRange->RenderXOROutlinesOn(NULL, pSpread, m_pTransMatrix, NULL);
09150 }
09151
09152
09153
09154
09155
09156
09157
09158
09159
09160
09161
09162
09163
09164
09165
09166
09167
09168
09169
09170
09171 void OpEditBlendEndObject::DragFinished(DocCoord PointerPos, ClickModifiers ClickMods, Spread* pSpread, BOOL Success, BOOL bSolidDrag)
09172 {
09173 GetApplication()->RemoveIdleProcessor(IDLEPRIORITY_HIGH, this);
09174
09175 DocCoord PointOnLine;
09176
09177 BOOL ValidPoint = GetClosestPointOnPath(PointerPos, &PointOnLine);
09178 if (!ValidPoint)
09179 {
09180 EndDrag();
09181 return;
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
09194
09195 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
09196 if (BlobMgr != NULL)
09197 {
09198
09199 BlobStyle MyBlobs;
09200
09201 MyBlobs.Object = TRUE;
09202 MyBlobs.Tiny = FALSE;
09203
09204 BlobMgr->ToolInterest(MyBlobs);
09205 }
09206
09207
09208 m_pSelState->Restore();
09209 if (Success)
09210 {
09211 SelRange* pSel = GetApplication()->FindSelection();
09212 pSel->Update();
09213 }
09214 else
09215 FailAndExecute();
09216
09217
09218 ObjChangeFlags cFlags;
09219 ObjChangeParam ObjChange(OBJCHANGE_FINISHED, cFlags, NULL, this);
09220
09221 UpdateChangedNodes(&ObjChange);
09222 End();
09223
09224
09225
09226 }
09227
09228
09229
09230
09231
09232
09233
09234
09235
09236
09237
09238
09239
09240
09241
09242
09243
09244 BOOL OpEditBlendEndObject::RecalculateBlend(DocCoord EndPosition)
09245 {
09246
09247 if (m_pNodeBlend == NULL)
09248 {
09249 ERROR3("NodeBlend is not initialised");
09250 return FALSE;
09251 }
09252
09253
09254 if (m_pNodeBlendPath == NULL)
09255 {
09256 ERROR3("NodeBlend is not on a path");
09257 return FALSE;
09258 }
09259
09260 double PathLength = m_pNodeBlendPath->GetPathLength();
09261 INT32 DistanceAlongPath = 0;
09262 BOOL Valid = m_pNodeBlendPath->InkPath.GetDistanceToPoint(EndPosition, &DistanceAlongPath);
09263
09264
09265
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
09279
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 }
09297
09298
09299
09300
09301
09302
09303
09304
09305
09306
09307
09308
09309
09310
09311
09312
09313
09314
09315
09316
09317
09318
09319
09320 BOOL OpEditBlendEndObject::InsertChangeEndActions(double NewPathProp, DocCoord NewPosition,
09321 Node* pNodeToEdit)
09322 {
09323
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
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
09351 if (Valid)
09352 Valid = InsertChangeProportion(NewPathProp, NodeIsFirst, pNodeBlender);
09353
09354 double AngleChange = 0.0;
09355
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
09379
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
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
09400 if (Valid)
09401 Valid = m_pNodeBlend->TransformNodeToPoint((NodeRenderableInk*)pNodeToEdit,&NewPosition,this,AngleChange);
09402
09403
09404 if (Valid)
09405 {
09406 BOOL OtherEnd;
09407 NodeBlender* pOtherBlender = m_pNodeBlend->NodeIsPartOfBlender( pNodeToEdit, pNodeBlender, &OtherEnd);
09408 if (pOtherBlender != NULL && pOtherBlender != pNodeBlender)
09409 {
09410
09411 if (!pOtherBlender->IsBlendedOnCurve())
09412 {
09413 ChangeBlenderOpParam Param;
09414 Param.m_ChangeType = CHANGEBLENDER_REGEN;
09415 Valid = ChangeBlenderAction::Init(this, &UndoActions, pOtherBlender, Param);
09416 }
09417
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
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 }
09464
09465
09466
09467
09468
09469
09470
09471
09472
09473
09474
09475
09476
09477
09478
09479
09480
09481
09482
09483
09484
09485
09486
09487
09488
09489 BOOL OpEditBlendEndObject::InsertChangeEndActions(double NewPathProp, DocCoord NewPosition,
09490 double StepDistance, Node* pNodeToEdit)
09491 {
09492
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
09509 BOOL NodeIsFirst;
09510 NodeBlender* pNodeBlender = GetBlenderAndPosition(pNodeToEdit, &NodeIsFirst);
09511 if (pNodeBlender == NULL)
09512 {
09513 ERROR3("No NodeBlender");
09514 return FALSE;
09515 }
09516
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
09532
09533
09534 if (NodeIsFirst)
09535 {
09536
09537 if (NewPathProp >= EndProp)
09538 {
09539
09540 Valid = InsertChangeProportion(NewPathProp, NodeIsFirst, pNodeBlender);
09541
09542 if (Valid) Valid = m_pNodeBlend->GetStartAndEndProportions(&StartProp, &EndProp);
09543
09544 OtherDistance = BlendDistance * StartProp;
09545 ThisDistance = BlendDistance * (1-NewPathProp);
09546
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
09580
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
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
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
09629 Valid = InsertChangeProportion(NewPathProp, NodeIsFirst, pNodeBlender);
09630
09631
09632 if (Valid) Valid = InsertChangeProportion(NewOtherProp, (!NodeIsFirst), pOtherBlender);
09633
09634
09635 if (Valid) Valid = m_pNodeBlend->TransformNodeToPoint((NodeRenderableInk*)pNodeToEdit,&NewPosition,this,0.0);
09636
09637
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
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 }
09665
09666
09667
09668
09669
09670
09671
09672
09673
09674
09675
09676
09677
09678
09679
09680
09681
09682
09683 BOOL OpEditBlendEndObject::InsertChangeProportion(double NewProp, BOOL FirstNode,
09684 NodeBlender* pEditBlender)
09685 {
09686
09687 ChangeBlenderOpParam BlenderParam;
09688 ChangeBlendOpParam BlendParam;
09689
09690 BOOL Valid;
09691
09692 if (FirstNode)
09693 {
09694
09695
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
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
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
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
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 }
09765
09766
09767
09768
09769
09770
09771
09772
09773
09774
09775
09776
09777
09778
09779
09780
09781
09782
09783
09784
09785
09786
09787
09788
09789
09790
09791
09792
09793
09794
09795
09796
09797
09798
09799
09800
09801
09802
09803
09804
09805
09806 BOOL OpEditBlendEndObject::CalculateNewNumStepsAndPosition(UINT32 OldNumSteps, double BlendDistance,
09807 double StepDistance, double* FixedDistance,
09808 double* MoveableDistance, UINT32* NewNumSteps)
09809 {
09810
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
09823 *NewNumSteps = 0;
09824
09825
09826 double DistanceUsed = BlendDistance - (*FixedDistance + *MoveableDistance);
09827
09828
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
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
09851
09852
09853 return FALSE;
09854 }
09855 }
09856
09857
09858 if (*NewNumSteps > 0)
09859 return TRUE;
09860 else
09861 return FALSE;
09862 }
09863
09864
09865
09866
09867
09868
09869
09870
09871
09872
09873
09874
09875
09876
09877
09878
09879
09880
09881
09882
09883
09884
09885
09886
09887 NodeBlender* OpEditBlendEndObject::GetBlenderAndPosition(Node* pEditNode, BOOL* pFirst)
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
09919
09920 if (pBlender->GetNodeStart ()->IsNodeInSubtree (pEditNode))
09921 {
09922 *pFirst = TRUE;
09923 return pBlender;
09924 }
09925 else
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
09939 ERROR3("Couldn't find a nodeblender");
09940 return NULL;
09941
09942
09943 }
09944
09945
09946
09947
09948
09949
09950
09951
09952
09953
09954
09955
09956
09957
09958
09959
09960
09961
09962 BOOL OpEditBlendEndObject::GetClosestPointOnPath(DocCoord PointerPos, DocCoord* ClosestPoint)
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
10001 *ClosestPoint = PointOnLine;
10002
10003 m_pNodeBlendPath = pNodeBlendPath;
10004 }
10005 else
10006 {
10007 INT32 Index=0;
10008 double Mu=0;
10009 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 }
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039 void OpEditBlendEndObject::GetOpName(String_256 * OpName)
10040 {
10041 String_256 test = "test string";
10042
10043
10044 }
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061 void OpEditBlendEndObject::RenderDragBlobs(Spread* pSpread, DocCoord CentrePosition, BOOL On)
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
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
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 }
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131 void OpEditBlendEndObject::RenderSelectedObjectBlobs(Spread* pSpread)
10132 {
10133
10134 Node** pSelectionNodes = NULL;
10135 UINT32 NumNodes = 0;
10136 SelNdRng* pSelectedRanges = NULL;
10137 UINT32 NumRanges = 0;
10138
10139
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
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
10195 pOnTopRegion = DocView::GetNextOnTop(NULL);
10196 }
10197 }
10198
10199
10200 }
10201
10202
10203
10204
10205
10206