FreeHandTool Class Reference

This class handles the Free Hand Tool that is used to draw lines that follow the path of the Mouse Pointer. More...

#include <freehand.h>

Inheritance diagram for FreeHandTool:

DragTool Tool_v1 List of all members.

Public Member Functions

 FreeHandTool ()
 Dummp Constructor - It does nothing. All the real initialisation is done in FreeHandTool::Init which is called by the Tool Manager.
 ~FreeHandTool ()
 Destructor (Virtual). Does nothing.
BOOL Init ()
 Used to check if the Tool was properly constructed.
void Describe (void *InfoPtr)
 Allows the tool manager to extract information about the tool.
UINT32 GetID ()
virtual void SelectChange (BOOL)
 Called when the tool is selected or deselected. Creates and pushes the tool's cursor; pops and destroys it.
virtual void OnClick (DocCoord, ClickType, ClickModifiers, Spread *)
 To handle a Mouse Click event for the FreeHand Tool. It starts up a FreeHand Operation.
virtual void OnMouseMove (DocCoord, Spread *, ClickModifiers)
 This routine is called whenever the mouse moves while we're in the freehand tool. it sees what is under the pointer, and flips the cursor if clicking will have a different effect. The rules are:.
virtual BOOL GetStatusLineText (String_256 *ptext, Spread *, DocCoord, ClickModifiers)
 Sets the status line text on request from the app.
virtual BOOL OnIdle ()
virtual void RenderToolBlobs (Spread *, DocRect *)
 Renders the Tools Blobs. This will be used to draw paths as they are retro fitted live, as the accuracy bar is dragged!
void SetSmoothness (INT32 Smooth)
 Sets the freehand tools accuracy setting.
INT32 GetSmoothness ()
 for finding out the freehand tools current smoothing accuracy value
void PreviousPathInvalid ()
 Marks the previous path as invalid. After calling this function, attempts to re-fit a path by changing the smoothing values will be ignored. This function should be called when something happens that would make it impossible to re-fit the path (eg the original is translated or rotated or undone).
void SetPreviousPath (NodePath *, INT32 Start, INT32 Len)
 Marks the previously drawn path as valid so that it can be retro fitted. Retro fitting will be allowed until PreviousPathInvalid() is called.
FreeHandInfoBarOpGetInfoBar ()
BOOL IsRetroPathStillValid ()
 Finds out if we are able to do retro fitting and is used by the info bar as well as the tool when it becomes the selected tool and when a drag of the slider starts.
INT32 BuildPathCRC (NodePath *)
 Goes though the path and adds all the coordinate offsets together to come up with a number that will hopefully identify the path uniquly, so that we can tell if this is in fact the path we want, only translated.
void TranslateTrackData ()
 If the path in the tree has been translated since it was drawn, we have to translate the original retro fit data to match. This functions checks if a translation is required, and translates all the coords if it is needed.
void RetroFitChanging ()
 Tries to re-fit the previous path with the current smoothness setting.
void RetroFitFinished ()
 Should be called when any changes to the accuracy slider have been completed.
void CreateBrush ()
 Called from the infobar, creates a brush definition from the ink objects in the selection and passes it over to the BrushComponent. Also creates a GRenderBrush render region which is used for rendering the brush into when the user begins to draw.
void SetCurrentBrushHandle ()
 Sets the brush handle member to that of the current default brush attribute.
MILLIPOINT GetBrushSpacing ()
 for finding out the freehand tools current brush spacing
void SetBrushSpacing (MILLIPOINT Spacing)
 for setting the freehand tools current brush spacing
BrushHandle GetBrushHandle ()
void BrushFinished ()
 Called by OpDrawBrush to tell the tool that the previous draw brush op has finished. Therefore the tool must prepare for the next one (if any).
BOOL BrushSelected (BrushHandle Handle, BOOL ApplyToSelection=TRUE)
 sets the brushhandle member of the tool to Handle. Designed to be called by the infobar when it receives a brushmessage. Also initiates a number of steps that must be taken to ensure that real time drawing with this brush can proceed smoothly
BOOL ApplyBrushToSelection (BrushHandle Handle)
 Applies the chosen brush to all items in the selection via the attribute manager. However we do not want to make this a default attribute so if the selection is empty then nothing happens.
void ScreenChanged (BOOL WipeRegion=FALSE)
 Called by the infobar to let the tool know that the screen has changed. Essentially this means that if we are in brush drawing mode then we need to blit the contents of the screen into our big render region.
void InitialiseJoinInfoForBrush (AttrBrushType *pAttrBrush, NodePath *pNodePath, DocCoord JoinPoint)
 Initialises the JoinInfo struct so that we correctly join the existing brush.
void BrushDeleted (BrushHandle Handle)
 Lets the tool know that a brush has been deactivated (we call it deleted in the UI but its actually still there). If this brush is the current brush then we need to set the current brush to default. Also informs the infobar.
BOOL SetBrushUpdateState (UPDATE_STATE State)
 Tells us when we should next update the offscreen buffer used by the brush. Often it is wise ot wait until the next idle to update because that gives time for the screen to redraw after the brush combo has closed.

Static Public Attributes

static BOOL FreehandPtrCrosshair = FALSE
 Determine whether freehand pointer has crosshairs or not.

Protected Member Functions

GRenderBrushGetBigGRenderBrush (Spread *pSpread)
 Gets a GRenderBrush the size of the current view, then renders into it the contents of the current view.
BOOL InitialiseBrushBitmaps (GRenderBrush *pGRender)
 To work out how large our brush bitmaps must be and allocate them to the render region supplied.
BrushDefinitionGetSelectedBrush ()
 In order to determine which brush to draw with when performing a real time draw brush operation.
BOOL LoadCursors ()
 Loads all the cursors used by the freehand tool and pushs the normal one onto the top of the cursor stack.
void RemoveCursors ()
 Pops the freehand tools cursor off the top of the cursor stack, frees the memory used by all the cursors in the freehand tool and sets all the pointers to NULL.
void ChangeCursor (Cursor *pCursor)
 Changes to the specified cursor. Will only change the cursor if it isn't already this cursor, so it doesn't flicker.
BOOL IsCursorNearEndPoint (NodePath *pPath, const DocRect &BlobRect)
 Scans the path in the NodePath to see any of its endpoints lie inside the DocRect supplied. The DocRect should be the snapping rectangle around the cursor position. If this function finds that one of the endpoints is in the rect, it will remember the path, and the position of the endpoint so that when a new freehand line is started, this data can be passed in. This function also changes the cursor to the Join cursor and sets the status bar text if it finds a match.
BOOL IsCursorNearPath (NodePath *pPath, INT32 Range, const DocCoord &PointerPos)
 This function tests to see if any point along the paths length is close to the cursor. If it finds that it is, then the cursor and the status bar help are changed and the information about the path is remembered in case a drag starts soon.
BOOL GetNewPaths ()
 Gets rid of the old path data and creates new paths. One of the useful side effects of doing this is that it helps to keep the path data near the top of the heap, make the freehand tool seem more responsive.
BOOL DeletePaths ()
 Deletes the paths that hold the track data and the smoothed path and sets thier params to NULL.
BOOL InitialiseBlendRef (NodeRenderableInk *pInk)
 To initialise a BlendRef object.
BOOL NodeHasLineWidth (NodeRenderableInk *pNode)
void SetColourEditorProcessing (BOOL Value)
 Tells the colour editor whether or not to do timer processing, we need to turn it off in order to draw a brush stroke.
DocRect GetLargestInkBoundingRect ()
 as above, note that the m_brushinknodes pointer must be initialised
void InitialiseBrushInkNodeArray (UINT32 NumObjects)
 Clears out the m_BrushRefPtrArray if it is not empty, and sets the size.
void LaunchBrushDefinitionDialog (BrushHandle Handle)
 launches the brush edit dialog for the brush handle supplied. A good idea to call this just after creating a brush so the user can edit it before using it.

Protected Attributes

GRenderBrushm_pGRenderBrush
UPDATE_STATE m_UpdateBrushState
INT32 Smoothness
String_256 StatusMsg
DocCoord StartPos
SpreadStartSpread
PathTrackData
PathRetroPath
INT32 StartSlot
INT32 NumSlots
INT32 PathCRC
NodePathPreviousPath
BOOL AreWeRetroFitting
BOOL IsPreviousPathValid
BOOL IsRetroPathValid
BOOL IsSelectBlobsOnScreen
CursorpNormalCursor
CursorpJoinCursor
CursorpActiveCursor
CursorpModifyCursor
INT32 CurrentCursorID
FreeHandJoinInfo JoinInfo
FreeHandInfoBarOppInfoBarOp
std::vector< NodeRenderableInk * > m_BrushInkNodeArray
BlendRefm_pBlendRef
MILLIPOINT m_BrushSpacing
UINT32 m_NumInkNodes
BrushHandle m_BrushHandle
BOOL m_bBrushReady
String_256 m_LastBrushDocument

Static Protected Attributes

static TCHARFamilyName = _T("Drawing Tools")
static TCHARToolName = _T("Free Hand Tool")
static TCHARPurpose = _T("To Draw arbitrary lines")
static TCHARAuthor = _T("Rik")

Private Member Functions

 CC_DECLARE_MEMDUMP (FreeHandTool)

Detailed Description

This class handles the Free Hand Tool that is used to draw lines that follow the path of the Mouse Pointer.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/7/93

Definition at line 170 of file freehand.h.


Constructor & Destructor Documentation

FreeHandTool::FreeHandTool  ) 
 

Dummp Constructor - It does nothing. All the real initialisation is done in FreeHandTool::Init which is called by the Tool Manager.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/6/93
See also:
FreeHandTool::Init

Definition at line 205 of file freehand.cpp.

00206 {
00207     // The Default smoothness
00208     Smoothness = 50;
00209     
00210     // No info bar or previous path by default
00211     pInfoBarOp = NULL;
00212     PreviousPath = NULL;
00213 
00214     // The previous path is not valid
00215     IsPreviousPathValid = FALSE;
00216     IsRetroPathValid = FALSE;
00217     AreWeRetroFitting = FALSE;
00218 
00219     // The actual paths
00220     TrackData = NULL;
00221     RetroPath = NULL;
00222 
00223     // Positions in the previous path to default values
00224     StartSlot = 0;
00225     NumSlots = 0;
00226     
00227     // Set the cursor pointers to null
00228     pNormalCursor = NULL;
00229     pActiveCursor = NULL;
00230     pJoinCursor = NULL;
00231 
00232     // Set the vars to deal with the Joining of paths
00233     JoinInfo.pJoinPath = NULL;
00234     JoinInfo.IsNearEndPoint = FALSE;
00235     JoinInfo.CloseSlot = 0;
00236     JoinInfo.Into = 0.0;
00237     JoinInfo.pAttrBrush = NULL;
00238     JoinInfo.FirstBrushSpacing = 25;
00239 
00240     // Make sure that the status line text is a valid string
00241     StatusMsg = String_256("");
00242     
00243     m_pBlendRef     = NULL;
00244     m_BrushSpacing  = 10000;
00245     m_NumInkNodes   = 0;
00246     m_pGRenderBrush = NULL;
00247     m_BrushHandle   = BrushHandle_NoBrush;
00248     
00249     m_LastBrushDocument = TEXT("No document");
00250 }

FreeHandTool::~FreeHandTool  ) 
 

Destructor (Virtual). Does nothing.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/6/93

Definition at line 264 of file freehand.cpp.

00265 {
00266     //Clear out the old paths
00267     DeletePaths();
00268 PORTNOTE("other", "Removed m_pGRenderBrush support");
00269 #ifndef EXCLUDE_FROM_XARALX
00270     if (m_pGRenderBrush != NULL)
00271         delete m_pGRenderBrush;
00272 #endif
00273 }


Member Function Documentation

BOOL FreeHandTool::ApplyBrushToSelection BrushHandle  Handle  ) 
 

Applies the chosen brush to all items in the selection via the attribute manager. However we do not want to make this a default attribute so if the selection is empty then nothing happens.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
Handle to the selected brush [INPUTS]
- [OUTPUTS]
Returns:
TRUE if successful, FALSE otherwise

Definition at line 2680 of file freehand.cpp.

02681 {
02682     // first check to see if we have a selection
02683     SelRange* pSel = GetApplication()->FindSelection();
02684     if (pSel == NULL)
02685     {
02686         ERROR3("No selection in FreeHandTool::ApplyBrushToSelection");
02687         return FALSE;
02688     }
02689 
02690     // we have decided that if the selection is not empty then we will not try to 
02691     // go ahead and apply the attribute, as this gets annoying when you only want to 
02692     // draw with a different brush
02693     if (pSel->IsEmpty())
02694         return TRUE;
02695 
02696     // ok so we have a selection, now get an attribute node from the brush component
02697     NodeAttribute* pNewAttr = BrushComponent::CreateNode(Handle);
02698     if (pNewAttr != NULL)
02699         AttributeManager::AttributeSelected(pNewAttr);
02700 
02701     // we may have a scenario where we wish to apply the default brush
02702     if (Handle == BrushHandle_NoBrush)
02703     {
02704         // in this case we just need to make an attribute node
02705         NodeAttribute* pAttr = new AttrBrushType;
02706         if (pAttr != NULL)
02707             AttributeManager::AttributeSelected(pAttr);
02708     }
02709     return TRUE;
02710     
02711 }

