// $Id: penedit.h 1282 2006-06-09 09:46:49Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ // The pen edit header file, providing operations used by the pen tool // Created by Mike on 25/9/94 #ifndef INC_PENEDIT #define INC_PENEDIT //#include "selop.h" - in camtypes.h [AUTOMATICALLY REMOVED] //#include "stockcol.h" - in camtypes.h [AUTOMATICALLY REMOVED] // #include "pentool.h" #define OPTOKEN_PENHANDLES _T("PenHandles") #define OPTOKEN_PENCREATEINTERNAL _T("CreatePenPoint") #define OPTOKEN_PENEDITINTERNAL _T("EditPenPoint") #define OPTOKEN_PENCREATEPATH _T("CreatePenPath") #define OPTOKEN_PENADDELEMENT _T("AddPenElement") #define OPTOKEN_PENCLOSEPATH _T("ClosePenPath") #define OPTOKEN_ADDPATH _T("AddPath") #define OPTOKEN_ADDNEWPATH _T("AddNewPath") #define OPTOKEN_ADDPATHTOPATH _T("AddPathToPath") #define OPTOKEN_CLOSEPATHWITHPATH _T("ClosePathWithPath") // define some types to act as return parameters. These tell a calling // do function what type of endop execute to call enum ExecuteType { ExeNone, ExeInclusive, ExeExclusive }; /******************************************************************************************** > class HandleFlags Author: Mike_Kenny (Xara Group Ltd) Created: 5/10/94 Purpose: Used to determin what to do when rendering drag handles. ie which handles should be rendered and how they relate to the drag mouse coord. ********************************************************************************************/ class HandleFlags { public: HandleFlags(BOOL rTrackEnd = TRUE, BOOL rGhostEnd = TRUE, BOOL TrackPtMoves = TRUE, BOOL GhostPtMoves = TRUE, BOOL TrackPtSpins = FALSE, BOOL GhostPtSpins = FALSE); BYTE RenderTrackEnd : 1; BYTE RenderGhostEnd : 1; BYTE TrackPointMoves : 1; BYTE GhostPointMoves : 1; BYTE TrackPointSpins : 1; BYTE GhostPointSpins : 1; BYTE Spare1 : 1; BYTE Spare2 : 1; }; /******************************************************************************************** > class WobbleFlags Author: Mike_Kenny (Xara Group Ltd) Created: 5/10/94 Purpose: Used to determin what to wobble when recalculating curve control points during a drag. The flags affect which handles around a curve endpoint are repositioned. ********************************************************************************************/ class WobbleFlags { public: WobbleFlags(BOOL pSister = FALSE, BOOL pBrother = TRUE, BOOL nBrother = FALSE, BOOL nSister = FALSE); BYTE PrevSister : 1; BYTE PrevBrother : 1; BYTE NextBrother : 1; BYTE NextSister : 1; }; /******************************************************************************************** > class ControlPts Author: Mike_Kenny (Xara Group Ltd) Created: 5/10/94 Purpose: ********************************************************************************************/ class ControlPts { public: ControlPts(); ~ControlPts(); public: DocCoord HndClick; DocCoord HndDrag; Spread* pHndSpread; }; /******************************************************************************************** > class OpPenHandles : public Operation Author: Mike_Kenny (Xara Group Ltd) Created: 26/9/94 Purpose: This operation simply provides functions for other operations to use. It is not intended to be used as an operation in its own right. Most useful pen classes are derived from this. ********************************************************************************************/ class OpPenHandles : public Operation { CC_DECLARE_DYNCREATE(OpPenHandles) public: OpPenHandles(); protected: void RenderHandles(); void UpdateHandles( RenderRegion* ); DocRect GetHandlesRect(); void RecalcHandles(DocCoord, BOOL); void SetDragHandles(HandleFlags, DocCoord, DocCoord, DocCoord, Spread* ); void ChangeTrackHandle(DocCoord, BOOL); DocCoord GetTrackHandle() const; DocCoord GetGhostHandle() const; DocCoord GetMidHandle() const; DocCoord CalcGhostEnd(DocCoord start, DocCoord end) const; void RenderTestRect( DocRect, Spread*, StockColour ); BOOL HasMouseMoved(DocCoord& OriginalPoint, DocCoord& PointerPos, double threshold=2); HandleFlags Hflags; // set some flags to control the handle positions DocCoord StartMousePos; // first click position DocCoord CurrentMousePos; // follow the mouse around Spread* StartSpread; // first click spread private: void SetHandleEnds(DocCoord, DocCoord, DocCoord); DocCoord TrackEnd; // end that follows the mouse usually DocCoord MidPoint; DocCoord GhostEnd; // other end }; /******************************************************************************************** > class OpPenDragBlobs : public OpPenHandles Author: Mike_Kenny (Xara Group Ltd) Created: 26/9/94 Purpose: This op class is defined as a base class only. It provides common dragging functionality which is inherited by create and edit pen classes. ********************************************************************************************/ class OpPenDragBlobs : public OpPenHandles { CC_DECLARE_DYNCREATE(OpPenDragBlobs) public: OpPenDragBlobs(); BOOL DoPenDragBlobs(); virtual void DragPointerMove(DocCoord Pos, ClickModifiers Mods, Spread* pSpread, BOOL bSolidDrag); virtual void DragFinished(DocCoord Pos, ClickModifiers Mods, Spread* pSpread, BOOL Success, BOOL bSolidDrag); virtual void RenderDragBlobs( DocRect, Spread* , BOOL bSolidDrag); }; /******************************************************************************************** > class OpPenCreateInternal : public OpPenDragBlobs Author: Mike_Kenny (Xara Group Ltd) Created: 27/9/94 Purpose: This operation is started by the pen tool when it receives a click on the document with no previous internal or external state set. ie the pen tool is not holding a moveto element inside iteslf from a previous click and there are no selected endpoints to add to. ********************************************************************************************/ class OpPenCreateInternal : public OpPenDragBlobs { CC_DECLARE_DYNCREATE(OpPenCreateInternal) public: OpPenCreateInternal(); static BOOL Init(); static OpState GetState(String_256*, OpDescriptor*); void DoPenCreateInternal( DocCoord, Spread*, ControlPts*); virtual void DragFinished(DocCoord Pos, ClickModifiers Mods, Spread* pSpread, BOOL Success, BOOL bSolidDrag); private: ControlPts* pUserHandles; // keep a pointer passed in by the caller }; /******************************************************************************************** > class OpPenEditInternal : public OpPenDragBlobs Author: Mike_Kenny (Xara Group Ltd) Created: 27/9/94 Purpose: This operation is started by the pen tool when it receives a click over its internal moveto point. The point will be converted into a dragto if a drag occurs. ********************************************************************************************/ class OpPenEditInternal : public OpPenDragBlobs { CC_DECLARE_DYNCREATE(OpPenEditInternal) public: OpPenEditInternal(); static BOOL Init(); static OpState GetState(String_256*, OpDescriptor*); void DoPenEditInternal(ControlPts*); virtual void DragFinished(DocCoord Pos, ClickModifiers Mods, Spread* pSpread, BOOL Success, BOOL bSolidDrag); private: ControlPts* pUserHandles; // keep a pointer passed in by the caller }; /******************************************************************************************** > class OpPenEditPath : public OpPenHandles Author: Mike_Kenny (Xara Group Ltd) Created: 29/9/94 Purpose: This operation is started by the pen tool when it receives a click on a document and needs to create a new path. The idea is, it will drag edit a path until such time as the user lets go of the mouse. and then add the path to the tree. The operation handles the internals of rendering the eor path. ********************************************************************************************/ class OpPenEditPath : public OpPenHandles { CC_DECLARE_DYNCREATE(OpPenEditPath) public: OpPenEditPath(); static BOOL Init(); static OpState GetState(String_256*, OpDescriptor*); BOOL DoPenDragPath(); virtual void DragPointerMove(DocCoord Pos, ClickModifiers Mods, Spread* pSpread, BOOL bSolidDrag); virtual void DragFinished(DocCoord Pos, ClickModifiers Mods, Spread* pSpread, BOOL Success, BOOL bSolidDrag); virtual void RenderDragBlobs(DocRect, Spread*, BOOL bSolidDrag); protected: DocRect GetBoundingRect(); // return the bounding rect of blobs and path void ConvertToLine(const INT32 index); // convert the edited curve element to a line void RemoveRotateEnd(const INT32 index); BOOL InsertBezier(DocCoord pt1, DocCoord pt2, DocCoord pt3); BOOL InsertCurvedLine(DocCoord pt1, DocCoord pt2); BOOL InsertGhostedBezier(DocCoord pt1, DocCoord pt2, DocCoord pt3); BOOL ConvertPathEnd(Path* pDocPath); void SetWobbleIndex(WobbleFlags wibble, const INT32 index); void WobbleCoords(); Path* pEditPath; // keep track of edit path INT32 WobbleIndex; // index of element being dragged WobbleFlags Wobble; // which controls on the edit curve do we wobble? }; /******************************************************************************************** > class OpPenCreatePath : public OpPenEditPath Author: Mike_Kenny (Xara Group Ltd) Created: 29/9/94 Purpose: This op is concerned with creating a new path in the tree. It is derived from OpPenEditPath, which handles all the dragging and redraw of a new path element. This op will use ********************************************************************************************/ class OpPenCreatePath : public OpPenEditPath { CC_DECLARE_DYNCREATE(OpPenCreatePath) public: OpPenCreatePath(); static BOOL Init(); static OpState GetState(String_256*, OpDescriptor*); void DoPenCreatePath(ControlPts*, DocCoord, Spread*, Path*); virtual void DragFinished(DocCoord Pos, ClickModifiers Mods, Spread* pSpread, BOOL Success, BOOL bSolidDrag); private: DocCoord Handle0; // control handles of previous path element. DocCoord Handle1; }; /******************************************************************************************** > class OpPenAddElement : public OpPenEditPath Author: Mike_Kenny (Xara Group Ltd) Created: 30/9/94 Purpose: Given a path in the tree with a selected end point, this operation will control the creation of a new element (through clicks and drags), at the end of the path. It is derived from OpPenEditPath which controls all the eoring of path elements such as blobs and lines. ********************************************************************************************/ class OpPenAddElement : public OpPenEditPath { CC_DECLARE_DYNCREATE(OpPenAddElement) public: OpPenAddElement(); static BOOL Init(); static OpState GetState(String_256*, OpDescriptor*); void DoPenAddElement(NodePath*, INT32, DocCoord, Spread*, Path*); virtual void DragFinished(DocCoord Pos, ClickModifiers Mods, Spread* pSpread, BOOL Success, BOOL bSolidDrag); private: NodePath* pEditNode; // keep track of the node we are editing in the document INT32 EditIndex; }; /******************************************************************************************** > class OpPenClosePath : public OpPenEditPath Author: Mike_Kenny (Xara Group Ltd) Created: 4/10/94 Purpose: This op controls the closing of an open path. It performs the eoring of path elements a blobs during a click or drag action. It is primarily used by the pen tool an is brought into being when a click occurs over the startpoint of a path, having a selected endpoint. ********************************************************************************************/ class OpPenClosePath : public OpPenEditPath { CC_DECLARE_DYNCREATE(OpPenClosePath) public: OpPenClosePath(); static BOOL Init(); static OpState GetState(String_256*, OpDescriptor*); void DoPenClosePath(NodePath*, INT32, Spread*, Path*); virtual void DragPointerMove(DocCoord Pos, ClickModifiers Mods, Spread* pSpread, BOOL bSolidDrag); virtual void DragFinished(DocCoord Pos, ClickModifiers Mods, Spread* pSpread, BOOL Success, BOOL bSolidDrag); private: BOOL AddFirstElement(Spread* pSpread); NodePath* pEditNode; // keep track of the node we are editing in the document INT32 EditIndex; BOOL OnMoveto; INT32 NumElements; BOOL FirstDrag; WobbleFlags FirstWFlags; HandleFlags FirstHFlags; }; /******************************************************************************************** > class OpAddPath : public SelOperation Author: Mike_Kenny (Xara Group Ltd) Created: 7/10/94 Purpose: The base class for various addpath operations. This is not really an operation in its own right as it does not provide an init and getstate function. Its use is to provide common functions required by distinct addpath operations. ********************************************************************************************/ class OpAddPath : public SelOperation { CC_DECLARE_DYNCREATE(OpAddPath) public: OpAddPath(); protected: ExecuteType AugmentPathWithPath(Path*, NodePath*, INT32); ActionCode DeselectPoint(NodePath* pDestNode, INT32 position); ActionCode DeselectHandle(NodePath* pDestNode, INT32 position); }; /******************************************************************************************** > class OpAddNewPath : public OpAddPath Author: Mike_Kenny (Xara Group Ltd) Created: 30/9/94 Purpose: This op actually adds a new path to the current document. The path has been created and edited with OpPenCreatePath() which will handle EOR drawing It can now be instantiated as a physical object by this op. ********************************************************************************************/ class OpAddNewPath : public OpAddPath { CC_DECLARE_DYNCREATE(OpAddNewPath) public: OpAddNewPath(); static BOOL Init(); static OpState GetState(String_256*, OpDescriptor*); void GetOpName(String_256* OpName); void DoAddNewPath(Path* pAddPath, Spread* pSpread); }; /******************************************************************************************** > class OpAddPathToPath : public OpAddPath Author: Mike_Kenny (Xara Group Ltd) Created: 3/9/94 Purpose: This op will add an element to an existing path within the tree. The new element and context path should be passed into the do function as parameters. ********************************************************************************************/ class OpAddPathToPath : public OpAddPath { CC_DECLARE_DYNCREATE(OpAddPathToPath) public: OpAddPathToPath(); static BOOL Init(); static OpState GetState(String_256*, OpDescriptor*); void GetOpName(String_256* OpName); void DoAddPathToPath(NodePath* pDestinNode, Path* pAddPath, INT32 index); }; /******************************************************************************************** > class OpClosePathWithPath : public OpAddPath Author: Mike_Kenny (Xara Group Ltd) Created: 7/10/94 Purpose: This op deals with a destination path being edited, and a source path which may be the result of a drag edit operation. The idea is that the op will take the components of the source path and add them in a deterministic way to the destination path, resulting in a closed destination path. The source path is assumed to have either 1 or 2 elements in it. The first element will be added to the end of the destination path and act as a closing piece. The second element of the source path will affect the first element in the destination path. If both elements match in type, ie are two curves, then the none end control handles of the source will be copied to the destination. This op as can be seen is rather specific, and is used by the pen tool to close an open path. Imagine clicking on the first control point of a path and draging out control handles. The handles will affect the previous and next elements of the path. The previous being a close element and the next being the first element of the path. Hence the need for this strange op. ********************************************************************************************/ class OpClosePathWithPath : public OpAddPath { CC_DECLARE_DYNCREATE(OpClosePathWithPath) public: OpClosePathWithPath(); static BOOL Init(); static OpState GetState(String_256*, OpDescriptor*); void GetOpName(String_256* OpName); void DoClosePathWithPath(NodePath* pDestinNode, Path* pAddPath, INT32 index); }; #endif