PenTool Class Reference

This class handles the Pen Tool that is used to draw lines and curves via clicking and draging on the workarea. More...

#include <pentool.h>

Inheritance diagram for PenTool:

Tool_v1 List of all members.

Public Member Functions

 PenTool ()
 Dummy Constructor - It does nothing. All the real initialisation is done in PenTool::Init which is called by the Tool Manager.
 ~PenTool ()
 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 ()
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 Pen Tool.
virtual void RenderToolBlobs (Spread *, DocRect *)
 The blobs this tool renders are (1) a moveto floating endpoint (2) a dragto floating endpoint These are usually rendered after the first click/drag on a document.
virtual BOOL GetStatusLineText (String_256 *, Spread *, DocCoord, ClickModifiers)
 generate up-to-date text for the status line (called on idles)
virtual void OnMouseMove (DocCoord, Spread *, ClickModifiers)
 This routine is called whenever the mouse moves while we're in the pen tool. it sees what is under the pointer, and flips the cursor if clicking will have a different effect.
virtual BOOL OnKeyPress (KeyPress *pKeyPress)
 To handle keypress events for the Pen Tool. If it is a keypress that it know about it starts up an appropiate operation. THIS IS BADLY WRONG AT THE MOMENT - WHEN THERE IS THE TECHNOLOGY FOR USER DEFINABLE KEY-SHORTCUTS THIS FUNCTION WILL NEED FIXING.
void GenerateStatusLineText (NodePath *pNodePath, penclick WhatToDo, String_256 *pStatusMsg)
 Loads up an appropriate help string into the text buffer pointed to by pStatusMsg, using the nodepath and 'whattodo' information passed.
void SetInternalState ()
 This function is called from an operation which tells the tool that there should be a virtual moveto coordinate and dragto coordinate set within the tool. If the dragto is equal to the moveto, then an internal move should be created, rather than an internal drag.
void ClearInternalState ()
 Clears the internal condition.
BOOL OverPathEnd (DocCoord, Spread *, NodePath **)
penclick DetermineClickEffect (DocCoord, Spread *, NodePath **)
 Used when single clicking. This routine determines what effect a click will have. In this tool, clicking will add a segment to the end of a line, adjust the last element of a path or start a new path entirely.
void RemoveSelection (DocCoord PointerPos, Spread *pSpread, NodePath *pNodePath=NULL)
 This routine scans the specified spread for all path objects and checks whether the mouse coord is over an open end point. It can be used to work out whether to change the mouse shape or not. This routine should really exist in some other file, available to all tools but I dont know where to put it yet so it shall have to stay here for the mo.
void ClearPath ()
 Throw away the internal data of the pen path.
void ClearOp ()
 Throw away the internal op state we've been holding.
void CreateNewPath ()
 Once a drag has finished we need to build a new path with the data.
void AddElementToPath ()
 Once a drag has finished we need to add the newly edited element to the specified path.
void CloseWithPath ()
 Once a drag has finished we need to add the newly edited element to the specified path.
penopstate GetPenOpState () const
 return the operation state the pen tool thinks its in.

Private Member Functions

 CC_DECLARE_MEMDUMP (PenTool)
void ClickOnEndPoint (ClickType Click, ClickModifiers ClickMods, Spread *pSpread, NodePath *pNodePath)
 An end point click has occured. This function acts on such a click by selecting the point or editing the point dependent on the click type.
BOOL CreatePenCursors ()
 Pen tool cursor creation.
void DeletePenCursors ()
 Pen tool cursor deletion.
void ChangeCursor (Cursor *cursor)
 Changes to the specified cursor. Will only change the cursor if it isn't already this cursor, so it doesn't flicker.

Private Attributes

penstate CurrPenState
penopstate CurrPenOpState
Path EditPath
ControlPts EditHandles
NodePathpNodePath
INT32 NodeIndex
CursorpcPenCursor
CursorpcPenAdjustCursor
CursorpcPenReshapeCursor
CursorpcMoveBezCursor
CursorMyCurrentCursor
INT32 CurrentCursorID
PenToolInfoBarOppPenInfoBarOp

Static Private Attributes

static TCHARFamilyName = _T("Drawing Tools")
static TCHARToolName = _T("Pen Tool")
static TCHARPurpose = _T("To draw lines and curves")
static TCHARAuthor = _T("Mike")

Detailed Description

This class handles the Pen Tool that is used to draw lines and curves via clicking and draging on the workarea.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/9/94

Definition at line 158 of file pentool.h.


Constructor & Destructor Documentation

PenTool::PenTool  ) 
 

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

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/9/94
See also:
PenTool::Init

Definition at line 162 of file pentool.cpp.

00163 {
00164     pcPenCursor = NULL;
00165     pcPenAdjustCursor = NULL;
00166     pcPenReshapeCursor = NULL;
00167     pcMoveBezCursor = NULL;
00168     MyCurrentCursor = NULL;
00169 
00170     CurrPenState = IS_Undefined;
00171 }

PenTool::~PenTool  ) 
 

Destructor (Virtual). Does nothing.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/9/94

Definition at line 186 of file pentool.cpp.

00187 {
00188     // Dummy destructor
00189 }


Member Function Documentation

void PenTool::AddElementToPath  ) 
 

Once a drag has finished we need to add the newly edited element to the specified path.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 1668 of file pentool.cpp.

01669 {
01670     // Right, the last drag has created a new path section for me
01671     // I need to add it in to the specified nodepath object
01672 
01673     OpAddPathToPath* pOpAddPathToPath = new OpAddPathToPath;
01674     pOpAddPathToPath->DoAddPathToPath(pNodePath, &EditPath, NodeIndex);
01675 }

PenTool::CC_DECLARE_MEMDUMP PenTool   )  [private]
 

void PenTool::ChangeCursor Cursor cursor  )  [private]
 

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

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
ID of the cursor you want to flip to [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: can fail if the cursor cannot be created - the cursor code will fail.

See also:
-

Definition at line 1492 of file pentool.cpp.

01493 {
01494     // only change if this cursor is different from the current cursor
01495     if (cursor != MyCurrentCursor)
01496     {
01497         // set this cursor as the current cursor and immediately display it
01498         CursorStack::GSetTop(cursor, CurrentCursorID);
01499         // remember this is our current cursor
01500         MyCurrentCursor = cursor;
01501     }
01502 }

void PenTool::ClearInternalState  ) 
 