void FreeHandTool::BrushDeleted BrushHandle  Handle  ) 
 

Lets the tool know that a brush has been deactivated (we call it deleted in the UI but its actually still there). If this brush is the current brush then we need to set the current brush to default. Also informs the infobar.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
Handle to the brush that has been deleted [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 2579 of file freehand.cpp.

02580 {
02581     if (Handle == m_BrushHandle)
02582         BrushSelected(BrushHandle_NoBrush, FALSE);
02583 
02584     if (pInfoBarOp != NULL)
02585         pInfoBarOp->RemoveBrush(Handle);
02586 }

void FreeHandTool::BrushFinished  ) 
 

Called by OpDrawBrush to tell the tool that the previous draw brush op has finished. Therefore the tool must prepare for the next one (if any).

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-
TRACEUSER( "Diccon", _T("Brush Finished\n"));

Definition at line 2601 of file freehand.cpp.

02602 {
02603     // turn the colour picker back on
02604     SetColourEditorProcessing(TRUE);
02605     
02606     // turn background rendering back on 
02607     Document* pDoc = Document::GetSelected();
02608     DocView* pDocView = pDoc->GetFirstDocView();
02609     
02610     while (pDocView)
02611     {
02612         pDocView->SetPreventRenderView(FALSE);
02613         pDocView = pDoc->GetNextDocView(pDocView);
02614     }
02615 
02616     /*
02617     DocView* pDocView = DocView::GetSelected(); //gotta be getselected in case we have multiple views
02618     if (pDocView != NULL)
02619         pDocView->SetPreventRenderView(FALSE);
02620     */
02621     m_bBrushReady = FALSE;
02622     m_UpdateBrushState = UPDATE_ONIDLE;
02624     BrushSelected(m_BrushHandle, FALSE);
02625 
02626 
02627 }

BOOL FreeHandTool::BrushSelected BrushHandle  Handle,
BOOL  ApplyToSelection = TRUE
 

sets the brushhandle member of the tool to Handle. Designed to be called by the infobar when it receives a brushmessage. Also initiates a number of steps that must be taken to ensure that real time drawing with this brush can proceed smoothly

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
Handle to the selected brush [INPUTS] ApplyToSelection - whether or not we wish to apply this brush to the selection
- [OUTPUTS]
Returns:
TRUE if successful, FALSE if something went wrong

Definition at line 2398 of file freehand.cpp.

02399 {
02400     if (m_UpdateBrushState == UPDATE_NEVER)
02401         return TRUE;
02402 
02403     // first apply what we've got to the selection
02404     if (ApplyToSelection)
02405     {
02406         // if this fails then quit
02407         if (!ApplyBrushToSelection(Handle))
02408             return FALSE;
02409 
02410         m_UpdateBrushState = UPDATE_ONIDLE; // So that we update on the next idle rather than immediately
02411     }
02412 
02413     //TRACEUSER( "Diccon", _T("Start Brush selected\n"));
02414     m_BrushHandle = Handle;
02415     
02416     // note that we do not do the update straight unless the flag is set.  If it is not set then
02417     // we set the flag and then do the update on the next idle event.  The reason for this is that
02418     // if we do not wait then the brush combo will still be on the screen whilst we do our screen grab
02419 
02420     if (m_UpdateBrushState == UPDATE_NOW)
02421         m_UpdateBrushState = UPDATE_NEVER;
02422     else
02423     {   
02424         m_UpdateBrushState = UPDATE_ONIDLE;
02425         return TRUE;
02426     }
02427 
02428     // if its the 'null' brush then just kill the render region and leave
02429     if (m_BrushHandle == BrushHandle_NoBrush)
02430     {
02431 PORTNOTE("other", "Removed m_pGRenderBrush support");
02432 #ifndef EXCLUDE_FROM_XARALX
02433         if (m_pGRenderBrush != NULL)
02434         {
02435             delete m_pGRenderBrush;
02436             m_pGRenderBrush = NULL;
02437         }
02438 #endif
02439         return TRUE;
02440     }
02441 
02442 PORTNOTE("other", "Removed m_pGRenderBrush support");
02443 #ifndef EXCLUDE_FROM_XARALX
02444     // if we are <24BPP display then make the whole thing again from scratch
02445     // as we will need different sized brush bitmaps and everything
02446     if (m_pGRenderBrush != NULL && m_pGRenderBrush->GetScreenDepth() < 24)
02447     {
02448         delete m_pGRenderBrush;
02449         m_pGRenderBrush = NULL;
02450     }
02451 
02452     String_32 ProgString = _T("Preparing brush, please wait..");
02453     Progress Hourglass(&ProgString, -1, FALSE);
02454     
02455     // set smoothness to zero
02456 //  SetSmoothness(0);
02457 
02458     Spread* pCurrentSpread = Document::GetSelectedSpread();
02459     // make a new GRenderBrush for the new brush
02460     if (pCurrentSpread == NULL)
02461     {
02462         ERROR3("No Spread in FreeHandTool::BrushSelected");
02463         return FALSE;
02464     }
02465         
02466     // inform the join info of what we're going to draw
02467     JoinInfo.m_BrushHandle = m_BrushHandle;
02468     
02469     if (m_pGRenderBrush == NULL)
02470     {
02471         m_pGRenderBrush = GetBigGRenderBrush(pCurrentSpread);
02472     
02473         if (m_pGRenderBrush != NULL)
02474         {
02475             if (!InitialiseBrushBitmaps(m_pGRenderBrush))
02476             {
02477                 InformWarning(_R(IDS_BRUSHBITMAP_INVALID));
02478                 delete m_pGRenderBrush;
02479                 m_pGRenderBrush = NULL;
02480 
02481                 return FALSE;
02482             }
02483 
02484             m_bBrushReady = TRUE;
02485 
02486         }
02487         else
02488         {
02489             ToolInformError(_R(IDS_OUT_OF_MEMORY));
02490         
02491             return FALSE;
02492         }
02493     }
02494     else
02495     {
02496         // grab whats on the screen
02497         BOOL ok = m_pGRenderBrush->CaptureView(pCurrentSpread);
02498 
02499         // tell GDraw to use this bitmap
02500         if (ok) m_pGRenderBrush->SetupMainBitmap();
02501         return ok; //m_pGRenderBrush->CaptureView(pCurrentSpread);
02502     }
02503 #endif
02504 
02505     return TRUE;
02506 }

INT32 FreeHandTool::BuildPathCRC NodePath PrevPath  ) 
 

Goes though the path and adds all the coordinate offsets together to come up with a number that will hopefully identify the path uniquly, so that we can tell if this is in fact the path we want, only translated.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/6/94
Parameters:
PrevPath - The path to build a CRC checksum for. [INPUTS]
Returns:
The CRC checksum for the path, relative to the first coord

Definition at line 1378 of file freehand.cpp.

01379 {
01380     INT32 TotalCRC = 0;
01381 
01382     // Get at the path in the NodePath
01383     Path* CRCPath = &(PrevPath->InkPath);
01384 
01385     // Find out about the coords and how many there are
01386     DocCoord* Coords = CRCPath->GetCoordArray();
01387     INT32 NumCoords = StartSlot+NumSlots;
01388 
01389     // go though the coords
01390     for (INT32 i=StartSlot; i<NumCoords; i++)
01391     {
01392         // Get the coords relative from the first coord
01393         // making this process transparent to trnslation
01394         // Add it in to the CRC total
01395         TotalCRC += (Coords[i].x-Coords[StartSlot].x) + (Coords[i].y-Coords[StartSlot].y);
01396     }
01397 
01398     // return the CRC I have
01399     return TotalCRC;
01400 }

FreeHandTool::CC_DECLARE_MEMDUMP FreeHandTool   )  [private]
 

void FreeHandTool::ChangeCursor Cursor pCursor  )  [protected]
 

Changes to the specified cursor. Will only change the cursor if it isn't already this cursor, so it doesn't flicker.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com>
Date:
16/3/94
Parameters:
ID of the cursor you want to flip to [INPUTS]
Returns:
Errors: can fail if the cursor cannot be created - the cursor code will fail.

Definition at line 708 of file freehand.cpp.

00709 {
00710     // only change if this cursor is different from the current cursor
00711     if ((pCursor!=pActiveCursor) && (pCursor!=NULL))
00712     {
00713         // set this cursor as the current cursor and immediately display it
00714         CursorStack::GSetTop(pCursor, CurrentCursorID);
00715 
00716         // remember this is our current cursor
00717         pActiveCursor = pCursor;
00718     }
00719 }

void FreeHandTool::CreateBrush  ) 
 

Called from the infobar, creates a brush definition from the ink objects in the selection and passes it over to the BrushComponent. Also creates a GRenderBrush render region which is used for rendering the brush into when the user begins to draw.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/10/99
Returns:
-

Definition at line 1758 of file freehand.cpp.

