#include <beztool.h>
Inheritance diagram for BezierTool:

Public Types | |
| enum | CurrentMode { New, Add, Change } |
Public Member Functions | |
| BezierTool () | |
| Dump Constructor - It does nothing. All the real initialisation is done in BezierTool::Init which is called by the Tool Manager. | |
| ~BezierTool () | |
| 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. | |
| void | OnClick (DocCoord, ClickType, ClickModifiers, Spread *) |
| To handle a Mouse Click event for the Bezier Tool. It starts up a Bezier Operation. | |
| virtual void | RenderToolBlobs (Spread *, DocRect *) |
| Renders the Tools Blobs. The only blob this tool renders is the floating endpoint which only appears the the flag is set. | |
| void | HandleInfoBarMessage (CDlgMessage DlgMsg, CGadgetID Gadget) |
| 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:. | |
| BOOL | OnKeyPress (KeyPress *) |
| To handle keypress events for the Bezier 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 | SetMoveTo (DocCoord MovePos, Spread *pSpread, Document *pDoc) |
| This function is called from an operation which tells the tool that there should be a virtual moveTo coordinate at the given point. This virtual coordinate looks much like the old single moveto used to in ArtWorks, with the added advantage that it doesn't really exist, so it can't cock up the tree like they used to do in ArtWorks. | |
| void | ClearMoveTo () |
| Clears the floating endpoint condition. | |
| BOOL | GetMoveTo (Spread **ppSpread, DocCoord *pCoord, Document **ppDoc) |
| Read the state of the floating endpoint. | |
| void | SetModeFlag () |
| Sets the current tool mode (new/add/change) and gets the infobar to redraw the text item that shows it. We are in New mode if there are no selected lines. We are in Add mode if there is just one endpoint on the end od a path selected. Otherwise we are in Change mode. | |
| BOOL | GetStatusLineText (String_256 *ptext, Spread *pSpread, DocCoord DocPos, ClickModifiers ClickMods) |
| generate up-to-date text for the status line (called on idles) | |
| void | GenerateStatusLineText (String_256 *ptext, Spread *pSpread, DocCoord DocPos, ClickModifiers ClickMods) |
| To find the string to display on the status line given the current mouse position. | |
Protected Member Functions | |
| BOOL | CyclePathPoints (BOOL Fowards) |
| Performs the cycle the selected points task. The selection status of each endpoint on selected paths is applied to the next endpoint. | |
| BOOL | HomePathPoints () |
| Moves the selected endpoints back along the selected path(s) so that the first point is selected. The pattern of selection remains the same. | |
| BOOL | EndPathPoints () |
| Moves the selected endpoints foward along the selected path(s) so that the last point is selected. The pattern of selection remains the same. | |
| BOOL | AutoClosePaths () |
| Runs through all selected lines. If the path is open and either of the ends are selected then the path is closed. | |
| void | RemoveFloater (DocCoord *FloatPos, Spread *FloatSpread, Document *pDoc) |
| Invokes the operation to remove the floating endpoint. | |
| void | RetroSmoothChanging (double Smooth) |
| Scan the selection for a path to smooth. If we find only one path object selected then we should tell the retro smooth code to begin smoothing. Arh!, actually we need to be able to keep track of the selected object? possibly.... Surely its fast enough already to find the selected objects, there must be some caching going on somewhere. Ok, best thing to do is to make sure theres only one selected object and ignore the slider change if there isn't. | |
| void | RetroSmoothFinished () |
| Calls the retro smooth finalisation code to perform the completed smoothing action. | |
| void | RetroSmoothSet (INT32 percent, BOOL Enabled) |
| Set the position of the retro smooth slider, given a percentage value. The function will also update the percent text field. | |
| void | RetroSmoothInvalidate () |
| Invalidate the retro smooth cached information. | |
| void | UpdateRetroSlider (Path *pPath) |
| Sets the retro smooth slider position for a given path. | |
| void | ResetRetroSlider () |
| There has been a change in the selection so we need to update the retro slider state. | |
| Node * | OneNodePathSelected () |
| Checks the selection and determins whether exactly one nodepath object is selected. | |
| 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. | |
| clickeffect | DetermineClickEffect (DocCoord PointerPos, Spread *pSpread, NodeRenderableInk **ReturnNode, INT32 *ReturnPosition, INT32 *NumSelectedPaths, INT32 *NumSelectedPoints) |
| Used when the cursor moves and when single clicking. This routine determines what effect a click will have. In this tool, clicking will either select a point on an already selected line, reshape a line segment (a la Corel), add a segment to the end of a line, or start a new path entirely. | |
| NodePath * | FindEditablePath (Node *pSelected) |
| Finds the node to edit (if it exists). This node could actually be the selected node passed as a parameter or one of its children which the node wants to be editable. | |
Protected Attributes | |
| DocCoord | StartPos |
| Spread * | StartSpread |
| Cursor * | pcMoveBezCursor |
| Cursor * | pcReshapeLineCursor |
| Cursor * | pcNewPathCursor |
| Cursor * | pcAddPathCursor |
| Cursor * | pcClosePathCursor |
| Cursor * | MyCurrentCursor |
| INT32 | CurrentCursorID |
| BOOL | FloatingEndpoint |
| Document * | MoveToDoc |
| DocCoord | MoveToPoint |
| Spread * | MoveToSpread |
| RetroSmooth * | pSmooth |
| BOOL | RetroFlag |
| Node * | pRetroNode |
| Spread * | pRetroSpread |
| BOOL | DontDrawOnClearMoveTo |
| CurrentMode | CurrentToolMode |
Static Protected Attributes | |
| static TCHAR * | FamilyName = _T("Drawing Tools") |
| static TCHAR * | ToolName = _T("Bezier Tool") |
| static TCHAR * | Purpose = _T("To Draw arbitrary lines") |
| static TCHAR * | Author = _T("Jim (latterly Peter)") |
| static BezToolInfoBarOp * | pBezToolInfoBarOp = NULL |
| static BOOL | CreateCurve = TRUE |
| static BOOL | CreateCusp = FALSE |
Private Member Functions | |
| CC_DECLARE_MEMDUMP (BezierTool) | |
Friends | |
| class | BezToolInfoBarOp |
Definition at line 242 of file beztool.h.
|
|
Definition at line 250 of file beztool.h.
|
|
|
Dump Constructor - It does nothing. All the real initialisation is done in BezierTool::Init which is called by the Tool Manager.
Definition at line 197 of file beztool.cpp. 00198 { 00199 StartSpread = NULL; 00200 FloatingEndpoint = FALSE; 00201 MoveToDoc = NULL; 00202 MoveToSpread = NULL; 00203 pSmooth = NULL; 00204 RetroFlag = FALSE; 00205 DontDrawOnClearMoveTo = FALSE; 00206 CurrentToolMode = New; 00207 }
|
|
|
Destructor (Virtual). Does nothing.
Definition at line 221 of file beztool.cpp. 00222 { 00223 // Destroy any resident retro smooth object 00224 if (pSmooth != NULL) 00225 { 00226 delete pSmooth; 00227 pSmooth = NULL; 00228 } 00229 00230 pBezToolInfoBarOp->pBezTool = NULL; 00231 }
|
|
|
Runs through all selected lines. If the path is open and either of the ends are selected then the path is closed.
Definition at line 4363 of file beztool.cpp. 04364 { 04365 OpState Calcium = OpCloseNodePaths::GetState(NULL, NULL); 04366 04367 if (!Calcium.Greyed) 04368 { 04369 OpParam Param(CreateCurve, !CreateCusp); 04370 OpDescriptor* Apple = OpDescriptor::FindOpDescriptor(CC_RUNTIME_CLASS(OpCloseNodePaths)); 04371 if (Apple != NULL) 04372 Apple->Invoke(&Param); 04373 } 04374 04375 return TRUE; 04376 }
|
|
|
|
|
|
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 1472 of file beztool.cpp. 01473 { 01474 // only change if this cursor is different from the current cursor 01475 if (cursor != MyCurrentCursor) 01476 { 01477 // set this cursor as the current cursor and immediately display it 01478 CursorStack::GSetTop(cursor, CurrentCursorID); 01479 // remember this is our current cursor 01480 MyCurrentCursor = cursor; 01481 } 01482 01483 }
|
|
|
Clears the floating endpoint condition.
Definition at line 1539 of file beztool.cpp. 01540 { 01541 if (FloatingEndpoint && IsCurrent() && !DontDrawOnClearMoveTo) 01542 { 01543 BlobManager* pBlobManager = GetApplication()->GetBlobManager(); 01544 ENSURE(pBlobManager, "Can't get BlobManager"); 01545 pBlobManager->RenderToolBlobsOff(this, MoveToSpread,NULL); 01546 } 01547 FloatingEndpoint = FALSE; 01548 }
|
|
|
Performs the cycle the selected points task. The selection status of each endpoint on selected paths is applied to the next endpoint.
Definition at line 2968 of file beztool.cpp. 02969 { 02970 // Obtain the current selections and the first node in the selection 02971 SelRange* Selected = GetApplication()->FindSelection(); 02972 Node* pNode = Selected->FindFirst(); 02973 NodePath* ThisPath; 02974 02975 // Holds the coords of the last selected point we find on our travels, 02976 // we then call DocView::ScrolToShowWithMargin to ensure that this point is visible 02977 DocCoord LastSelectedPoint; 02978 BOOL LastSelectedPointValid = FALSE; // does LastSelectedPoint hold a valid value? 02979 02980 while (pNode != NULL) 02981 { // we're only interested in NodePaths which have selected points 02982 NodePath* pSelected = FindEditablePath(pNode); 02983 if (pSelected) 02984 { 02985 // for convenience, cast the pointer to a pointer to a NodePath 02986 ThisPath = pSelected; 02987 02988 // First get pointers to the arrays 02989 PathFlags* Flags = ThisPath->InkPath.GetFlagArray(); 02990 PathVerb* Verbs = ThisPath->InkPath.GetVerbArray(); 02991 DocCoord* Coords = ThisPath->InkPath.GetCoordArray(); 02992 const INT32 NumCoords = ThisPath->InkPath.GetNumCoords(); 02993 02994 if (pSelected->InkPath.IsSubSelection()) 02995 { 02996 // Render off the current selection blobs 02997 ThisPath->InkPath.RenderPathSelectedControlBlobs(pNode->FindParentSpread()); 02998 02999 if (Fowards) 03000 { 03001 INT32 Current = 0; 03002 INT32 Next = 0; 03003 BOOL MoreEndpoints = TRUE; 03004 BOOL PrevSelected = Flags[0].IsSelected; 03005 03006 while (MoreEndpoints) 03007 { 03008 // Find the next endpoint 03009 MoreEndpoints = ThisPath->InkPath.FindNextEndPoint(&Next); 03010 if (MoreEndpoints && (Verbs[Next] & PT_CLOSEFIGURE)) 03011 MoreEndpoints = ThisPath->InkPath.FindNextEndPoint(&Next); 03012 if (MoreEndpoints) 03013 { 03014 BOOL temp = Flags[Next].IsSelected; 03015 Flags[Next].IsSelected = PrevSelected; 03016 if (Flags[Next].IsSelected) 03017 { 03018 LastSelectedPoint = Coords[Next]; 03019 LastSelectedPointValid = TRUE; 03020 } 03021 PrevSelected= temp; 03022 Current = Next; 03023 } 03024 else 03025 { 03026 Flags[0].IsSelected = PrevSelected; 03027 if (Flags[0].IsSelected) 03028 { 03029 LastSelectedPoint = Coords[0]; 03030 LastSelectedPointValid = TRUE; 03031 } 03032 } 03033 } 03034 03035 // Tidy up the selection state 03036 ThisPath->InkPath.EnsureSelection(TRUE); 03037 } 03038 else 03039 { 03040 INT32 Current = NumCoords-1; 03041 INT32 Next = Current; 03042 BOOL MoreEndpoints = TRUE; 03043 BOOL PrevSelected = Flags[Current].IsSelected; 03044 BOOL ClosedPath = (Verbs[Next] & PT_CLOSEFIGURE); 03045 03046 while (MoreEndpoints) 03047 { 03048 // Find the previous endpoint 03049 MoreEndpoints = ThisPath->InkPath.FindPrevEndPoint(&Next); 03050 if (MoreEndpoints && ClosedPath && (Verbs[Next] == PT_MOVETO)) 03051 MoreEndpoints = ThisPath->InkPath.FindPrevEndPoint(&Next); 03052 if (MoreEndpoints) 03053 { 03054 BOOL temp = Flags[Next].IsSelected; 03055 Flags[Next].IsSelected = PrevSelected; 03056 if (Flags[Next].IsSelected) 03057 { 03058 LastSelectedPoint = Coords[Next]; 03059 LastSelectedPointValid = TRUE; 03060 } 03061 PrevSelected = temp; 03062 Current = Next; 03063 } 03064 else 03065 { 03066 Flags[NumCoords-1].IsSelected = PrevSelected; 03067 if (Flags[NumCoords-1].IsSelected) 03068 { 03069 LastSelectedPoint = Coords[NumCoords-1]; 03070 LastSelectedPointValid = TRUE; 03071 } 03072 } 03073 } 03074 03075 // Tidy up the selection state 03076 ThisPath->InkPath.EnsureSelection(FALSE); 03077 } 03078 03079 } 03080 // If no SubSelection 03081 else 03082 { 03083 if (Fowards) 03084 { 03085 Flags[0].IsSelected = TRUE; 03086 ThisPath->InkPath.EnsureSelection(TRUE); 03087 } 03088 else 03089 Flags[NumCoords-1].IsSelected = TRUE; 03090 ThisPath->InkPath.EnsureSelection(FALSE); 03091 } 03092 03093 // Render on the new selection blobs 03094 ThisPath->InkPath.RenderPathSelectedControlBlobs(pNode->FindParentSpread()); 03095 } 03096 pNode = Selected->FindNext(pNode); 03097 } 03098 DialogBarOp::SetSystemStateChanged(); 03099 if (LastSelectedPointValid) 03100 { 03101 DocView* pDocView = DocView::GetSelected(); 03102 if (pDocView != NULL) 03103 { 03104 pDocView->ScrollToShowWithMargin(&LastSelectedPoint); 03105 } 03106 } 03107 return TRUE; 03108 }
|
|
|
Allows the tool manager to extract information about the tool.
Reimplemented from Tool_v1. Definition at line 334 of file beztool.cpp. 00335 { 00336 // Cast structure into the latest one we understand. 00337 ToolInfo_v1 *Info = (ToolInfo_v1 *) InfoPtr; 00338 00339 Info -> InfoVersion = 1; 00340 00341 Info -> InterfaceVersion = GetToolInterfaceVersion(); // You should always have this line. 00342 00343 // These are all arbitrary at present. 00344 Info -> Version = 1; 00345 Info -> ID = GetID(); 00346 Info -> TextID = _R(IDS_BEZIER_TOOL); 00347 00348 Info -> Family = FamilyName; 00349 Info -> Name = ToolName; 00350 Info -> Purpose = Purpose; 00351 Info -> Author = Author; 00352 00353 Info -> InfoBarDialog = _R(IDD_BEZTOOLBAR); 00354 00355 Info -> BubbleID = _R(IDBBL_LINETOOL); 00356 Info -> StatusID = _R(IDS_LINETOOL); 00357 }
|
|
||||||||||||||||||||||||||||
|
Used when the cursor moves and when single clicking. This routine determines what effect a click will have. In this tool, clicking will either select a point on an already selected line, reshape a line segment (a la Corel), add a segment to the end of a line, or start a new path entirely.
Definition at line 1199 of file beztool.cpp. 01202 { 01203 clickeffect WhatToDo = NewPath; // tells me what effect the click would have 01204 INT32 PathPosition = 0; // temp var for return value 01205 INT32 TempIndex = 0; // Temporary index into a path 01206 INT32 NumSelPaths = 0; // Number of selected paths 01207 double Distance = 0; // gets the returned distance from the nearest point 01208 double Nearest = 0; // distance of current nearest point 01209 NodeRenderableInk* WhichNode = NULL; // Saves me using a pointer to a pointer 01210 01211 // Scan through the selected paths, and see if any of them want the click 01212 01213 DocRect BlobRect; 01214 DocView* pDocView = DocView::GetCurrent(); 01215 ERROR2IF( pDocView==NULL, NewPath, "BezierTool::DetermineClickEffect: Can't find current DocView"); 01216 01217 // Find the selected range of objects 01218 SelRange* Selected = GetApplication()->FindSelection(); 01219 Node* pNode = Selected->FindFirst(); 01220 01221 INT32 NumSelectedEndpoints = 0; // Count selected points in paths 01222 01223 if (pNode != NULL) 01224 { 01225 Spread* NodeSpread = pNode->FindParentSpread(); 01226 if (NodeSpread == pSpread) 01227 { 01228 // On the same spread, so see if the pointer is over an endpoint 01229 while ((pNode != NULL) && WhatToDo!=OnPoint) 01230 { 01231 NodePath* pActNode = FindEditablePath(pNode); 01232 if (pActNode) 01233 { 01234 01235 // Now we know it's a NodePath, get a pointer to the Path object within it, so 01236 // we can find any endpoints 01237 01238 Path* ThisPath = &((pActNode)->InkPath); 01239 01240 // Increment the number of selected paths 01241 NumSelPaths++; 01242 01243 // count the number of selected points on the path (excluding control points) 01244 INT32 NumCoords = ThisPath->GetNumCoords(); 01245 PathFlags* Flags = ThisPath->GetFlagArray(); 01246 01247 for (INT32 i=0; i<NumCoords; i++) 01248 { 01249 if (Flags[i].IsSelected && Flags[i].IsEndPoint) 01250 NumSelectedEndpoints++; 01251 } 01252 01253 if (ThisPath->FindStartOfPath()) 01254 { 01255 // First, check to see if this click occurs on a selected point 01256 INT32 tempPos; 01257 if (ThisPath->FindNearestPoint(PointerPos, 01258 POINTFLAG_ENDPOINTS | 01259 POINTFLAG_CONTROLPOINTS | 01260 POINTFLAG_ENDSFIRST, 01261 &tempPos) 01262 ) 01263 { 01264 // The click occurred on one of the points on the line 01265 // so remember this path, the position, and the fact that 01266 // the user clicked on a point 01267 01268 WhatToDo = OnPoint; 01269 WhichNode = (NodeRenderableInk*)pActNode; 01270 PathPosition = tempPos; 01271 } 01272 else if (WhatToDo != OnPoint && ThisPath->PointCloseToLine(PointerPos, &tempPos)) 01273 { 01274 WhatToDo = ReshapeLine; 01275 WhichNode = (NodeRenderableInk*)pActNode; 01276 PathPosition = tempPos; 01277 } 01278 else if ((WhatToDo == AddSegment || WhatToDo == NewPath) && ThisPath->ClosestSelectedEndpoint(PointerPos,&TempIndex,&Distance)) 01279 { 01280 // TempIndex is the index into the path for the closest selected endpoint 01281 // Distance is the distance 01282 if (WhatToDo == NewPath) 01283 { 01284 WhatToDo = AddSegment; 01285 WhichNode = (NodeRenderableInk*)pActNode; 01286 Nearest = Distance; 01287 PathPosition = TempIndex; 01288 } 01289 else if (Nearest > Distance) 01290 { 01291 Nearest = Distance; 01292 WhichNode = (NodeRenderableInk*)pActNode; 01293 PathPosition = TempIndex; 01294 } 01295 } 01296 } 01297 } 01298 // Now find the next selected node 01299 pNode = Selected->FindNext(pNode); 01300 } 01301 } 01302 } 01303 01304 // WhatToDo tells us what the action will be 01305 // WhichNode points to the node we are dealing with 01306 // PathPosition is the index into that path of the element we are using 01307 01308 // If WhatToDo == OnPoint and it's the end of a subpath, and the opposite 01309 // end is selected, and the path isn't closed we should change WhatToDo 01310 // to be ClosePath 01311 01312 if (WhatToDo == OnPoint && NumSelectedEndpoints == 1) 01313 { 01314 Path* ThisPath = &(((NodePath*)WhichNode)->InkPath); 01315 PathFlags* Flags = ThisPath->GetFlagArray(); 01316 PathVerb* Verbs = ThisPath->GetVerbArray(); 01317 // DocCoord* Coords = ThisPath->GetCoordArray(); 01318 INT32 NumCoords = ThisPath->GetNumCoords(); 01319 if (Verbs[PathPosition] == PT_MOVETO) // Start of subpath 01320 { 01321 INT32 i = PathPosition; 01322 ThisPath->FindEndElOfSubPath(&i); // i = index to end element 01323 01324 if ((Flags[i].IsSelected) && !(Verbs[i] & PT_CLOSEFIGURE)) 01325 WhatToDo = ClosePath; 01326 } 01327 else if (PathPosition+1 == NumCoords || Verbs[PathPosition+1] == PT_MOVETO) 01328 { 01329 if (!(Verbs[PathPosition] & PT_CLOSEFIGURE)) 01330 { 01331 INT32 i = PathPosition; 01332 ThisPath->FindStartOfSubPath(&i); 01333 if (Flags[i].IsSelected) 01334 WhatToDo = ClosePath; 01335 } 01336 } 01337 // Now we must detect the case of an attempted closepath on a path consisting 01338 // of a moveto and one segment 01339 if ((WhatToDo == ClosePath) && ( (((NodePath*)WhichNode)->InkPath.GetNumCoords() == 2) || 01340 ((((NodePath*)WhichNode)->InkPath.GetNumCoords() == 4) && (Verbs[3] == PT_BEZIERTO)) ) ) 01341 { 01342 WhatToDo = OnPoint; 01343 } 01344 } 01345 01346 01347 if ((WhatToDo == AddSegment || WhatToDo == ClosePath) && NumSelectedEndpoints > 1) 01348 WhatToDo = NewPath; 01349 01350 if (WhatToDo == AddSegment || WhatToDo == ReshapeLine) 01351 { 01352 // If we're pointing at a curve, make sure we're pointing to the first element 01353 Path* ThisPath = &(((NodePath*)WhichNode)->InkPath); 01354 PathFlags* flags = ThisPath->GetFlagArray(); 01355 while(!(flags[PathPosition].IsEndPoint )) 01356 PathPosition++; 01357 ThisPath->SetPathPosition(PathPosition); 01358 if (ThisPath->GetVerb() == PT_BEZIERTO) 01359 PathPosition-=2; 01360 } 01361 01362 *ReturnPosition = PathPosition; 01363 *ReturnNode = WhichNode; 01364 *NumSelectedPoints = NumSelectedEndpoints; 01365 *NumSelectedPaths = NumSelPaths; 01366 return (WhatToDo); 01367 }
|
|
|
Moves the selected endpoints foward along the selected path(s) so that the last point is selected. The pattern of selection remains the same.
Definition at line 3247 of file beztool.cpp. 03248 { 03249 // Obtain the current selections and the first node in the selection 03250 SelRange* Selected = GetApplication()->FindSelection(); 03251 Node* pNode = Selected->FindFirst(); 03252 NodePath* ThisPath; 03253 03254 // Variable to hold the position of the last 'end point'. This is updated as we 03255 // loop through the selection until it holds the end point of the last line 03256 // in the selection with subselection. 03257 DocCoord LastEndPoint; 03258 BOOL LastEndPointValid = FALSE; 03259 03260 while (pNode != NULL) 03261 { // we're only interested in NodePaths which have selected points 03262 NodePath* pSelected = FindEditablePath(pNode); 03263 if (pSelected) 03264 { 03265 // for convenience, cast the pointer to a pointer to a NodePath 03266 ThisPath = pSelected; 03267 03268 // First get pointers to the arrays 03269 PathFlags* Flags = ThisPath->InkPath.GetFlagArray(); 03270 PathVerb* Verbs = ThisPath->InkPath.GetVerbArray(); 03271 DocCoord* Coords = ThisPath->InkPath.GetCoordArray(); 03272 INT32 NumCoords = ThisPath->InkPath.GetNumCoords()-1; 03273 if (pSelected->InkPath.IsSubSelection() ) 03274 { 03275 // We only need to bother if the last endpoint is not selected! 03276 if (!Flags[NumCoords].IsSelected) 03277 { 03278 // Render off the current selection blobs 03279 ThisPath->InkPath.RenderPathSelectedControlBlobs(pNode->FindParentSpread()); 03280 03281 // Find the last selected point 03282 INT32 Offset = NumCoords; 03283 while ((Offset > -1) && !(Flags[Offset].IsSelected && Flags[Offset].IsEndPoint)) 03284 03285 { 03286 Offset--; 03287 } 03288 03289 ERROR3IF(Offset == -1,"No selected endpoint found when there was one"); 03290 03291 // Now we can move the selection on to the end 03292 INT32 Current = NumCoords; 03293 BOOL MoreEndpoints = TRUE; 03294 03295 while (MoreEndpoints) 03296 { 03297 Flags[Current].IsSelected = Flags[Offset].IsSelected; 03298 MoreEndpoints = ThisPath->InkPath.FindPrevEndPoint(&Offset); 03299 if (MoreEndpoints && (Verbs[Offset] & PT_CLOSEFIGURE)) 03300 MoreEndpoints = ThisPath->InkPath.FindPrevEndPoint(&Offset); 03301 if (MoreEndpoints) 03302 { 03303 ThisPath->InkPath.FindPrevEndPoint(&Current); 03304 if (Verbs[Current] & PT_CLOSEFIGURE) 03305 ThisPath->InkPath.FindPrevEndPoint(&Current); 03306 } 03307 else 03308 Current --; 03309 } 03310 03311 // Unselect the remaining endpoints 03312 while (Current > -1) 03313 { 03314 Flags[Current--].IsSelected = FALSE; 03315 } 03316 03317 // Now fix up the selections so if the starts of subpaths are selected then so are the ends 03318 ThisPath->InkPath.EnsureSelection(FALSE); 03319 03320 // Render on the new selection blobs 03321 ThisPath->InkPath.RenderPathSelectedControlBlobs(pNode->FindParentSpread()); 03322 } 03323 03324 // this path is in the selection, and has a subselection, so remember its end point 03325 // position, as it may be the last end point 03326 LastEndPoint = Coords[NumCoords]; 03327 LastEndPointValid = TRUE; 03328 } 03329 03330 else 03331 { 03332 Flags[NumCoords].IsSelected = TRUE; 03333 // Now fix up the selections so if the starts of subpaths are selected then so are the ends 03334 ThisPath->InkPath.EnsureSelection(FALSE); 03335 // Render on the new selection blobs 03336 ThisPath->InkPath.RenderPathSelectedControlBlobs(pNode->FindParentSpread()); 03337 } 03338 } 03339 pNode = Selected->FindNext(pNode); 03340 } 03341 DialogBarOp::SetSystemStateChanged(); 03342 03343 // scroll to show the last end point (if it exists) at the coordinates we remembered earlier 03344 if (LastEndPointValid) 03345 { 03346 DocView* pDocView = DocView::GetSelected(); 03347 if (pDocView != NULL) 03348 { 03349 pDocView->ScrollToShowWithMargin(&LastEndPoint); 03350 } 03351 } 03352 03353 return TRUE; 03354 }
|
|
|
Finds the node to edit (if it exists). This node could actually be the selected node passed as a parameter or one of its children which the node wants to be editable.
Definition at line 1387 of file beztool.cpp. 01388 { 01389 if (pSelected->IsNodePath()) 01390 return ((NodePath*)pSelected); 01391 01392 return ((NodePath*)pSelected->HasEditableChild(CC_RUNTIME_CLASS(NodePath), NULL)); 01393 }
|
|
||||||||||||||||||||
|
To find the string to display on the status line given the current mouse position.
Definition at line 3623 of file beztool.cpp. 03624 { 03625 // Call DetermineClickEffect to see what a click will do at this position 03626 03627 INT32 PathPosition; // Needed to receive a return, not used otherwise 03628 NodeRenderableInk* node; // again, only temporary 03629 INT32 NumPts; // Number of selected points 03630 INT32 NumPaths; // Number of selected paths 03631 clickeffect WhatToDo = DetermineClickEffect(coord, pSpread, &node, &PathPosition, &NumPaths, &NumPts); 03632 03633 switch (WhatToDo) 03634 { 03635 case AddSegment: 03636 if (CreateCurve) 03637 ptext->Load(_R(IDS_ADD_SEGMENT),Tool::GetModuleID(GetID())); 03638 else 03639 ptext->Load(_R(IDS_ADDLINESEGMENT),Tool::GetModuleID(GetID())); 03640 break; 03641 case NewPath: 03642 if (FloatingEndpoint) 03643 { 03644 if (CreateCurve) 03645 { 03646 if (NumPts == 0) 03647 ptext->Load(_R(IDS_CLICK_TO_MAKE_NEW),Tool::GetModuleID(GetID())); 03648 else 03649 ptext->Load(_R(IDS_CLICK_TO_MAKE_NEW),Tool::GetModuleID(GetID())); 03650 } 03651 else 03652 { 03653 ptext->Load(_R(IDS_CLICKMAKENEWLINE),Tool::GetModuleID(GetID())); 03654 } 03655 } 03656 else 03657 { 03658 if (CreateCurve) 03659 { 03660 if (NumPts == 0) 03661 ptext->Load(_R(IDS_STARTNEWCURVENOSEL),Tool::GetModuleID(GetID())); 03662 else 03663 ptext->Load(_R(IDS_CREATE_NEW_PATH),Tool::GetModuleID(GetID())); 03664 } 03665 else 03666 { 03667 if (NumPts == 0) 03668 ptext->Load(_R(IDS_STARTNEWLINENOSEL),Tool::GetModuleID(GetID())); 03669 else 03670 ptext->Load(_R(IDS_STARTNEWLINE),Tool::GetModuleID(GetID())); 03671 } 03672 } 03673 break; 03674 case OnPoint: 03675 // There are various different combinations of selected/unselected, which require 03676 // different status line messages 03677 { 03678 NodePath* ThisPath = (NodePath*)node; 03679 // PathVerb* Verbs = ThisPath->InkPath.GetVerbArray(); 03680 PathFlags* Flags = ThisPath->InkPath.GetFlagArray(); 03681 INT32 ptype = 0; 03682 if (Flags[PathPosition].IsSelected) 03683 ptype |= 1; 03684 if (Flags[PathPosition].IsEndPoint) 03685 ptype |= 2; 03686 if (Flags[PathPosition].IsRotate) 03687 ptype |= 4; 03688 03689 // Now ptype holds a number from 0 to 7 which completely describes what type of 03690 // point this is, so we can use that to select the correct string 03691 switch(ptype) 03692 { 03693 case 0: //Unselected, unsmoothed control point 03694 case 4: // UnSelected, smoothed control point 03695 case 1: // Selected, unsmoothed control point 03696 case 5: // Selected, smoothed control point 03697 ptext->Load(_R(IDS_SELCONTROL),Tool::GetModuleID(GetID())); 03698 break; 03699 case 2: // UnSelected, unsmoothed end point 03700 ptext->Load(_R(IDS_UNSELCUSP),Tool::GetModuleID(GetID())); 03701 break; 03702 case 3: // Selected, unsmoothed end point 03703 ptext->Load(_R(IDS_SELCUSP),Tool::GetModuleID(GetID())); 03704 break; 03705 case 6: // UnSelected, smoothed end point 03706 ptext->Load(_R(IDS_UNSELSMOOTH),Tool::GetModuleID(GetID())); 03707 break; 03708 case 7: // Selected, smoothed end point 03709 ptext->Load(_R(IDS_SELSMOOTH),Tool::GetModuleID(GetID())); 03710 break; 03711 } 03712 } 03713 break; 03714 case ReshapeLine: 03715 ptext->Load(_R(IDS_RESHAPE_LINE),Tool::GetModuleID(GetID())); 03716 break; 03717 case ClosePath: 03718 ptext->Load(_R(IDS_CLOSEPATH),Tool::GetModuleID(GetID())); 03719 break; 03720 } 03721 }
|
|
|
Reimplemented from Tool_v1. Definition at line 256 of file beztool.h. 00256 { return TOOLID_BEZTOOL; };
|
|
||||||||||||||||
|
Read the state of the floating endpoint.
Definition at line 1570 of file beztool.cpp. 01571 { 01572 if (FloatingEndpoint) 01573 { 01574 *ppSpread = MoveToSpread; 01575 *pCoord = MoveToPoint; 01576 *ppDoc = MoveToDoc; 01577 return TRUE; 01578 } 01579 else 01580 return FALSE; 01581 }
|
|
||||||||||||||||||||
|
generate up-to-date text for the status line (called on idles)
Reimplemented from Tool_v1. Definition at line 3592 of file beztool.cpp. 03593 { 03594 ERROR2IF(ptext==NULL,FALSE,"ptext was NULL"); 03595 03596 *ptext = ""; 03597 03598 GenerateStatusLineText(ptext, pSpread, DocPos, ClickMods); 03599 03600 return TRUE; 03601 }
|
|
||||||||||||
|
|
|
|
Moves the selected endpoints back along the selected path(s) so that the first point is selected. The pattern of selection remains the same.
Definition at line 3125 of file beztool.cpp. 03126 { 03127 // Obtain the current selections and the first node in the selection 03128 SelRange* Selected = GetApplication()->FindSelection(); 03129 Node* |