Clears the internal condition.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 1556 of file pentool.cpp.

01557 {
01558     if (CurrPenState == IS_MoveTo || CurrPenState == IS_DragTo)
01559     {
01560         BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01561         ENSURE(BlobMgr!=NULL, "Blob Manager was not there");
01562         BlobMgr->RenderToolBlobsOff(this, EditHandles.pHndSpread,NULL);
01563     }
01564     CurrPenState = IS_Undefined;
01565 }

void PenTool::ClearOp  ) 
 

Throw away the internal op state we've been holding.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/94
Parameters:
- [INPUTS]

Definition at line 1604 of file pentool.cpp.

01605 {
01606     CurrPenOpState = OS_Undefined;
01607 }

void PenTool::ClearPath  ) 
 

Throw away the internal data of the pen path.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 1585 of file pentool.cpp.

01586 {
01587     // call the path clearing function!
01588 
01589     ClearInternalState();
01590     EditPath.ClearPath();
01591 }

void PenTool::ClickOnEndPoint ClickType  Click,
ClickModifiers  ClickMods,
Spread pSpread,
NodePath pNodePath
[private]
 

An end point click has occured. This function acts on such a click by selecting the point or editing the point dependent on the click type.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/9/94
Parameters:
Click - Describes the type of click that was detected. [INPUTS] ClickMods - Indicates which buttons caused the click and which modifers were pressed at the same time pSpread - the spread in which the click happened pNodePath - The path on which the click happened (current pos set to the point clicked on)
- [OUTPUTS]
Returns:
-

Definition at line 913 of file pentool.cpp.

00914 {
00915     Path* pPath = &(pNodePath->InkPath);
00916 
00917     DocCoord* Coords = pPath->GetCoordArray();
00918     PathFlags* Flags = pPath->GetFlagArray();
00919     PathVerb*  Verbs = pPath->GetVerbArray();
00920     INT32 NumCoords = pPath->GetNumCoords();
00921 
00922     // grab the index of the point actually clicked on!
00923     INT32 Pos = pPath->GetPathPosition();
00924 
00925     // Clicks on control points have no effect
00926     // but clicks on endpoints do have an effect
00927 
00928     switch (Click)
00929     {
00930         case CLICKTYPE_SINGLE:
00931         {
00932             if (Flags[Pos].IsEndPoint)
00933             {
00934                 pPath->RenderPathPenBlobs(pSpread);
00935 
00936                 BOOL CurSelState = Flags[Pos].IsSelected;
00937                 BOOL NewSelState = TRUE;
00938                 BOOL ClearOthers = FALSE;
00939                 
00940                 // if shift held down then toggle the point whatever
00941                 if (ClickMods.Adjust) 
00942                     NewSelState = !CurSelState;
00943 
00944                 // if the end point is not selected and we're not toggling
00945                 if (!CurSelState && !ClickMods.Adjust)
00946                     ClearOthers=TRUE;
00947                     
00948                 if (ClearOthers)
00949                 {
00950                     for (INT32 i=0; i<NumCoords; i++)
00951                     {
00952                         Flags[i].IsSelected = FALSE;
00953                     }
00954                 }
00955 
00956                 // Now change the selection of this point
00957                 Flags[Pos].IsSelected = NewSelState;
00958 
00959                 if ((Pos>0) && (!Flags[Pos-1].IsEndPoint))
00960                     Flags[Pos-1].IsSelected = NewSelState;
00961 
00962                 if ((Pos+1<NumCoords) && (!Flags[Pos+1].IsEndPoint))
00963                     Flags[Pos+1].IsSelected = NewSelState;
00964 
00965                 // Check for this being the first element in a closed subpath
00966                 // If this element is a moveto, and the end of the path has the
00967                 // CLOSEFIGURE flag set, we should select the endpoint as well
00968                 if (Verbs[Pos] == PT_MOVETO)
00969                 {
00970                     // This for loop will find either the end of the path, or the next moveto
00971                     INT32 j;
00972                     for (j=Pos+1;j<NumCoords && Verbs[j] != PT_MOVETO;j++); // ; is intentional!
00973                     j--;
00974                     if (Verbs[j] & PT_CLOSEFIGURE)
00975                     {
00976                         //HandleBlobClick(Coords,Flags,j,NumCoords,TRUE);
00977                         Flags[j].IsSelected = NewSelState;
00978                         // If the previous point is a control point then deal with it
00979                         if ((j>0) && (!Flags[j-1].IsEndPoint))
00980                         {
00981                             // Change the control point's selection state
00982                             Flags[j-1].IsSelected = NewSelState;
00983                         }
00984                     }
00985 
00986                 }
00987 
00988                 pPath->RenderPathPenBlobs(pSpread);
00989             }
00990             break;
00991         }
00992 
00993         case CLICKTYPE_DOUBLE:
00994             break;
00995 
00996         case CLICKTYPE_DRAG:
00997         {
00998             if ((Flags[Pos].IsEndPoint) && (!ClickMods.Menu))
00999             {
01000                 // Need to do a drag on the selected points, so we had better start an operation
01001                 OpNodePathEditBlob* pOpNodePath = new OpNodePathEditBlob;
01002                 if (pOpNodePath == NULL)
01003                     InformError();
01004                 else
01005                     pOpNodePath->DoStartDragEdit(pNodePath, Coords[Pos], pSpread);
01006             }
01007         }
01008         break;
01009 
01010         default:
01011         {
01012         }
01013         break;
01014     }
01015 }

void PenTool::CloseWithPath  ) 
 

Once a drag has finished we need to add the newly edited element to the specified path.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 1694 of file pentool.cpp.

01695 {
01696     // Right, the last drag has closed a path.
01697     // I need to add it in to the specified nodepath object
01698 
01699     OpClosePathWithPath* pOpClosePathWithPath = new OpClosePathWithPath;
01700     pOpClosePathWithPath->DoClosePathWithPath(pNodePath, &EditPath, NodeIndex);
01701 }

void PenTool::CreateNewPath  ) 
 

Once a drag has finished we need to build a new path with the data.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Definition at line 1642 of file pentool.cpp.