01759 {
01760     //TRACEUSER( "Diccon", _T("\nCreating Brush"));
01761 
01762 
01763         SelRange* pSel = GetApplication()->FindSelection();
01764 
01765         if (pSel == NULL)
01766         {
01767             return ;
01768         }
01769 
01770         m_NumInkNodes = 0;
01771 
01772         Node* pNode = pSel->FindFirst();
01773         
01774         if (pNode == NULL)
01775         {
01776             InformWarning(_R(IDS_BRUSHCREATENOSEL));
01777             return;
01778         }
01779 
01780         // first count the number of objects
01781         while (pNode != NULL)
01782         {
01783             if (pNode->IsAnObject())
01784             {
01785                 if (BrushDefinition::ObjectCanCreateBrush((NodeRenderableInk*)pNode))
01786                     m_NumInkNodes++;
01787 
01788                 if (m_NumInkNodes >= MAX_BRUSH_OBJECTS)
01789                 {
01790                     InformWarning(_R(IDS_BRUSHCREATE_TOOMANY));
01791                     break;
01792                 }
01793             }
01794             pNode = pSel->FindNext(pNode);
01795         }
01796 
01797         if (m_NumInkNodes == 0)
01798         {
01799             InformWarning(_R(IDS_BRUSHCREATE_INVALID));
01800             return;
01801         }
01802 
01803         InitialiseBrushInkNodeArray((UINT32)m_NumInkNodes);
01804         
01805         DocRect BBox; // 
01806 
01807         // iterate through again and assign the selection pointers to the new array
01808         UINT32 Counter = 0;
01809         pNode = pSel->FindFirst();
01810 
01811         while (pNode != NULL && Counter < m_NumInkNodes)
01812         {
01813             if (pNode->IsAnObject())
01814             {               
01815                 // check to see that its not too big
01816                 BBox = ((NodeRenderableInk*)pNode)->GetBoundingRect();
01817                 if (BBox.Height() > MAX_BRUSH_SPACING || BBox.Width() > MAX_BRUSH_SPACING)
01818                 {
01819                     InformWarning(_R(IDS_BRUSH_TOOBIG));
01820                     return;
01821                 }
01822                 if (BrushDefinition::ObjectCanCreateBrush((NodeRenderableInk*)pNode))
01823                 {
01824                     m_BrushInkNodeArray[Counter++] = (NodeRenderableInk*)pNode;
01825                 }
01826             }
01827             pNode = pSel->FindNext(pNode);
01828         }
01829     
01830         Spread *pBrushSpread = new Spread;
01831         if (pBrushSpread == NULL)
01832         {
01833             ERROR3("Couldn't create new brush spread");
01834             return;
01835         }
01836 
01837         Layer *pBrushLayer = new Layer(pBrushSpread, FIRSTCHILD, String_256(TEXT("Diccon did this")));
01838         if (pBrushLayer == NULL)
01839         {
01840             ERROR3("Couldn't create new brush (5)");
01841             delete pBrushSpread;
01842             return;
01843         }
01844 
01845         BOOL LineWidth = FALSE;
01846         BOOL Compound = FALSE;
01847         // And attach the clipart tree to our new layer
01848         Node* pLastNode = NULL;
01849 //      AttrBrushType* pAttrBrush = NULL;
01850 
01851         for (UINT32 i = 0; i < m_NumInkNodes; i++)
01852         {
01853             NodeRenderableInk* pInk = m_BrushInkNodeArray[i];
01854             
01855             // do a quick line width check - we need this info later
01856             if (NodeHasLineWidth(pInk))
01857                 LineWidth = TRUE;
01858             if (pInk->IsCompound())
01859                 Compound = TRUE;
01860             pInk->MakeAttributeComplete();
01861 
01862             Node* pInsertNode = NULL;
01863             // OK if we're trying to make a brush out of an object that is already a brush then 
01864             // convert the object to normal shapes first.
01865         /*  pInk->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrBrushType), 
01866                                                     (NodeAttribute**)&pAttrBrush);
01867 
01868             if (pAttrBrush && pAttrBrush->GetBrushHandle() != BrushHandle_NoBrush)
01869             {
01870                 //Turn the brush into a group with lots of nodepaths
01871                 BrushBecomeAGroup BecomeA(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath), NULL);
01872                 pAttrBrush->DoBecomeA(&BecomeA, pInk);
01873         
01874                 // the brush will create a group out of itself and we want to retrieve that
01875                 NodeGroup* pBrushGroup = BecomeA.GetNodeGroup();
01876                 if (pBrushGroup != NULL)
01877                     pInsertNode = pBrushGroup;
01878                 else
01879                 {
01880                     ERROR3("Unable to make group from brush");
01881                     return;
01882                 }
01883 
01884                 pAttrBrush = NULL;
01885             }
01886             else*/
01887             {   
01888                 // the normal case
01889                 pInsertNode = pInk->PublicCopy();
01890                 
01891                 if (pInsertNode == NULL)
01892                 {
01893                     ERROR3("Error copying node");
01894                     return;
01895                 }
01896 
01897                 pInk->CopyChildrenTo(pInsertNode);
01898             
01899             }
01900             pInk->NormaliseAttributes();
01901             if (i==0)
01902                 pInsertNode->AttachNode(pBrushLayer, FIRSTCHILD, FALSE, TRUE);
01903             else
01904                 pInsertNode->AttachNode(pLastNode, NEXT, FALSE, TRUE);
01905 
01906             pLastNode = pInsertNode;
01907         }
01908 
01909         // convert any indexed colours in our subtree
01910         LineDefinition::ConvertIndexedColours(pBrushSpread);
01911 
01912         // now create the brush definition
01913         BrushDefinition* pBrushDef = new BrushDefinition(pBrushSpread);
01914 
01915         if (pBrushDef == NULL)
01916         {
01917             ERROR3("Couldn't allocate brush def");
01918             delete pBrushSpread;
01919             delete pBrushLayer;
01920             return;
01921         }
01922 
01923         // just double check
01924         if (!pBrushDef->IsActivated())
01925         {
01926             ERROR3("Brush failed to initialise correctly, aborting Create Brush");
01927             delete pBrushDef;
01928             delete pBrushSpread;
01929             delete pBrushLayer;
01930             return;
01931         }
01932 
01933         // set the default spacing
01934         DocRect BRect = pBrushDef->GetLargestBoundingBox();
01935         MILLIPOINT Width = BRect.Width();
01936         if (pBrushDef->GetNumBrushObjects() > 1 || LineWidth || Compound)
01937         {
01938             MILLIPOINT Spacing = (MILLIPOINT)(Width * 1.1);
01939             if (Spacing > MAX_BRUSH_SPACING)
01940                 Spacing = MAX_BRUSH_SPACING;
01941 
01942             pBrushDef->SetSpacing(Spacing);
01943         }
01944         else
01945             pBrushDef->SetSpacing(Width / 5);
01946 
01947         // get the brush component of the document
01948         Document* pDoc = Document::GetCurrent();
01949         if (pDoc == NULL)
01950         {
01951             ERROR3("No document");
01952             delete pBrushSpread;
01953             delete pBrushLayer;
01954             return;
01955         }
01956         BrushComponent *pBrushComp = (BrushComponent*)(pDoc->GetDocComponent(CC_RUNTIME_CLASS(BrushComponent)));
01957         if (pBrushComp == NULL)
01958         {
01959             ERROR3("Couldn't get brush component");
01960             delete pBrushSpread;
01961             delete pBrushLayer;
01962             return;
01963         }
01964         BrushHandle NewHandle = pBrushComp->AddNewItem(pBrushDef, TRUE);
01965         
01966         if (NewHandle != BrushHandle_NoBrush)
01967         {
01968             if (pInfoBarOp != NULL)
01969                 pInfoBarOp->AddBrush();
01970 
01971             // we want this brush selected
01972             BrushSelected(NewHandle, FALSE);
01973 
01974             // and we want to clear the document selection
01975             NodeRenderableInk::DeselectAll();
01976         }
01977         else
01978             delete pBrushDef;
01979         
01980 }

BOOL FreeHandTool::DeletePaths  )  [protected]
 

Deletes the paths that hold the track data and the smoothed path and sets thier params to NULL.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/5/95
Returns:
TRUE - always

Definition at line 1684 of file freehand.cpp.

01685 {
01686     // Retro fitting is no longer an option
01687     PreviousPathInvalid();
01688 
01689     // Clear out the old Track Data
01690     if (TrackData!=NULL)
01691     {
01692         delete TrackData;
01693         TrackData = NULL;
01694     }
01695     // Clear out the smoothed version of the path
01696     if (RetroPath!=NULL)
01697     {
01698         delete RetroPath;
01699         RetroPath = NULL;
01700     }
01701     // always return TRUE at present
01702     return TRUE;
01703 }

void FreeHandTool::Describe void *  InfoPtr  )  [virtual]
 

Allows the tool manager to extract information about the tool.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/6/93
Parameters:
InfoPtr - A pointer to a tool info block. It is passed cast to void* as [INPUTS] the version of the tool is unknown at this point. Later versions of the Tool class may have more items in this block, that this tool will not use
InfoPtr - The structure pointed to by InfoPtr will have had all the info [OUTPUTS] that this version of the Tool knows about

Reimplemented from Tool_v1.

Definition at line 368 of file freehand.cpp.

00369 {
00370     // Cast structure into the latest one we understand.
00371     ToolInfo_v1 *Info = (ToolInfo_v1 *) InfoPtr;
00372 
00373     Info->InfoVersion = 1;
00374     Info->InterfaceVersion = GetToolInterfaceVersion();  // You should always have this line.
00375         
00376     // These are all arbitrary at present.
00377     Info->Version = 1;
00378     Info->ID      = GetID();
00379     Info->TextID  = _R(IDS_FREE_HAND_TOOL);
00380     Info->BubbleID = _R(IDBBL_FHND_TOOLBOX);
00381 
00382     Info->Family  = FamilyName;
00383     Info->Name    = ToolName;
00384     Info->Purpose = Purpose;
00385     Info->Author  = Author;
00386 
00387     Info->InfoBarDialog = _R(IDD_FREEHANDTOOL);
00388 }

GRenderBrush * FreeHandTool::GetBigGRenderBrush Spread pSpread  )  [protected]
 

Gets a GRenderBrush the size of the current view, then renders into it the contents of the current view.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Returns:
-

Definition at line 2081 of file freehand.cpp.

02082 {
02083 PORTNOTE("other", "Removed m_pGRenderBrush support");
02084 #ifndef EXCLUDE_FROM_XARALX
02085     m_bBrushReady = FALSE;
02086     Document* pDoc = Document::GetSelected();
02087     if (!pDoc)
02088         return NULL;
02089 
02090     DocView * pDocView = DocView::GetSelected();
02091     
02092     // get the docview rect and convert to spread coords 
02093     DocRect ViewRect = pDocView->GetDocViewRect(pSpread);
02094     pSpread->DocCoordToSpreadCoord(&ViewRect);
02095     
02096     // find out about our device 
02097     //View* pView = View::GetSelectedView();
02098     CCamView* pCCamView = pDocView->GetConnectionToOilView(); 
02099     CDC* pDevContext = ((ScreenCamView*)pCCamView)->GetRenderDC();
02100     HDC DeviceHdc = pDevContext->GetSafeHdc();
02101     INT32 DeviceBPP = GetDeviceCaps(DeviceHdc, BITSPIXEL);
02102     
02103     // a couple more variables we need to get the GRenderBrush
02104     Matrix  RenderMat = pDocView->ConstructRenderingMatrix(pSpread);    
02105     FIXED16 Scale = 1;
02106 //  INT32 i = 0;
02107     GRenderBrush* pGRender = NULL;  
02108     
02109     INT32 DeviceRes = GetDeviceCaps( DeviceHdc, LOGPIXELSX );
02110     // create a new GRenderBrush at 32BPP and 96 dpi
02111     pGRender = new GRenderBrush(ViewRect, RenderMat, Scale, 32, DeviceRes); 
02112 
02113     // Check to see if the Render Region is valid!
02114     if (pGRender == NULL)
02115     {
02116         ERROR3("Failed to allocate DIB");
02117         return NULL;
02118     }
02119 
02120     BOOL ok = pGRender->AttachDevice(pDocView, pDevContext, pSpread);
02121     if (!ok)
02122     {   
02123         delete pGRender;
02124         pGRender = NULL;    
02125         return NULL;
02126     }
02127     
02128     if (DeviceBPP < 24)
02129         pGRender->SetDeepDIB(FALSE);
02130     else
02131         pGRender->SetDeepDIB(TRUE);
02132 
02133     
02134     pGRender->InitDevice();
02135     pGRender->m_DoCompression = TRUE;
02136     
02137     pGRender->InitAttributes();
02138     pGRender->RRQuality.SetQuality(QUALITY_MAX);
02139     pGRender->SetQualityLevel();
02140     pGRender->SetLineAttributes();
02141     pGRender->SetFillAttributes();
02142 
02143 
02144     // lleeeets geeet ready to render!  
02145     if (!pGRender->StartRender())
02146     {
02147         ERROR3("Unable to setup bitmap");
02148         delete pGRender;
02149         return NULL;
02150     }
02151     
02152     // if we're less than 24 bit then we need to allocate smaller brush bitmaps as well
02153     if (DeviceBPP < 24)
02154     {
02155         if (!InitialiseBrushBitmaps(pGRender))
02156         {
02157             InformWarning(_R(IDS_BRUSHBITMAP_INVALID));
02158             delete pGRender;
02159             return NULL;
02160         }
02161     }
02162 
02163     // or blit, in this case, as it is quicker than rendering the view
02164     if (!pGRender->CaptureView(pSpread))
02165     {
02166         ERROR3("Unable to capture view");
02167         delete pGRender;
02168         return NULL;
02169     }
02170 
02171 
02172     m_bBrushReady = TRUE;
02173     return pGRender;
02174 #else
02175     return NULL;
02176 #endif
02177 }

BrushHandle FreeHandTool::GetBrushHandle void   )  [inline]
 

Definition at line 219 of file freehand.h.

00219 { return m_BrushHandle;}

MILLIPOINT FreeHandTool::GetBrushSpacing  ) 
 

for finding out the freehand tools current brush spacing

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/99
Returns:
The current brush spacing

Definition at line 2191 of file freehand.cpp.

02192 {
02193     return m_BrushSpacing;
02194 }

UINT32 FreeHandTool::GetID  )  [virtual]
 

Reimplemented from Tool_v1.

Definition at line 391 of file freehand.cpp.

00392 {
00393     return TOOLID_FREEHAND;
00394 }

FreeHandInfoBarOp* FreeHandTool::GetInfoBar  )  [inline]
 

Definition at line 199 of file freehand.h.

00199 { return pInfoBarOp;}

DocRect FreeHandTool::GetLargestInkBoundingRect  )  [protected]
 

as above, note that the m_brushinknodes pointer must be initialised

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
the bounding rect of the largest brush ink object, or an empty rect

Definition at line 2263 of file freehand.cpp.

02264 {
02265     DocRect LargestBRect;  //create an empty rect
02266 
02267     
02268 
02269     INT32 BiggestArea = 0;
02270     for (UINT32 i = 0; i < m_NumInkNodes; i++)
02271     {
02272         DocRect TempRect = m_BrushInkNodeArray[i]->GetBoundingRect();
02273         INT32 TempArea = TempRect.Height() * TempRect.Width();
02274         if (TempArea > BiggestArea)
02275         {
02276             LargestBRect = TempRect;
02277             BiggestArea  = TempArea;
02278         }
02279     }
02280     return LargestBRect;
02281 }

BOOL FreeHandTool::GetNewPaths  )  [protected]
 

Gets rid of the old path data and creates new paths. One of the useful side effects of doing this is that it helps to keep the path data near the top of the heap, make the freehand tool seem more responsive.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/5/95
Returns:
TRUE if everything worked like a dream, FALSE if it screwed up big time

Definition at line 1628 of file freehand.cpp.

