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
00111
00112
00113
00114
00115 #include "infobar.h"
00116 #include "csrstack.h"
00117
00118 #include "osrndrgn.h"
00119 #include "oilfiles.h"
00120 #include "blobs.h"
00121
00122
00123 #include "bevinfo.h"
00124 #include "bevtool.h"
00125 #include "module.h"
00126 #include "ezmodule.h"
00127
00128 #include "progress.h"
00129 #include "opbevel.h"
00130
00131
00132
00133 #include "nodetxts.h"
00134 #include "attrbev.h"
00135
00136
00137
00138 #include "cntrtool.h"
00139 #include "gclips.h"
00140 #include "bubbleid.h"
00141 #include "objchge.h"
00142 #include "nodemold.h"
00143 #include "ndclpcnt.h"
00144 #include "ncntrcnt.h"
00145
00146
00147
00148 #include "helpuser.h"
00149 #include "dragmgr.h"
00150 #include "lineattr.h"
00151
00152 #include "strkattr.h"
00153 #include "nodebev.h"
00154 #include "nbevcont.h"
00155 #include "ophist.h"
00156
00157 #ifdef BUILDSHADOWS
00158
00159
00160 DECLARE_SOURCE("$Revision: 1282 $");
00161
00162
00163
00164 TCHAR* BevelTool::FamilyName = _T("Bevelling Tool");
00165 TCHAR* BevelTool::ToolName = _T("Bevelling Tool");
00166 TCHAR* BevelTool::Purpose = _T("To Bevel things");
00167 TCHAR* BevelTool::Author = _T("DMc");
00168
00169 BevelInfoBarOp * BevelTool::pBevelInfoBarOp = NULL;
00170 BOOL BevelTool::m_bActive = FALSE;
00171 UINT32 BevelTool::StatusID = _R(IDS_BEVELSTATUSHELP);
00172 OpDragBevel * BevelTool::m_pDragBevelOp = NULL;
00173
00174 CC_IMPLEMENT_MEMDUMP( BevelTool, Tool_v1 )
00175 CC_IMPLEMENT_MEMDUMP( BevelBlob, ListItem )
00176 CC_IMPLEMENT_DYNCREATE(OpDragBevel,SelOperation)
00177
00179
00180 const MILLIPOINT BevelToolFlatness=200;
00181
00182
00183
00184 #define new CAM_DEBUG_NEW
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 BevelTool::BevelTool()
00199 {
00200
00201 pNormalCursor = NULL;
00202 pActiveCursor = NULL;
00203 pBevelInfoBarOp = NULL;
00204 pMouseOverCursor = NULL;
00205 m_bRegenBlobsOnNextRender = FALSE;
00206 m_LastZoom = FIXED16(0);
00207 m_bDisableBlobRendering = FALSE;
00208 m_pDragBevelOp = NULL;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 BevelTool::~BevelTool()
00226 {
00227
00228 m_BevelBlobList.DeleteAll();
00229
00230 RemoveCursors();
00231
00232 if (m_pDragBevelOp)
00233 {
00234 delete m_pDragBevelOp;
00235 m_pDragBevelOp = NULL;
00236 }
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 BOOL BevelTool::Init()
00254 {
00255 BOOL ok = OpDragBevel::Declare();
00256
00257 if (!m_pDragBevelOp)
00258 m_pDragBevelOp = new OpDragBevel;
00259
00260
00261
00262
00263 if (ok)
00264 {
00265 #if 0
00266 CCResTextFile file;
00267 BevelInfoBarOpCreate BarCreate;
00268
00269 ok = file.open(_R(IDM_BEVEL_BAR), _R(IDT_INFO_BAR_RES));
00270 if (ok) ok = DialogBarOp::ReadBarsFromFile(file,BarCreate);
00271 if (ok) file.close();
00272
00273 ERROR3IF(!ok,"Unable to load bevbar.ini from resource\n");
00274
00275 if (ok)
00276 {
00277
00278 String_32 str = String_32(_R(IDS_BEVELTOOL_INFOBARNAME));
00279 DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(str);
00280 ok = (pDialogBarOp != NULL);
00281
00282 if (ok)
00283 ok = pDialogBarOp->IsKindOf(CC_RUNTIME_CLASS(BevelInfoBarOp));
00284
00285 if (ok)
00286 {
00287 pBevelInfoBarOp = (BevelInfoBarOp*)pDialogBarOp;
00288 pBevelInfoBarOp->pTool = this;
00289 }
00290 }
00291 #endif
00292 pBevelInfoBarOp = new BevelInfoBarOp();
00293 ok = (pBevelInfoBarOp != NULL);
00294 if (ok) pBevelInfoBarOp->pTool = this;
00295
00296 ERROR3IF(!ok,"Error finding the bevel tool info bar");
00297 }
00298
00299 return (ok);
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317 void BevelTool::Describe(void *InfoPtr)
00318 {
00319
00320 ToolInfo_v1 *Info = (ToolInfo_v1 *) InfoPtr;
00321
00322 Info->InfoVersion = 1;
00323 Info->InterfaceVersion = GetToolInterfaceVersion();
00324
00325
00326 Info->Version = 1;
00327 Info->ID = GetID();
00328 Info->TextID = _R(IDS_BEVEL_TOOL);
00329 Info->BubbleID = _R(IDBBL_BEVEL_TOOLBOX);
00330
00331 Info->Family = FamilyName;
00332 Info->Name = ToolName;
00333 Info->Purpose = Purpose;
00334 Info->Author = Author;
00335
00336 Info->InfoBarDialog = _R(IDD_BEVELINFOBAR);
00337 }
00338
00339
00340 UINT32 BevelTool::GetID()
00341 {
00342 return TOOLID_BEVELTOOL;
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 void BevelTool::SelectChange(BOOL isSelected)
00364 {
00365
00366 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00367 Spread * pSpread = Document::GetSelectedSpread();
00368
00369
00370 BlobStyle BevelBlobs;
00371
00372 if (isSelected)
00373 {
00374
00375 m_bDisableBlobRendering = TRUE;
00376 if (!LoadCursors())
00377 InformError();
00378
00379
00380 BevelBlobs.Tiny = TRUE;
00381 BlobMgr->ToolInterest(BevelBlobs);
00382
00383 m_bActive = TRUE;
00384
00385
00386
00387
00388 SetupBlobList();
00389
00390
00391 pBevelInfoBarOp->Create();
00392
00393 if (pBevelInfoBarOp->pCurrentBar)
00394 {
00395 pBevelInfoBarOp->Open();
00396 }
00397
00398 if (pBevelInfoBarOp)
00399 {
00400 pBevelInfoBarOp->SetToolActiveState(TRUE);
00401 }
00402
00403 m_bDisableBlobRendering = FALSE;
00404
00405 if (BlobMgr && pSpread)
00406 {
00407
00408 BlobMgr->RenderToolBlobsOn(this, pSpread, NULL);
00409 }
00410 }
00411 else
00412 {
00413
00414
00415
00416
00417 if (BlobMgr && pSpread)
00418 {
00419
00420
00421 BlobMgr->RenderToolBlobsOff(this, pSpread, NULL);
00422 }
00423
00424 m_bDisableBlobRendering = TRUE;
00425
00426 RemoveCursors();
00427
00428 BevelBlobs.Tiny = FALSE;
00429 BlobMgr->ToolInterest(BevelBlobs);
00430
00431 m_bActive = FALSE;
00432
00433 if (pBevelInfoBarOp)
00434 {
00435 pBevelInfoBarOp->SetToolActiveState(FALSE);
00436 pBevelInfoBarOp->Delete();
00437 }
00438
00439
00440 BlobStyle bsRemoves;
00441 bsRemoves.ToolObject = TRUE;
00442 BlobMgr->RemoveInterest(bsRemoves);
00443
00444 m_BevelBlobList.DeleteAll();
00445
00446
00447
00448 m_bDisableBlobRendering = FALSE;
00449 }
00450 }
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 void BevelTool::RecalculateSelectionBoundingBoxes(BOOL InvalidateDoc)
00468 {
00469 Spread * pSpread = Document::GetSelectedSpread();
00470
00471
00472 if (!pSpread)
00473 return;
00474
00475 Document * pDoc = Document::GetCurrent();
00476
00477 if (!pDoc)
00478 return;
00479
00480 DocRect ClipRect;
00481 Node * pNode = NULL;
00482
00483 Range Sel(*(GetApplication()->FindSelection()));
00484
00485 if (Sel.IsEmpty())
00486 return;
00487
00488 pNode = Sel.FindFirst(TRUE);
00489
00490 while (pNode)
00491 {
00492 if (pNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableBounded)) &&
00493 !pNode->IsNodeHidden())
00494 {
00495 ClipRect = ClipRect.Union(((NodeRenderableBounded *)pNode)->GetBlobBoundingRect());
00496 }
00497
00498 pNode = Sel.FindNext(pNode, TRUE);
00499 }
00500
00501 if (InvalidateDoc)
00502 {
00503 pDoc->ForceRedraw(pSpread, ClipRect, TRUE);
00504 }
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 BOOL BevelTool::LoadCursors()
00521 {
00522
00523 pActiveCursor = NULL;
00524
00525
00526 pNormalCursor = new Cursor(this, _R(IDC_POINTER_BEVEL));
00527 pMouseOverCursor = new Cursor(this, _R(IDC_ELIPTOOLOVERBLOB));
00528 pSizeCursor = new Cursor(this, _R(IDC_SIZE_BEVEL));
00529
00530
00531 if (pNormalCursor==NULL || pMouseOverCursor==NULL || pSizeCursor==NULL)
00532 {
00533
00534
00535 delete pNormalCursor;
00536
00537
00538 pNormalCursor = NULL;
00539
00540
00541 ERROR1(FALSE, _R(IDE_FHAND_BADCURSORS));
00542 }
00543
00544
00545
00546 CurrentCursorID = CursorStack::GPush(pNormalCursor, FALSE);
00547 pActiveCursor = pNormalCursor;
00548
00549
00550 return TRUE;
00551
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 void BevelTool::RemoveCursors()
00570 {
00571
00572 if (pActiveCursor!=NULL)
00573 {
00574
00575 CursorStack::GPop(CurrentCursorID);
00576
00577
00578 delete pNormalCursor;
00579
00580 delete pMouseOverCursor;
00581
00582 delete pSizeCursor;
00583
00584
00585 pNormalCursor = NULL;
00586 pActiveCursor = NULL;
00587 pMouseOverCursor = NULL;
00588 pSizeCursor = NULL;
00589 CurrentCursorID = 0;
00590 }
00591 }
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604 void BevelTool::OnMouseMove(DocCoord Pos, Spread* pSpread, ClickModifiers ClickMods)
00605 {
00606
00607 BOOL bFound = FALSE;
00608
00609
00610 BevelBlob * pBlob = (BevelBlob *)m_BevelBlobList.GetHead();
00611
00612 while (pBlob && !bFound)
00613 {
00614 if (pBlob->HitTest(Pos))
00615 {
00616 bFound = TRUE;
00617 TRACEUSER( "MarkH", _T("Hittesting!\n"));
00618 }
00619
00620 pBlob = (BevelBlob *)m_BevelBlobList.GetNext(pBlob);
00621 }
00622
00623 if (bFound)
00624 {
00625 ChangeCursor(pMouseOverCursor);
00626
00627
00628 DisplayStatusBarHelp(_R(IDS_BEVELDRAGBLOBHELP));
00629
00630 }
00631 else
00632 {
00633 if (IsPointOverSelectionBlob(Pos, NULL))
00634 {
00635 ChangeCursor(pSizeCursor);
00636 DisplayStatusBarHelp(_R(IDS_BEVELDRAGSTATUSHELP));
00637 }
00638 else
00639 {
00640 ChangeCursor(pNormalCursor);
00641 DisplayStatusBarHelp(_R(IDS_BEVELSTATUSHELP));
00642 }
00643 }
00644 }
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660 void BevelTool::DisplayStatusBarHelp(UINT32 StatusIDX)
00661 {
00662 String_256 StatusMsg("");
00663 StatusMsg.Load(StatusIDX);
00664 GetApplication()->UpdateStatusBarText(&StatusMsg);
00665 BevelTool::StatusID = StatusIDX;
00666 }
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 BOOL BevelTool::GetStatusLineText(String_256* ptext, Spread* pSpread, DocCoord DocPos, ClickModifiers ClickMods)
00683 {
00684 ptext->Load(BevelTool::StatusID);
00685 return TRUE;
00686 }
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 void BevelTool::ChangeCursor(Cursor* pCursor)
00702 {
00703
00704 if ((pCursor!=pActiveCursor) && (pCursor!=NULL))
00705 {
00706
00707 CursorStack::GSetTop(pCursor, CurrentCursorID);
00708
00709
00710 pActiveCursor = pCursor;
00711
00712 DisplayStatusBarHelp(BevelTool::StatusID);
00713 }
00714 }
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 void BevelTool::OnClick( DocCoord PointerPos, ClickType Click, ClickModifiers ClickMods,
00741 Spread* pSpread )
00742 {
00743 ERROR3IF_PF(pSpread==NULL,("pSpread is NULL"));
00744
00745 if (ClickMods.Menu) return;
00746
00747
00748
00749 DocRect BlobRect;
00750
00751 switch (Click)
00752 {
00753
00754 case CLICKTYPE_DRAG:
00755 {
00756
00757 BOOL bDoingDrag = FALSE;
00758 BevelBlob* pBlob = (BevelBlob *) m_BevelBlobList.GetHead();
00759
00760 while (pBlob && !bDoingDrag)
00761 {
00762 if (pBlob->HitTest(PointerPos))
00763 {
00764 bDoingDrag = TRUE;
00765 pBevelInfoBarOp->BeginDrag(pBlob);
00766 }
00767
00768 pBlob = (BevelBlob *)m_BevelBlobList.GetNext(pBlob);
00769 }
00770
00771
00772 if (!bDoingDrag)
00773 {
00774 if (m_pDragBevelOp)
00775 {
00776 DocRect BlobRect;
00777
00778 m_pDragBevelOp->DoDrag(pBevelInfoBarOp, PointerPos,
00779 IsPointOverSelectionBlob(PointerPos, &BlobRect), &BlobRect);
00780 }
00781 }
00782 }
00783 break;
00784
00785 case CLICKTYPE_SINGLE:
00786 {
00787
00788 List ContourList;
00789 BevelTools::BuildListOfSelectedNodes(&ContourList, CC_RUNTIME_CLASS(NodeContourController));
00790
00791 if (!ContourList.IsEmpty())
00792 {
00793 ContourList.DeleteAll();
00794
00795 DocRect BlobRect;
00796
00797
00798 if (IsPointOverSelectionBlob(PointerPos, &BlobRect))
00799 {
00800 DocView * pView = DocView::GetCurrent();
00801
00802 if (pView)
00803 pView->EndDrag(NULL);
00804
00805 InformWarningContourExistsInSelection();
00806 }
00807 }
00808
00809
00810
00811 DragTool::OnClick (PointerPos, Click, ClickMods, pSpread);
00812 }
00813 break;
00814
00815 default:
00816
00817
00818 DragTool::OnClick (PointerPos, Click, ClickMods, pSpread);
00819 break;
00820 }
00821
00822 }
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 void BevelTool::InformWarningContourExistsInSelection()
00834 {
00835 String_256 QueryString(_R(IDS_CANTBEVELCONTOUR));
00836
00837 Error::SetError(0, QueryString, 0);
00838
00839 INT32 DlgResult = InformError(_R(IDS_CANTBEVELCONTOUR),
00840 _R(IDS_OK), _R(IDS_HELP));
00841
00842 if (DlgResult == 2)
00843 {
00844 HelpUserTopic(_R(IDS_HELPPATH_Message__Contour_already_applied));
00845 }
00846 }
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 void BevelTool::RenderBlob(BevelBlob * pBlob)
00859 {
00860 Spread * pSpread = Document::GetSelectedSpread();
00861
00862
00863 DocRect dr = pBlob->GetRect();
00864
00865
00866 RenderRegion * pRegion = DocView::RenderOnTop(NULL, pSpread, UnclippedEOR);
00867
00868 while (pRegion)
00869 {
00870 pBlob->RenderBlob(pRegion);
00871
00872 pRegion = DocView::GetNextOnTop(NULL);
00873 }
00874 }
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898 void BevelTool::RenderToolBlobs(Spread* pSpread, DocRect* pClipRect)
00899 {
00900
00901
00902 if (m_bDisableBlobRendering)
00903 return;
00904
00905
00906 DocView * pView = DocView::GetSelected();
00907
00908 if (pView)
00909 {
00910 if (m_LastZoom != pView->GetViewScale())
00911 {
00912
00913 SetupBlobList();
00914 m_LastZoom = pView->GetViewScale();
00915 }
00916 }
00917
00918
00919
00920
00921
00922 RenderRegion * pRegion = DocView::RenderOnTop(pClipRect, pSpread, UnclippedEOR);
00923
00924 BevelBlob * pBlob = NULL;
00925
00926 while (pRegion)
00927 {
00928
00929 pBlob = (BevelBlob *)m_BevelBlobList.GetHead();
00930
00931 while (pBlob)
00932 {
00933 pBlob->RenderBlob(pRegion);
00934
00935 pBlob = (BevelBlob *)m_BevelBlobList.GetNext(pBlob);
00936 }
00937
00938
00939 pRegion->SaveContext();
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951 pRegion->DrawBitmapBlob(m_BlobPoints[6], _R(IDBMP_CONTOUR_LEFTRIGHT));
00952 pRegion->DrawBitmapBlob(m_BlobPoints[7], _R(IDBMP_CONTOUR_LEFTRIGHT));
00953
00954
00955 pRegion->DrawBitmapBlob(m_BlobPoints[4], _R(IDBMP_CONTOUR_UPDOWN));
00956 pRegion->DrawBitmapBlob(m_BlobPoints[5], _R(IDBMP_CONTOUR_UPDOWN));
00957
00958
00959 pRegion->DrawBitmapBlob(m_BlobPoints[0], _R(IDBMP_CONTOUR_ACUTE));
00960 pRegion->DrawBitmapBlob(m_BlobPoints[3], _R(IDBMP_CONTOUR_ACUTE));
00961
00962
00963 pRegion->DrawBitmapBlob(m_BlobPoints[2], _R(IDBMP_CONTOUR_GRAVE));
00964 pRegion->DrawBitmapBlob(m_BlobPoints[1], _R(IDBMP_CONTOUR_GRAVE));
00965
00966 pRegion->RestoreContext();
00967
00968 pRegion = DocView::GetNextOnTop(NULL);
00969 }
00970 }
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983 BOOL BevelTool::IsPointOverSelectionBlob(DocCoord &Point, DocRect * pRect)
00984 {
00985
00986 BlobManager * pBlobMgr = GetApplication()->GetBlobManager();
00987
00988 INT32 BlobSize = 0;
00989
00990
00991
00992
00993 if (pBlobMgr)
00994 BlobSize = pBlobMgr->GetBlobSize();
00995
00996
00997 for (INT32 i = 0; i < 8; i++)
00998 {
00999 DocRect dr( m_BlobPoints[i].x - BlobSize,
01000 m_BlobPoints[i].y - BlobSize,
01001 m_BlobPoints[i].x + BlobSize,
01002 m_BlobPoints[i].y + BlobSize);
01003
01004 if (dr.ContainsCoord(Point))
01005 {
01006 if (pRect)
01007 *pRect = dr;
01008 return TRUE;
01009 }
01010 }
01011
01012 return FALSE;
01013 }
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026 BOOL BevelTool::SetupBlobList()
01027 {
01028
01029 SetupSelectionBlobs();
01030
01031
01032 m_BevelBlobList.DeleteAll();
01033
01034 m_BlobListBounds.hi.x = 0;
01035 m_BlobListBounds.lo.x = 0;
01036 m_BlobListBounds.hi.y = 0;
01037 m_BlobListBounds.lo.y = 0;
01038
01039
01040
01041
01042 BOOL bHandled = FALSE;
01043
01044 BevelBlob * pBlob;
01045
01046 List BevelNodeList;
01047
01048
01049 if (!BevelTools::BuildListOfSelectedNodes(&BevelNodeList, CC_RUNTIME_CLASS(NodeBevel)))
01050 {
01051
01052 return FALSE;
01053 }
01054
01055 NodeListItem * pItem = (NodeListItem *)BevelNodeList.GetHead();
01056 Node * pNode = NULL;
01057
01058
01059
01060 while (pItem)
01061 {
01062 pNode = pItem->pNode->FindParent();
01063
01064 if (pNode->IsKindOf(CC_RUNTIME_CLASS(NodeBevelController))
01065 && !pNode->IsNodeHidden()
01066 && !pNode->IsLocked()
01067 && pNode->IsRenderable())
01068 {
01069
01070
01071 pBlob = (BevelBlob *)m_BevelBlobList.GetHead();
01072
01073 bHandled = FALSE;
01074
01075 while (pBlob && !bHandled)
01076 {
01077
01078 if (pBlob->AddNode((NodeBevelController *)pNode))
01079 {
01080 bHandled = TRUE;
01081
01082
01083 if (m_BlobListBounds.Width() == 0 &&
01084 m_BlobListBounds.Height() == 0)
01085 {
01086 m_BlobListBounds = pBlob->GetRect();
01087 }
01088 else
01089 {
01090 m_BlobListBounds = m_BlobListBounds.Union(pBlob->GetRect());
01091 }
01092 }
01093
01094 pBlob = (BevelBlob *)m_BevelBlobList.GetNext(pBlob);
01095 }
01096
01097
01098
01099 if (!bHandled)
01100 {
01101
01102 pBlob = new BevelBlob;
01103
01104 if (!pBlob)
01105 {
01106 ERROR3("Cannot create bevel blob");
01107 BevelNodeList.DeleteAll();
01108 return FALSE;
01109 }
01110
01111 if (!pBlob->AddNode((NodeBevelController *)pNode))
01112 {
01113 ERROR3("Cannot add attribute to bevel blob");
01114 BevelNodeList.DeleteAll();
01115 return FALSE;
01116 }
01117
01118
01119 m_BevelBlobList.AddTail(pBlob);
01120
01121
01122 if (m_BlobListBounds.Width() == 0 &&
01123 m_BlobListBounds.Height() == 0)
01124 {
01125 m_BlobListBounds = pBlob->GetRect();
01126 }
01127 else
01128 {
01129 m_BlobListBounds = m_BlobListBounds.Union(pBlob->GetRect());
01130 }
01131 }
01132 }
01133
01134 pItem = (NodeListItem *)BevelNodeList.GetNext(pItem);
01135 }
01136
01137 BevelNodeList.DeleteAll();
01138
01139 return TRUE;
01140 }
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164 void BevelTool::SetupSelectionBlobs()
01165 {
01166
01167 for (INT32 i = 0 ; i < 8; i++)
01168 {
01169 m_BlobPoints[i].x = 0;
01170 m_BlobPoints[i].y = 0;
01171 }
01172
01173
01174 if (GetApplication()->FindSelection() == NULL ||
01175 GetApplication()->FindSelection()->IsEmpty())
01176 return;
01177
01178 BlobManager * pBlobMgr = GetApplication()->GetBlobManager();
01179 if (pBlobMgr == NULL)
01180 return;
01181
01182
01183 INT32 BlobGap = 0;
01184 DocView* pDocView = DocView::GetSelected();
01185 if (pDocView != NULL)
01186 BlobGap = pDocView->GetScaledPixelWidth().MakeLong();
01187
01188
01189 SelRange Sel(*(GetApplication()->FindSelection()));
01190 DocRect drBounds;
01191 Node* pN = Sel.FindFirst();
01192 while (pN != NULL)
01193 {
01194 if (pN->IsBounded())
01195 {
01196 Node* pParent = pN->FindParent();
01197 while (pParent != NULL && pParent->IS_KIND_OF(NodeBevelController))
01198 {
01199 pN = pParent;
01200 pParent = pN->FindParent();
01201 }
01202
01203 drBounds = drBounds.Union( ((NodeRenderableBounded*)pN)->GetBoundingRect() );
01204 }
01205 pN = Sel.FindNext(pN);
01206 }
01207
01208
01209 DocCoord dc;
01210 INT32 BlobSize = pBlobMgr->GetBlobSize();
01211 drBounds.Inflate(BlobGap + BlobSize);
01212
01213 dc.x = drBounds.lo.x;
01214 dc.y = drBounds.lo.y;
01215 m_BlobPoints[0] = dc;
01216
01217 dc.x = drBounds.hi.x;
01218 dc.y = drBounds.lo.y;
01219 m_BlobPoints[1] = dc;
01220
01221 dc.x = drBounds.lo.x;
01222 dc.y = drBounds.hi.y;
01223 m_BlobPoints[2] = dc;
01224
01225 dc.x = drBounds.hi.x;
01226 dc.y = drBounds.hi.y;
01227 m_BlobPoints[3] = dc;
01228
01229 dc.x = (drBounds.lo.x + drBounds.hi.x) / 2;
01230 dc.y = drBounds.hi.y + BlobGap;
01231 m_BlobPoints[4] = dc;
01232
01233 dc.x = (drBounds.lo.x + drBounds.hi.x) / 2;
01234 dc.y = drBounds.lo.y - BlobGap;
01235 m_BlobPoints[5] = dc;
01236
01237 dc.x = drBounds.lo.x - BlobGap;
01238 dc.y = (drBounds.lo.y + drBounds.hi.y) / 2;
01239 m_BlobPoints[6] = dc;
01240
01241 dc.x = drBounds.hi.x + BlobGap;
01242 dc.y = (drBounds.lo.y + drBounds.hi.y) / 2;
01243 m_BlobPoints[7] = dc;
01244 }
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256 void BevelTool::DoSelectBevelNodesFromChildren()
01257 {
01258
01259
01260
01261
01262 Range Sel(*(GetApplication()->FindSelection()));
01263 RangeControl rg = Sel.GetRangeControlFlags();
01264 rg.PromoteToParent = TRUE;
01265 Sel.Range::SetRangeControl(rg);
01266
01267
01268
01269 BOOL bSelChanged = FALSE;
01270
01271 if (Sel.IsEmpty())
01272 return ;
01273
01274
01275 Node *pNode = Sel.FindFirst(TRUE);
01276
01277 if (!pNode)
01278 {
01279 pNode = Sel.FindFirst(FALSE);
01280 }
01281
01282 if (!pNode)
01283 return ;
01284
01285 Node * pOldNode = NULL;
01286
01287
01288
01289
01290 Node * pParent;
01291
01292
01293 List SelList;
01294 NodeListItem * pListItem = NULL;
01295
01296
01297
01298 while (pNode)
01299 {
01300 pParent = pNode->FindParent();
01301
01302 if (pParent)
01303 {
01304 if (pParent->IsKindOf(CC_RUNTIME_CLASS(NodeBevelController)))
01305 {
01306
01307 if (!pParent->IsSelected())
01308 {
01309 pListItem = new NodeListItem;
01310
01311 if (!pListItem)
01312 {
01313 ERROR3("Can't create list item");
01314 return;
01315 }
01316
01317 pListItem->pNode = pParent;
01318 SelList.AddTail(pListItem);
01319 bSelChanged = TRUE;
01320 }
01321 }
01322 }
01323
01324 pOldNode = pNode;
01325 pNode = Sel.FindNext(pNode, TRUE);
01326
01327 if (!pNode)
01328 {
01329 pNode = Sel.FindNext(pOldNode, FALSE);
01330 }
01331 }
01332
01333 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01334
01335 Spread * pSpread = Document::GetSelectedSpread();
01336
01337 DocRect dr;
01338
01339
01340 if (bSelChanged && BlobMgr && pSpread)
01341 {
01342
01343 dr = Sel.GetBoundingRect();
01344 BlobMgr->RenderOff(&dr, pSpread);
01345
01346
01347 pListItem = (NodeListItem *)SelList.GetHead();
01348
01349 while (pListItem)
01350 {
01351 if (pListItem->pNode)
01352 {
01353 pListItem->pNode->SetSelected(TRUE);
01354 }
01355
01356 pListItem = (NodeListItem *)SelList.GetNext(pListItem);
01357 }
01358
01359
01360 GetApplication()->UpdateSelection();
01361
01362
01363 SetupBlobList();
01364
01365
01366 Range NewSel(*(GetApplication()->FindSelection()));
01367 RangeControl rg = Sel.GetRangeControlFlags();
01368 rg.PromoteToParent = TRUE;
01369 Sel.Range::SetRangeControl(rg);
01370
01371 dr = NewSel.GetBoundingRect();
01372 BlobMgr->RenderOn(&dr, pSpread);
01373 }
01374
01375 SelList.DeleteAll();
01376 }
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388 void BevelTool::InvalidateToolBlobs()
01389 {
01390
01391
01392
01393 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01394 Spread * pSpread = Document::GetSelectedSpread();
01395
01396 if (!BlobMgr || !pSpread)
01397 return;
01398
01399
01400 BlobMgr->RenderToolBlobsOff(this, pSpread, NULL);
01401
01402 SetupBlobList();
01403
01404
01405 BlobMgr->RenderToolBlobsOn(this, pSpread, NULL);
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417 }
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429 void BevelTool::ChangeBlobAngles(INT32 Angle)
01430 {
01431 if (m_BevelBlobList.IsEmpty())
01432 return;
01433
01434
01435 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01436 Spread * pSpread = Document::GetSelectedSpread();
01437
01438 if (!BlobMgr || !pSpread)
01439 return;
01440
01441
01442
01443
01444 BevelBlob * pBlob = (BevelBlob *)m_BevelBlobList.GetHead();
01445
01446 Document * pDoc = Document::GetCurrent();
01447
01448
01449 while (pBlob)
01450 {
01451 pBlob->SetAngle(Angle);
01452
01453 pBlob->RenderNodes();
01454
01455 if (pDoc)
01456 pDoc->ForceRedraw(pSpread, m_BlobListBounds);
01457
01458 pBlob = (BevelBlob *)m_BevelBlobList.GetNext(pBlob);
01459 }
01460
01461 GetApplication()->ServiceRendering();
01462
01463
01464
01465 }
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477 void BevelTool::ChangeBlobTilts(INT32 Tilt)
01478 {
01479 if (m_BevelBlobList.IsEmpty())
01480 return;
01481
01482
01483 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01484 Spread * pSpread = Document::GetSelectedSpread();
01485
01486 if (!BlobMgr || !pSpread)
01487 return;
01488
01489
01490
01491
01492 BevelBlob * pBlob = (BevelBlob *)m_BevelBlobList.GetHead();
01493
01494 Document * pDoc = Document::GetCurrent();
01495
01496
01497 while (pBlob)
01498 {
01499 pBlob->SetTilt(Tilt);
01500
01501 pBlob->RenderNodes();
01502
01503 if (pDoc)
01504 pDoc->ForceRedraw(pSpread, m_BlobListBounds);
01505
01506 pBlob = (BevelBlob *)m_BevelBlobList.GetNext(pBlob);
01507 }
01508
01509 GetApplication()->ServiceRendering();
01510
01511
01512
01513 }
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526 void BevelTool::ChangeContrastAndReRender(INT32 NewContrast)
01527 {
01528 if (m_BevelBlobList.IsEmpty())
01529 return;
01530
01531
01532 BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01533 Spread * pSpread = Document::GetSelectedSpread();
01534
01535 if (!BlobMgr || !pSpread)
01536 return;
01537
01538 BevelBlob * pBlob = (BevelBlob *)m_BevelBlobList.GetHead();
01539
01540 Document * pDoc = Document::GetCurrent();
01541
01542
01543 while (pBlob)
01544 {
01545
01546 pBlob->ChangeContrast(NewContrast);
01547
01548 if (pDoc)
01549 {
01550 pDoc->ForceRedraw(pSpread, pBlob->GetRect());
01551 }
01552
01553 pBlob = (BevelBlob *)m_BevelBlobList.GetNext(pBlob);
01554 }
01555
01556 GetApplication()->ServiceRendering();
01557 }
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573 BOOL BevelTool::AreManyBevelTypes()
01574 {
01575 if (m_BevelBlobList.IsEmpty())
01576 return FALSE;
01577
01578
01579
01580 BevelBlob * pItem = (BevelBlob *)m_BevelBlobList.GetHead();
01581
01582 INT32 Type = -1;
01583
01584 while (pItem)
01585 {
01586 NodeListItem * pNodeItem = (NodeListItem *)pItem->GetList()->GetHead();
01587
01588 while (pNodeItem)
01589 {
01590 if (Type < 0)
01591 {
01592 Type = ((NodeBevelController *)pNodeItem->pNode)->m_BevelType;
01593 }
01594 else
01595 {
01596 if (Type != ((NodeBevelController *)pNodeItem->pNode)->m_BevelType)
01597 {
01598 return TRUE;
01599 }
01600 }
01601
01602 pNodeItem = (NodeListItem *)pItem->GetList()->GetNext(pNodeItem);
01603 }
01604
01605 pItem = (BevelBlob *)m_BevelBlobList.GetNext(pItem);
01606 }
01607
01608
01609 Range Rng(*(GetApplication()->FindSelection()));
01610 RangeControl rg = Rng.GetRangeControlFlags();
01611 rg.PromoteToParent = TRUE;
01612 Rng.SetRangeControl(rg);
01613
01614 List BevelList;
01615
01616 Node * pNode = Rng.FindFirst(FALSE);
01617
01618
01619 while (pNode)
01620 {
01621 BevelList.DeleteAll();
01622
01623 BevelTools::GetAllNodesUnderNode(pNode, &BevelList, CC_RUNTIME_CLASS(NodeBevel));
01624
01625 if (BevelList.IsEmpty())
01626 {
01627 BevelList.DeleteAll();
01628 return TRUE;
01629 }
01630
01631 pNode = Rng.FindNext(pNode, FALSE);
01632 }
01633
01634 BevelList.DeleteAll();
01635 return FALSE;
01636 }
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651 BOOL BevelTool::AreManyBevelDirections()
01652 {
01653 if (m_BevelBlobList.IsEmpty())
01654 return FALSE;
01655
01656 BevelBlob * pItem = (BevelBlob *)m_BevelBlobList.GetHead();
01657
01658 BOOL bOuter = FALSE;
01659 BOOL bFirst = TRUE;
01660
01661 while (pItem)
01662 {
01663 NodeListItem * pNodeItem = (NodeListItem *)pItem->GetList()->GetHead();
01664
01665 while (pNodeItem)
01666 {
01667 if (bFirst)
01668 {
01669 bOuter = ((NodeBevelController *)pNodeItem->pNode)->m_bOuter;
01670 bFirst = FALSE;
01671 }
01672 else
01673 {
01674 if ((bOuter && !((NodeBevelController *)pNodeItem->pNode)->m_bOuter) ||
01675 (!bOuter && ((NodeBevelController *)pNodeItem->pNode)->m_bOuter))
01676 {
01677 return TRUE;
01678 }
01679 }
01680
01681 pNodeItem = (NodeListItem *)pItem->GetList()->GetNext(pNodeItem);
01682 }
01683
01684 pItem = (BevelBlob *)m_BevelBlobList.GetNext(pItem);
01685 }
01686
01687 return FALSE;
01688 }
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703 BOOL BevelTool::AreManyBevelIndents()
01704 {
01705 if (m_BevelBlobList.IsEmpty())
01706 return FALSE;
01707
01708 BevelBlob * pItem = (BevelBlob *)m_BevelBlobList.GetHead();
01709
01710 MILLIPOINT Indent = 0;
01711 BOOL bFirst = TRUE;
01712
01713 while (pItem)
01714 {
01715 NodeListItem * pNodeItem = (NodeListItem *)pItem->GetList()->GetHead();
01716
01717 while (pNodeItem)
01718 {
01719 if (bFirst)
01720 {
01721 Indent = ((NodeBevelController *)pNodeItem->pNode)->m_Indent;
01722 bFirst = FALSE;
01723 }
01724 else
01725 {
01726 if (Indent != ((NodeBevelController *)pNodeItem->pNode)->m_Indent)
01727 {
01728 return TRUE;
01729 }
01730 }
01731
01732 pNodeItem = (NodeListItem *)pItem->GetList()->GetNext(pNodeItem);
01733 }
01734
01735 pItem = (BevelBlob *)m_BevelBlobList.GetNext(pItem);
01736 }
01737
01738 return FALSE;
01739 }
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755 BOOL BevelTool::AreManyBevelContrasts()
01756 {
01757 if (m_BevelBlobList.IsEmpty())
01758 return FALSE;
01759
01760 BevelBlob * pItem = (BevelBlob *)m_BevelBlobList.GetHead();
01761
01762 INT32 Contrast = 0;
01763 BOOL bFirst = TRUE;
01764
01765 while (pItem)
01766 {
01767 NodeListItem * pNodeItem = (NodeListItem *)pItem->GetList()->GetHead();
01768
01769 while (pNodeItem)
01770 {
01771 if (bFirst)
01772 {
01773 Contrast = ((NodeBevelController *)pNodeItem->pNode)->m_Contrast;
01774 bFirst = FALSE;
01775 }
01776 else
01777 {
01778 if (Contrast != ((NodeBevelController *)pNodeItem->pNode)->m_Contrast)
01779 {
01780 return TRUE;
01781 }
01782 }
01783
01784 pNodeItem = (NodeListItem *)pItem->GetList()->GetNext(pNodeItem);
01785 }
01786
01787 pItem = (BevelBlob *)m_BevelBlobList.GetNext(pItem);
01788 }
01789
01790 return FALSE;
01791 }
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806 BOOL BevelTool::AreManyBevelLightAngles()
01807 {
01808 if (m_BevelBlobList.IsEmpty())
01809 return FALSE;
01810
01811 BevelBlob * pItem = (BevelBlob *)m_BevelBlobList.GetHead();
01812
01813 double LightAngle = 0;
01814 BOOL bFirst = TRUE;
01815
01816 while (pItem)
01817 {
01818 NodeListItem * pNodeItem = (NodeListItem *)pItem->GetList()->GetHead();
01819
01820 while (pNodeItem)
01821 {
01822 if (bFirst)
01823 {
01824 LightAngle = ((NodeBevelController *)pNodeItem->pNode)->m_LightAngle;
01825 bFirst = FALSE;
01826 }
01827 else
01828 {
01829 if (LightAngle != ((NodeBevelController *)pNodeItem->pNode)->m_LightAngle)
01830 {
01831 return TRUE;
01832 }
01833 }
01834
01835 pNodeItem = (NodeListItem *)pItem->GetList()->GetNext(pNodeItem);
01836 }
01837
01838 pItem = (BevelBlob *)m_BevelBlobList.GetNext(pItem);
01839 }
01840
01841 return FALSE;
01842 }
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857 BOOL BevelTool::AreManyBevelLightTilts()
01858 {
01859 if (m_BevelBlobList.IsEmpty())
01860 return FALSE;
01861
01862 BevelBlob * pItem = (BevelBlob *)m_BevelBlobList.GetHead();
01863
01864 double LightTilt = 0;
01865 BOOL bFirst = TRUE;
01866
01867 while (pItem)
01868 {
01869 NodeListItem * pNodeItem = (NodeListItem *)pItem->GetList()->GetHead();
01870
01871 while (pNodeItem)
01872 {
01873 if (bFirst)
01874 {
01875 LightTilt = ((NodeBevelController *)pNodeItem->pNode)->m_Tilt;
01876 bFirst = FALSE;
01877 }
01878 else
01879 {
01880 if (LightTilt != ((NodeBevelController *)pNodeItem->pNode)->m_Tilt)
01881 {
01882 return TRUE;
01883 }
01884 }
01885
01886 pNodeItem = (NodeListItem *)pItem->GetList()->GetNext(pNodeItem);
01887 }
01888
01889 pItem = (BevelBlob *)m_BevelBlobList.GetNext(pItem);
01890 }
01891
01892 return FALSE;
01893 }
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928 INT32 BevelTool::CalculateBevelWidth(DocRect &br, DocCoord &PointerPos)
01929 {
01930 DocCoord Centre = br.Centre();
01931
01932 INT32 Width = 0;
01933
01934 INT32 OffsetX = 0;
01935 INT32 OffsetY = 0;
01936
01937 double dOffsetX = 0;
01938 double dOffsetY = 0;
01939
01940
01941
01942 if (!br.ContainsCoord(PointerPos))
01943 {
01944
01945 if (PointerPos.x < br.lo.x && PointerPos.y >= br.lo.y &&
01946 PointerPos.y <= br.hi.y)
01947 {
01948 Width = br.lo.x - PointerPos.x;
01949 }
01950 else if (PointerPos.x > br.hi.x && PointerPos.y >= br.lo.y &&
01951 PointerPos.y <= br.hi.y)
01952 {
01953 Width = PointerPos.x - br.hi.x;
01954 }
01955 else if (PointerPos.x >= br.lo.x && PointerPos.x <= br.hi.x &&
01956 PointerPos.y < br.lo.y)
01957 {
01958 Width = br.lo.y - PointerPos.y;
01959 }
01960 else if (PointerPos.x >= br.lo.x && PointerPos.x <= br.hi.x &&
01961 PointerPos.y > br.hi.y)
01962 {
01963 Width = PointerPos.y - br.hi.y;
01964 }
01965 else if (PointerPos.x < br.lo.x && PointerPos.y < br.lo.y)
01966 {
01967 OffsetX = br.lo.x - PointerPos.x;
01968 OffsetY = br.lo.y - PointerPos.y;
01969
01970 if (OffsetX > OffsetY)
01971 {
01972 Width = OffsetX;
01973 }
01974 else
01975 {
01976 Width = OffsetY;
01977 }
01978 }
01979 else if (PointerPos.x > br.hi.x && PointerPos.y < br.lo.y)
01980 {
01981 OffsetX = PointerPos.x - br.hi.x ;
01982 OffsetY = br.lo.y - PointerPos.y;
01983
01984 if (OffsetX > OffsetY)
01985 {
01986 Width = OffsetX;
01987 }
01988 else
01989 {
01990 Width = OffsetY;
01991 }
01992 }
01993 else if (PointerPos.x > br.hi.x && PointerPos.y > br.hi.y)
01994 {
01995 OffsetX = PointerPos.x - br.hi.x ;
01996 OffsetY = PointerPos.y - br.hi.y;
01997
01998 if (OffsetX > OffsetY)
01999 {
02000 Width = OffsetX;
02001 }
02002 else
02003 {
02004 Width = OffsetY;
02005 }
02006 }
02007 else if (PointerPos.x < br.lo.x && PointerPos.y > br.hi.y)
02008 {
02009 OffsetX = br.lo.x - PointerPos.x ;
02010 OffsetY = PointerPos.y - br.hi.y;
02011
02012 if (OffsetX > OffsetY)
02013 {
02014 Width = OffsetX;
02015 }
02016 else
02017 {
02018 Width = OffsetY;
02019 }
02020 }
02021
02022 Width = -Width;
02023 }
02024 else
02025 {
02026
02027
02028
02029 dOffsetX = ((double)(PointerPos.x - Centre.x));
02030 dOffsetY = ((double)(PointerPos.y - Centre.y));
02031
02032 INT32 RWidth = br.Width()/2;
02033 INT32 RHeight = br.Height()/2;
02034
02035 if (RWidth > RHeight)
02036 {
02037 INT32 DistX = RWidth - RHeight;
02038
02039 if (PointerPos.x < Centre.x + DistX &&
02040 PointerPos.x > Centre.x - DistX)
02041 {
02042 if (dOffsetY > 0)
02043 {
02044 Width = br.hi.y - PointerPos.y;
02045 }
02046 else
02047 {
02048 Width = PointerPos.y - br.lo.y;
02049 }
02050 }
02051 else if (PointerPos.x > Centre.x + DistX)
02052 {
02053 dOffsetX -= (double)DistX;
02054
02055 if (dOffsetY > 0)
02056 {
02057 if (dOffsetX > dOffsetY)
02058 {
02059 Width = br.hi.x - PointerPos.x;
02060 }
02061 else
02062 {
02063 Width = br.hi.y - PointerPos.y;
02064 }
02065 }
02066 else
02067 {
02068 if (dOffsetX > -dOffsetY)
02069 {
02070 Width = br.hi.x - PointerPos.x;
02071 }
02072 else
02073 {
02074 Width = PointerPos.y - br.lo.y;
02075 }
02076 }
02077 }
02078 else
02079 {
02080 dOffsetX += (double)DistX;
02081 dOffsetX = -dOffsetX;
02082
02083 if (dOffsetY > 0)
02084 {
02085 if (dOffsetX > dOffsetY)
02086 {
02087 Width = PointerPos.x - br.lo.x;
02088 }
02089 else
02090 {
02091 Width = br.hi.y - PointerPos.y;
02092 }
02093 }
02094 else
02095 {
02096 if (dOffsetX > -dOffsetY)
02097 {
02098 Width = PointerPos.x - br.lo.x;
02099 }
02100 else
02101 {
02102 Width = PointerPos.y - br.lo.y;
02103 }
02104 }
02105 }
02106 }
02107 else
02108 {
02109 INT32 DistY = RHeight - RWidth;
02110
02111 if (PointerPos.y < Centre.y + DistY &&
02112 PointerPos.y > Centre.y - DistY)
02113 {
02114 if (dOffsetX > 0)
02115 {
02116 Width = br.hi.x - PointerPos.x;
02117 }
02118 else
02119 {
02120 Width = PointerPos.x - br.lo.x;
02121 }
02122 }
02123 else if (PointerPos.y > Centre.y + DistY)
02124 {
02125 dOffsetY -= (double)DistY;
02126
02127 if (dOffsetX > 0)
02128 {
02129 if (dOffsetY > dOffsetX)
02130 {
02131 Width = br.hi.y - PointerPos.y;
02132 }
02133 else
02134 {
02135 Width = br.hi.x - PointerPos.x;
02136 }
02137 }
02138 else
02139 {
02140 if (dOffsetY > -dOffsetX)
02141 {
02142 Width = br.hi.y - PointerPos.y;
02143 }
02144 else
02145 {
02146 Width = PointerPos.x - br.lo.x;
02147 }
02148 }
02149 }
02150 else
02151 {
02152 dOffsetY += (double)DistY;
02153 dOffsetY = -dOffsetY;
02154
02155 if (dOffsetX > 0)
02156 {
02157 if (dOffsetY > dOffsetX)
02158 {
02159 Width = PointerPos.y - br.lo.y;
02160 }
02161 else
02162 {
02163 Width = br.hi.x - PointerPos.x;
02164 }
02165 }
02166 else
02167 {
02168 if (dOffsetY > -dOffsetX)
02169 {
02170 Width = PointerPos.y - br.lo.y;
02171 }
02172 else
02173 {
02174 Width = PointerPos.x - br.lo.x;
02175 }
02176 }
02177 }
02178 }
02179 }
02180
02181 return Width;
02182 }
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248 BevelBlob::BevelBlob()
02249 {
02250 m_bDragging = FALSE;
02251 m_BlobAngle = 0;
02252 m_BevelNodeList.DeleteAll();
02253 }
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265 BevelBlob::~BevelBlob()
02266 {
02267 m_bDragging = FALSE;
02268 m_BlobAngle = 0;
02269 m_BevelNodeList.DeleteAll();
02270 }
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284 BOOL BevelBlob::AddNode(NodeBevelController * pNode)
02285 {
02286
02287 if (!pNode)
02288 return FALSE;
02289
02290 if (!pNode->IsKindOf(CC_RUNTIME_CLASS(NodeBevelController)))
02291 return FALSE;
02292
02293 NodeListItem * pListItem = NULL;
02294
02295
02296 AttrBevelLightAngle * pAttr = NULL;
02297
02298 pNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrBevelLightAngle),
02299 (NodeAttribute **)(&pAttr));
02300
02301 INT32 LightAngle = 0;
02302
02303 if (pAttr)
02304 {
02305 LightAngle = (INT32)pAttr->Value.m_LightAngle;
02306 }
02307 else
02308 {
02309 LightAngle = (INT32)((NodeBevelController *)pNode)->m_LightAngle;
02310 }
02311
02312
02313 if (m_BevelNodeList.IsEmpty())
02314 {
02315
02316
02317 m_BevelNodeListRect = pNode->GetBlobBoundingRect();
02318
02319
02320 pListItem = new NodeListItem;
02321 if (!pListItem)
02322 {
02323 ERROR3("Can't create list item");
02324 return FALSE;
02325 }
02326
02327 pListItem->pNode = pNode;
02328
02329
02330 m_BlobAngle = LightAngle;
02331
02332 m_BevelNodeList.AddTail(pListItem);
02333
02334 return TRUE;
02335 }
02336
02337
02338 if (LightAngle != m_BlobAngle)
02339 {
02340
02341 return FALSE;
02342 }
02343
02344
02345 pListItem = new NodeListItem;
02346 if (!pListItem)
02347 {
02348 ERROR3("Can't create list item");
02349 return FALSE;
02350 }
02351
02352 pListItem->pNode = pNode;
02353
02354 m_BevelNodeListRect = m_BevelNodeListRect.Union(pNode->GetBlobBoundingRect());
02355
02356 m_BevelNodeList.AddTail(pListItem);
02357
02358 return TRUE;
02359 }
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371 void BevelBlob::RenderBlob(RenderRegion * pRegion)
02372 {
02373
02374
02375 pRegion->SaveContext();
02376
02377
02378 pRegion->SetLineColour(COLOUR_NONE);
02379 pRegion->SetFillColour(COLOUR_BLACK);
02380
02381 DocRect dr = m_BevelNodeListRect;
02382
02383 DocCoord blob1((dr.hi.x + dr.lo.x) / 2, (dr.hi.y + dr.lo.y) / 2);
02384 DocCoord blob2;
02385
02386
02387
02388
02389 double angle = m_BlobAngle;
02390 TRACEUSER( "DavidM", _T("Blob angle %d\n"), m_BlobAngle);
02391
02392 angle = (angle * 3.142) / 180.0;
02393
02394
02395 DocView * pView = DocView::GetSelected();
02396
02397 if (!pView)
02398 {
02399 pRegion->RestoreContext();
02400 return;
02401 }
02402
02403 double len = pView->GetScaledPixelWidth().MakeDouble() * 40.0;
02404
02405 double dx = len * cos(angle);
02406 double dy = len * sin(angle);
02407
02408 blob2.x = blob1.x - ((INT32)dx);
02409 blob2.y = blob1.y - ((INT32)dy);
02410
02411
02412
02413
02414 m_BlobCentre = blob1;
02415
02416
02417 pRegion->SetLineColour(COLOUR_BLACK);
02418
02419 pRegion->SetLineWidth((INT32)((pRegion->GetScaledPixelWidth()) * 2));
02420
02421
02422 StartCapAttribute SCA;
02423 SCA.StartCap = LineCapButt;
02424 pRegion->SetStartCap(&SCA, FALSE);
02425
02426 ArrowRec mArrow;
02427 mArrow.CreateStockArrow(SA_STRAIGHTARROW);
02428 mArrow.SetArrowSize(mArrow.GetArrowWidth() * 2);
02429
02430
02431 DocCoord ArrowBottom;
02432
02433 pRegion->DrawLine(blob1, blob2);
02434
02435
02436 if (!pRegion->DrawArrowHead(mArrow, blob2, blob1))
02437 ERROR3("Cannot draw arrow");
02438
02439
02440
02441 DocCoord blob3;
02442
02443
02444 len += (pView->GetScaledPixelWidth().MakeDouble()) * 15.0;
02445
02446 dx = len * cos(angle);
02447 dy = len * sin(angle);
02448
02449 blob3.x = blob1.x - ((INT32)dx);
02450 blob3.y = blob1.y - ((INT32)dy);
02451
02452 pRegion->SetFillColour(COLOUR_RED);
02453 pRegion->SetLineColour(COLOUR_NONE);
02454 pRegion->DrawBlob(blob3, BT_SELECTED);
02455
02456
02457 if (GetApplication()->GetBlobManager())
02458 {
02459 GetApplication()->GetBlobManager()->GetBlobRect(blob3, &m_BlobDocRect);
02460 }
02461
02462 pRegion->RestoreContext();
02463 }
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475 BOOL BevelBlob::IsBlobValid()
02476 {
02477 NodeListItem * pItem = (NodeListItem *)m_BevelNodeList.GetHead();
02478
02479 if (pItem)
02480 {
02481 if (pItem->pNode)
02482 {
02483 if (pItem->pNode->IsNodeHidden() ||
02484 pItem->pNode->IsLocked() ||
02485 !pItem->pNode->IsRenderable())
02486 {
02487 return FALSE;
02488 }
02489 }
02490
02491 pItem = (NodeListItem *)m_BevelNodeList.GetNext(pItem);
02492 }
02493
02494 return TRUE;
02495 }
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508 BOOL BevelBlob::HitTest(const DocCoord &dc)
02509 {
02510 return m_BlobDocRect.ContainsCoord(dc);
02511 }
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526 void BevelBlob::CalculateAngle(const DocCoord &dc, BOOL bConstrain)
02527 {
02528
02529 double dx = dc.x - m_BlobCentre.x;
02530 double dy = dc.y - m_BlobCentre.y;
02531
02532
02533 double len = sqrt(dx*dx + dy*dy);
02534
02535
02536 if (len <= 0)
02537 return;
02538
02539 dx /= len;
02540 dy /= len;
02541
02542
02543 double angle = acos(dx);
02544
02545 angle *= ((double)180) / (3.142);
02546
02547
02548 angle = 180.0 - angle;
02549
02550 if (dy > 0)
02551 {
02552 angle = 360.0 - angle;
02553 }
02554
02555
02556 if (bConstrain)
02557 {
02558
02559
02560 double ConstrainAngle = 0.0;
02561 INT32 ConstrainAngleInDegrees = 0;
02562 BOOL ReadOk = Camelot.GetPrefValue(TEXT("Constraints"), TEXT("Constrain Angle"), &ConstrainAngle);
02563
02564 if (ReadOk)
02565 {
02566 ConstrainAngleInDegrees = (INT32)((ConstrainAngle * 180.0/PI) + 0.5);
02567
02568 INT32 NewAngle = ((INT32)angle) / ConstrainAngleInDegrees;
02569 angle = NewAngle * ConstrainAngleInDegrees;
02570 }
02571 }
02572
02573
02574 SetAngle((INT32)angle);
02575 }
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590 void BevelBlob::SetAngle(INT32 Angle, BOOL bSetList)
02591 {
02592
02593 m_BlobAngle = Angle;
02594
02595 NodeListItem * pItem = NULL;
02596
02597
02598 if (bSetList)
02599 {
02600 pItem = (NodeListItem *)m_BevelNodeList.GetHead();
02601
02602 while (pItem)
02603 {
02604 if (pItem->pNode)
02605 {
02606 if (pItem->pNode->IsKindOf(CC_RUNTIME_CLASS(NodeBevelController)))
02607 {
02608
02609 ((NodeBevelController *)pItem->pNode)->m_LightAngle = 360 - Angle;
02610 ((NodeBevelController *)pItem->pNode)->ReleaseCached();
02611 }
02612 }
02613
02614 pItem = (NodeListItem *)m_BevelNodeList.GetNext(pItem);
02615 }
02616 }
02617 }
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632 void BevelBlob::SetTilt(INT32 Angle, BOOL bSetList)
02633 {
02634 NodeListItem * pItem = NULL;
02635
02636 NodeBevelController * pControl = NULL;
02637 NodeBevel * pBevel = NULL;
02638
02639
02640 if (bSetList)
02641 {
02642 pItem = (NodeListItem *)m_BevelNodeList.GetHead();
02643
02644 while (pItem)
02645 {
02646 if (pItem->pNode)
02647 {
02648 if (pItem->pNode->IsKindOf(CC_RUNTIME_CLASS(NodeBevelController)))
02649 {
02650 pControl = ((NodeBevelController *)pItem->pNode);
02651 pControl->m_Tilt = Angle;
02652
02653 pBevel = pControl->GetBevelNode();
02654
02655 if (pBevel)
02656 {
02657 pBevel->m_Tilt = Angle;
02658 }
02659 }
02660 ((NodeBevelController *)pItem->pNode)->ReleaseCached();
02661 }
02662
02663 pItem = (NodeListItem *)m_BevelNodeList.GetNext(pItem);
02664 }
02665 }
02666 }
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681 void BevelBlob::RenderNodes()
02682 {
02683 TRACEUSER( "DavidM", _T("BevelBlob - render nodes\n"));
02684
02685 NodeListItem * pItem = (NodeListItem *)m_BevelNodeList.GetHead();
02686
02687 while (pItem)
02688 {
02689 ((NodeBevelController *)pItem->pNode)->ReRenderBevelBitmap((double)m_BlobAngle);
02690
02691 pItem = (NodeListItem *)m_BevelNodeList.GetNext(pItem);
02692 }
02693 }
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707 void BevelBlob::ChangeContrast(INT32 NewContrast)
02708 {
02709 NodeListItem * pItem = (NodeListItem *)m_BevelNodeList.GetHead();
02710
02711 NodeBevelController * pControl = NULL;
02712
02713
02714
02715
02716
02717 while (pItem)
02718 {
02719 pControl = (NodeBevelController *)pItem->pNode;
02720 pControl->m_Contrast = NewContrast;
02721 ((NodeBevelController *)pItem->pNode)->ReleaseCached();
02722
02723 pItem = (NodeListItem *)m_BevelNodeList.GetNext(pItem);
02724 }
02725 }
02726
02727 BOOL BevelTool::AreToolBlobsRenderedOnSelection()
02728 {
02729 return TRUE;
02730 }
02731
02733
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751 OpDragBevel::OpDragBevel()
02752 {
02753 m_pBarOp = NULL;
02754
02755 m_bHasDragged = FALSE;
02756
02757 m_pPathList = NULL;
02758 m_NumPaths = 0;
02759 m_pSetList = NULL;
02760 m_NumSets = 0;
02761 m_pPathOuterList = NULL;
02762 m_JoinType = RoundJoin;
02763 m_pPathLineWidthList = NULL;
02764 }
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776 OpDragBevel::~OpDragBevel()
02777 {
02778 if (m_pPathList)
02779 {
02780 delete [] m_pPathList;
02781 }
02782
02783 if (m_pSetList)
02784 {
02785 delete [] m_pSetList;
02786 }
02787
02788 if (m_pPathOuterList)
02789 {
02790 delete [] m_pPathOuterList;
02791 }
02792
02793 if (m_pPathLineWidthList)
02794 {
02795 delete [] m_pPathLineWidthList;
02796 }
02797 }
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811 BOOL OpDragBevel::SetupDragInfo()
02812 {
02813 Range Sel((*GetApplication()->FindSelection()));
02814
02815 if (Sel.IsEmpty())
02816 return FALSE;
02817
02818 RangeControl rg = Sel.GetRangeControlFlags();
02819 rg.PromoteToParent = TRUE;
02820 Sel.SetRangeControl(rg);
02821
02822
02823
02824 CProfileBiasGain Profile;
02825
02826
02827
02828 Node * pNode = Sel.FindFirst();
02829
02830 DocRect dr(0,0,0,0);
02831
02832
02833 m_NumPaths = 0;
02834
02835 Node * pSubNode = NULL;
02836
02837
02838
02839
02840 m_NumSets = 0;
02841
02842
02843
02844 BOOL bBevelNodesExist = FALSE;
02845
02846 List BevelNodeList;
02847 BevelTools::BuildListOfSelectedNodes(&BevelNodeList, CC_RUNTIME_CLASS(NodeBevelController),TRUE);
02848
02849 if (!BevelNodeList.IsEmpty())
02850 {
02851 bBevelNodesExist = TRUE;
02852 }
02853
02854 BevelNodeList.DeleteAll();
02855
02856 DocView * pView = DocView::GetCurrent();
02857 m_Flatness = 200.0;
02858
02859 if (pView)
02860 {
02861 double ZoomFactor = pView->GetScaledPixelWidth().MakeDouble() / pView->GetPixelWidth().MakeDouble();
02862 m_Flatness *= ZoomFactor;
02863 }
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878 Node* pLastController = NULL;
02879 Node* pParentController = NULL;
02880 AttrJoinType* pJoinType = NULL;
02881 AttrLineWidth* pLineWidth = NULL;
02882
02883 BOOL bFoundJoinType = FALSE;
02884 UINT32 ObjectCount = 0;
02885
02886 m_JoinType = RoundJoin;
02887 BecomeA MyTestBecomeA(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath));
02888 MyTestBecomeA.ResetCount();
02889
02890 while (pNode)
02891 {
02892 pSubNode = pNode->FindFirstDepthFirst();
02893
02894
02895 if (bBevelNodesExist)
02896 {
02897 pLastController = pSubNode->FindParent(CC_RUNTIME_CLASS(NodeBevelController));
02898
02899 if(pLastController)
02900 {
02901 ((NodeRenderableInk *)pLastController)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrJoinType), (NodeAttribute **)(&pJoinType));
02902
02903 if (pJoinType)
02904 {
02905 bFoundJoinType = TRUE;
02906 m_JoinType = pJoinType->Value.JoinType;
02907 }
02908 }
02909 }
02910
02911 while (pSubNode)
02912 {
02913 if(pSubNode->IsABevel())
02914 {
02915 ((NodeRenderableInk *)pSubNode)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrJoinType),
02916 (NodeAttribute **)(&pJoinType));
02917
02918 if (pJoinType)
02919 {
02920 bFoundJoinType = TRUE;
02921 m_JoinType = pJoinType->Value.JoinType;
02922 }
02923 }
02924
02925 MyTestBecomeA.ResetCount();
02926 if (NodeCanBeDragBevelled(pSubNode, pNode, bBevelNodesExist) &&
02927 pSubNode->CanBecomeA(&MyTestBecomeA))
02928 {
02929
02930 if (!bBevelNodesExist ||
02931 pSubNode->FindParent(CC_RUNTIME_CLASS(NodeBevelController)) != NULL)
02932 m_NumPaths += MyTestBecomeA.GetCount();
02933
02934 if (!bFoundJoinType)
02935 {
02936 ((NodeRenderableInk *)pSubNode)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrJoinType),
02937 (NodeAttribute **)(&pJoinType));
02938
02939 if (pJoinType)
02940 {
02941 bFoundJoinType = TRUE;
02942 m_JoinType = pJoinType->Value.JoinType;
02943 }
02944 }
02945
02946
02947
02948 if (bBevelNodesExist)
02949 {
02950 pParentController = pSubNode->FindParent(CC_RUNTIME_CLASS(NodeBevelController));
02951
02952 if (pParentController)
02953 {
02954 if (pParentController != pLastController &&
02955 pLastController != NULL)
02956 {
02957 m_NumSets ++;
02958 }
02959
02960 pLastController = pParentController;
02961 }
02962 }
02963 }
02964
02965 pSubNode = pSubNode->FindNextDepthFirst(pNode);
02966 }
02967
02968 m_NumSets ++;
02969
02970 pNode = Sel.FindNext(pNode);
02971 }
02972
02973
02974 m_NumSets++;
02975
02976 ERROR2IF(m_NumPaths == 0, FALSE, "Nothing to bevel");
02977
02978 if (m_pPathList)
02979 delete [] m_pPathList;
02980
02981 if (m_pSetList)
02982 delete [] m_pSetList;
02983
02984 if (m_pPathOuterList)
02985 delete [] m_pPathOuterList;
02986
02987 if (m_pPathLineWidthList)
02988 delete [] m_pPathLineWidthList;
02989
02990
02991
02992 ALLOC_WITH_FAIL(m_pPathOuterList, new BOOL[m_NumPaths], this);
02993 ALLOC_WITH_FAIL(m_pPathList, new Path[m_NumPaths], this);
02994 ALLOC_WITH_FAIL(m_pPathLineWidthList, new LineWidthAttribute*[m_NumPaths], this);
02995 ALLOC_WITH_FAIL(m_pSetList, new UINT32[m_NumSets], this);
02996
02997 UINT32 i;
02998 for (i = 0; i < m_NumPaths; i++)
02999 {
03000 m_pPathList[i].Initialise();
03001 m_pPathOuterList[i] = TRUE;
03002 m_pPathLineWidthList[i] = NULL;
03003 }
03004
03005
03006 pOurDoc = Document::GetCurrent();
03007
03008
03009 ContourDragBecomeA MyBecomeA(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath), this, FALSE,
03010 m_pPathList, m_NumPaths);
03011
03012 pNode = Sel.FindFirst();
03013
03014
03015
03016
03017
03018 NodeBevelController * pControl = NULL;
03019
03020 UINT32 SetCount = 0;
03021 NodeAttribute* pAttr = NULL;
03022 BOOL IsVariableWidth = FALSE;
03023 Node* pNodePath = NULL;
03024 UINT32 StartCount = 0;
03025 UINT32 x = 0;
03026
03027 while (pNode)
03028 {
03029 pSubNode = pNode->FindFirstDepthFirst();
03030
03031
03032 if (bBevelNodesExist)
03033 pLastController = pSubNode->FindParent(CC_RUNTIME_CLASS(NodeBevelController));
03034
03035
03036 m_pSetList[SetCount++] = MyBecomeA.GetCount();
03037
03038 ERROR3IF(SetCount >= m_NumSets, "Number of sets doesn't match");
03039
03040 while (pSubNode)
03041 {
03042
03043 if (NodeCanBeDragBevelled(pSubNode, pNode, bBevelNodesExist) &&
03044 pSubNode->CanBecomeA(&MyTestBecomeA) &&
03045 pSubNode->IsAnObject())
03046 {
03047
03048
03049 if (bBevelNodesExist)
03050 {
03051 pParentController = pSubNode->FindParent(CC_RUNTIME_CLASS(NodeBevelController));
03052
03053 if (pParentController)
03054 {
03055 if (pParentController != pLastController && pLastController != NULL)
03056 m_pSetList[SetCount++] = MyBecomeA.GetCount();
03057
03058 pLastController = pParentController;
03059 }
03060 }
03061
03062
03063 if (!bBevelNodesExist || pSubNode->FindParent(CC_RUNTIME_CLASS(NodeBevelController)) != NULL)
03064 {
03065
03066 StartCount = MyBecomeA.GetCount();
03067
03068
03069 pControl = (NodeBevelController *)pSubNode->FindParent(CC_RUNTIME_CLASS(NodeBevelController));
03070
03071 pLineWidth = NULL;
03072 ((NodeRenderableInk *)pSubNode)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrLineWidth),(NodeAttribute**)(&pLineWidth));
03073
03074
03075 if (!pSubNode->IsNodePath())
03076 pSubNode->DoBecomeA(&MyBecomeA);
03077 else
03078 {
03079
03080 pNodePath = ((NodePath *)pSubNode)->MakeNodePathFromAttributes(m_Flatness,NULL,FALSE,FALSE);
03081
03082 if(pNodePath)
03083 {
03084 pNodePath->DoBecomeA(&MyBecomeA);
03085 delete pNodePath;
03086 }
03087 }
03088
03089 if(((NodePath*)pSubNode)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrVariableWidth),&pAttr))
03090 IsVariableWidth = (pAttr && ((VariableWidthAttrValue*)pAttr->GetAttributeValue())->GetWidthFunction() != NULL);
03091
03092 if (pLineWidth && !IsVariableWidth)
03093 m_pPathLineWidthList[ObjectCount] = &pLineWidth->Value;
03094
03095 ObjectCount++;
03096
03097
03098
03099 if (pControl)
03100 {
03101
03102 for (x = StartCount; x < MyBecomeA.GetCount(); x++)
03103 {
03104 if (!pControl->m_bOuter)
03105 m_pPathOuterList[x] = FALSE;
03106 }
03107 }
03108 }
03109 }
03110
03111 pSubNode = pSubNode->FindNextDepthFirst(pNode);
03112 }
03113
03114 pNode = Sel.FindNext(pNode);
03115 }
03116
03117
03118 m_pSetList[SetCount] = MyBecomeA.GetCount();
03119
03120 m_SelRect.MakeEmpty();
03121
03122
03123 for (i = 0 ; i < m_NumPaths; i++)
03124 {
03125 if (m_pPathList[i].GetNumCoords() > 2)
03126 {
03127 m_pPathList[i].GetTrueBoundingRect(&dr);
03128 m_SelRect = m_SelRect.Union(dr);
03129 }
03130 }
03131
03132
03133 BlobManager * pBlobMgr = GetApplication()->GetBlobManager();
03134
03135 if(pBlobMgr)
03136 m_SelRect.Inflate(pBlobMgr->GetBlobSize());
03137
03138 return TRUE;
03139 }
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169 BOOL OpDragBevel::NodeCanBeDragBevelled(Node* pSubNode,
03170 Node* pNode,
03171 BOOL bBevelNodesExist)
03172 {
03173
03174 BOOL ok = !pSubNode->NeedsParent(NULL);
03175
03176
03177 if (ok) ok = pSubNode->IsAnObject();
03178
03179
03180 if (ok) ok = !pSubNode->IsCompound() || pSubNode->IsABaseTextClass() ||
03181 pSubNode->IS_KIND_OF(NodeMould) || pSubNode->IsANodeClipViewController();
03182
03183
03184 if (ok) ok = (pSubNode->FindParent(CC_RUNTIME_CLASS(NodeMould)) == NULL);
03185
03186
03187 if (ok)
03188 {
03189
03190
03191
03192 if (bBevelNodesExist)
03193 {
03194 Node* pNCC = pSubNode->FindParent(CC_RUNTIME_CLASS(NodeBevelController));
03195 if (pNCC != NULL)
03196 {
03197 Node* pNodeTest = pNCC;
03198 while (pNodeTest != pNode && pNodeTest != NULL)
03199 pNodeTest = pNodeTest->FindParent();
03200 if (pNodeTest != NULL)
03201 {
03202
03203
03204
03205 ok = !pSubNode->IsFamily(CC_RUNTIME_CLASS(NodeClipViewController), pNCC);
03206 }
03207 }
03208 }
03209
03210
03211
03212 else
03213 ok = !pSubNode->IsFamily(CC_RUNTIME_CLASS(NodeClipViewController), pNode);
03214 }
03215
03216 return ok;
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231 }
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246 void OpDragBevel::AlterPointerPosToAccountForBlob(DocCoord * pPoint)
03247 {
03248 DocCoord PPos;
03249
03250 DocCoord Offset;
03251
03252 double Scale = 0;
03253
03254 BlobManager * pBlobMgr = GetApplication()->GetBlobManager();
03255
03256 double BlobSize = 0;
03257
03258 if (pBlobMgr)
03259 BlobSize = pBlobMgr->GetBlobSize()/2;
03260 else
03261 return;
03262
03263 if (m_BlobRect.IsValid())
03264 {
03265 DocCoord Centre = m_BlobRect.Centre();
03266
03267 if (m_BlobRect.ContainsCoord(*pPoint))
03268 {
03269
03270 pPoint->x = Centre.x;
03271 pPoint->y = Centre.y;
03272 }
03273 else
03274 {
03275
03276
03277
03278
03279
03280 PPos.x = pPoint->x - Centre.x;
03281 PPos.y = pPoint->y - Centre.y;
03282
03283 if (abs(PPos.x) > abs(PPos.y))
03284 {
03285 Scale = ((double)abs(PPos.y)) / ((double)abs(PPos.x));
03286 Scale *= BlobSize;
03287
03288 if (PPos.x > 0)
03289 {
03290 Offset.x = (INT32)BlobSize;
03291 }
03292 else
03293 {
03294 Offset.x = (INT32)-BlobSize;
03295 }
03296
03297 if (PPos.y > 0)
03298 {
03299 Offset.y = (INT32)Scale;
03300 }
03301 else
03302 {
03303 Offset.y = (INT32)-Scale;
03304 }
03305 }
03306 else
03307 {
03308 Scale = ((double)PPos.x) / ((double)PPos.y);
03309 Scale *= BlobSize;
03310
03311 if (PPos.y > 0)
03312 {
03313 Offset.y = (INT32)BlobSize;
03314 }
03315 else
03316 {
03317 Offset.y = (INT32)-BlobSize;
03318 }
03319
03320 if (PPos.x > 0)
03321 {
03322 Offset.x = (INT32)Scale;
03323 }
03324 else
03325 {
03326 Offset.x = (INT32)-Scale;
03327 }
03328 }
03329
03330 pPoint->x -= Offset.x;
03331 pPoint->y -= Offset.y;
03332 }
03333 }
03334 }
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353 BOOL OpDragBevel::DoDrag(BevelInfoBarOp * pBar, DocCoord &PointerPos, BOOL bDragOnBlob,
03354 DocRect *pBlobRect)
03355 {
03356
03357 DocView *pView = DocView::GetCurrent();
03358 Spread * pSpread = Document::GetSelectedSpread();
03359
03360 if (pView && pSpread)
03361 {
03362 pView->Snap(pSpread, &PointerPos, FALSE, TRUE);
03363 }
03364
03366
03367
03368
03369
03370
03371
03372
03373 if (bDragOnBlob)
03374 GetApplication()->FindSelection()->MakePartialSelectionWhole();
03375
03376
03377 else
03378 return FALSE;
03379
03381
03382
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401 m_pBarOp = pBar;
03402 m_bHasDragged = FALSE;
03403 m_LastPointerPos = PointerPos;
03404 m_ThisPointerPos = PointerPos;
03405
03406 if (pBlobRect)
03407 m_BlobRect = *pBlobRect;
03408 else
03409 m_BlobRect = DocRect(0,0,0,0);
03410
03411 m_bDragStartedOnBlob = bDragOnBlob;
03412
03413
03414 if (!GetApplication()->FindSelection())
03415 return FALSE;
03416
03417
03418 List BevelList;
03419 BevelTools::BuildListOfSelectedNodes(&BevelList, CC_RUNTIME_CLASS(NodeBevelController));
03420
03421 if (BevelList.IsEmpty())
03422 {
03423 m_OriginalWidth = 0;
03424 }
03425 else
03426 {
03427 NodeListItem * pItem = (NodeListItem *)BevelList.GetHead();
03428
03429 m_OriginalWidth = ((NodeBevelController *)(pItem->pNode))->m_Indent;
03430
03431 if (((NodeBevelController *)(pItem->pNode))->m_bOuter)
03432 m_OriginalWidth = -m_OriginalWidth;
03433
03434 BevelList.DeleteAll();
03435 }
03436
03437
03438 StartDrag( DRAGTYPE_AUTOSCROLL );
03439
03440 if (bDragOnBlob)
03441 {
03442 if (!SetupDragInfo())
03443 {
03444 EndDrag();
03445 return FALSE;
03446 }
03447
03448 DocCoord BlobCentre(pBlobRect->Centre());
03449
03450 m_LastPointerPos = BlobCentre;
03451 m_ThisPointerPos = BlobCentre;
03452
03453
03454 INT32 Width = ContourTool::CalculateContourWidth(m_SelRect,
03455 BlobCentre);
03456
03457 m_StartDragWidth = Width;
03458 }
03459
03460 return TRUE;
03461 }
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481 void OpDragBevel::DragPointerMove( DocCoord PointerPos, ClickModifiers ClickMods,
03482 Spread* pSpread, BOOL bSolidDrag)
03483 {
03484 ERROR3IF(!m_pBarOp, "No info bar op");
03485
03486
03487 DocView *pView = DocView::GetCurrent();
03488
03489 if (pView && pSpread)
03490 {
03491 pView->Snap(pSpread, &PointerPos, FALSE, TRUE);
03492 }
03493
03494 if (PointerPos == m_LastPointerPos)
03495 return;
03496
03497 if (!m_bDragStartedOnBlob)
03498 {
03499 m_bHasDragged = TRUE;
03500 return;
03501 }
03502
03503
03504 if (m_bHasDragged)
03505 RenderDragBlobs(m_SelRect, pSpread, bSolidDrag);
03506
03507 m_bHasDragged = TRUE;
03508 m_LastPointerPos = PointerPos;
03509 m_ThisPointerPos = PointerPos;
03510
03511 BevelTool::DisplayStatusBarHelp(_R(IDS_BEVELDRAGSTATUSHELP));
03512
03513
03514 INT32 Width = (ContourTool::CalculateContourWidth(m_SelRect, PointerPos) - m_StartDragWidth)
03515 + m_OriginalWidth;
03516
03517 RenderDragBlobs(m_SelRect, pSpread, bSolidDrag);
03518
03519 if (Width < 0)
03520 {
03521
03522 m_pBarOp->SetBoolGadgetSelected(_R(IDC_BTN_BEVELOUTER), TRUE);
03523 m_pBarOp->SetBoolGadgetSelected(_R(IDC_BTN_BEVELINNER), FALSE);
03524 }
03525 else
03526 {
03527
03528 m_pBarOp->SetBoolGadgetSelected(_R(IDC_BTN_BEVELOUTER), FALSE);
03529 m_pBarOp->SetBoolGadgetSelected(_R(IDC_BTN_BEVELINNER), TRUE);
03530 }
03531
03532 m_pBarOp->PaintGadgetNow(_R(IDC_BTN_BEVELINNER));
03533 m_pBarOp->PaintGadgetNow(_R(IDC_BTN_BEVELOUTER));
03534
03535 m_pBarOp->m_Depth = abs(Width);
03536 m_pBarOp->SliderUpdate(FALSE, FALSE);
03537 }
03538
03539
03540
03541
03542
03543
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554
03555
03556
03557
03558
03559
03560
03561 void OpDragBevel::DragFinished( DocCoord PointerPos, ClickModifiers ClickMods,
03562 Spread* pSpread, BOOL Success, BOOL bSolidDrag)
03563 {
03564
03565 DocView *pView = DocView::GetCurrent();
03566
03567 if (pView && pSpread)
03568 {
03569 pView->Snap(pSpread, &PointerPos, FALSE, TRUE);
03570 }
03571
03572 if (Tool::GetCurrentID() != TOOLID_BEVELTOOL)
03573 return;
03574
03575
03576
03577
03578
03579
03580
03581 BevelTool * pTool = (BevelTool *)Tool::GetCurrent();
03582
03583
03584
03585
03586 EndDrag();
03587
03588
03589
03590 if (!m_bDragStartedOnBlob)
03591 return;
03592
03593
03594 INT32 Width = (ContourTool::CalculateContourWidth(m_SelRect, PointerPos) - m_StartDragWidth)
03595 + m_OriginalWidth;
03596
03597
03598 if (!m_bHasDragged)
03599 return;
03600
03601 if (m_pBarOp)
03602 m_pBarOp->UpdateState();
03603
03604 m_bHasDragged = FALSE;
03605
03606 if (!pSpread)
03607 pSpread = Document::GetSelectedSpread();
03608
03609
03610 RenderDragBlobs(m_SelRect, pSpread, bSolidDrag);
03611
03612
03613 if (Success)
03614 {
03615 if (pTool)
03616 {
03617 pTool->RenderToolBlobs(pSpread, NULL);
03618 pTool->SetBlobRendering(FALSE);
03619 }
03620
03621
03622 BevelInfo Info;
03623
03624 Info.m_bCreateNewBevels = FALSE;
03625
03626 Info.m_Indent = abs(Width);
03627 Info.m_bBevelIndentChanged = TRUE;
03628
03629 if (Width < 0)
03630 {
03631 Info.m_bOuter = TRUE;
03632 }
03633 else
03634 {
03635 Info.m_bOuter = FALSE;
03636 }
03637
03638 Info.m_bBevelDirectionChanged = (m_OriginalWidth > 0 && Width < 0) || (m_OriginalWidth < 0 && Width > 0);
03639
03640
03641 Info.m_BevelType = 0;
03642 Info.m_Contrast = 50;
03643 Info.m_LightAngle = 300;
03644
03645 OpDescriptor * pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpCreateBevel));
03646
03647 if (pOpDesc)
03648 {
03649 pOpDesc->Invoke(&Info);
03650 }
03651
03652
03653 if (pTool)
03654 {
03655 pTool->SetBlobRendering(TRUE);
03656 pTool->SetupBlobList();
03657 pTool->RenderToolBlobs(pSpread, NULL);
03658 }
03659 }
03660
03661 delete [] m_pPathList;
03662 m_pPathList = NULL;
03663
03664 delete [] m_pSetList;
03665 m_pSetList = NULL;
03666
03667 delete [] m_pPathOuterList;
03668 m_pPathOuterList = NULL;
03669 }
03670
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686 void OpDragBevel::RenderDragBlobs(MILLIPOINT Width,Spread* pSpread, BOOL bKeepDirections)
03687 {
03688 bool Outer = false;
03689 if(Width < 0)
03690 Outer = true;
03691
03692 if (bKeepDirections)
03693 Width = abs(Width);
03694
03695 if (m_pPathLineWidthList == NULL || m_pPathList == NULL || m_pSetList == NULL)
03696 {
03697 ERROR3("No list defined");
03698 return;
03699 }
03700
03701
03702
03703 Path * pSetPathList = NULL;
03704 ALLOC_WITH_FAIL(pSetPathList, new Path[m_NumSets-1], this);
03705
03706
03707 Path * pDrawPathList = NULL;
03708 ALLOC_WITH_FAIL(pDrawPathList, new Path[m_NumPaths], this);
03709
03710
03711 Path CopyPath;
03712 Path TempPath;
03713 CopyPath.Initialise();
03714 TempPath.Initialise();
03715
03716 DocRect DrawBounds(0,0,0,0);
03717 DocRect dri(0,0,0,0);
03718 DocRect drj(0,0,0,0);
03719 UINT32 j = 0;
03720 INT32 PathWidth = 0;
03721
03722
03723 JoinStyles JoinS = (m_JoinType==MitreJoin) ? JOIN_MITER : (m_JoinType==RoundJoin) ? JOIN_ROUND : JOIN_BEVEL;
03724
03725 INT32 CurrentWidth = 0;
03726 UINT32 i;
03727
03728 for (i = 0 ; i < m_NumPaths; i++)
03729 {
03730 pDrawPathList[i].Initialise();
03731 PathWidth = Width;
03732
03733
03734 if(m_pPathLineWidthList[i] != NULL)
03735 {
03736 CurrentWidth = m_pPathLineWidthList[i]->LineWidth;
03737 PathWidth -= (CurrentWidth >> 1);
03738 Outer |= (Width >= 0 && Width < (CurrentWidth >> 1));
03739 }
03740
03741
03742 BOOL IsPathClosed = m_pPathList[i].IsClosed() && m_pPathList[i].IsFilled;
03743 m_pPathList[i].InitializeContourValues(abs(PathWidth)*2,JoinS,Outer,m_Flatness,IsPathClosed,IsPathClosed,CAPS_ROUND);
03744 m_pPathList[i].GetContourForStep(&pDrawPathList[i],1.0);
03745 }
03746
03747
03748 for (i = 0 ; i < m_NumSets - 1; i++)
03749 {
03750 pSetPathList[i].Initialise();
03751 pSetPathList[i].GetTrueBoundingRect(&dri);
03752
03753 for (j = m_pSetList[i]; j < m_pSetList[i+1]; j++)
03754 {
03755 pDrawPathList[j].GetTrueBoundingRect(&drj);
03756 pSetPathList[i].MergeTwoPaths(pDrawPathList[j]);
03757 }
03758
03759 if(m_NumSets > 1)
03760 {
03761 CopyPath.ClearPath(FALSE);
03762 CopyPath.MergeTwoPaths(pSetPathList[i]);
03763 pSetPathList[i].ClearPath(FALSE);
03764 TempPath.ClipPathToPath(CopyPath,&pSetPathList[i],7|(1<<4),50,m_Flatness,m_Flatness);
03765 }
03766
03767 pSetPathList[i].IsFilled = TRUE;
03768 pSetPathList[i].IsStroked = FALSE;
03769
03770 DrawBounds = DrawBounds.Union(dri);
03771 }
03772
03773
03774 DrawBounds.Inflate(750);
03775
03776
03777 RenderRegion* pRegion = DocView::RenderOnTop( NULL, pSpread, UnclippedEOR );
03778
03779 while ( pRegion != NULL )
03780 {
03781
03782 pRegion->SaveContext();
03783
03784 pRegion->SetLineWidth(0);
03785
03786 pRegion->SetWindingRule(PositiveWinding);
03787
03788 pRegion->SetLineColour(COLOUR_RED);
03789 pRegion->SetFillColour(COLOUR_NONE);
03790
03791
03792 for (i = 0 ; i < m_NumSets-1; i++)
03793 {
03794 pRegion->DrawPath(&(pSetPathList[i]));
03795 }
03796
03797
03798 pRegion->RestoreContext();
03799 pRegion = DocView::GetNextOnTop( NULL );
03800 }
03801
03802
03803 delete [] pDrawPathList;
03804 delete [] pSetPathList;
03805 }
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820 void OpDragBevel::RenderDragBlobs(DocRect Rect,Spread* pSpread, BOOL bSolidDrag)
03821 {
03822 if (m_pPathList == NULL || m_NumPaths == 0)
03823 {
03824 ERROR3("Render drag blobs - no path list");
03825 return;
03826 }
03827
03828
03829 INT32 Width = (ContourTool::CalculateContourWidth(m_SelRect, m_ThisPointerPos) - m_StartDragWidth)
03830 + m_OriginalWidth;
03831
03832 RenderDragBlobs(Width, pSpread);
03833 }
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846 BOOL OpDragBevel::Declare()
03847 {
03848 return (RegisterOpDescriptor(
03849 0,
03850 _R(IDS_BEVEL_TOOL),
03851 CC_RUNTIME_CLASS(OpDragBevel),
03852 OPTOKEN_DRAGBEVEL,
03853 OpDragBevel::GetState,
03854 0,
03855 _R(IDBBL_NOOP),
03856 0
03857 ));
03858 }
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875 OpState OpDragBevel::GetState(String_256* Description, OpDescriptor*)
03876 {
03877 OpState State;
03878
03879 return State;
03880 }
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898 void OpDragBevel::GetOpName(String_256* OpName)
03899 {
03900 *OpName = String_256(_R(IDS_BEVELDRAGCREATEOP));
03901 }
03902
03903
03904
03905 #endif
03906
03907