01643 {
01644     // Ok, the last drag has altered our internal drag path. We now
01645     // have a path ready to add to the tree, so we need to get on with it!
01646     OpAddNewPath* pOpAddNewPath = new OpAddNewPath;
01647     pOpAddNewPath->DoAddNewPath(&EditPath, EditHandles.pHndSpread);
01648 }

BOOL PenTool::CreatePenCursors  )  [private]
 

Pen tool cursor creation.

BOOL PenTool::CreatePenCursors()

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/9/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 406 of file pentool.cpp.

00407 {
00408     pcPenAdjustCursor = new Cursor(this, _R(IDC_PENADJUSTCURSOR));
00409     if (!pcPenAdjustCursor || !pcPenAdjustCursor->IsValid())
00410     {
00411         DeletePenCursors();
00412         InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
00413         return FALSE;                                        
00414     }
00415 
00416     pcPenCursor = new Cursor(this, _R(IDC_NEWPATHCURSOR));
00417     if (!pcPenCursor || !pcPenCursor->IsValid())
00418     {
00419         DeletePenCursors();
00420         InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
00421         return FALSE;
00422     }
00423 
00424     pcPenReshapeCursor = new Cursor(this, _R(IDC_RESHAPECURSOR));
00425     if (!pcPenReshapeCursor || !pcPenReshapeCursor->IsValid())
00426     {
00427         DeletePenCursors();
00428         InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
00429         return FALSE;                                        
00430     }
00431 
00432     pcMoveBezCursor = new Cursor(this, _R(IDC_MOVEBEZIERCURSOR));
00433     if (!pcMoveBezCursor || !pcMoveBezCursor->IsValid())
00434     {
00435         DeletePenCursors();
00436         InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
00437         return FALSE;
00438     }
00439 
00440     return TRUE;
00441 }

void PenTool::DeletePenCursors  )  [private]
 

Pen tool cursor deletion.

BOOL PenTool::DeletePenCursors()

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/9/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 457 of file pentool.cpp.

00458 {
00459     if (pcPenCursor!=NULL)
00460     {
00461         delete pcPenCursor;
00462         pcPenCursor=NULL;
00463     }
00464     
00465     if (pcPenAdjustCursor!=NULL)
00466     {
00467         delete pcPenAdjustCursor;
00468         pcPenAdjustCursor=NULL;
00469     }
00470 
00471     if (pcPenReshapeCursor!=NULL)
00472     {
00473         delete pcPenReshapeCursor;
00474         pcPenReshapeCursor=NULL;
00475     }
00476 
00477     if (pcMoveBezCursor!=NULL)
00478     {
00479         delete pcMoveBezCursor;
00480         pcMoveBezCursor=NULL;
00481     }
00482 }

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

Allows the tool manager to extract information about the tool.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
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 277 of file pentool.cpp.

00278 {
00279     // Cast structure into the latest one we understand.
00280     ToolInfo_v1 *Info = (ToolInfo_v1 *) InfoPtr;
00281 
00282     Info -> InfoVersion = 1;
00283     
00284     Info -> InterfaceVersion = GetToolInterfaceVersion();  // You should always have this line.
00285         
00286     // These are all arbitrary at present.
00287     Info -> Version = 1;
00288     Info -> ID      = GetID();
00289     Info -> TextID  = _R(IDS_PEN_TOOL);
00290 
00291     Info -> Family  = FamilyName;
00292     Info -> Name    = ToolName;
00293     Info -> Purpose = Purpose;
00294     Info -> Author  = Author;
00295     
00296     Info -> InfoBarDialog = _R(IDD_FREEHANDTOOL);
00297 
00298     Info -> BubbleID = _R(IDBBL_PEN_TOOL);
00299 
00300 }

penclick PenTool::DetermineClickEffect DocCoord  PointerPos,
Spread pSpread,
NodePath **  ReturnNode
 

Used when single clicking. This routine determines what effect a click will have. In this tool, clicking will add a segment to the end of a line, adjust the last element of a path or start a new path entirely.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/9/94
Parameters:
PointerPos is the mouse position [INPUTS] pSpread is a pointer to the spread containing the mouse position
ReturnNode returns a pointer to the node the mouse has clicked on [OUTPUTS]
Returns:
The effect of clicking - one of NewPath, AddSegment, OnPoint or EditInternalMove

Definition at line 752 of file pentool.cpp.