01629 {
01630     // Delete the paths that we have
01631     DeletePaths();
01632 
01633     // Create some new paths
01634     if ((RetroPath==NULL) && (TrackData==NULL))
01635     {
01636         // Create a new path for the track data
01637         TrackData = new Path();
01638         if (TrackData==NULL)
01639             return FALSE;
01640     
01641         // Create a new path for the smoothed data
01642         RetroPath = new Path();
01643         if (RetroPath==NULL)
01644         {
01645             delete TrackData;
01646             TrackData = NULL;
01647             return FALSE;
01648         }
01649     
01650         // init the track buffer and fail if it does not work
01651         if (!TrackData->Initialise(48,48))
01652         {
01653             DeletePaths();
01654             return FALSE;
01655         }
01656     
01657         // Same with the retro fitting path
01658         if (!RetroPath->Initialise(12, 12))
01659         {
01660             DeletePaths();
01661             return FALSE;
01662         }
01663 
01664     }
01665 
01666     // All Worked
01667     return TRUE;
01668 }

BrushDefinition * FreeHandTool::GetSelectedBrush  )  [protected]
 

In order to determine which brush to draw with when performing a real time draw brush operation.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
pointer to the brush definition of the current default brush attribute this can be NULL.

Definition at line 2334 of file freehand.cpp.

02335 {
02336     Document* pDoc = Document::GetCurrent();
02337     ERROR2IF(pDoc == NULL, NULL, "No document");
02338     
02339     BrushComponent* pBrushComp = (BrushComponent*)pDoc->GetDocComponent(CC_RUNTIME_CLASS(BrushComponent));
02340     if (pBrushComp == NULL)
02341     {
02342         ERROR3("No brush component");
02343         return NULL;
02344     }
02345 
02346     return pBrushComp->FindBrushDefinition(m_BrushHandle);
02347     
02348 }

INT32 FreeHandTool::GetSmoothness  ) 
 

for finding out the freehand tools current smoothing accuracy value

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/5/94
Returns:
The freehand accuracy setting

Definition at line 1242 of file freehand.cpp.

01243 {
01244     return Smoothness;
01245 }

BOOL FreeHandTool::GetStatusLineText String_256 ptext,
Spread ,
DocCoord  ,
ClickModifiers 
[virtual]
 

Sets the status line text on request from the app.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/1/95
Parameters:
Others not used [INPUTS]
pText - pointer to a string that will hold the text [OUTPUTS]
Returns:
TRUE if it set the text, FALSE if not

Reimplemented from Tool_v1.

Definition at line 1043 of file freehand.cpp.

01044 {
01045     *ptext = StatusMsg;
01046     return TRUE;
01047 }

BOOL FreeHandTool::Init void   )  [virtual]
 

Used to check if the Tool was properly constructed.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/6/93
Returns:
FALSE if it does not want to be created, TRUE otherwise
See also:
FreeHandTool::FreeHandTool

Reimplemented from Tool_v1.

Definition at line 289 of file freehand.cpp.

00290 {
00291     // This should be set to NULL by default. It will be set properly below, if
00292     // everthing is working as it should
00293     pInfoBarOp = NULL;
00294 
00295     if (!OpRetroFit::Init())
00296         return FALSE;
00297 
00298     // Now we have to declare all our operations and if that works, try to find
00299     // the freehand tools info bar and create it
00300     if (OpFreeHand::Declare())
00301     {
00302         pInfoBarOp = new FreeHandInfoBarOp();
00303         if (pInfoBarOp)
00304             pInfoBarOp->pTool = this;
00305 PORTNOTE("dialog", "Removed Bar reading")
00306 #if 0
00307         // Resource File and Object that creates FreeHandInfoBarOp objects
00308         CCResTextFile           ResFile;
00309         FreeHandInfoBarOpCreate BarCreate;
00310 
00311         if (ResFile.open(_R(IDM_FREEHAND_BAR), _R(IDT_INFO_BAR_RES)))
00312         {
00313             // Found the file and opened it
00314             if (DialogBarOp::ReadBarsFromFile(ResFile,BarCreate))
00315             {
00316                 // read it in ok, so close it
00317                 ResFile.close();
00318 
00319                 // Info bar now exists.  Now get a pointer to it
00320                 String_32 str = String_32(_R(IDS_FREEHAND_INFOBARNAME));
00321                 DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(str);
00322 
00323                 // Should have a dialog bar op by now
00324                 if (pDialogBarOp != NULL)
00325                 {
00326                     // Make sure it is what we were expecting and set it
00327                     if (pDialogBarOp->IsKindOf(CC_RUNTIME_CLASS(FreeHandInfoBarOp)))
00328                     {
00329                         pInfoBarOp = (FreeHandInfoBarOp*) pDialogBarOp;
00330                         pInfoBarOp->pTool = this;
00331                     }
00332                 }
00333             }
00334         }
00335 #endif
00336     }
00337 
00338     GetApplication()->DeclareSection(_T("Mouse"), 10);
00339     GetApplication()->DeclarePref(_T("Mouse"), _T("FreehandPtrCrosshair"), &FreehandPtrCrosshair, FALSE, TRUE);
00340 
00341     // See if it all worked and return depending on the result
00342     ENSURE(pInfoBarOp!=NULL, "Failed to create FreeHand Info Bar" );
00343     if (pInfoBarOp==NULL)
00344         return FALSE;
00345     else
00346         return TRUE;
00347 }

BOOL FreeHandTool::InitialiseBlendRef NodeRenderableInk pInk  )  [protected]
 

To initialise a BlendRef object.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
pInk - inknode to generate the blendref from [INPUTS]
- [OUTPUTS]
Returns:
TRUE if successful, false otherwise

Definition at line 2229 of file freehand.cpp.

02230 {
02231     ERROR2IF(pInk == NULL,FALSE,"InkNode is NULL");
02232     
02233     if (m_pBlendRef != NULL)
02234     {   
02235         delete m_pBlendRef;
02236         m_pBlendRef = NULL;
02237     }
02238     m_pBlendRef = new BlendRef;
02239     
02240     BOOL ok = (m_pBlendRef != NULL);
02241     // initialise the blender
02242     Progress* pProgress = NULL;
02243     if (ok)  ok = m_pBlendRef->Initialise(pInk, -1, NULL, pProgress, FALSE, NULL);  
02244 
02245     return ok;
02246 }

BOOL FreeHandTool::InitialiseBrushBitmaps GRenderBrush pGRender  )  [protected]
 

To work out how large our brush bitmaps must be and allocate them to the render region supplied.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
pGRender - the render region for which we want brush bitmaps for [INPUTS]
- [OUTPUTS]
Returns:
TRUE if successful, FALSE if something went wrong

Definition at line 2523 of file freehand.cpp.

02524 {
02525     ERROR2IF(pGRender == NULL, FALSE, "GRenderBrush is NULL in FreeHandTool::InitialiseBrushBitmaps");
02526 
02527     // first work out the largest possible size of our brush        
02528     BrushDefinition* pBrushDef = GetSelectedBrush();
02529     if (pBrushDef == NULL)
02530     {
02531         ERROR3("No brush definition");
02532         return FALSE;
02533     }
02534     // find out how big the biggest shape is
02535     DocRect LargestRect = pBrushDef->GetLargestPossibleRect(TRUE);
02536     if (LargestRect.IsEmpty())
02537     {
02538         ERROR3("Empty bounding rect");  
02539         return FALSE;
02540     }
02541 
02542     // Oh dear it still isn't big enough, guess I'll just have to resort to 
02543     // this nasty hack (please look away)
02544 /*  INT32 Height = LargestRect.Height();
02545     INT32 Width = LargestRect.Width();
02546 
02547     LargestRect.Inflate((INT32)(Height * 0.1), (INT32)(Width *0.1));
02548 */
02549 PORTNOTE("other", "Removed m_pGRenderBrush support");
02550 #ifndef EXCLUDE_FROM_XARALX
02551     if (!pGRender->InitialiseBrushBitmaps(LargestRect))
02552     {
02553         return FALSE;
02554     }
02555 #endif
02556     return TRUE;
02557 }

void FreeHandTool::InitialiseBrushInkNodeArray UINT32  NumObjects  )  [protected]
 

Clears out the m_BrushRefPtrArray if it is not empty, and sets the size.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/10/99
Parameters:
Number of objects to size the array at [INPUTS]
Returns:
-

Definition at line 2049 of file freehand.cpp.

02050 {
02051     UINT32 i = 0;
02052     // we don't wish to delete any pointers as they point to objects
02053     // that are actually in the document.
02054     m_BrushInkNodeArray.clear();
02055 
02056     m_BrushInkNodeArray.resize(NumObjects);
02057 
02058     // fill the array with NULL objects so that we can check later
02059     // to see if our allocations have worked
02060     i = 0;
02061     while (i < m_BrushInkNodeArray.size())
02062     {
02063         m_BrushInkNodeArray[i++] = NULL;
02064     }
02065 
02066 }

void FreeHandTool::InitialiseJoinInfoForBrush AttrBrushType pAttrBrush,
NodePath pPath,
DocCoord  JoinPoint
 

Initialises the JoinInfo struct so that we correctly join the existing brush.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
23/5/2000
Parameters:
pAttrBrush - the brush that we are going to join to [INPUTS] NodepPath - the path that we are going to join to JoinPoint - the point where we will join
Returns:
-

Definition at line 2813 of file freehand.cpp.

02814 {
02815     if (pAttrBrush == NULL || pPath == NULL)
02816     {
02817         ERROR3("NULL entry pointers in FreeHandTool::InitialiseJoinInfoForBrush");
02818         return;
02819     }
02820 
02821     // initialise joininfo with the data
02822     JoinInfo.m_BrushHandle = pAttrBrush->GetBrushHandle();
02823 
02824     // Now we need to find out the spacing of the first brush object.
02825 
02826     //find out how far along the path we are
02827     MILLIPOINT Distance = 0;
02828     if (!pPath->InkPath.GetDistanceToPoint(JoinPoint, &Distance))
02829     {
02830         ERROR3("Unable to find distance to point in FreeHandTool::InitialiseJoinInfoForBrush");
02831         return;
02832     }
02833 
02834     // didn't bother to write an access fn. for this, ask the path processor to work
02835     // out the spacing.
02836     BrushAttrValue* pVal = (BrushAttrValue*)pAttrBrush->GetAttributeValue();
02837     if (pVal != NULL)
02838     {
02839         PathProcessorBrush* pPPB = pVal->GetPathProcessor();
02840         if (pPPB != NULL)
02841         {
02842             // we want to get the scaling and spacing at this distance along the path
02843             double Scaling = 1.0;
02844             MILLIPOINT Spacing = pPPB->GetSpacing();
02845             pPPB->GetSpacingAndScalingAtDistance(Distance, &Spacing, &Scaling);
02846             JoinInfo.FirstBrushSpacing = (MILLIPOINT)((double)Spacing * Scaling);
02847             JoinInfo.BrushDistance = Distance;
02848 
02849             pPPB->CopyBrushData(&JoinInfo.m_BrushData);
02850 
02851             // get the stroke colour
02852             JoinInfo.UseLocalColour = pPPB->GetUseLocalFillColour();
02853             JoinInfo.UseNamedColour = pPPB->GetUseNamedColours();
02854             if ( JoinInfo.UseLocalColour == TRUE || JoinInfo.UseNamedColour == FALSE)
02855             {
02856                 AttrStrokeColour *pStrokeCol = NULL;
02857                 pPath->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeColour), (NodeAttribute**)&pStrokeCol);
02858                 if (pStrokeCol)
02859                 {
02860                     JoinInfo.StrokeColour = pStrokeCol->Value.Colour;
02861                 }
02862             }
02863 
02864         }
02865 
02866         JoinInfo.pAttrBrush = pAttrBrush;
02867         
02868     }
02869 
02870 
02871 
02872 }

BOOL FreeHandTool::IsCursorNearEndPoint NodePath pNodePath,
const DocRect BlobRect
[protected]
 

Scans the path in the NodePath to see any of its endpoints lie inside the DocRect supplied. The DocRect should be the snapping rectangle around the cursor position. If this function finds that one of the endpoints is in the rect, it will remember the path, and the position of the endpoint so that when a new freehand line is started, this data can be passed in. This function also changes the cursor to the Join cursor and sets the status bar text if it finds a match.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/10/94
Parameters:
pNodePath - The Node Path that we want to test [INPUTS] BlobRect - The rectangle that the endpoints have to be in to qualify
Returns:
TRUE if it found an endpoint in the rect, FALSE if it did not

Definition at line 1069 of file freehand.cpp.

