#include <freehand.h>
Inheritance diagram for FreeHandTool:
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. | |
FreeHandInfoBarOp * | GetInfoBar () |
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 | |
GRenderBrush * | GetBigGRenderBrush (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. | |
BrushDefinition * | GetSelectedBrush () |
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 | |
GRenderBrush * | m_pGRenderBrush |
UPDATE_STATE | m_UpdateBrushState |
INT32 | Smoothness |
String_256 | StatusMsg |
DocCoord | StartPos |
Spread * | StartSpread |
Path * | TrackData |
Path * | RetroPath |
INT32 | StartSlot |
INT32 | NumSlots |
INT32 | PathCRC |
NodePath * | PreviousPath |
BOOL | AreWeRetroFitting |
BOOL | IsPreviousPathValid |
BOOL | IsRetroPathValid |
BOOL | IsSelectBlobsOnScreen |
Cursor * | pNormalCursor |
Cursor * | pJoinCursor |
Cursor * | pActiveCursor |
Cursor * | pModifyCursor |
INT32 | CurrentCursorID |
FreeHandJoinInfo | JoinInfo |
FreeHandInfoBarOp * | pInfoBarOp |
std::vector< NodeRenderableInk * > | m_BrushInkNodeArray |
BlendRef * | m_pBlendRef |
MILLIPOINT | m_BrushSpacing |
UINT32 | m_NumInkNodes |
BrushHandle | m_BrushHandle |
BOOL | m_bBrushReady |
String_256 | m_LastBrushDocument |
Static Protected Attributes | |
static TCHAR * | FamilyName = _T("Drawing Tools") |
static TCHAR * | ToolName = _T("Free Hand Tool") |
static TCHAR * | Purpose = _T("To Draw arbitrary lines") |
static TCHAR * | Author = _T("Rik") |
Private Member Functions | |
CC_DECLARE_MEMDUMP (FreeHandTool) |
Definition at line 170 of file freehand.h.
|
Dummp Constructor - It does nothing. All the real initialisation is done in FreeHandTool::Init which is called by the Tool Manager.
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 }
|
|
Destructor (Virtual). Does nothing.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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).
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 }
|
|
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
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 }
|
|
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.
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 }
|
|
|
|
Changes to the specified cursor. Will only change the cursor if it isn't already this cursor, so it doesn't flicker.
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 }
|
|
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.
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 }
|
|
Deletes the paths that hold the track data and the smoothed path and sets thier params to NULL.
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 }
|
|
Allows the tool manager to extract information about the tool.
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 }
|
|
Gets a GRenderBrush the size of the current view, then renders into it the contents of the current view.
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 }
|
|
Definition at line 219 of file freehand.h. 00219 { return m_BrushHandle;}
|
|
for finding out the freehand tools current brush spacing
Definition at line 2191 of file freehand.cpp. 02192 { 02193 return m_BrushSpacing; 02194 }
|
|
Reimplemented from Tool_v1. Definition at line 391 of file freehand.cpp. 00392 { 00393 return TOOLID_FREEHAND; 00394 }
|
|
Definition at line 199 of file freehand.h. 00199 { return pInfoBarOp;}
|
|
as above, note that the m_brushinknodes pointer must be initialised
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 }
|
|
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.
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 }
|
|
In order to determine which brush to draw with when performing a real time draw brush operation.
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 }
|
|
for finding out the freehand tools current smoothing accuracy value
Definition at line 1242 of file freehand.cpp. 01243 { 01244 return Smoothness; 01245 }
|
|
Sets the status line text on request from the app.
Reimplemented from Tool_v1. Definition at line 1043 of file freehand.cpp.
|
|
Used to check if the Tool was properly constructed.
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 }
|
|
To initialise a BlendRef object.
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 }
|
|
To work out how large our brush bitmaps must be and allocate them to the render region supplied.
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 }
|
|
Clears out the m_BrushRefPtrArray if it is not empty, and sets the size.
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 }
|
|
Initialises the JoinInfo struct so that we correctly join the existing brush.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
Loads all the cursors used by the freehand tool and pushs the normal one onto the top of the cursor stack.
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 }
|
|
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 }
|
|
To handle a Mouse Click event for the FreeHand Tool. It starts up a FreeHand Operation.
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 }
|
|
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 }
|
|
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:.
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 }
|
|
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).
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 }
|
|
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.
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 }
|
|
Renders the Tools Blobs. This will be used to draw paths as they are retro fitted live, as the accuracy bar is dragged!
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 }
|
|
Tries to re-fit the previous path with the current smoothness setting.
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 }
|
|
Should be called when any changes to the accuracy slider have been completed.
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 }
|
|
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.
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 }
|
|
Called when the tool is selected or deselected. Creates and pushes the tool's cursor; pops and destroys it.
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 }
|
|
for setting the freehand tools current brush spacing
Definition at line 2209 of file freehand.cpp. 02210 { 02211 m_BrushSpacing = Spacing; 02212 }
|
|
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.
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 }
|
|
Tells the colour editor whether or not to do timer processing, we need to turn it off in order to draw a brush stroke.
Definition at line 2790 of file freehand.cpp. 02791 { 02792 ColourEditDlg* pColourEditor = ColourEditDlg::GetColourEditDlg(); 02793 if (pColourEditor != NULL) 02794 pColourEditor->SetDoTimerProcessing(Value); 02795 }
|
|
Sets the brush handle member to that of the current default brush attribute.
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 }
|
|
Marks the previously drawn path as valid so that it can be retro fitted. Retro fitting will be allowed until PreviousPathInvalid() is called.
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 }
|
|
Sets the freehand tools accuracy setting.
Definition at line 1223 of file freehand.cpp. 01224 { 01225 Smoothness = Smooth; 01226 }
|
|
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.
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 }
|
|
Definition at line 296 of file freehand.h. |
|
Reimplemented from DragTool. Definition at line 276 of file freehand.h. |
|
Definition at line 306 of file freehand.h. |
|
Reimplemented from DragTool. Definition at line 273 of file freehand.h. |
|
Determine whether freehand pointer has crosshairs or not. Preference: FreehandPtrCrosshair Section: Mouse Range: FALSE, TRUE Definition at line 327 of file freehand.h. |
|
Definition at line 297 of file freehand.h. |
|
Definition at line 298 of file freehand.h. |
|
Definition at line 299 of file freehand.h. |
|
Definition at line 309 of file freehand.h. |
|
Definition at line 321 of file freehand.h. |
|
Definition at line 320 of file freehand.h. |
|
Definition at line 314 of file freehand.h. |
|
Definition at line 318 of file freehand.h. |
|
Definition at line 323 of file freehand.h. |
|
Definition at line 319 of file freehand.h. |
|
Definition at line 317 of file freehand.h. |
|
Definition at line 243 of file freehand.h. |
|
Definition at line 248 of file freehand.h. |
|
Definition at line 293 of file freehand.h. |
|
Definition at line 304 of file freehand.h. |
|
Definition at line 294 of file freehand.h. |
|
Definition at line 312 of file freehand.h. |
|
Definition at line 303 of file freehand.h. |
|
Definition at line 305 of file freehand.h. |
|
Definition at line 302 of file freehand.h. |
|
Definition at line 295 of file freehand.h. |
|
Reimplemented from DragTool. Definition at line 275 of file freehand.h. |
|
Definition at line 291 of file freehand.h. |
|
Definition at line 279 of file freehand.h. |
|
Definition at line 285 of file freehand.h. |
|
Definition at line 292 of file freehand.h. |
|
Definition at line 286 of file freehand.h. |
|
Definition at line 282 of file freehand.h. |
|
Reimplemented from DragTool. Definition at line 274 of file freehand.h. |
|
Definition at line 290 of file freehand.h. |