00753 {
00754     penclick WhatToDo = PenNewPath; // tells me what effect the click would have
00755     NodePath* WhichNode = NULL;     // Saves me using a pointer to a pointer
00756 
00757     // Now scan through the selected paths, and see if we've clicked on any endpoints
00758     DocView* pDocView = DocView::GetSelected();
00759     ENSURE( pDocView != NULL, "PenTool::DetermineClickEffect: Can't find selected DocView");
00760     if (pDocView==NULL)
00761         return(PenNewPath);
00762 
00763     // Find the Rect round the mouse pos that counts as a hit
00764     DocRect BlobRect;
00765     OSRenderRegion::GetBlobRect(pDocView->GetViewScale(), PointerPos, BT_SELECTEDLARGEST, &BlobRect);
00766 
00767     // if we're in an internal state and someone has clicked on the moveto
00768     // again then go and edit it.
00769     if (CurrPenState == IS_MoveTo || CurrPenState == IS_DragTo)
00770     {
00771         if (BlobRect.ContainsCoord(EditHandles.HndClick))
00772             return (PenEditInternalMove);
00773     }
00774 
00775 
00776     // Find the selected range of objects
00777     SelRange* Selected = GetApplication()->FindSelection();
00778     Node* pNode = Selected->FindFirst();
00779 
00780     INT32 TotSelectedEndpoints = 0;     // Count selected points in paths
00781     BOOL MultiSegments = FALSE;
00782 
00783     if (pNode != NULL)
00784     {
00785         Spread* NodeSpread = pNode->FindParentSpread();
00786         if (NodeSpread == pSpread)
00787         {
00788             // On the same spread, so see if the pointer is over an endpoint
00789             while ((pNode!=NULL) && ((WhatToDo==PenNewPath) || (WhatToDo==PenAddSegment)))
00790             {
00791                 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodePath))
00792                 {
00793                     // Now we know it's a NodePath, get a pointer to the Path object within it, so
00794                     // we can find any endpoints
00795                     Path* ThisPath = &(((NodePath*)pNode)->InkPath);
00796 
00797                     // count the number of selected points on the path (excluding control points)
00798                     INT32 NumCoords = ThisPath->GetNumCoords();
00799                     PathFlags* Flags = ThisPath->GetFlagArray();
00800 
00801                     // Count selected points in this path
00802                     INT32 NumSelectedEndpoints = 0;     
00803                     INT32 lastsel = 0;
00804                     for (INT32 i=0; i<NumCoords; i++)
00805                     {
00806                         if (Flags[i].IsSelected && Flags[i].IsEndPoint)
00807                         {
00808                             lastsel = i;
00809                             NumSelectedEndpoints++;
00810                         }
00811                     }
00812                     // Sum up
00813                     TotSelectedEndpoints+=NumSelectedEndpoints;
00814 
00815                     INT32 point;
00816                     // First, see if the mouse is over a point.
00817                     if (ThisPath->FindNearestPoint(PointerPos, POINTFLAG_ENDPOINTS | POINTFLAG_ENDSFIRST, &point))
00818                     {
00819                         WhichNode = (NodePath*)pNode;
00820                         WhatToDo = PenOnPoint;
00821                         ThisPath->SetPathPosition(point);
00822 
00823                         // if the mouse was over an open end and the other end of this sub
00824                         // path is selected then we need to close the path
00825                         // find the start and end of the subpath the point was found in
00826                         INT32 start = point;
00827                         INT32 end = point;
00828                         ThisPath->FindStartOfSubPath(&start);
00829                         ThisPath->FindEndElOfSubPath(&end);
00830                         if (point==start || point==end)
00831                         {
00832                             INT32 other;
00833                             (point==start) ? (other=end) : (other=start);
00834                             if ((Flags[other].IsSelected) && (!Flags[point].IsSelected))
00835                                 WhatToDo = PenClosePath;
00836                         }
00837                         continue;
00838                     }
00839 
00840                     // if the mouse is close to an element, then it might be close
00841                     // enough to reshape the line
00842                     if (ThisPath->PointCloseToLine(PointerPos, &point))
00843                     {
00844                         WhichNode=(NodePath*)pNode;
00845                         WhatToDo=PenReshapeLine;
00846                         ThisPath->SetPathPosition(point);
00847                         continue;
00848                     }
00849 
00850                     if (!MultiSegments && NumSelectedEndpoints==1)
00851                     {
00852                         INT32 start = lastsel;
00853                         INT32 end = lastsel;
00854                         ThisPath->FindStartOfSubPath(&start);
00855                         ThisPath->FindEndElOfSubPath(&end);
00856                         if (lastsel==start || lastsel==end)
00857                         {
00858                             if (WhatToDo==PenNewPath)
00859                             {   
00860                                 WhichNode=(NodePath*)pNode;
00861                                 WhatToDo=PenAddSegment;
00862                                 ThisPath->SetPathPosition(lastsel);
00863                             }
00864                             else
00865                             {
00866                                 // We have more than one path with a selected end point.
00867                                 // Adding elements is ambiguous so force a NewPath creation
00868                                 WhichNode=(NodePath*)pNode;
00869                                 WhatToDo=PenNewPath;
00870                                 MultiSegments=TRUE;
00871                             }
00872                         }
00873                     }
00874                 }
00875                 // Now find the next selected node
00876                 pNode = Selected->FindNext(pNode);
00877             }
00878         }
00879     }
00880 
00881     // WhatToDo tells us what the action will be
00882     // WhichNode points to the node we are dealing with
00883     // PathPosition is the index into that path of the element we are using
00884 
00885     *ReturnNode = WhichNode;
00886     return (WhatToDo);
00887 }

void PenTool::GenerateStatusLineText NodePath pNodePath,
penclick  WhatToDo,
String_256 pStatusMsg
 

Loads up an appropriate help string into the text buffer pointed to by pStatusMsg, using the nodepath and 'whattodo' information passed.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
05/01/95
Parameters:
pNodePath = pointer to a node path the mouse is over [INPUTS] (can be NULL) WhatToDo = what action to be taken (return param of DetermineClickEffect) pStatusMsg = pointer to a 256 character text buffer
pStatusMsg - holds a text string [OUTPUTS]
Returns:
-

Errors: -

Definition at line 1200 of file pentool.cpp.

01201 {
01202     switch (WhatToDo)
01203     {
01204         case PenNewPath:
01205             switch(CurrPenState)
01206             {
01207                 case IS_MoveTo:
01208                     pStatusMsg->Load(_R(IDS_PENADDPOINT), Tool::GetModuleID(GetID()));  
01209                     break;
01210                 case IS_DragTo:
01211                     pStatusMsg->Load(_R(IDS_PENADDCURVE), Tool::GetModuleID(GetID()));  
01212                     break;
01213                 default:
01214                     pStatusMsg->Load(_R(IDS_PENNEWPATH), Tool::GetModuleID(GetID()));
01215                     break;
01216             }
01217             break;
01218 
01219         case PenAddSegment:
01220             if (pNodePath != NULL)
01221             {
01222                 PathVerb  Verb  = (pNodePath->InkPath).GetVerb();
01223                 PathFlags Flags = (pNodePath->InkPath).GetFlags();
01224                 switch (Verb)
01225                 {
01226                     case PT_BEZIERTO:
01227                         if (Flags.IsRotate)
01228                             pStatusMsg->Load(_R(IDS_PENADDCURVE), Tool::GetModuleID(GetID()));
01229                         else
01230                             pStatusMsg->Load(_R(IDS_PENADDPOINT), Tool::GetModuleID(GetID()));
01231                         break;
01232                     default:
01233                         pStatusMsg->Load(_R(IDS_PENADDPOINT), Tool::GetModuleID(GetID()));
01234                         break;
01235                 }
01236             }
01237             else
01238                 pStatusMsg->Load(_R(IDS_PENADDPOINT), Tool::GetModuleID(GetID()));
01239             break;
01240 
01241         case PenEditInternalMove: 
01242             pStatusMsg->Load(_R(IDS_PENEDITINT), Tool::GetModuleID(GetID()));
01243             break;
01244             
01245         case PenClosePath:
01246             pStatusMsg->Load(_R(IDS_PENCLOSEPATH), Tool::GetModuleID(GetID()));
01247             break;
01248 
01249         case PenReshapeLine:
01250             pStatusMsg->Load(_R(IDS_RESHAPE_LINE),Tool::GetModuleID(GetID()));
01251             break;
01252 
01253         case PenOnPoint:
01254             if (pNodePath != NULL)
01255             {
01256                 PathFlags Flags = (pNodePath->InkPath).GetFlags();
01257                 if (Flags.IsSelected)
01258                     pStatusMsg->Load(_R(IDS_PENONSELPOINT), Tool::GetModuleID(GetID()));
01259                 else
01260                     pStatusMsg->Load(_R(IDS_PENONPOINT), Tool::GetModuleID(GetID()));
01261             }
01262             break;
01263             
01264         default:
01265             pStatusMsg->Load(_R(IDS_PENADDPOINT), Tool::GetModuleID(GetID()));
01266             break;
01267     }
01268 }