01070 {
01071     // Find the path associated with this NodePath
01072     Path* pPath = &(pNodePath->InkPath);
01073 
01074     // Test to see if the cursor was anywhere near any of the paths endpoints
01075     INT32 CloseSlot;
01076     if (pPath->IsNearOpenEnd(BlobRect, &CloseSlot))
01077     {
01078         // Yep, so set the eventual starting position of any new freehand paths to the
01079         // endpoint in question
01080         pPath->SetPathPosition(CloseSlot);
01081         StartPos = pPath->GetCoord();
01082         
01083         // Also remember the path that we can Join with
01084         JoinInfo.pJoinPath = pNodePath;
01085         JoinInfo.IsNearEndPoint = TRUE;
01086 
01087         // And set the cursor
01088         ChangeCursor(pJoinCursor);
01089 
01090         // And the status bar text
01091         StatusMsg.Load(_R(IDS_FREEHANDSTARTJOIN), Tool::GetModuleID(GetID()));
01092         GetApplication()->UpdateStatusBarText(&StatusMsg);
01093 
01094         // now test to see if our nodepath is brushed
01095         NodeAttribute* pAttr = NULL;
01096         pNodePath->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrBrushType), &pAttr);
01097         if (pAttr != NULL)
01098         {
01099             InitialiseJoinInfoForBrush((AttrBrushType*)pAttr, pNodePath, BlobRect.Centre());
01100         }
01101         
01102         // and tell our caller that we found a match
01103         return TRUE;
01104     }
01105     
01106     // No match was found
01107     return FALSE;
01108 }

BOOL FreeHandTool::IsCursorNearPath NodePath pNodePath,
INT32  Range,
const DocCoord PointerPos
[protected]
 

This function tests to see if any point along the paths length is close to the cursor. If it finds that it is, then the cursor and the status bar help are changed and the information about the path is remembered in case a drag starts soon.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/10/94
Parameters:
pNodePath - The Path that we want to see if we are near [INPUTS] Range - The squared distance away from the path that we count as being close to the line PointerPos - The position of the mouse cursor
Returns:
TRUE if we find that the path goes through the rectangle, FALSE if not

Definition at line 1131 of file freehand.cpp.

01132 {
01133     // Find the path associated with this NodePath
01134     Path* pPath = &(pNodePath->InkPath);
01135 
01136     // Test to see if the cursor was anywhere near any of the paths endpoints
01137     INT32 CloseSlot = 0;
01138     double mu;
01139     if (pPath->IsPointCloseTo(PointerPos, Range, &CloseSlot, &mu))
01140     {
01141         // Yep, so set the eventual starting position of any new freehand paths to the
01142         // endpoint in question
01143         StartPos = pPath->ClosestPointTo(mu, CloseSlot);
01144 
01145         // Also remember the path that we can Join with
01146         JoinInfo.pJoinPath = pNodePath;
01147         JoinInfo.IsNearEndPoint = FALSE;
01148         JoinInfo.CloseSlot = CloseSlot;
01149         JoinInfo.Into = mu;
01150 
01151         // And set the cursor
01152         ChangeCursor(pModifyCursor);
01153 
01154         // And the status bar text
01155         StatusMsg.Load(_R(IDS_FREEHANDMODSTART), Tool::GetModuleID(GetID()));
01156         GetApplication()->UpdateStatusBarText(&StatusMsg);
01157 
01158         // now test to see if our nodepath is brushed
01159         NodeAttribute* pAttr = NULL;
01160         pNodePath->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrBrushType), &pAttr);
01161         if (pAttr != NULL)
01162         {
01163             AttrBrushType* pAttrBrush = (AttrBrushType*)pAttr;
01164             InitialiseJoinInfoForBrush(pAttrBrush, pNodePath, PointerPos);
01165         }
01166 
01167         // tell the caller that some point along the path is close to the pointer
01168         return TRUE;
01169     }
01170 
01171     // This path is not close to the cursor
01172     return FALSE;   
01173 }

BOOL FreeHandTool::IsRetroPathStillValid  ) 
 

Finds out if we are able to do retro fitting and is used by the info bar as well as the tool when it becomes the selected tool and when a drag of the slider starts.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/8/94
Returns:
TRUE if we can Retro fit the currently selected object

Definition at line 1336 of file freehand.cpp.

01337 {
01338     // Need to find out if we can retro fit the path or not
01339     BOOL IsStillValid = FALSE;
01340     SelRange* Selected = GetApplication()->FindSelection();
01341     DocView* pDocView = DocView::GetSelected();
01342 
01343     // If there is only one thing selected
01344     if ((pDocView!=NULL) && (Selected->Count()==1))
01345     {
01346         // Get the selected node
01347         Node* pNode = Selected->FindFirst();
01348 
01349         // see if it is our path
01350         if ((pNode==PreviousPath) && (pNode->IS_KIND_OF(NodePath)))
01351         {
01352             // Build the CRC for the path now and if it matches, flag that we can do retro fitting
01353             INT32 CurrentCRC = BuildPathCRC(PreviousPath);
01354             if (CurrentCRC==PathCRC)
01355                 IsStillValid = TRUE;
01356         }
01357     }
01358 
01359     // and return the state of IsStillValid
01360     return IsStillValid;
01361 }

void FreeHandTool::LaunchBrushDefinitionDialog BrushHandle  Handle  )  [protected]
 

launches the brush edit dialog for the brush handle supplied. A good idea to call this just after creating a brush so the user can edit it before using it.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/10/99
Parameters:
Handle of the brush definition to edit [INPUTS]
Returns:
-

Definition at line 1997 of file freehand.cpp.

01998 {
01999     // first get the brush definition from the component
02000     // get the brush component from the document
02001     Document* pDoc = Document::GetCurrent();
02002     if (!pDoc) return;
02003     BrushComponent* pBrushComp = (BrushComponent*)pDoc->GetDocComponent(CC_RUNTIME_CLASS(BrushComponent));
02004     if (!pBrushComp) return;
02005 
02006     BrushDefinition* pBrushDef = pBrushComp->FindBrushDefinition(Handle);
02007     if (!pBrushDef) return;
02008 
02009     // now launch the edit dialog
02010     BrushData* pData = pBrushDef->GetBrushData();
02011     
02012     if (pData != NULL)
02013     {
02014 PORTNOTE("other", "Removed CBrushGadget support");
02015 #ifndef EXCLUDE_FROM_XARALX
02016         // get the line gallery, as we want to edit the definition version
02017         LineGallery* pLineGallery = LineGallery::GetInstance();
02018         if (pLineGallery != NULL)
02019         {
02020             // get a pointer to the gadget
02021             CBrushGadget* pGadget = pLineGallery->GetBrushGadget();
02022             if (pGadget != NULL)
02023             {
02024                 // brush definitions don't know their own handle so we need to tell the data
02025                 pData->m_BrushHandle = Handle;
02026             
02027                 pGadget->EnableEditingBrushDefinition ();
02028                 pGadget->HandleBrushButtonClick(pData->m_BrushHandle);
02029             }
02030             // we need to delete the data
02031             delete pData;
02032         }
02033 #endif
02034     }
02035 }

BOOL FreeHandTool::LoadCursors  )  [protected]
 

Loads all the cursors used by the freehand tool and pushs the normal one onto the top of the cursor stack.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/10/94
Returns:
TRUE if it worked, FALSE if it did not

Errors: ERROR1 (_R(IDE_FHAND_BADCURSORS)) if it fails to load the cursors

Definition at line 607 of file freehand.cpp.

00608 {
00609     // This tool has just been selected, so it is not displaying a cursor
00610     pActiveCursor = NULL;
00611 
00612     // Try to create all our cursors - The normal cursor
00613     if (FreehandPtrCrosshair)
00614     {
00615         pNormalCursor = new Cursor(this, _R(IDC_FREEHANDTOOLCURSOR_X));
00616         pJoinCursor   = new Cursor(this, _R(IDC_FREEHANDJOINCURSOR_X));
00617         pModifyCursor = new Cursor(this, _R(IDC_FREEHANDMODIFY_X));
00618     }
00619     else
00620     {
00621         pNormalCursor = new Cursor(this, _R(IDC_FREEHANDTOOLCURSOR));
00622         pJoinCursor   = new Cursor(this, _R(IDC_FREEHANDJOINCURSOR));
00623         pModifyCursor = new Cursor(this, _R(IDC_FREEHANDMODIFY));
00624     }
00625 
00626     // did we get all the cursors ok
00627     if ((pNormalCursor==NULL) || (!pNormalCursor->IsValid()) || 
00628         (pJoinCursor==NULL)   || (!pJoinCursor->IsValid()) ||
00629         (pModifyCursor==NULL) || (!pModifyCursor->IsValid()))
00630     {
00631         // No, at least one of them was NULL, so delete them all
00632         // Deleting the null cursor will be ok
00633         delete pNormalCursor;
00634         delete pJoinCursor;
00635         delete pModifyCursor;
00636 
00637         // and ensure that the pointers are set to NULL
00638         pNormalCursor = NULL;
00639         pJoinCursor = NULL;
00640         pModifyCursor = NULL;
00641 
00642         // and set an error and return
00643         ERROR1(FALSE, _R(IDE_FHAND_BADCURSORS));
00644     }
00645 
00646     // All the cursors loaded ok if we got to here
00647     // So push the normal cursor onto the stack and mark it as active
00648     CurrentCursorID = CursorStack::GPush(pNormalCursor, FALSE);
00649     pActiveCursor = pNormalCursor;
00650 
00651     // return that it worked
00652     return TRUE;
00653 }

BOOL FreeHandTool::NodeHasLineWidth NodeRenderableInk pNode  )  [protected]
 

Definition at line 2297 of file freehand.cpp.

02298 {
02299     ERROR2IF(pNode == NULL, FALSE, "pNode is NULL in FreeHandTool::NodeHasLineWidth");
02300     NodeAttribute* pAttr = NULL;
02301     pNode->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrStrokeColour), &pAttr);
02302     
02303     if (pAttr == NULL)
02304         return FALSE;
02305 
02306     // ok so we've got an attribute, lets see if it has the NoColour flag set
02307     StrokeColourAttribute* pVal = (StrokeColourAttribute*)pAttr->GetAttributeValue();
02308     if (pVal != NULL)
02309     {
02310         DocColour Col = pVal->Colour;
02311         if (Col.IsTransparent())
02312             return FALSE;
02313     }
02314 
02315     return TRUE;
02316 }

void FreeHandTool::OnClick DocCoord  PointerPos,
ClickType  Click,
ClickModifiers  ClickMods,
Spread pSpread
[virtual]
 

To handle a Mouse Click event for the FreeHand Tool. It starts up a FreeHand Operation.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/6/93
Parameters:
PointerPos - The Coords (in spread coords) of the point where the mouse [INPUTS] button was clicked Click - Describes the type of click that was detected. ClickMods - Indicates which buttons caused the click and which modifers were pressed at the same time pSpread - the spread in which the click happened
Returns:
TRUE if it handled the Click, FALSE otherwise
See also:
Tool::MouseClick; ClickType; ClickModifiers

Reimplemented from DragTool.

Definition at line 746 of file freehand.cpp.

