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
00104 #include "camtypes.h"
00105
00106
00107
00108
00109
00110 #include "pentool.h"
00111 #include "oilfiles.h"
00112
00113
00114 #include "csrstack.h"
00115 #include "blobs.h"
00116
00117
00118
00119 #include "nodepath.h"
00120
00121 #include "osrndrgn.h"
00122 #include "penedit.h"
00123
00124 #include "pathedit.h"
00125 #include "cutop.h"
00126
00127 #include "keypress.h"
00128
00129 #include "opbreak.h"
00130 #include "vkextra.h"
00131 #include "nodepath.h"
00132
00133
00134
00135
00136 TCHAR* PenTool::FamilyName = _T("Drawing Tools");
00137 TCHAR* PenTool::ToolName = _T("Pen Tool");
00138 TCHAR* PenTool::Purpose = _T("To draw lines and curves");
00139 TCHAR* PenTool::Author = _T("Mike");
00140
00141
00142 CC_IMPLEMENT_MEMDUMP( PenTool, Tool_v1 )
00143 CC_IMPLEMENT_DYNCREATE( PenToolInfoBarOp, InformationBarOp )
00144
00145
00146 #define new CAM_DEBUG_NEW
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 PenTool::PenTool()
00163 {
00164 pcPenCursor = NULL;
00165 pcPenAdjustCursor = NULL;
00166 pcPenReshapeCursor = NULL;
00167 pcMoveBezCursor = NULL;
00168 MyCurrentCursor = NULL;
00169
00170 CurrPenState = IS_Undefined;
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 PenTool::~PenTool()
00187 {
00188
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 BOOL PenTool::Init()
00205 {
00206
00207 BOOL ok;
00208 CCResTextFile file;
00209 PenToolInfoBarOpCreate BarCreate;
00210
00211
00212
00213 pPenInfoBarOp = NULL;
00214
00215
00216 pcPenCursor = 0;
00217
00218 pPenInfoBarOp = new PenToolInfoBarOp();
00219 ok = (pPenInfoBarOp != NULL);
00220 if (ok) pPenInfoBarOp->pPenTool = this;
00221
00222 #if 0
00223 ok = file.open(_R(IDM_PENTOOL_BAR), _R(IDT_INFO_BAR_RES));
00224 if (ok) ok = DialogBarOp::ReadBarsFromFile(file,BarCreate);
00225 if (ok) file.close();
00226
00227 ENSURE(ok,"Unable to load penbar.ini from resource\n");
00228
00229 if (ok)
00230 {
00231
00232 String_32 str = String_32(_R(IDS_PENTOOL_INFOBARNAME));
00233 DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(str);
00234
00235 ok = (pDialogBarOp != NULL);
00236 if (ok) ok = pDialogBarOp->IsKindOf(CC_RUNTIME_CLASS(PenToolInfoBarOp));
00237 if (ok) pPenInfoBarOp = (PenToolInfoBarOp*)pDialogBarOp;
00238 if (ok) pPenInfoBarOp->pPenTool = this;
00239
00240 ENSURE(ok,"Failed to create PENTOOL info bar");
00241 }
00242 #endif
00243
00244 if (ok) ok = EditPath.Initialise(12,24);
00245
00246
00247 if (ok)
00248 {
00249 ok = OpPenCreateInternal::Init();
00250 if (ok) ok = OpPenEditInternal::Init();
00251 if (ok) ok = OpPenCreatePath::Init();
00252 if (ok) ok = OpPenAddElement::Init();
00253 if (ok) ok = OpAddNewPath::Init();
00254 if (ok) ok = OpPenClosePath::Init();
00255 }
00256
00257 return ok;
00258
00259 }
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 void PenTool::Describe(void *InfoPtr)
00278 {
00279
00280 ToolInfo_v1 *Info = (ToolInfo_v1 *) InfoPtr;
00281
00282 Info -> InfoVersion = 1;
00283
00284 Info -> InterfaceVersion = GetToolInterfaceVersion();
00285
00286
00287 Info -> Version = 1;
00288 Info -> ID = GetID();
00289 Info -> TextID = _R(IDS_PEN_TOOL);
00290
00291 Info -> Family = FamilyName;
00292 Info -> Name = ToolName;
00293 Info -> Purpose = Purpose;
00294 Info -> Author = Author;
00295
00296 Info -> InfoBarDialog = _R(IDD_FREEHANDTOOL);
00297
00298 Info -> BubbleID = _R(IDBBL_PEN_TOOL);
00299
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 void PenTool::SelectChange(BOOL isSelected)
00320 {
00321 if (isSelected)
00322 {
00323
00324
00325
00326
00327 MyCurrentCursor = NULL;
00328
00329 if (!CreatePenCursors())
00330 return;
00331
00332 CurrentCursorID = CursorStack::GPush(pcPenCursor, FALSE);
00333 MyCurrentCursor = pcPenCursor;
00334
00335
00336 if (pPenInfoBarOp != NULL)
00337 pPenInfoBarOp->Create();
00338
00339
00340 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00341 if (BlobMgr != NULL)
00342 {
00343
00344 BlobStyle MyBlobs;
00345 MyBlobs.Pen = TRUE;
00346
00347
00348 BlobMgr->ToolInterest(MyBlobs);
00349 }
00350
00351
00352
00353 CurrPenState = IS_Undefined;
00354
00355
00356
00357
00358
00359
00360
00361
00362 }
00363 else
00364 {
00365
00366 if (MyCurrentCursor)
00367 {
00368 CursorStack::GPop(CurrentCursorID);
00369 MyCurrentCursor = NULL;
00370 CurrentCursorID = 0;
00371 }
00372 DeletePenCursors();
00373
00374
00375 if (pPenInfoBarOp != NULL)
00376 pPenInfoBarOp->Delete();
00377
00378
00379 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00380 if (BlobMgr != NULL)
00381 {
00382 BlobStyle bsRemoves;
00383 bsRemoves.ToolObject = TRUE;
00384 BlobMgr->RemoveInterest(bsRemoves);
00385 }
00386
00387 ClearInternalState();
00388 }
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 BOOL PenTool::CreatePenCursors()
00407 {
00408 pcPenAdjustCursor = new Cursor(this, _R(IDC_PENADJUSTCURSOR));
00409 if (!pcPenAdjustCursor || !pcPenAdjustCursor->IsValid())
00410 {
00411 DeletePenCursors();
00412 InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
00413 return FALSE;
00414 }
00415
00416 pcPenCursor = new Cursor(this, _R(IDC_NEWPATHCURSOR));
00417 if (!pcPenCursor || !pcPenCursor->IsValid())
00418 {
00419 DeletePenCursors();
00420 InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
00421 return FALSE;
00422 }
00423
00424 pcPenReshapeCursor = new Cursor(this, _R(IDC_RESHAPECURSOR));
00425 if (!pcPenReshapeCursor || !pcPenReshapeCursor->IsValid())
00426 {
00427 DeletePenCursors();
00428 InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
00429 return FALSE;
00430 }
00431
00432 pcMoveBezCursor = new Cursor(this, _R(IDC_MOVEBEZIERCURSOR));
00433 if (!pcMoveBezCursor || !pcMoveBezCursor->IsValid())
00434 {
00435 DeletePenCursors();
00436 InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
00437 return FALSE;
00438 }
00439
00440 return TRUE;
00441 }
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 void PenTool::DeletePenCursors()
00458 {
00459 if (pcPenCursor!=NULL)
00460 {
00461 delete pcPenCursor;
00462 pcPenCursor=NULL;
00463 }
00464
00465 if (pcPenAdjustCursor!=NULL)
00466 {
00467 delete pcPenAdjustCursor;
00468 pcPenAdjustCursor=NULL;
00469 }
00470
00471 if (pcPenReshapeCursor!=NULL)
00472 {
00473 delete pcPenReshapeCursor;
00474 pcPenReshapeCursor=NULL;
00475 }
00476
00477 if (pcMoveBezCursor!=NULL)
00478 {
00479 delete pcMoveBezCursor;
00480 pcMoveBezCursor=NULL;
00481 }
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 MsgResult PenToolInfoBarOp::Message(Msg* Message)
00501 {
00502 if (MESSAGE_IS_A(Message,OpMsg))
00503 {
00504 OpMsg* pOpMsg = (OpMsg*)Message;
00505
00506 if (pOpMsg->MsgType == OpMsg::AFTER_UNDO)
00507 {
00508 pPenTool->ClearInternalState();
00509 }
00510
00511 if (pOpMsg->MsgType == OpMsg::END)
00512 {
00513
00514
00515 if (IS_A(pOpMsg->pOp, OpPenCreateInternal) ||
00516 IS_A(pOpMsg->pOp, OpPenEditInternal))
00517 if (pPenTool->GetPenOpState() == OS_EditInternal)
00518 {
00519 if (!(pOpMsg->pOp->GetOpFlgs()).Failed)
00520 pPenTool->SetInternalState();
00521 pPenTool->ClearOp();
00522 }
00523
00524 if (IS_A(pOpMsg->pOp, OpPenCreatePath))
00525 if (pPenTool->GetPenOpState() == OS_CreatePath)
00526 {
00527 if (!(pOpMsg->pOp->GetOpFlgs()).Failed)
00528 pPenTool->CreateNewPath();
00529 pPenTool->ClearPath();
00530 pPenTool->ClearOp();
00531 }
00532
00533 if (IS_A(pOpMsg->pOp, OpPenAddElement))
00534 if (pPenTool->GetPenOpState() == OS_AddElement)
00535 {
00536 if (!(pOpMsg->pOp->GetOpFlgs()).Failed)
00537 pPenTool->AddElementToPath();
00538 pPenTool->ClearPath();
00539 pPenTool->ClearOp();
00540 }
00541
00542 if (IS_A(pOpMsg->pOp, OpPenClosePath))
00543 if (pPenTool->GetPenOpState() == OS_ClosePath)
00544 {
00545 if (!(pOpMsg->pOp->GetOpFlgs()).Failed)
00546 pPenTool->CloseWithPath();
00547 pPenTool->ClearPath();
00548 pPenTool->ClearOp();
00549 }
00550 }
00551 }
00552 else if (MESSAGE_IS_A(Message,DocChangingMsg))
00553 {
00554 DocChangingMsg* pDocChangingMsg = (DocChangingMsg*)Message;
00555
00556
00557 switch (pDocChangingMsg->State)
00558 {
00559 case DocChangingMsg::SELCHANGED:
00560 case DocChangingMsg::KILLED:
00561 pPenTool->ClearInternalState();
00562 break;
00563 default:
00564 break;
00565 }
00566 }
00567
00568
00569 return (DialogBarOp::Message(Message));
00570 }
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 void PenTool::OnClick( DocCoord PointerPos, ClickType Click, ClickModifiers ClickMods,
00593 Spread* pSpread )
00594 {
00595 if (ClickMods.Menu) return;
00596
00597
00598 penclick WhatToDo = DetermineClickEffect(PointerPos, pSpread, &pNodePath);
00599
00600
00601 if (Click==CLICKTYPE_SINGLE && ClickMods.Adjust && WhatToDo!=PenOnPoint)
00602 {
00603 RemoveSelection(PointerPos,pSpread);
00604 ClearInternalState();
00605 return;
00606 }
00607
00608 switch (Click)
00609 {
00610 case CLICKTYPE_SINGLE:
00611 switch (WhatToDo)
00612 {
00613 case PenNewPath:
00614 {
00615 BOOL MakeInternal = TRUE;
00616 if ((CurrPenState == IS_MoveTo) || (CurrPenState == IS_DragTo))
00617 {
00618
00619
00620
00621 if (EditHandles.pHndSpread==pSpread)
00622 {
00623 MakeInternal = FALSE;
00624 OpPenCreatePath* pOpCreatePath = new OpPenCreatePath;
00625 if (pOpCreatePath!=NULL)
00626 {
00627 pOpCreatePath->DoPenCreatePath(&EditHandles, PointerPos, pSpread, &EditPath);
00628 CurrPenOpState = OS_CreatePath;
00629 }
00630 }
00631 }
00632
00633 if (MakeInternal)
00634 {
00635
00636
00637 RemoveSelection(PointerPos,pSpread);
00638 OpPenCreateInternal* pOpCreateInternal = new OpPenCreateInternal;
00639 if (pOpCreateInternal!=NULL)
00640 {
00641 pOpCreateInternal->DoPenCreateInternal(PointerPos, pSpread, &EditHandles);
00642 CurrPenOpState = OS_EditInternal;
00643 }
00644 }
00645 }
00646 break;
00647
00648 case PenClosePath:
00649 {
00650 NodeIndex = pNodePath->InkPath.GetPathPosition();
00651 OpPenClosePath* pOpPenClosePath = new OpPenClosePath;
00652 if (pOpPenClosePath!=NULL)
00653 {
00654 pOpPenClosePath->DoPenClosePath(pNodePath, NodeIndex, pSpread, &EditPath);
00655 CurrPenOpState = OS_ClosePath;
00656 }
00657 }
00658 break;
00659
00660 case PenOnPoint:
00661 {
00662
00663
00664
00665 RemoveSelection(PointerPos,pSpread,pNodePath);
00666 ClickOnEndPoint(Click, ClickMods, pSpread, pNodePath);
00667 }
00668 break;
00669
00670 case PenAddSegment:
00671 {
00672 NodeIndex = pNodePath->InkPath.GetPathPosition();
00673 OpPenAddElement* pOpPenAddElement = new OpPenAddElement;
00674 if (pOpPenAddElement!=NULL)
00675 {
00676 pOpPenAddElement->DoPenAddElement(pNodePath, NodeIndex, PointerPos, pSpread, &EditPath);
00677 CurrPenOpState = OS_AddElement;
00678 }
00679 }
00680 break;
00681
00682 case PenEditInternalMove:
00683 {
00684 OpPenEditInternal* pOpEditInternal = new OpPenEditInternal;
00685 if (pOpEditInternal!=NULL)
00686 {
00687 pOpEditInternal->DoPenEditInternal(&EditHandles);
00688 CurrPenOpState = OS_EditInternal;
00689 }
00690 }
00691 break;
00692
00693 case PenReshapeLine:
00694 {
00695 double pdist;
00696 INT32 tempel;
00697 pNodePath->InkPath.SqrDistanceToPoint(PointerPos, &tempel, &pdist);
00698 INT32 PathPos = pNodePath->InkPath.GetPathPosition();
00699
00700 OpReshapeOrAddPoint* pOpReshape = new OpReshapeOrAddPoint;
00701 if (pOpReshape!=NULL)
00702 pOpReshape->DoStartDragEdit(pNodePath, PointerPos, pSpread, PathPos, pdist);
00703 else
00704 InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
00705 }
00706 break;
00707
00708 }
00709 break;
00710
00711 case CLICKTYPE_DOUBLE:
00712 break;
00713
00714 case CLICKTYPE_DRAG:
00715 switch (WhatToDo)
00716 {
00717 case PenOnPoint:
00718 if (pNodePath)
00719 ClickOnEndPoint(Click, ClickMods, pSpread, pNodePath);
00720 break;
00721
00722 default:
00723 break;
00724 }
00725 break;
00726
00727 default:
00728 break;
00729 }
00730
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752 penclick PenTool::DetermineClickEffect(DocCoord PointerPos, Spread* pSpread, NodePath** ReturnNode )
00753 {
00754 penclick WhatToDo = PenNewPath;
00755 NodePath* WhichNode = NULL;
00756
00757
00758 DocView* pDocView = DocView::GetSelected();
00759 ENSURE( pDocView != NULL, "PenTool::DetermineClickEffect: Can't find selected DocView");
00760 if (pDocView==NULL)
00761 return(PenNewPath);
00762
00763
00764 DocRect BlobRect;
00765 OSRenderRegion::GetBlobRect(pDocView->GetViewScale(), PointerPos, BT_SELECTEDLARGEST, &BlobRect);
00766
00767
00768
00769 if (CurrPenState == IS_MoveTo || CurrPenState == IS_DragTo)
00770 {
00771 if (BlobRect.ContainsCoord(EditHandles.HndClick))
00772 return (PenEditInternalMove);
00773 }
00774
00775
00776
00777 SelRange* Selected = GetApplication()->FindSelection();
00778 Node* pNode = Selected->FindFirst();
00779
00780 INT32 TotSelectedEndpoints = 0;
00781 BOOL MultiSegments = FALSE;
00782
00783 if (pNode != NULL)
00784 {
00785 Spread* NodeSpread = pNode->FindParentSpread();
00786 if (NodeSpread == pSpread)
00787 {
00788
00789 while ((pNode!=NULL) && ((WhatToDo==PenNewPath) || (WhatToDo==PenAddSegment)))
00790 {
00791 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodePath))
00792 {
00793
00794
00795 Path* ThisPath = &(((NodePath*)pNode)->InkPath);
00796
00797
00798 INT32 NumCoords = ThisPath->GetNumCoords();
00799 PathFlags* Flags = ThisPath->GetFlagArray();
00800
00801
00802 INT32 NumSelectedEndpoints = 0;
00803 INT32 lastsel = 0;
00804 for (INT32 i=0; i<NumCoords; i++)
00805 {
00806 if (Flags[i].IsSelected && Flags[i].IsEndPoint)
00807 {
00808 lastsel = i;
00809 NumSelectedEndpoints++;
00810 }
00811 }
00812
00813 TotSelectedEndpoints+=NumSelectedEndpoints;
00814
00815 INT32 point;
00816
00817 if (ThisPath->FindNearestPoint(PointerPos, POINTFLAG_ENDPOINTS | POINTFLAG_ENDSFIRST, &point))
00818 {
00819 WhichNode = (NodePath*)pNode;
00820 WhatToDo = PenOnPoint;
00821 ThisPath->SetPathPosition(point);
00822
00823
00824
00825
00826 INT32 start = point;
00827 INT32 end = point;
00828 ThisPath->FindStartOfSubPath(&start);
00829 ThisPath->FindEndElOfSubPath(&end);
00830 if (point==start || point==end)
00831 {
00832 INT32 other;
00833 (point==start) ? (other=end) : (other=start);
00834 if ((Flags[other].IsSelected) && (!Flags[point].IsSelected))
00835 WhatToDo = PenClosePath;
00836 }
00837 continue;
00838 }
00839
00840
00841
00842 if (ThisPath->PointCloseToLine(PointerPos, &point))
00843 {
00844 WhichNode=(NodePath*)pNode;
00845 WhatToDo=PenReshapeLine;
00846 ThisPath->SetPathPosition(point);
00847 continue;
00848 }
00849
00850 if (!MultiSegments && NumSelectedEndpoints==1)
00851 {
00852 INT32 start = lastsel;
00853 INT32 end = lastsel;
00854 ThisPath->FindStartOfSubPath(&start);
00855 ThisPath->FindEndElOfSubPath(&end);
00856 if (lastsel==start || lastsel==end)
00857 {
00858 if (WhatToDo==PenNewPath)
00859 {
00860 WhichNode=(NodePath*)pNode;
00861 WhatToDo=PenAddSegment;
00862 ThisPath->SetPathPosition(lastsel);
00863 }
00864 else
00865 {
00866
00867
00868 WhichNode=(NodePath*)pNode;
00869 WhatToDo=PenNewPath;
00870 MultiSegments=TRUE;
00871 }
00872 }
00873 }
00874 }
00875
00876 pNode = Selected->FindNext(pNode);
00877 }
00878 }
00879 }
00880
00881
00882
00883
00884
00885 *ReturnNode = WhichNode;
00886 return (WhatToDo);
00887 }
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 void PenTool::ClickOnEndPoint( ClickType Click, ClickModifiers ClickMods, Spread *pSpread, NodePath* pNodePath )
00914 {
00915 Path* pPath = &(pNodePath->InkPath);
00916
00917 DocCoord* Coords = pPath->GetCoordArray();
00918 PathFlags* Flags = pPath->GetFlagArray();
00919 PathVerb* Verbs = pPath->GetVerbArray();
00920 INT32 NumCoords = pPath->GetNumCoords();
00921
00922
00923 INT32 Pos = pPath->GetPathPosition();
00924
00925
00926
00927
00928 switch (Click)
00929 {
00930 case CLICKTYPE_SINGLE:
00931 {
00932 if (Flags[Pos].IsEndPoint)
00933 {
00934 pPath->RenderPathPenBlobs(pSpread);
00935
00936 BOOL CurSelState = Flags[Pos].IsSelected;
00937 BOOL NewSelState = TRUE;
00938 BOOL ClearOthers = FALSE;
00939
00940
00941 if (ClickMods.Adjust)
00942 NewSelState = !CurSelState;
00943
00944
00945 if (!CurSelState && !ClickMods.Adjust)
00946 ClearOthers=TRUE;
00947
00948 if (ClearOthers)
00949 {
00950 for (INT32 i=0; i<NumCoords; i++)
00951 {
00952 Flags[i].IsSelected = FALSE;
00953 }
00954 }
00955
00956
00957 Flags[Pos].IsSelected = NewSelState;
00958
00959 if ((Pos>0) && (!Flags[Pos-1].IsEndPoint))
00960 Flags[Pos-1].IsSelected = NewSelState;
00961
00962 if ((Pos+1<NumCoords) && (!Flags[Pos+1].IsEndPoint))
00963 Flags[Pos+1].IsSelected = NewSelState;
00964
00965
00966
00967
00968 if (Verbs[Pos] == PT_MOVETO)
00969 {
00970
00971 INT32 j;
00972 for (j=Pos+1;j<NumCoords && Verbs[j] != PT_MOVETO;j++);
00973 j--;
00974 if (Verbs[j] & PT_CLOSEFIGURE)
00975 {
00976
00977 Flags[j].IsSelected = NewSelState;
00978
00979 if ((j>0) && (!Flags[j-1].IsEndPoint))
00980 {
00981
00982 Flags[j-1].IsSelected = NewSelState;
00983 }
00984 }
00985
00986 }
00987
00988 pPath->RenderPathPenBlobs(pSpread);
00989 }
00990 break;
00991 }
00992
00993 case CLICKTYPE_DOUBLE:
00994 break;
00995
00996 case CLICKTYPE_DRAG:
00997 {
00998 if ((Flags[Pos].IsEndPoint) && (!ClickMods.Menu))
00999 {
01000
01001 OpNodePathEditBlob* pOpNodePath = new OpNodePathEditBlob;
01002 if (pOpNodePath == NULL)
01003 InformError();
01004 else
01005 pOpNodePath->DoStartDragEdit(pNodePath, Coords[Pos], pSpread);
01006 }
01007 }
01008 break;
01009
01010 default:
01011 {
01012 }
01013 break;
01014 }
01015 }
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 BOOL PenTool::OnKeyPress(KeyPress* pKeyPress)
01035 {
01036
01037 if (pKeyPress->IsRelease())
01038 return FALSE;
01039
01040
01041
01042 if (*pKeyPress == KeyPress(CAMKEY(ESCAPE)))
01043 {
01044 if ((CurrPenState == IS_MoveTo) || (CurrPenState == IS_DragTo))
01045 {
01046 ClearInternalState();
01047 return TRUE;
01048 }
01049 }
01050
01051
01052 if (*pKeyPress == KeyPress(CAMKEY(B)))
01053 {
01054 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpBreakAtPoints));
01055 String_256 UIDesc;
01056 if (pOpDesc != NULL)
01057 {
01058 OpState State = OpBreakAtPoints::GetState(&UIDesc, pOpDesc);
01059 if (!State.Greyed)
01060 {
01061 pOpDesc->Invoke();
01062 return TRUE;
01063 }
01064 }
01065 }
01066
01067
01068 if ((pKeyPress->GetVirtKey() == CAMKEY(DELETE)) || (*pKeyPress == KeyPress(CAMKEY(BACK))) )
01069 {
01070 OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpDeletePoints));
01071 String_256 UIDesc;
01072 if (pOpDesc != NULL)
01073 {
01074 OpState State = OpDeletePoints::GetState(&UIDesc, NULL);
01075 if (!State.Greyed)
01076 {
01077 pOpDesc->Invoke();
01078 return TRUE;
01079 }
01080 }
01081 }
01082
01083
01084 return FALSE;
01085 }
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 void PenTool::OnMouseMove(DocCoord coord, Spread* pSpread, ClickModifiers mods)
01108 {
01109 NodePath* pNodePath = NULL;
01110 Cursor* whichCursor = NULL;
01111
01112
01113 penclick WhatToDo = DetermineClickEffect(coord, pSpread, &pNodePath);
01114
01115 String_256 StatusMsg("");
01116 GenerateStatusLineText(pNodePath, WhatToDo, &StatusMsg);
01117 GetApplication()->UpdateStatusBarText(&StatusMsg);
01118
01119 switch (WhatToDo)
01120 {
01121 case PenNewPath:
01122 case PenAddSegment:
01123 case PenEditInternalMove:
01124 whichCursor = pcPenCursor;
01125 break;
01126 case PenOnPoint:
01127 whichCursor = pcMoveBezCursor;
01128 break;
01129 case PenClosePath:
01130 whichCursor = pcPenAdjustCursor;
01131 break;
01132 case PenReshapeLine:
01133 whichCursor = pcPenReshapeCursor;
01134 break;
01135 default:
01136 whichCursor = pcPenCursor;
01137 }
01138 ChangeCursor(whichCursor);
01139 }
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161 BOOL PenTool::GetStatusLineText(String_256* ptext, Spread* pSpread, DocCoord coord, ClickModifiers mods)
01162 {
01163 ERROR1IF(ptext==NULL,FALSE,"PenTool::GetStatusLineText() passed a NULL text buffer");
01164
01165 *ptext = "";
01166
01167 NodePath* pNodePath = NULL;
01168
01169
01170 penclick WhatToDo = DetermineClickEffect(coord, pSpread, &pNodePath);
01171 GenerateStatusLineText(pNodePath, WhatToDo, ptext);
01172
01173 return TRUE;
01174 }
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200 void PenTool::GenerateStatusLineText(NodePath* pNodePath, penclick WhatToDo, String_256* pStatusMsg)
01201 {
01202 switch (WhatToDo)
01203 {
01204 case PenNewPath:
01205 switch(CurrPenState)
01206 {
01207 case IS_MoveTo:
01208 pStatusMsg->Load(_R(IDS_PENADDPOINT), Tool::GetModuleID(GetID()));
01209 break;
01210 case IS_DragTo:
01211 pStatusMsg->Load(_R(IDS_PENADDCURVE), Tool::GetModuleID(GetID()));
01212 break;
01213 default:
01214 pStatusMsg->Load(_R(IDS_PENNEWPATH), Tool::GetModuleID(GetID()));
01215 break;
01216 }
01217 break;
01218
01219 case PenAddSegment:
01220 if (pNodePath != NULL)
01221 {
01222 PathVerb Verb = (pNodePath->InkPath).GetVerb();
01223 PathFlags Flags = (pNodePath->InkPath).GetFlags();
01224 switch (Verb)
01225 {
01226 case PT_BEZIERTO:
01227 if (Flags.IsRotate)
01228 pStatusMsg->Load(_R(IDS_PENADDCURVE), Tool::GetModuleID(GetID()));
01229 else
01230 pStatusMsg->Load(_R(IDS_PENADDPOINT), Tool::GetModuleID(GetID()));
01231 break;
01232 default:
01233 pStatusMsg->Load(_R(IDS_PENADDPOINT), Tool::GetModuleID(GetID()));
01234 break;
01235 }
01236 }
01237 else
01238 pStatusMsg->Load(_R(IDS_PENADDPOINT), Tool::GetModuleID(GetID()));
01239 break;
01240
01241 case PenEditInternalMove:
01242 pStatusMsg->Load(_R(IDS_PENEDITINT), Tool::GetModuleID(GetID()));
01243 break;
01244
01245 case PenClosePath:
01246 pStatusMsg->Load(_R(IDS_PENCLOSEPATH), Tool::GetModuleID(GetID()));
01247 break;
01248
01249 case PenReshapeLine:
01250 pStatusMsg->Load(_R(IDS_RESHAPE_LINE),Tool::GetModuleID(GetID()));
01251 break;
01252
01253 case PenOnPoint:
01254 if (pNodePath != NULL)
01255 {
01256 PathFlags Flags = (pNodePath->InkPath).GetFlags();
01257 if (Flags.IsSelected)
01258 pStatusMsg->Load(_R(IDS_PENONSELPOINT), Tool::GetModuleID(GetID()));
01259 else
01260 pStatusMsg->Load(_R(IDS_PENONPOINT), Tool::GetModuleID(GetID()));
01261 }
01262 break;
01263
01264 default:
01265 pStatusMsg->Load(_R(IDS_PENADDPOINT), Tool::GetModuleID(GetID()));
01266 break;
01267 }
01268 }
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358 void PenTool::RemoveSelection( DocCoord PointerPos, Spread *pSpread, NodePath* pNodePath )
01359 {
01360
01361 SelRange* Selected = GetApplication()->FindSelection();
01362 Node* pNode = Selected->FindFirst();
01363 if (pNode && pNode->FindParentSpread() == pSpread )
01364 {
01365 while (pNode)
01366 {
01367 if (pNode!=pNodePath)
01368 {
01369 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodePath))
01370 {
01371 Path* ThisPath = &(((NodePath*)pNode)->InkPath);
01372 PathFlags* Flags = ThisPath->GetFlagArray();
01373 INT32 UsedSlots = ThisPath->GetNumCoords();
01374
01375 BOOL selected = FALSE;
01376 for (INT32 i=0; i<UsedSlots; i++)
01377 {
01378 if (Flags[i].IsSelected)
01379 {
01380 if (!selected)
01381 {
01382
01383 ThisPath->RenderPathPenBlobs(pSpread);
01384 selected = TRUE;
01385 }
01386 Flags[i].IsSelected=FALSE;
01387 }
01388 }
01389
01390 if (selected)
01391 ThisPath->RenderPathPenBlobs(pSpread);
01392 }
01393 }
01394 pNode = Selected->FindNext(pNode);
01395 }
01396 }
01397 }
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417 void PenTool::RenderToolBlobs(Spread* pSpread, DocRect* pClipRect)
01418 {
01419
01420 ERROR3IF(pSpread==NULL,"PenTool::RenderToolBlobs() called with a null spread");
01421
01422 RenderRegion* pRegion;
01423 DocCoord LastMove = EditHandles.HndClick;
01424 DocCoord LastDrag = EditHandles.HndDrag;
01425
01426 switch (CurrPenState)
01427 {
01428 case IS_MoveTo:
01429 pRegion = DocView::RenderOnTop(pClipRect, pSpread, ClippedEOR);
01430 while (pRegion)
01431 {
01432
01433 pRegion->SetLineColour(COLOUR_BEZIERBLOB);
01434 pRegion->SetFillColour(COLOUR_TRANS);
01435 pRegion->DrawBlob(LastMove,BT_SELECTED);
01436
01437
01438 pRegion = DocView::GetNextOnTop(pClipRect);
01439 }
01440 break;
01441
01442 case IS_DragTo:
01443 {
01444 pRegion = DocView::RenderOnTop(pClipRect, pSpread, ClippedEOR);
01445 DocCoord OtherDrag;
01446 OtherDrag.x = LastMove.x - (LastDrag.x - LastMove.x);
01447 OtherDrag.y = LastMove.y - (LastDrag.y - LastMove.y);
01448
01449 while (pRegion)
01450 {
01451
01452 pRegion->SetLineColour(COLOUR_BEZIERLINE);
01453 pRegion->DrawLine(OtherDrag,LastDrag);
01454 pRegion->SetLineColour(COLOUR_BEZIERBLOB);
01455 pRegion->SetFillColour(COLOUR_TRANS);
01456 pRegion->DrawBlob(LastMove,BT_SELECTED);
01457 pRegion->SetFillColour(COLOUR_UNSELECTEDBLOB);
01458 pRegion->SetLineColour(COLOUR_TRANS);
01459 pRegion->DrawBlob(LastDrag,BT_UNSELECTED);
01460 pRegion->DrawBlob(OtherDrag,BT_UNSELECTED);
01461
01462
01463 pRegion = DocView::GetNextOnTop(pClipRect);
01464 }
01465 break;
01466 }
01467 default:
01468 break;
01469 }
01470 }
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492 void PenTool::ChangeCursor(Cursor* cursor)
01493 {
01494
01495 if (cursor != MyCurrentCursor)
01496 {
01497
01498 CursorStack::GSetTop(cursor, CurrentCursorID);
01499
01500 MyCurrentCursor = cursor;
01501 }
01502 }
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523 void PenTool::SetInternalState()
01524 {
01525
01526 if (EditHandles.pHndSpread==NULL)
01527 return;
01528
01529 if (EditHandles.HndClick == EditHandles.HndDrag)
01530 CurrPenState = IS_MoveTo;
01531 else
01532 CurrPenState = IS_DragTo;
01533
01534
01535 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01536 ENSURE(BlobMgr!=NULL, "Blob Manager was not there");
01537 BlobMgr->RenderToolBlobsOn(this, EditHandles.pHndSpread, NULL);
01538
01539 }
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556 void PenTool::ClearInternalState()
01557 {
01558 if (CurrPenState == IS_MoveTo || CurrPenState == IS_DragTo)
01559 {
01560 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01561 ENSURE(BlobMgr!=NULL, "Blob Manager was not there");
01562 BlobMgr->RenderToolBlobsOff(this, EditHandles.pHndSpread,NULL);
01563 }
01564 CurrPenState = IS_Undefined;
01565 }
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585 void PenTool::ClearPath()
01586 {
01587
01588
01589 ClearInternalState();
01590 EditPath.ClearPath();
01591 }
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604 void PenTool::ClearOp()
01605 {
01606 CurrPenOpState = OS_Undefined;
01607 }
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621 penopstate PenTool::GetPenOpState() const
01622 {
01623 return (CurrPenOpState);
01624 }
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642 void PenTool::CreateNewPath()
01643 {
01644
01645
01646 OpAddNewPath* pOpAddNewPath = new OpAddNewPath;
01647 pOpAddNewPath->DoAddNewPath(&EditPath, EditHandles.pHndSpread);
01648 }
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668 void PenTool::AddElementToPath()
01669 {
01670
01671
01672
01673 OpAddPathToPath* pOpAddPathToPath = new OpAddPathToPath;
01674 pOpAddPathToPath->DoAddPathToPath(pNodePath, &EditPath, NodeIndex);
01675 }
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694 void PenTool::CloseWithPath()
01695 {
01696
01697
01698
01699 OpClosePathWithPath* pOpClosePathWithPath = new OpClosePathWithPath;
01700 pOpClosePathWithPath->DoClosePathWithPath(pNodePath, &EditPath, NodeIndex);
01701 }
01702