UINT32 PenTool::GetID void   )  [inline, virtual]
 

Reimplemented from Tool_v1.

Definition at line 169 of file pentool.h.

00169 { return TOOLID_PEN; };

penopstate PenTool::GetPenOpState  )  const
 

return the operation state the pen tool thinks its in.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/9/94
Parameters:
- [INPUTS]

Definition at line 1621 of file pentool.cpp.

01622 {
01623     return (CurrPenOpState);
01624 }

BOOL PenTool::GetStatusLineText String_256 ptext,
Spread pSpread,
DocCoord  coord,
ClickModifiers  mods
[virtual]
 

generate up-to-date text for the status line (called on idles)

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
05/01/95
Parameters:
pSpread - pointer to spread under mouse (else NULL) [INPUTS] DocPos - position of mouse in doc (in spread coords) ClickMods - mouse click modifiers
ptext - text for status line [OUTPUTS]
Returns:
TRUE if outputting valid text

Errors: ERROR3 if ptext is NULL

Reimplemented from Tool_v1.

Definition at line 1161 of file pentool.cpp.

01162 {
01163     ERROR1IF(ptext==NULL,FALSE,"PenTool::GetStatusLineText() passed a NULL text buffer");
01164 
01165     *ptext = "";
01166 
01167     NodePath* pNodePath = NULL;
01168 
01169     // find what type of click we will generate
01170     penclick WhatToDo = DetermineClickEffect(coord, pSpread, &pNodePath);
01171     GenerateStatusLineText(pNodePath, WhatToDo, ptext);
01172 
01173     return TRUE;
01174 }

BOOL PenTool::Init void   )  [virtual]
 

Used to check if the Tool was properly constructed.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/9/94
Returns:
FALSE if it does not want to be created, TRUE otherwise
See also:
PenTool::PenTool

Reimplemented from Tool_v1.

Definition at line 204 of file pentool.cpp.

00205 {
00206 
00207     BOOL                    ok;
00208     CCResTextFile           file;               // Resource File
00209     PenToolInfoBarOpCreate  BarCreate;          // Object that creates PenInfoBarOp objects
00210 
00211     // This should be set to NULL by default. It will be set properly below, if
00212     // everthing is working as it should
00213     pPenInfoBarOp = NULL;
00214 
00215     // initially, no cursor
00216     pcPenCursor = 0;
00217 
00218     pPenInfoBarOp = new PenToolInfoBarOp();
00219     ok = (pPenInfoBarOp != NULL);
00220     if (ok) pPenInfoBarOp->pPenTool = this;             // Set a pointer from the op to this tool
00221 
00222 #if 0
00223         ok = file.open(_R(IDM_PENTOOL_BAR), _R(IDT_INFO_BAR_RES));          // Open resource
00224     if (ok) ok = DialogBarOp::ReadBarsFromFile(file,BarCreate);     // Read and create info bar
00225     if (ok) file.close();                                           // Close resource.
00226 
00227     ENSURE(ok,"Unable to load penbar.ini from resource\n"); 
00228 
00229     if (ok)
00230     {
00231         // Info bar now exists.  Now get a pointer to it
00232         String_32 str = String_32(_R(IDS_PENTOOL_INFOBARNAME));
00233         DialogBarOp* pDialogBarOp = DialogBarOp::FindDialogBarOp(str);
00234 
00235                 ok = (pDialogBarOp != NULL);
00236         if (ok) ok = pDialogBarOp->IsKindOf(CC_RUNTIME_CLASS(PenToolInfoBarOp));
00237         if (ok) pPenInfoBarOp = (PenToolInfoBarOp*)pDialogBarOp;
00238         if (ok) pPenInfoBarOp->pPenTool = this;             // Set a pointer from the op to this tool
00239 
00240         ENSURE(ok,"Failed to create PENTOOL info bar");
00241     }
00242 #endif
00243 
00244     if (ok) ok = EditPath.Initialise(12,24);                // create the edit path buffers please
00245 
00246     // Register our pen operation(s).
00247     if (ok)
00248     {
00249         ok = OpPenCreateInternal::Init();
00250         if (ok) ok = OpPenEditInternal::Init();
00251         if (ok) ok = OpPenCreatePath::Init();
00252         if (ok) ok = OpPenAddElement::Init();
00253         if (ok) ok = OpAddNewPath::Init();
00254         if (ok) ok = OpPenClosePath::Init();
00255     }
00256 
00257     return ok;
00258 
00259 }

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

To handle a Mouse Click event for the Pen Tool.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> (via Rik)
Date:
20/9/94
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 Tool_v1.

Definition at line 592 of file pentool.cpp.