00748 {
00749     if (ClickMods.Menu) return;                         // Don't do anything if the user clicked the Menu button
00750 
00751     // See if there is already a drag going on
00752     if (Operation::GetCurrentDragOp()!=NULL)
00753         return;
00754 
00755     // If we get a click, treat it like a mouse move, allowing the tool to set up
00756     // any info that is passed to the operation in the drag
00757     // NEW 17/4/2000 Now we also want to click-select in the Freehand tool
00758     if (Click==CLICKTYPE_SINGLE)
00759     {
00760         OnMouseMove(PointerPos, pSpread, ClickMods);
00761         DragTool::OnClick (PointerPos, Click, ClickMods, pSpread);
00762     }
00763     if (Click == CLICKTYPE_UP)
00764     {
00765         // so long as we are not interfering with any drawing operations we will
00766         // try and change the selection
00767         //if (JoinInfo.pJoinPath == NULL)
00768         {
00769             DragTool::OnClick (PointerPos, Click, ClickMods, pSpread);
00770 
00771             BROADCAST_TO_ALL(CommonAttrsChangedMsg);
00772         }
00773     }
00774     // Make sure this click is one that we want
00775     if (Click==CLICKTYPE_DRAG)
00776     {
00777         // Just what we wanted - Someone is dragging the mouse about
00778         // We need to make an operation to perform the drag with
00779     
00780         // quick safety check - if the current line width is less than 501MP then we want
00781         // to launch a freehand op even if we have a brush selected
00782         MILLIPOINT LineWidth = OpDrawBrush::GetCurrentLineWidthIfNotDefault();
00783         
00784         // Added a condition here - if our join info brush handle indicates no brush
00785         // then we are adding to a normal line, hence don't use the brush
00786         if (m_BrushHandle == BrushHandle_NoBrush || (LineWidth != -1 && LineWidth < 501)
00787             || JoinInfo.m_BrushHandle == BrushHandle_NoBrush)
00788         {
00789             OpFreeHand* pOpFreeHand = new OpFreeHand;
00790             if ((pOpFreeHand!=NULL) && (GetNewPaths()))
00791             {   
00792                 // Start the drag operation and pass in the Anchor Point to the push operation
00793                 pOpFreeHand->DoDrag(StartPos, StartSpread, Smoothness, &JoinInfo, TrackData);
00794             }
00795             else
00796             {
00797                 // Failed to get the memory to do the job
00798                 ToolInformError(_R(IDS_OUT_OF_MEMORY), _R(IDS_OK));
00799             }
00800         }
00801         else
00802         {
00803         // launch a brush op
00804             Document* pDoc = Document::GetCurrent();
00805             if (pDoc == NULL)
00806             {
00807                 ERROR3("No document in FreeHandTool::OnClick");
00808                 return;
00809             }
00810         
00811             String_256 CurrentDoc = pDoc->GetDocName();
00812             if (CurrentDoc != m_LastBrushDocument)
00813             {
00814                 m_LastBrushDocument = CurrentDoc;
00815                 m_UpdateBrushState = UPDATE_NOW;
00816                 BrushSelected(m_BrushHandle, FALSE);
00817             }
00818         
00819 PORTNOTE("other", "Removed m_pGRenderBrush support");
00820 #ifndef EXCLUDE_FROM_XARALX
00821             // This is a bit of a bodge to try to stop the internal error in 8bpp
00822             if (m_pGRenderBrush && m_pGRenderBrush->GetRenderDC()->GetSafeHdc() == NULL)
00823             {
00824                 delete m_pGRenderBrush;
00825                 m_pGRenderBrush = NULL;
00826             }
00827 #endif
00828 
00829             if (m_pGRenderBrush == NULL || CurrentDoc != m_LastBrushDocument)
00830             {
00831                 // or don't if we are not ready
00832                 String_32 ProgString = _T("Preparing brush, please wait..");
00833                 Progress Hourglass(&ProgString, -1, FALSE);
00834                 m_pGRenderBrush = GetBigGRenderBrush(pSpread);
00835                 
00836 PORTNOTE("other", "Removed m_pGRenderBrush support");
00837 #ifndef EXCLUDE_FROM_XARALX
00838                 if (m_pGRenderBrush == NULL)
00839                 {
00840                     ToolInformError(_R(IDS_OUT_OF_MEMORY), _R(IDS_OK));
00841                     return;
00842                 }
00843 #endif
00844                 m_LastBrushDocument = CurrentDoc;
00845                 return;
00846             
00847             }
00848             // ensures that if we are over another brush we get the correct info
00849             OnMouseMove(PointerPos, pSpread, ClickMods);
00850 
00851             OpDrawBrush* pOpDrawBrush = new OpDrawBrush(this);
00852             //TRACEUSER( "Diccon", _T("About to start new stroke\n"));
00853             if ((pOpDrawBrush != NULL)&& (GetNewPaths()))
00854             {
00855                 // turn off background rendering whilst we are in progress
00856                 // note that we must turn off the selected docview or else we will 
00857                 // screw up background rendering when we have multiple views (as I just found out)
00858                 DocView* pDocView = DocView::GetCurrent(); //DocView::GetSelected(); //Current();
00859                 if (pDocView != NULL)
00860                     pDocView->SetPreventRenderView(TRUE);
00861 
00862                 // turn off the colour picker, as it munches CPU
00863                 SetColourEditorProcessing(FALSE);
00864 PORTNOTE("other", "Removed m_pGRenderBrush support");
00865 #ifndef EXCLUDE_FROM_XARALX
00866                 m_pGRenderBrush->SetupMainBitmap();
00867 #endif
00868                 // find out if our brush definition wants time stamping, and tell the op
00869                 BrushDefinition* pBrushDef = GetSelectedBrush();
00870                 if (pBrushDef != NULL)
00871                     pOpDrawBrush->SetTimeStamp(pBrushDef->GetTimeStampingPeriod());
00872 
00873                 pOpDrawBrush->DoDrag(StartPos, StartSpread, Smoothness, m_BrushHandle, &JoinInfo, TrackData,
00874                                     m_pGRenderBrush, ClickMods);
00875 
00876                 m_UpdateBrushState = UPDATE_NEVER; // we REALLY don't want to be updating whilst in the middle of drawing
00877             }
00878             else
00879             {
00880                 // Failed to get the memory to do the job
00881                 ToolInformError(_R(IDS_OUT_OF_MEMORY), _R(IDS_OK));
00882 PORTNOTE("other", "Removed m_pGRenderBrush support");
00883 #ifndef EXCLUDE_FROM_XARALX
00884                 delete m_pGRenderBrush;
00885                 m_pGRenderBrush = NULL;
00886 #endif
00887             }
00888             
00889         }
00890     }
00891 
00892 
00893 }

BOOL FreeHandTool::OnIdle  )  [virtual]
 

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
FALSE always as we need more idles

Reimplemented from Tool_v1.

Definition at line 2726 of file freehand.cpp.

02727 {
02728     // just check that we have a document
02729     if (Document::GetCurrent() == NULL)
02730     {
02731         m_UpdateBrushState = UPDATE_NEVER;
02732         return FALSE;
02733     }
02734 
02735     if (m_UpdateBrushState == UPDATE_ONIDLE)
02736     {
02737 #ifdef NEWFASTBRUSHES
02738         static Application* pApp = GetApplication ();
02739 
02740         BOOL doCaptureNow = TRUE;
02741 
02742         if (pApp)
02743         {
02744             if (!pApp->IsRenderingComplete ())
02745             {
02746                 // TEST
02747                 // there are still regions that are rendering,
02748                 // we probably should NOT grab the screen yet!
02749                 doCaptureNow = FALSE;
02750                 TRACEUSER( "ChrisS", _T("Brush System:  Not finished rendering - just ignored screen capture request ...."));
02751             }
02752         }
02753 
02754         if (doCaptureNow)
02755         {
02756 #endif
02757             // bodge so that we do not end up with the freehand cursor
02758 PORTNOTE("other", "Removed cursor bodge");
02759 #ifndef EXCLUDE_FROM_XARALX
02760             HCURSOR Cursor = GetCursor();
02761 #endif
02762             m_UpdateBrushState = UPDATE_NOW;
02763             BrushSelected(m_BrushHandle, FALSE);
02764 PORTNOTE("other", "Removed cursor bodge");
02765 #ifndef EXCLUDE_FROM_XARALX
02766             SetCursor(Cursor);
02767 #endif
02768 #ifdef NEWFASTBRUSHES
02769         }
02770 #endif
02771 
02772     }
02773     return FALSE;
02774 }

void FreeHandTool::OnMouseMove DocCoord  Coord,
Spread pSpread,
ClickModifiers  mods
[virtual]
 

This routine is called whenever the mouse moves while we're in the freehand tool. it sees what is under the pointer, and flips the cursor if clicking will have a different effect. The rules are:.

Author:
Jim_Lynn (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/3/94
Parameters:
coordinate of mouse move, pointer to spread containing coord; click modifiers [INPUTS]
Over space, no selection - freehand cursor Over selected endpoint - add freehand to line

Reimplemented from Tool_v1.

Definition at line 914 of file freehand.cpp.

00915 {
00916     // Assume that we are not going to find anything of interest, so set the params to good values
00917     JoinInfo.pJoinPath = NULL;
00918     StartPos = Coord;
00919     StartSpread = pSpread;
00920     JoinInfo.FirstBrushSpacing = 25;
00921     // make sure the join info always reflects the brush that we should draw with
00922     JoinInfo.m_BrushHandle = m_BrushHandle;
00923     JoinInfo.pAttrBrush = NULL;
00924     JoinInfo.BrushDistance = 0;
00925     
00926     // We are interested in any selected paths that the cursor is over
00927     // we will also be needing the current docview
00928     SelRange* Selected = GetApplication()->FindSelection();
00929     Node* pNode = Selected->FindFirst();
00930 
00931     // Check to see if the selection is on the same spread as the mouse
00932     if (pNode!=NULL)
00933     {
00934         // Get the spread and return if it is different from the one with the cursor
00935         Spread* pNodeSpread = pNode->FindParentSpread();
00936         if (pNodeSpread!=pSpread)
00937             return;
00938     }
00939 
00940     // Find the Blob manager, so we can find out how big a rect to use
00941     BlobManager* pBlobMgr = GetApplication()->GetBlobManager();
00942     if (pBlobMgr==NULL)
00943         return;
00944     
00945     // Find the Rect round the mouse pos that counts as a hit
00946     DocRect BlobRect;
00947     pBlobMgr->GetBlobRect(Coord, &BlobRect);
00948     
00949     // Work out the square of the distance that we will count as 'close' to the line
00950     INT32 Range = BlobRect.Width() / 2;
00951     Range *= Range;
00952 
00953 
00954     // loop through the selection
00955     while (pNode!=NULL)
00956     {
00957         // We are only interested in NodePaths
00958         // Diccon 9/99 now we are also interested in NodeBlends, as long
00959         // as they are blended on a path..
00960         if (pNode->IsNodePath())
00961         {
00962             // get the node as a NodePath
00963             NodePath* pPath = (NodePath*) pNode;
00964 
00965             // Go and see if we are near any of the endpoints of this path
00966             // (and stop looking if it is)
00967             if (IsCursorNearEndPoint(pPath, BlobRect))
00968                 return;
00969 
00970             // We were not near the open ends of the selected path, so test
00971             // to see if we are anywhere near any point along the path
00972             if (IsCursorNearPath(pPath, Range, Coord))
00973                 return;
00974         }
00975         // Diccon added 9/99
00976         else if (pNode->IS_KIND_OF(NodeBlend))
00977         {
00978             UINT32 NBPCounter = 0;
00979             NodeBlendPath* pNodeBlendPath = ((NodeBlend*)pNode)->GetNodeBlendPath(NBPCounter++);
00980             
00981             while (pNodeBlendPath != NULL) 
00982             {
00983                 NodePath* pPath = (NodePath*)pNodeBlendPath;
00984                 // Go and see if we are near any of the endpoints of this path
00985                 // (and stop looking if it is)
00986                 if (IsCursorNearEndPoint(pPath, BlobRect))
00987                     return;
00988 
00989                 // We were not near the open ends of the selected path, so test
00990                 // to see if we are anywhere near any point along the path
00991                 if (IsCursorNearPath(pPath, Range, Coord))
00992                     return;
00993 
00994                 pNodeBlendPath = ((NodeBlend*)pNode)->GetNodeBlendPath(NBPCounter++);
00995             }
00996         }
00997              
00998         // Now find the next selected node
00999         pNode = Selected->FindNext(pNode);
01000     }
01001 
01002     // if we are in brush mode then check to see if the document we are over is 
01003     // the same as the last document we drew on. If it is different we will need to update
01004     if (m_BrushHandle != BrushHandle_NoBrush)
01005     {
01006         Document* pDoc = Document::GetCurrent();
01007         if (pDoc != NULL)
01008         {
01009             String_256 CurrentDoc = pDoc->GetDocName();
01010             if (CurrentDoc != m_LastBrushDocument)
01011             {
01012                 m_LastBrushDocument = CurrentDoc;
01013                 m_UpdateBrushState = UPDATE_NOW;
01014                 BrushSelected(m_BrushHandle, FALSE);
01015             }
01016         }
01017     }
01018 
01019 
01020     // We did not find anything good, so set the cursor to the normal one
01021     ChangeCursor(pNormalCursor);
01022 
01023     // And set the status bar text
01024     StatusMsg.Load(_R(IDS_FREEHANDSTART), Tool::GetModuleID(GetID()));
01025     GetApplication()->UpdateStatusBarText(&StatusMsg);
01026 }

void FreeHandTool::PreviousPathInvalid  ) 
 

Marks the previous path as invalid. After calling this function, attempts to re-fit a path by changing the smoothing values will be ignored. This function should be called when something happens that would make it impossible to re-fit the path (eg the original is translated or rotated or undone).

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/5/94

Definition at line 1262 of file freehand.cpp.

01263 {
01264     // The previous path is no longer valid, so set all
01265     // the flags and vars associated with it
01266     IsPreviousPathValid = FALSE;
01267     IsRetroPathValid = FALSE;
01268     IsSelectBlobsOnScreen = FALSE;
01269     PreviousPath = NULL;
01270     StartSlot = 0;
01271     NumSlots = 0;
01272     PathCRC = 0;
01273 
01274     // Tell the info bar to show that retro fitting is no longer possible
01275     if (pInfoBarOp != NULL)
01276         pInfoBarOp->SetRetroState(FALSE);
01277 }

void FreeHandTool::RemoveCursors  )  [protected]
 

Pops the freehand tools cursor off the top of the cursor stack, frees the memory used by all the cursors in the freehand tool and sets all the pointers to NULL.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/10/94
See also:
FreeHandTool::LoadCursors

Definition at line 670 of file freehand.cpp.