00594 {
00595     if (ClickMods.Menu) return;                         // Don't do anything if the user clicked the Menu button
00596 
00597     // determine what to do with this click
00598     penclick WhatToDo = DetermineClickEffect(PointerPos, pSpread, &pNodePath);
00599 
00600     // if someones holding the adjust down and we're not on a point then clear the sel
00601     if (Click==CLICKTYPE_SINGLE && ClickMods.Adjust && WhatToDo!=PenOnPoint)
00602     {
00603         RemoveSelection(PointerPos,pSpread);
00604         ClearInternalState();   
00605         return;
00606     }
00607 
00608     switch (Click)
00609     {
00610         case CLICKTYPE_SINGLE:
00611             switch (WhatToDo)
00612             {
00613                 case PenNewPath:
00614                 {
00615                     BOOL MakeInternal = TRUE;
00616                     if ((CurrPenState == IS_MoveTo) || (CurrPenState == IS_DragTo))
00617                     {
00618                         // create a new path using the internal data points.
00619                         // If LastDragTo==LastMoveTo, then the internal is a point,
00620                         // else a curve control end exists.
00621                         if (EditHandles.pHndSpread==pSpread)
00622                         {
00623                             MakeInternal = FALSE;
00624                             OpPenCreatePath* pOpCreatePath = new OpPenCreatePath;
00625                             if (pOpCreatePath!=NULL)
00626                             {
00627                                 pOpCreatePath->DoPenCreatePath(&EditHandles, PointerPos, pSpread, &EditPath);
00628                                 CurrPenOpState = OS_CreatePath;
00629                             }
00630                         }
00631                     }
00632                     
00633                     if (MakeInternal)
00634                     {
00635                         // First remove any selected points in the spread and create an
00636                         // internal move or dragto
00637                         RemoveSelection(PointerPos,pSpread);
00638                         OpPenCreateInternal* pOpCreateInternal = new OpPenCreateInternal;
00639                         if (pOpCreateInternal!=NULL)
00640                         {
00641                             pOpCreateInternal->DoPenCreateInternal(PointerPos, pSpread, &EditHandles);
00642                             CurrPenOpState = OS_EditInternal; 
00643                         }
00644                     }
00645                 }
00646                 break;
00647 
00648                 case PenClosePath:
00649                     {
00650                         NodeIndex = pNodePath->InkPath.GetPathPosition();
00651                         OpPenClosePath* pOpPenClosePath = new OpPenClosePath;
00652                         if (pOpPenClosePath!=NULL)
00653                         {
00654                             pOpPenClosePath->DoPenClosePath(pNodePath, NodeIndex, pSpread, &EditPath);
00655                             CurrPenOpState = OS_ClosePath;
00656                         }
00657                     }
00658                     break;
00659 
00660                 case PenOnPoint:
00661                     {
00662                         // Ordinary click from OnPoint
00663                         // Currently this does not work correctly because of eor'ing. The wrong
00664                         // Eor blobs get put on by the node path click handler 
00665                         RemoveSelection(PointerPos,pSpread,pNodePath);
00666                         ClickOnEndPoint(Click, ClickMods, pSpread, pNodePath);
00667                     }
00668                     break;
00669 
00670                 case PenAddSegment:
00671                     {
00672                         NodeIndex = pNodePath->InkPath.GetPathPosition();
00673                         OpPenAddElement* pOpPenAddElement = new OpPenAddElement;
00674                         if (pOpPenAddElement!=NULL)
00675                         {
00676                             pOpPenAddElement->DoPenAddElement(pNodePath, NodeIndex, PointerPos, pSpread, &EditPath);
00677                             CurrPenOpState = OS_AddElement;
00678                         }
00679                     }
00680                     break;
00681 
00682                 case PenEditInternalMove:
00683                     {
00684                         OpPenEditInternal* pOpEditInternal = new OpPenEditInternal;
00685                         if (pOpEditInternal!=NULL)
00686                         {
00687                             pOpEditInternal->DoPenEditInternal(&EditHandles);
00688                             CurrPenOpState = OS_EditInternal;
00689                         }
00690                     }
00691                     break;
00692                
00693                case PenReshapeLine:
00694                     {
00695                         double pdist;
00696                         INT32 tempel;
00697                         pNodePath->InkPath.SqrDistanceToPoint(PointerPos, &tempel, &pdist);
00698                         INT32 PathPos = pNodePath->InkPath.GetPathPosition();
00699 
00700                         OpReshapeOrAddPoint* pOpReshape = new OpReshapeOrAddPoint;
00701                         if (pOpReshape!=NULL)
00702                             pOpReshape->DoStartDragEdit(pNodePath, PointerPos, pSpread, PathPos, pdist);
00703                         else
00704                             InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) );
00705                     }
00706                     break;
00707 
00708             }
00709             break;
00710 
00711         case CLICKTYPE_DOUBLE:
00712             break;
00713 
00714         case CLICKTYPE_DRAG:
00715             switch (WhatToDo)
00716             {
00717                 case PenOnPoint:
00718                     if (pNodePath)
00719                         ClickOnEndPoint(Click, ClickMods, pSpread, pNodePath);
00720                     break;
00721 
00722                 default:
00723                     break;
00724             }
00725             break;
00726 
00727         default:
00728             break;
00729     }
00730 
00731 }

BOOL PenTool::OnKeyPress KeyPress pKeyPress  )  [virtual]
 

To handle keypress events for the Pen Tool. If it is a keypress that it know about it starts up an appropiate operation. THIS IS BADLY WRONG AT THE MOMENT - WHEN THERE IS THE TECHNOLOGY FOR USER DEFINABLE KEY-SHORTCUTS THIS FUNCTION WILL NEED FIXING.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/08/94
Parameters:
pKeyPress - pointer to a keypress object [INPUTS]
Returns:
TRUE if it handled the keypress, FALSE otherwise

Reimplemented from Tool_v1.

Definition at line 1034 of file pentool.cpp.

01035 {
01036     // We don't want to know about key release events
01037     if (pKeyPress->IsRelease())
01038         return FALSE;
01039 
01040     // If ESCAPE is pressed then clear the floating endpoint, but don't claim the keypress
01041     // so the selection is also cleared.
01042     if (*pKeyPress == KeyPress(CAMKEY(ESCAPE)))
01043     {
01044         if ((CurrPenState == IS_MoveTo) || (CurrPenState == IS_DragTo))
01045         {
01046             ClearInternalState();
01047             return TRUE;
01048         }
01049     }
01050 
01051     // break at points op key short cut.
01052     if (*pKeyPress == KeyPress(CAMKEY(B)))
01053     {
01054         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpBreakAtPoints));
01055         String_256  UIDesc;
01056         if (pOpDesc != NULL)
01057         {
01058             OpState State = OpBreakAtPoints::GetState(&UIDesc, pOpDesc);
01059             if (!State.Greyed)
01060             {
01061                 pOpDesc->Invoke();
01062                 return TRUE;
01063             }
01064         }
01065     } 
01066 
01067     // if delete pressed, try to delete the selected points in this path
01068     if ((pKeyPress->GetVirtKey() == CAMKEY(DELETE)) || (*pKeyPress == KeyPress(CAMKEY(BACK))) ) 
01069     {
01070         OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpDeletePoints));
01071         String_256 UIDesc;
01072         if (pOpDesc != NULL)
01073         {
01074             OpState State = OpDeletePoints::GetState(&UIDesc, NULL);
01075             if (!State.Greyed)
01076             {
01077                 pOpDesc->Invoke();
01078                 return TRUE;
01079             }
01080         }
01081     } 
01082 
01083     // If we get this far then the keypress wasn't handled
01084     return FALSE;
01085 }