00671 {
00672     // If we ever had a cursor
00673     if (pActiveCursor!=NULL)
00674     {
00675         // pop it off the stack
00676         CursorStack::GPop(CurrentCursorID);
00677 
00678         // and free up the cursors we allocated
00679         delete pNormalCursor;
00680         delete pJoinCursor;
00681         delete pModifyCursor;
00682 
00683         // and set them all to NULL
00684         pNormalCursor = NULL;
00685         pJoinCursor = NULL;
00686         pActiveCursor = NULL;
00687         pModifyCursor = NULL;
00688         CurrentCursorID = 0;
00689     }
00690 }

void FreeHandTool::RenderToolBlobs Spread pSpread,
DocRect pClipRect
[virtual]
 

Renders the Tools Blobs. This will be used to draw paths as they are retro fitted live, as the accuracy bar is dragged!

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/5/94
Parameters:
pSpread - The spread that the blob is to appear on [INPUTS] pClipRect - Pointer to the rect that contains the blobs

Reimplemented from Tool_v1.

Definition at line 1190 of file freehand.cpp.

01191 {
01192     // Can only draw the path if there is a path to draw
01193     if (IsPreviousPathValid && IsRetroPathValid && RetroPath!=NULL)
01194     {
01195         RenderRegion* pRegion = DocView::RenderOnTop(pClipRect, pSpread, ClippedEOR);
01196         while (pRegion)
01197         {
01198             // Draw a Cross Hair
01199             pRegion->SetLineColour(COLOUR_XOREDIT);
01200             pRegion->SetLineWidth(0);
01201             pRegion->DrawPath(RetroPath);
01202 
01203             // Get the next region in the list
01204             pRegion = DocView::GetNextOnTop(pClipRect);
01205         }
01206     }   
01207 }

void FreeHandTool::RetroFitChanging  ) 
 

Tries to re-fit the previous path with the current smoothness setting.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/5/94

Definition at line 1455 of file freehand.cpp.

01456 {
01457     BOOL IsStillValid = IsRetroPathStillValid();
01458     if (IsStillValid)
01459     {
01460         // Find the spread that the previous path was on
01461         Spread* pSpread = PreviousPath->FindParentSpread();
01462 
01463         // Find the docview that we are looking at
01464         DocView* pDocView = DocView::GetSelected();
01465 
01466         // if both of those are ok, carry on
01467         if (pSpread!=NULL && pDocView!=NULL)
01468         {
01469             BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01470             ENSURE(BlobMgr!=NULL, "Blob Manager was not there");
01471 
01472             // Translate the original data if the path moved
01473             TranslateTrackData();
01474 
01475             // Get rid of the Selection blobs if they are still on screen
01476             if (IsSelectBlobsOnScreen)
01477             {
01478                 BlobMgr->RenderMyBlobs(NULL, pSpread, PreviousPath);
01479                 IsSelectBlobsOnScreen = FALSE;
01480             }
01481 
01482             // Erase the old EORed path (if it was there)
01483             BlobMgr->RenderToolBlobsOff(this, pSpread, NULL);
01484 
01485             // Refit the path - First work out the current error factor
01486             double ScaleFactor = (pDocView->GetViewScale()).MakeDouble();
01487             double ErrorLevel = (64 + (160*Smoothness)) / ScaleFactor;
01488             ErrorLevel = ErrorLevel * ErrorLevel;
01489 
01490             // and perform all the maths
01491             if ((RetroPath!=NULL) && (TrackData!=NULL))
01492             {
01493                 CurveFitObject CurveFitter(RetroPath, ErrorLevel);
01494                 if (CurveFitter.Initialise(TrackData, TrackData->GetNumCoords()))
01495                     CurveFitter.FitCurve();
01496             }
01497 
01498             // Draw in the new path
01499             IsRetroPathValid = TRUE;
01500             BlobMgr->RenderToolBlobsOn(this, pSpread, NULL);
01501             AreWeRetroFitting = TRUE;
01502         }
01503         else
01504         {
01505             IsStillValid = FALSE;
01506         }
01507     }
01508 
01509     // If the retro fit is not valid, then invalidate the path properly
01510     if (!IsStillValid)
01511     {
01512         // mark the path as invalid
01513         PreviousPathInvalid();
01514     }
01515 }

void FreeHandTool::RetroFitFinished  ) 
 

Should be called when any changes to the accuracy slider have been completed.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/5/94

Definition at line 1529 of file freehand.cpp.

01530 {
01531     // Start an operation here that will hide the original path and put a new one in
01532     // Make sure that we have a path that we are able to change
01533     if ((IsPreviousPathValid && AreWeRetroFitting) && (RetroPath!=NULL))
01534     {
01535         // Find the spread that the previous path was on
01536         Spread* pSpread = PreviousPath->FindParentSpread();
01537         if (pSpread!=NULL)
01538         {
01539             BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01540             ENSURE(BlobMgr!=NULL, "Blob Manager was not there");
01541 
01542             // Draw the selection blobs back on again
01543             if (!IsSelectBlobsOnScreen)
01544             {
01545                 BlobMgr->RenderMyBlobs(NULL, pSpread, PreviousPath);
01546                 IsSelectBlobsOnScreen = TRUE;
01547             }
01548 
01549             // Erase the old EORed path (if it was there)
01550             BlobMgr->RenderToolBlobsOff(this, pSpread, NULL);
01551             
01552             // Build the undo info to change the existing path to the new one
01553             if (IsRetroPathValid)
01554             {
01555                 // Make a copy of the node we are joining with
01556                 Node* pNode;
01557                 if (PreviousPath->NodeCopy(&pNode))
01558                 {
01559                     // Start a slow job
01560                     BeginSlowJob();
01561 
01562                     // Clear out the old data in the path
01563                     NodePath* pNewPath = (NodePath*) pNode;
01564 
01565                     // Go and replace the section that we have changed
01566                     BOOL IsOk;
01567                     if (StartSlot==0)
01568                         IsOk = pNewPath->InkPath.RetroReplaceSection(StartSlot, NumSlots, RetroPath, TRUE);
01569                     else
01570                         IsOk = pNewPath->InkPath.RetroReplaceSection(StartSlot, NumSlots, RetroPath, FALSE);
01571                     
01572                     // If it worked, then build a bit of undo
01573                     if (IsOk)
01574                     {
01575                         // Create a new Retro Fit Operation
01576                         OpRetroFit* pRetroOp = new OpRetroFit;
01577                         if (pRetroOp!=NULL)
01578                         {
01579                             // Make a note of the start slot and length of the section we are
01580                             // changing as the operation causes this information to be invalidated
01581                             INT32 OldStartSlot = StartSlot;
01582                             INT32 OldNumSlots = RetroPath->GetNumCoords();
01583                             if (pRetroOp->BuildUndo(PreviousPath, (NodePath*)pNode))
01584                                 SetPreviousPath(pNewPath, OldStartSlot, OldNumSlots);
01585                         }
01586                         else
01587                         {
01588                             // Did not get the memory for the operation
01589                             IsOk = FALSE;
01590                         }
01591                     }
01592 
01593                     // End the slow job we started
01594                     EndSlowJob();
01595 
01596                     // If things generally did not work, tell the happy user
01597                     if (!IsOk)
01598                         ToolInformError(_R(IDS_RETROOUTOFMEM));
01599                 }
01600             }
01601 
01602             // Clear out the data in the fitted version of the path, as this is no longer needed
01603             // We do keep the Original track data though.
01604             RetroPath->ClearPath();
01605             IsRetroPathValid = FALSE;
01606         }
01607     }
01608 
01609     // We are no longer retro fitting the path, so reset the flag to indicate this
01610     AreWeRetroFitting = FALSE;
01611 }

void FreeHandTool::ScreenChanged BOOL  WipeRegion = FALSE  ) 
 

Called by the infobar to let the tool know that the screen has changed. Essentially this means that if we are in brush drawing mode then we need to blit the contents of the screen into our big render region.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 2643 of file freehand.cpp.

02644 {
02645     //TRACEUSER( "Diccon", _T("FreehandTool::ScreenChanged\n"));
02646 
02647     if (WipeRegion == TRUE)
02648     {
02649 PORTNOTE("other", "Removed m_pGRenderBrush support");
02650 #ifndef EXCLUDE_FROM_XARALX
02651         if (m_pGRenderBrush != NULL)
02652         {
02653             delete m_pGRenderBrush;
02654             m_pGRenderBrush = NULL;
02655         }
02656 #endif
02657     }
02658 
02659     m_bBrushReady = FALSE;
02660     
02661     m_UpdateBrushState = UPDATE_ONIDLE;
02662 }

void FreeHandTool::SelectChange BOOL  isSelected  )  [virtual]
 

Called when the tool is selected or deselected. Creates and pushes the tool's cursor; pops and destroys it.

Author:
Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/11/93
Parameters:
IsSelected - TRUE if the tool is becoming selected, FALSE if it is loosing [INPUTS] the selection
Returns:
Errors: Sends warning to debugging terminal if creating the cursor fails.

Reimplemented from Tool_v1.

Definition at line 414 of file freehand.cpp.

00415 {
00416     
00417     if (isSelected)
00418     {
00419         CCPen *pPen = Camelot.GetPressurePen();
00420         if (pPen != NULL)
00421         {
00422             PressureMode NewState = (pPen->IsRealPen()) ? PressureMode_Pen : PressureMode_None;
00423             pPen->SetPressureMode(NewState);
00424         }
00425     
00426         m_UpdateBrushState = UPDATE_ONIDLE;
00427 
00428         BOOL ok = BrushSelected(m_BrushHandle, FALSE);
00429         // if that didn't work then we won't use a brush
00430         if (!ok)
00431             m_BrushHandle = BrushHandle_NoBrush;
00432         
00433         // if we have a brush then default to no smoothness
00434     /*  if (m_BrushHandle != BrushHandle_NoBrush)
00435             Smoothness = 0;
00436         else
00437             Smoothness = 50;
00438 */
00439         m_LastBrushDocument = TEXT("No document");
00440 
00441         // Load the cursors
00442         if (!LoadCursors())
00443             InformError();
00444         
00445         // reset the join path pointer
00446         JoinInfo.pJoinPath = NULL;
00447         JoinInfo.FirstBrushSpacing = 25;
00448         // Find the blob manager ready for later
00449         BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00450 
00451         // Clear the sub-selection on all the paths in the current selection
00452         BOOL IsPathWithSubSelection = FALSE;
00453         if (Document::GetSelected() != NULL)
00454         {
00455             // Get the selection
00456             SelRange* Selected = GetApplication()->FindSelection();
00457             Node* pNode = Selected->FindFirst();
00458             while ((pNode!=NULL) && (!IsPathWithSubSelection))
00459             {
00460                 // clear the sub-selection if this is a path
00461                 if (pNode->IsNodePath())
00462                 {
00463                     // If this path has a sub-selection, then set the flag
00464                     if (((NodePath*)pNode)->InkPath.IsSubSelection())
00465                         IsPathWithSubSelection = TRUE;
00466                 }
00467 
00468                 // Now find the next selected node
00469                 pNode = Selected->FindNext(pNode);
00470             }
00471 
00472             // if there was a sub-selection, then get rid of it
00473             if ((IsPathWithSubSelection) && (BlobMgr!=NULL))
00474             {
00475                 // Get rid of the object blobs while we clear the paths sub-selection
00476                 BlobStyle ClearBlobs;
00477                 ClearBlobs.Object = FALSE;
00478                 BlobMgr->ToolInterest(ClearBlobs);
00479 
00480                 // There are now no object blobs on screen, so we can clear the subselection
00481                 pNode = Selected->FindFirst();
00482                 while (pNode!=NULL)
00483                 {
00484                     // clear the sub-selection if this is a path
00485                     if (pNode->IsNodePath())
00486                         ((NodePath*)pNode)->InkPath.ClearSubSelection();
00487 
00488                     // Now find the next selected node
00489                     pNode = Selected->FindNext(pNode);
00490                 }
00491             }
00492         }
00493     
00494     // Diccon 9/99 Code copied from Beztool::SelectChange() complete with original comments
00495 
00496     // If there is are TextStories or Blends with paths selected then select the paths
00497     // (PS. This is a rather disgusting way of doing things, and one you can't blame on me - MarkN 17-5-99)
00498 
00499     Range SelRng(*(GetApplication()->FindSelection()));
00500     Node* pNode = SelRng.FindFirst();
00501     
00502     while (pNode != NULL)
00503     {
00504         if (IS_A(pNode, TextStory))
00505         {
00506             TextStory* pStory = (TextStory*)pNode;
00507             if (pStory->GetTextPath() != NULL)
00508                 pStory->GetTextPath()->Select(TRUE);
00509         }
00510 
00511         if (IS_A(pNode, NodeBlend))
00512         {
00513             NodeBlend* pNodeBlend = (NodeBlend*)pNode;
00514             UINT32 NBPCounter = 0;
00515             while (pNodeBlend->GetNodeBlendPath(NBPCounter) != NULL)
00516                 pNodeBlend->GetNodeBlendPath(NBPCounter++)->Select(TRUE);
00517         }
00518 
00519         pNode = SelRng.FindNext(pNode);
00520     }
00521     
00522         // Create and display my info bar please
00523         if (pInfoBarOp != NULL)
00524         {
00525             pInfoBarOp->Create();
00526             pInfoBarOp->SetToolActiveState(TRUE);
00527         }
00528 
00529         // Make sure that Objects blobs are on
00530         if (BlobMgr != NULL)
00531         {
00532             // Decide which blobs to display
00533             BlobStyle MyBlobs;
00534             MyBlobs.Object = TRUE;
00535 
00536             // tell the blob manager
00537             BlobMgr->ToolInterest(MyBlobs);
00538         }
00539 
00540         // Set the retro field on the info bar
00541         if (pInfoBarOp != NULL)
00542         {
00543             // Find out if we can retro fit and set the field appropriatly
00544             BOOL IsStillValid = IsRetroPathStillValid();
00545             pInfoBarOp->SetRetroState(IsStillValid);
00546         }
00547 
00548     }
00549     else
00550     {
00551         // Deselection of the tool
00552         // Get rid of all the tools cursors
00553         RemoveCursors();
00554 
00555 PORTNOTE("other", "Removed m_pGRenderBrush support");
00556 #ifndef EXCLUDE_FROM_XARALX
00557         if (m_pGRenderBrush != NULL)
00558         {
00559             delete m_pGRenderBrush;
00560             m_pGRenderBrush = NULL;
00561         }
00562 #endif
00563         
00564         // Hide and destroy my info bar please
00565         if (pInfoBarOp != NULL)
00566         {
00567             pInfoBarOp->SetToolActiveState(FALSE);
00568             
00569 PORTNOTE("other", "Removed brush gadget support");
00570 #ifndef EXCLUDE_FROM_XARALX
00571             if (FreeHandInfoBarOp::GetBrushGadget()->IsDialogOpen ())
00572             {
00573                 FreeHandInfoBarOp::GetBrushGadget()->CloseDialog ();
00574             }
00575 #endif          
00576             pInfoBarOp->Delete();
00577         }
00578         // ensure that the colour picker is working
00579         SetColourEditorProcessing(TRUE);
00580 
00581         // ensure any tool object blobs are removed.
00582         BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00583         if (BlobMgr != NULL)
00584         {
00585             BlobStyle bsRemoves;
00586             bsRemoves.ToolObject = TRUE;
00587             BlobMgr->RemoveInterest(bsRemoves);
00588         }
00589     }
00590 }