void PenTool::OnMouseMove DocCoord  coord,
Spread pSpread,
ClickModifiers  mods
[virtual]
 

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

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
coord - The DocCoord of the point where the mouse has moved to [INPUTS] pSpread - The spread in which the move occurred mods - which buttons/keys are down
- [OUTPUTS]
Returns:
-

Errors: -

See also:
-

Reimplemented from Tool_v1.

Definition at line 1107 of file pentool.cpp.

01108 {
01109     NodePath* pNodePath = NULL;
01110     Cursor* whichCursor = NULL;
01111 
01112     // find what type of click we will generate
01113     penclick WhatToDo = DetermineClickEffect(coord, pSpread, &pNodePath);
01114 
01115     String_256 StatusMsg("");
01116     GenerateStatusLineText(pNodePath, WhatToDo, &StatusMsg);
01117     GetApplication()->UpdateStatusBarText(&StatusMsg);
01118 
01119     switch (WhatToDo)
01120     {
01121         case PenNewPath:
01122         case PenAddSegment:
01123         case PenEditInternalMove: 
01124             whichCursor = pcPenCursor;
01125             break;
01126         case PenOnPoint:
01127             whichCursor = pcMoveBezCursor;
01128             break;
01129         case PenClosePath:
01130             whichCursor = pcPenAdjustCursor;
01131             break;
01132         case PenReshapeLine:
01133             whichCursor = pcPenReshapeCursor;
01134             break;
01135         default:
01136             whichCursor = pcPenCursor;
01137     }
01138     ChangeCursor(whichCursor);
01139 }

BOOL PenTool::OverPathEnd DocCoord  ,
Spread ,
NodePath ** 
 

void PenTool::RemoveSelection DocCoord  PointerPos,
Spread pSpread,
NodePath pNodePath = NULL
 

This routine scans the specified spread for all path objects and checks whether the mouse coord is over an open end point. It can be used to work out whether to change the mouse shape or not. This routine should really exist in some other file, available to all tools but I dont know where to put it yet so it shall have to stay here for the mo.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/10/94
Parameters:
PointerPos = The position of the mouse click [INPUTS] pSpread = The spread that the occured on pNodePath = A pointer to a particular node path to leave out (defaults to NULL)

Definition at line 1358 of file pentool.cpp.

01359 {                                                                   
01360     // deselect any points within the spread the click occured over
01361     SelRange* Selected = GetApplication()->FindSelection();
01362     Node* pNode = Selected->FindFirst();
01363     if (pNode && pNode->FindParentSpread() == pSpread )
01364     {
01365         while (pNode)
01366         {
01367             if (pNode!=pNodePath)
01368             {
01369                 if (pNode->GetRuntimeClass() == CC_RUNTIME_CLASS(NodePath))
01370                 {
01371                     Path* ThisPath = &(((NodePath*)pNode)->InkPath);
01372                     PathFlags* Flags = ThisPath->GetFlagArray();
01373                     INT32 UsedSlots = ThisPath->GetNumCoords();
01374 
01375                     BOOL selected = FALSE;
01376                     for (INT32 i=0; i<UsedSlots; i++)
01377                     {
01378                         if (Flags[i].IsSelected)
01379                         {
01380                             if (!selected)
01381                             {
01382                                 // right, red selection blobs off!
01383                                 ThisPath->RenderPathPenBlobs(pSpread);
01384                                 selected = TRUE;
01385                             }
01386                             Flags[i].IsSelected=FALSE;
01387                         }
01388                     }
01389                     // now, black selection blobs back on!
01390                     if (selected)
01391                         ThisPath->RenderPathPenBlobs(pSpread);
01392                 }
01393             }
01394             pNode = Selected->FindNext(pNode);
01395         }
01396     }
01397 }

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

The blobs this tool renders are (1) a moveto floating endpoint (2) a dragto floating endpoint These are usually rendered after the first click/drag on a document.

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

Reimplemented from Tool_v1.

Definition at line 1417 of file pentool.cpp.

01418 {
01419     // Can only draw the path if there is a path to draw
01420     ERROR3IF(pSpread==NULL,"PenTool::RenderToolBlobs() called with a null spread");
01421 
01422     RenderRegion* pRegion;
01423     DocCoord LastMove = EditHandles.HndClick;
01424     DocCoord LastDrag = EditHandles.HndDrag;
01425 
01426     switch (CurrPenState)
01427     {
01428         case IS_MoveTo:
01429             pRegion = DocView::RenderOnTop(pClipRect, pSpread, ClippedEOR);
01430             while (pRegion)
01431             {
01432                 // Draw a moveto blob
01433                 pRegion->SetLineColour(COLOUR_BEZIERBLOB);
01434                 pRegion->SetFillColour(COLOUR_TRANS);
01435                 pRegion->DrawBlob(LastMove,BT_SELECTED);
01436                 
01437                 // Get the next region in the list
01438                 pRegion = DocView::GetNextOnTop(pClipRect);
01439             }
01440             break;
01441 
01442         case IS_DragTo:
01443             {
01444                 pRegion = DocView::RenderOnTop(pClipRect, pSpread, ClippedEOR);
01445                 DocCoord OtherDrag;
01446                 OtherDrag.x = LastMove.x - (LastDrag.x - LastMove.x);
01447                 OtherDrag.y = LastMove.y - (LastDrag.y - LastMove.y);
01448     
01449                 while (pRegion)
01450                 {
01451                     // Draw three end blobs and an eor'd dotted line
01452                     pRegion->SetLineColour(COLOUR_BEZIERLINE);
01453                     pRegion->DrawLine(OtherDrag,LastDrag);
01454                     pRegion->SetLineColour(COLOUR_BEZIERBLOB);
01455                     pRegion->SetFillColour(COLOUR_TRANS);
01456                     pRegion->DrawBlob(LastMove,BT_SELECTED);
01457                     pRegion->SetFillColour(COLOUR_UNSELECTEDBLOB);
01458                     pRegion->SetLineColour(COLOUR_TRANS);
01459                     pRegion->DrawBlob(LastDrag,BT_UNSELECTED);
01460                     pRegion->DrawBlob(OtherDrag,BT_UNSELECTED);
01461     
01462                     // Get the next region in the list
01463                     pRegion = DocView::GetNextOnTop(pClipRect);
01464                 }
01465                 break;
01466             }
01467         default:
01468             break;
01469     }   
01470 }

void PenTool::SelectChange BOOL  isSelected  )  [virtual]
 

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

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Errors: Sends warning to debugging terminal if creating the cursor fails.

See also:
-

Reimplemented from Tool_v1.

Definition at line 319 of file pentool.cpp.

00320 {
00321     if (isSelected)
00322     {
00323         // This tool has just been selected.  Create an appropriate cursor, and push it
00324         // onto the top of the cursor stack so it'll appear when the pointer moves into
00325         // our window.
00326 
00327         MyCurrentCursor = NULL;
00328 
00329         if (!CreatePenCursors())
00330             return;
00331 
00332         CurrentCursorID = CursorStack::GPush(pcPenCursor, FALSE);       // Push, but don't display now
00333         MyCurrentCursor = pcPenCursor;
00334         
00335         // Create and display my info bar please
00336         if (pPenInfoBarOp != NULL)
00337             pPenInfoBarOp->Create();
00338 
00339             // Which blobs do I want displayed
00340         BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00341         if (BlobMgr != NULL)
00342         {
00343             // Decide which blobs we will display
00344             BlobStyle MyBlobs;
00345             MyBlobs.Pen = TRUE;
00346 
00347             // Tell the blob manager
00348             BlobMgr->ToolInterest(MyBlobs);
00349         }
00350 
00351         // Now set some local variables so we know what state we are
00352         // in to start with
00353         CurrPenState = IS_Undefined;
00354 
00355         // alias the delete function to delete points.
00356         // OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_DELETE);  
00357         // pOpDesc->AliasOperation(CC_RUNTIME_CLASS(OpDeletePoints),OpDeletePoints::GetState,0);  
00358 
00359         // remove the alias to the delete function
00360         // OpDescriptor* pOpDesc = OpDescriptor::FindOpDescriptor(OPTOKEN_DELETE);  
00361         // pOpDesc->RemoveAlias();
00362     }
00363     else
00364     {
00365         // Deselection - destroy the tool's current cursor, if there is one.
00366         if (MyCurrentCursor)
00367         {
00368             CursorStack::GPop(CurrentCursorID);
00369             MyCurrentCursor = NULL;
00370             CurrentCursorID = 0;
00371         }
00372         DeletePenCursors();
00373 
00374         // Hide and destroy my info bar please
00375         if (pPenInfoBarOp != NULL)
00376             pPenInfoBarOp->Delete();
00377 
00378         // ensure any tool object blobs are removed.
00379         BlobManager* BlobMgr = GetApplication()->GetBlobManager();
00380         if (BlobMgr != NULL)
00381         {
00382             BlobStyle bsRemoves;
00383             bsRemoves.ToolObject = TRUE;
00384             BlobMgr->RemoveInterest(bsRemoves);
00385         }
00386 
00387         ClearInternalState();
00388     }
00389 }

void PenTool::SetInternalState  ) 
 

This function is called from an operation which tells the tool that there should be a virtual moveto coordinate and dragto coordinate set within the tool. If the dragto is equal to the moveto, then an internal move should be created, rather than an internal drag.

Author:
Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 1523 of file pentool.cpp.

01524 {
01525     // Check that the handles are actually defined.
01526     if (EditHandles.pHndSpread==NULL)
01527         return;
01528 
01529     if (EditHandles.HndClick == EditHandles.HndDrag)
01530         CurrPenState = IS_MoveTo;
01531     else
01532         CurrPenState = IS_DragTo;
01533 
01534     // Now display the blobs
01535     BlobManager* BlobMgr = GetApplication()->GetBlobManager();
01536     ENSURE(BlobMgr!=NULL, "Blob Manager was not there");
01537     BlobMgr->RenderToolBlobsOn(this, EditHandles.pHndSpread, NULL);
01538 
01539 }


Member Data Documentation

TCHAR * PenTool::Author = _T("Mike") [static, private]
 

Definition at line 203 of file pentool.h.

INT32 PenTool::CurrentCursorID [private]
 

Definition at line 221 of file pentool.h.

penopstate PenTool::CurrPenOpState [private]
 

Definition at line 206 of file pentool.h.

penstate PenTool::CurrPenState [private]
 

Definition at line 205 of file pentool.h.

ControlPts PenTool::EditHandles [private]
 

Definition at line 209 of file pentool.h.

Path PenTool::EditPath [private]
 

Definition at line 208 of file pentool.h.

TCHAR * PenTool::FamilyName = _T("Drawing Tools") [static, private]
 

Definition at line 200 of file pentool.h.

Cursor* PenTool::MyCurrentCursor [private]
 

Definition at line 219 of file pentool.h.

INT32 PenTool::NodeIndex [private]
 

Definition at line 212 of file pentool.h.

Cursor* PenTool::pcMoveBezCursor [private]
 

Definition at line 218 of file pentool.h.

Cursor* PenTool::pcPenAdjustCursor [private]
 

Definition at line 216 of file pentool.h.

Cursor* PenTool::pcPenCursor [private]
 

Definition at line 215 of file pentool.h.

Cursor* PenTool::pcPenReshapeCursor [private]
 

Definition at line 217 of file pentool.h.

NodePath* PenTool::pNodePath [private]
 

Definition at line 211 of file pentool.h.

PenToolInfoBarOp* PenTool::pPenInfoBarOp [private]
 

Definition at line 225 of file pentool.h.

TCHAR * PenTool::Purpose = _T("To draw lines and curves") [static, private]
 

Definition at line 202 of file pentool.h.

TCHAR * PenTool::ToolName = _T("Pen Tool") [static, private]
 

Definition at line 201 of file pentool.h.


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