void FreeHandTool::SetBrushSpacing MILLIPOINT  Spacing  ) 
 

for setting the freehand tools current brush spacing

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/99 inputs: the spacing value to set
Returns:
-

Definition at line 2209 of file freehand.cpp.

02210 {
02211     m_BrushSpacing = Spacing;
02212 }

BOOL FreeHandTool::SetBrushUpdateState UPDATE_STATE  Update  ) 
 

Tells us when we should next update the offscreen buffer used by the brush. Often it is wise ot wait until the next idle to update because that gives time for the screen to redraw after the brush combo has closed.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
Update - when we want the brush to update next upon entering brush selected [INPUTS] UPDATE_NOW: updates immediately UPDATE_ONIDLE: updates on the next idle UPDATE_NEVER: will not update until the flag is changed
- [OUTPUTS]
Returns:
TRUE if successful, FALSE if Update is invalid

Definition at line 2371 of file freehand.cpp.

02372 {
02373     if (Update < UPDATE_NOW || Update > UPDATE_NEVER)
02374     {
02375         ERROR3("Invalid update flag");
02376         return FALSE;
02377     }
02378     m_UpdateBrushState = Update;
02379     return TRUE;
02380 }

void FreeHandTool::SetColourEditorProcessing BOOL  Value  )  [protected]
 

Tells the colour editor whether or not to do timer processing, we need to turn it off in order to draw a brush stroke.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/11/99
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 2790 of file freehand.cpp.

02791 {
02792     ColourEditDlg* pColourEditor = ColourEditDlg::GetColourEditDlg();
02793     if (pColourEditor != NULL)
02794         pColourEditor->SetDoTimerProcessing(Value);
02795 }

void FreeHandTool::SetCurrentBrushHandle  ) 
 

Sets the brush handle member to that of the current default brush attribute.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
10/10/99
Returns:
-

Definition at line 1717 of file freehand.cpp.

01718 {
01719     Document* pDoc = Document::GetCurrent();
01720     if (pDoc == NULL)
01721     {
01722         ERROR3("No document");
01723         return;
01724     }
01725 
01726     AttributeManager* pAttrMgr = &(pDoc->GetAttributeMgr());
01727     if (pAttrMgr == NULL)
01728     {
01729         ERROR3("No attribute manager");
01730         return;
01731     }
01732 
01733     AttrBrushType* pAttr = (AttrBrushType*)(pAttrMgr->GetCurrentAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), CC_RUNTIME_CLASS(AttrBrushType)));
01734 
01735     if (pAttr == NULL)
01736     {
01737         ERROR3("No current brush attribute");
01738         return;
01739     }
01740     m_BrushHandle = pAttr->GetBrushHandle();
01741     
01742 }

void FreeHandTool::SetPreviousPath NodePath PrevPath,
INT32  Start,
INT32  Len
 

Marks the previously drawn path as valid so that it can be retro fitted. Retro fitting will be allowed until PreviousPathInvalid() is called.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/5/94
Parameters:
PrevPath - The path that has just been added to the tree. ie the one most [INPUTS] recently drawn with the freehand tool Start - The Start slot at which the new section of path begins. Len - The number of slots that the new path section contains.
See also:
FreeHandTool::PreviousPathInvalid

Definition at line 1298 of file freehand.cpp.

01299 {
01300     // Set all the params associated with the previous path
01301     PreviousPath = PrevPath;
01302     StartSlot = Start;
01303     NumSlots = Len;
01304 
01305     // Calculate the CRC for the path.
01306     PathCRC = BuildPathCRC(PreviousPath);
01307 
01308     // Set the flags so that we know what is valid and what is not
01309     IsPreviousPathValid = TRUE;
01310     IsRetroPathValid = FALSE;
01311     IsSelectBlobsOnScreen = TRUE;
01312 
01313     // Tell the info bar to flash up a little indicator that retro fitting is possible
01314     if (pInfoBarOp != NULL)
01315         pInfoBarOp->SetRetroState(TRUE);
01316 
01317     // Clear out the retro fit path
01318     RetroPath->ClearPath();
01319 }

void FreeHandTool::SetSmoothness INT32  Smooth  ) 
 

Sets the freehand tools accuracy setting.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
17/5/94
Parameters:
Smooth - The new value for the smoothness [INPUTS]

Definition at line 1223 of file freehand.cpp.

01224 {
01225     Smoothness = Smooth;
01226 }

void FreeHandTool::TranslateTrackData  ) 
 

If the path in the tree has been translated since it was drawn, we have to translate the original retro fit data to match. This functions checks if a translation is required, and translates all the coords if it is needed.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/6/94

Definition at line 1416 of file freehand.cpp.

01417 {
01418     // if we do not have any track data then stop now
01419     if (TrackData==NULL)
01420         return;
01421 
01422     // Get the two coord sections of the paths
01423     DocCoord* TrackCoords = TrackData->GetCoordArray();
01424     DocCoord* TreeCoords = PreviousPath->InkPath.GetCoordArray();
01425 
01426     // see if the first coord matches
01427     if ((TrackCoords[0].x!=TreeCoords[StartSlot].x) || (TrackCoords[0].y!=TreeCoords[StartSlot].y))
01428     {
01429         // Nop, so find the offset
01430         INT32 Dx = TreeCoords[StartSlot].x - TrackCoords[0].x;
01431         INT32 Dy = TreeCoords[StartSlot].y - TrackCoords[0].y;
01432 
01433         // Loop through all the coords and add on the offset
01434         INT32 NumCoords = TrackData->GetNumCoords();
01435         for (INT32 i=0; i<NumCoords; i++)
01436         {
01437             // Offset the track data
01438             TrackCoords[i].x += Dx;
01439             TrackCoords[i].y += Dy;
01440         }
01441     }
01442 }


Member Data Documentation

BOOL FreeHandTool::AreWeRetroFitting [protected]
 

Definition at line 296 of file freehand.h.

TCHAR * FreeHandTool::Author = _T("Rik") [static, protected]
 

Reimplemented from DragTool.

Definition at line 276 of file freehand.h.

INT32 FreeHandTool::CurrentCursorID [protected]
 

Definition at line 306 of file freehand.h.

TCHAR * FreeHandTool::FamilyName = _T("Drawing Tools") [static, protected]
 

Reimplemented from DragTool.

Definition at line 273 of file freehand.h.

BOOL FreeHandTool::FreehandPtrCrosshair = FALSE [static]
 

Determine whether freehand pointer has crosshairs or not.

Preference: FreehandPtrCrosshair Section: Mouse Range: FALSE, TRUE

Definition at line 327 of file freehand.h.

BOOL FreeHandTool::IsPreviousPathValid [protected]
 

Definition at line 297 of file freehand.h.

BOOL FreeHandTool::IsRetroPathValid [protected]
 

Definition at line 298 of file freehand.h.

BOOL FreeHandTool::IsSelectBlobsOnScreen [protected]
 

Definition at line 299 of file freehand.h.

FreeHandJoinInfo FreeHandTool::JoinInfo [protected]
 

Definition at line 309 of file freehand.h.

BOOL FreeHandTool::m_bBrushReady [protected]
 

Definition at line 321 of file freehand.h.

BrushHandle FreeHandTool::m_BrushHandle [protected]
 

Definition at line 320 of file freehand.h.

std::vector< NodeRenderableInk * > FreeHandTool::m_BrushInkNodeArray [protected]
 

Definition at line 314 of file freehand.h.

MILLIPOINT FreeHandTool::m_BrushSpacing [protected]
 

Definition at line 318 of file freehand.h.

String_256 FreeHandTool::m_LastBrushDocument [protected]
 

Definition at line 323 of file freehand.h.

UINT32 FreeHandTool::m_NumInkNodes [protected]
 

Definition at line 319 of file freehand.h.

BlendRef* FreeHandTool::m_pBlendRef [protected]
 

Definition at line 317 of file freehand.h.

GRenderBrush* FreeHandTool::m_pGRenderBrush [protected]
 

Definition at line 243 of file freehand.h.

UPDATE_STATE FreeHandTool::m_UpdateBrushState [protected]
 

Definition at line 248 of file freehand.h.

INT32 FreeHandTool::NumSlots [protected]
 

Definition at line 293 of file freehand.h.

Cursor* FreeHandTool::pActiveCursor [protected]
 

Definition at line 304 of file freehand.h.

INT32 FreeHandTool::PathCRC [protected]
 

Definition at line 294 of file freehand.h.

FreeHandInfoBarOp* FreeHandTool::pInfoBarOp [protected]
 

Definition at line 312 of file freehand.h.

Cursor* FreeHandTool::pJoinCursor [protected]
 

Definition at line 303 of file freehand.h.

Cursor* FreeHandTool::pModifyCursor [protected]
 

Definition at line 305 of file freehand.h.

Cursor* FreeHandTool::pNormalCursor [protected]
 

Definition at line 302 of file freehand.h.

NodePath* FreeHandTool::PreviousPath [protected]
 

Definition at line 295 of file freehand.h.

TCHAR * FreeHandTool::Purpose = _T("To Draw arbitrary lines") [static, protected]
 

Reimplemented from DragTool.

Definition at line 275 of file freehand.h.

Path* FreeHandTool::RetroPath [protected]
 

Definition at line 291 of file freehand.h.

INT32 FreeHandTool::Smoothness [protected]
 

Definition at line 279 of file freehand.h.

DocCoord FreeHandTool::StartPos [protected]
 

Definition at line 285 of file freehand.h.

INT32 FreeHandTool::StartSlot [protected]
 

Definition at line 292 of file freehand.h.

Spread* FreeHandTool::StartSpread [protected]
 

Definition at line 286 of file freehand.h.

String_256 FreeHandTool::StatusMsg [protected]
 

Definition at line 282 of file freehand.h.

TCHAR * FreeHandTool::ToolName = _T("Free Hand Tool") [static, protected]
 

Reimplemented from DragTool.

Definition at line 274 of file freehand.h.

Path* FreeHandTool::TrackData [protected]
 

Definition at line 290 of file freehand.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:54:39 2007 for Camelot by  doxygen 1.4.4