#include <shapeops.h>
Inheritance diagram for OpReformShapeEdge:
Public Member Functions | |
OpReformShapeEdge () | |
Constructor - set member variables to default values. | |
void | DoStartDragEdit (NodeRegularShape *OrigShape, BOOL EdgeOne, DocCoord Anchor, Spread *pSpread, INT32 SegmentIndex) |
This is called when a Drag operation has been started on the edge of a shape. It will try and reshape the edge as it's dragged according to the maths in the function RecalculatePath. | |
virtual void | DragPointerMove (DocCoord Pos, ClickModifiers Mods, Spread *pSpread, BOOL bSolidDrag) |
This is called every time the mouse moves, during a drag. | |
virtual void | DragFinished (DocCoord Pos, ClickModifiers Mods, Spread *pSpread, BOOL Success, BOOL bSolidDrag) |
This is called when a drag operation finishes. | |
virtual void | RenderDragBlobs (DocRect, Spread *, BOOL bSolidDrag) |
Renders the drag blobs of this operation. | |
Static Public Member Functions | |
static BOOL | Init () |
Adds the operation to the list of all known operations. | |
static OpState | GetState (String_256 *Description, OpDescriptor *) |
Find out the state of the operation at the specific time. | |
Private Types | |
enum | DragType { DRAG_EDGE1, DRAG_EDGE2 } |
Private Member Functions | |
void | RecalculateEdge (DocCoord Offset) |
Will reshape the edge being edited using Jims curve distorting method. | |
BOOL | BuildEditEdge () |
Builds a copy of the shape and the edge path that we can edit, without destroying the original data. | |
BOOL | BuildEditShape (BOOL CopyToBoth, BOOL ShouldMirror) |
Builds a copy of the shape into EditShape based upon the current edge path. | |
BOOL | ReversePath (Path *NewPath, BOOL ShouldMirror) |
Use to reverse an edit path before copying it to the other edge path NOTE: This function assumes that the edge path consists of a MoveTo-BezierTo. | |
Private Attributes | |
NodeRegularShape * | EditShape |
NodeRegularShape * | OriginalShape |
DocCoord | StartMousePos |
DocCoord | UTStartMousePos |
DocCoord | OrigControl1 |
DocCoord | OrigControl2 |
Spread * | StartSpread |
Path * | EditEdge |
INT32 | Index |
double | paramdist |
DragType | EdgeDrag |
Definition at line 310 of file shapeops.h.
|
Definition at line 336 of file shapeops.h. 00336 {DRAG_EDGE1, DRAG_EDGE2};
|
|
Constructor - set member variables to default values.
Definition at line 2779 of file shapeops.cpp.
|
|
Builds a copy of the shape and the edge path that we can edit, without destroying the original data.
Definition at line 3005 of file shapeops.cpp. 03006 { 03007 // Copy the shape 03008 if ( (EditShape = new (NodeRegularShape)) == NULL) 03009 return FALSE; 03010 OriginalShape->CopyNodeContents(EditShape); 03011 03012 // Copy the edge path 03013 if ( (EditEdge = new (Path)) == NULL) 03014 return FALSE; 03015 03016 // We need to make a copy of the edge path as it appears in the shape. 03017 INT32 Count1 = OriginalShape->EdgePath1.GetNumCoords(); 03018 INT32 Count2 = OriginalShape->EdgePath2.GetNumCoords(); 03019 if (Count1 == 2) 03020 Count1 = 4; 03021 if (Count2 == 2) 03022 Count2 = 4; 03023 Path* RenderPath; 03024 03025 if (!OriginalShape->BuildShapePath(&RenderPath)) 03026 return FALSE; 03027 03028 // Run through the path makeing linetos into straight curvetos 03029 BOOL FoundLine = TRUE; 03030 while (FoundLine) 03031 { 03032 INT32 NumCoords = RenderPath->GetNumCoords(); 03033 03034 // find a lineto 03035 INT32 loop = 0; 03036 while ((loop < NumCoords) && ((RenderPath->GetVerbArray()[loop] & ~PT_CLOSEFIGURE) != PT_LINETO)) 03037 { 03038 loop ++; 03039 } 03040 03041 if (loop < NumCoords) 03042 { 03043 DocCoord* EdgeCoords = RenderPath->GetCoordArray(); 03044 DocCoord CP1 (EdgeCoords[loop-1].x + (EdgeCoords[loop].x-EdgeCoords[loop-1].x)/3, 03045 EdgeCoords[loop-1].y + (EdgeCoords[loop].y-EdgeCoords[loop-1].y)/3); 03046 DocCoord CP2 (EdgeCoords[loop].x + (EdgeCoords[loop-1].x-EdgeCoords[loop].x)/3, 03047 EdgeCoords[loop].y + (EdgeCoords[loop-1].y-EdgeCoords[loop].y)/3); 03048 DocCoord End = EdgeCoords[loop]; 03049 RenderPath->SetPathPosition(loop); 03050 RenderPath->InsertCurveTo(CP1,CP2,End); 03051 RenderPath->DeleteSection(loop+3,1); 03052 } 03053 else 03054 FoundLine = FALSE; 03055 } 03056 03057 // Now calculate paramdist 03058 RenderPath->SqrDistanceToPoint(StartMousePos, &Index, ¶mdist); 03059 03060 // Now set Index to point to the first element in the edge 03061 PathFlags* RenderFlags = RenderPath->GetFlagArray(); 03062 while ((!RenderFlags[Index].IsEndPoint) && (Index >= 0) ) 03063 { 03064 Index--; 03065 } 03066 03067 INT32 EndCount = EdgeDrag==DRAG_EDGE1 ? Count1 : Count2; 03068 03069 // Ask for a path with the required number of free slots in it 03070 if (!EditEdge->Initialise(EndCount, 1)) 03071 return FALSE; 03072 03073 // now copy the data from the appropitae place in RenderPath into EdgeEdge 03074 if (!EditEdge->CopySectionFrom(*RenderPath, Index, EndCount)) 03075 return FALSE; 03076 03077 // Set the first verb to be a MoveTo and clear any closefigure from the last verb 03078 PathVerb* EdgeVerbs = EditEdge->GetVerbArray(); 03079 DocCoord* EdgeCoords = EditEdge->GetCoordArray(); 03080 EdgeVerbs[0] = PT_MOVETO; 03081 EdgeVerbs[EditEdge->GetNumCoords()-1] = EdgeVerbs[EditEdge->GetNumCoords()-1] & ~PT_CLOSEFIGURE; 03082 03083 // Untransform the path 03084 Matrix TransMat; 03085 EditShape->GetTransformMatrix(&TransMat); 03086 TransMat = TransMat.Inverse(); 03087 TransMat.transform((Coord*)EdgeCoords, EditEdge->GetNumCoords()); 03088 03089 // We also need an untransformed starting point of the drag 03090 TransMat.transform(&UTStartMousePos); 03091 03092 // Record the original positions of the two control points of the drag segment 03093 // NOTE Assumes that the edit path consists of one segment 03094 if (EdgeVerbs[1] == PT_BEZIERTO) 03095 { 03096 OrigControl1 = EdgeCoords[1]; 03097 OrigControl2 = EdgeCoords[2]; 03098 } 03099 Index = 1; 03100 03101 return TRUE; 03102 }
|
|
Builds a copy of the shape into EditShape based upon the current edge path.
Definition at line 3121 of file shapeops.cpp. 03122 { 03123 ERROR2IF(EditShape == NULL, FALSE, "Can't build into a non-existant shape!"); 03124 03125 BOOL Success = TRUE; 03126 if (CopyToBoth) 03127 { 03128 Path* RevPath = new Path; 03129 Path* Path1; 03130 Path* Path2; 03131 03132 if ((RevPath == NULL) || !ReversePath(RevPath, ShouldMirror)) 03133 { 03134 if (RevPath != NULL) 03135 delete RevPath; 03136 RevPath = EditEdge; 03137 } 03138 03139 if (EdgeDrag == DRAG_EDGE1) 03140 { 03141 Path1 = EditEdge; 03142 Path2 = RevPath; 03143 } 03144 else 03145 { 03146 Path1 = RevPath; 03147 Path2 = EditEdge; 03148 } 03149 03150 Success = EditShape->EdgePath1.CopyPathDataFrom(Path1); 03151 if (Success) 03152 Success = EditShape->EdgePath2.CopyPathDataFrom(Path2); 03153 03154 if (RevPath != EditEdge) 03155 delete RevPath; 03156 } 03157 else 03158 { 03159 if (EdgeDrag == DRAG_EDGE1) 03160 { 03161 Success = EditShape->EdgePath1.CopyPathDataFrom(EditEdge); 03162 if (Success) 03163 Success = EditShape->EdgePath2.CopyPathDataFrom(&(OriginalShape->EdgePath2)); 03164 } 03165 else 03166 { 03167 Success = EditShape->EdgePath2.CopyPathDataFrom(EditEdge); 03168 if (Success) 03169 Success = EditShape->EdgePath1.CopyPathDataFrom(&(OriginalShape->EdgePath1)); 03170 } 03171 } 03172 03173 if (!Success) 03174 { 03175 Error::SetError(_R(IDS_OUT_OF_MEMORY)); 03176 } 03177 03178 EditShape->InvalidateCache(); 03179 03180 return Success; 03181 }
|
|
This is called when a Drag operation has been started on the edge of a shape. It will try and reshape the edge as it's dragged according to the maths in the function RecalculatePath.
Definition at line 2808 of file shapeops.cpp. 02810 { 02811 // We had better take a note of the starting point of the drag 02812 StartMousePos = Anchor; 02813 UTStartMousePos = Anchor; // We'll untransform this later in BuildEditShape 02814 StartSpread = pSpread; 02815 OriginalShape = OrigShape; 02816 Index = SegmentIndex; 02817 EdgeDrag = EdgeOne ? DRAG_EDGE1 : DRAG_EDGE2; 02818 02819 // We need to make a version of the shape that we can change 02820 if (!BuildEditEdge()) 02821 { 02822 // Inform the person doing the clicking that life is not looking so good 02823 InformError( _R(IDS_OUT_OF_MEMORY), _R(IDS_OK) ); 02824 End(); 02825 return; 02826 } 02827 02828 // Render the bits of the path that are different 02829 DocRect EditPathBBox = EditShape->GetBoundingRect(); 02830 RenderDragBlobs(EditPathBBox, pSpread, FALSE); 02831 02832 // And tell the Dragging system that we need drags to happen 02833 StartDrag(DRAGTYPE_AUTOSCROLL, &EditPathBBox, &StartMousePos); 02834 }
|
|
This is called when a drag operation finishes.
Reimplemented from Operation. Definition at line 2903 of file shapeops.cpp. 02904 { 02905 RenderDragBlobs( EditEdge->GetBoundingRect(), StartSpread, bSolidDrag ); 02906 EndDrag(); 02907 BeginSlowJob(); 02908 02909 BOOL Failed = FALSE; 02910 02911 if ( Success ) 02912 { 02913 // Start the undo ball rolling 02914 Failed = !DoStartSelOp(FALSE, TRUE, FALSE, TRUE); 02915 02916 if (!Failed) 02917 { 02918 Failed = RecalcBoundsAction::DoRecalc(this, &UndoActions, OriginalShape) == AC_FAIL; 02919 } 02920 02921 // Will the original shape allow the op to happen? 02922 ObjChangeFlags cFlags; 02923 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,OriginalShape,this); 02924 if (!Failed) 02925 Failed = !OriginalShape->AllowOp(&ObjChange); 02926 02927 if (!Failed) 02928 { 02929 if ((EdgeDrag == DRAG_EDGE1) || ClickMods.Constrain) 02930 { 02931 Failed = ChangeShapePathAction::DoReshape(this, &UndoActions, OriginalShape, 02932 ChangeShapePathAction::CHANGE_PATH1, &(OriginalShape->EdgePath1)) == AC_FAIL ; 02933 } 02934 if ((EdgeDrag == DRAG_EDGE2) || ClickMods.Constrain || !OriginalShape->IsStellated()) 02935 { 02936 if (!Failed) 02937 { 02938 Failed = ChangeShapePathAction::DoReshape(this, &UndoActions, OriginalShape, 02939 ChangeShapePathAction::CHANGE_PATH2, &(OriginalShape->EdgePath2)) == AC_FAIL ; 02940 } 02941 } 02942 } 02943 02944 // Now do the change 02945 if (!Failed) 02946 { 02947 if ((EdgeDrag == DRAG_EDGE1) || ClickMods.Constrain ) 02948 { 02949 OriginalShape->EdgePath1.ClearPath(); 02950 OriginalShape->EdgePath1.CopyPathDataFrom(&(EditShape->EdgePath1)); 02951 } 02952 if ((EdgeDrag == DRAG_EDGE2) || ClickMods.Constrain || !OriginalShape->IsStellated() ) 02953 { 02954 OriginalShape->EdgePath2.ClearPath(); 02955 OriginalShape->EdgePath2.CopyPathDataFrom(&(EditShape->EdgePath2)); 02956 } 02957 02958 // Recalculate the path's bounding box 02959 OriginalShape->InvalidateBoundingRect(); 02960 OriginalShape->InvalidateCache(); 02961 02962 // tell the world that something in the selection has changed 02963 // so that selection bounds are updated 02964 GetApplication()->FindSelection()->Update(TRUE); 02965 02966 Failed = RecordBoundsAction::DoRecord(this, &UndoActions, OriginalShape) == AC_FAIL ; 02967 } 02968 02969 if (!Failed) 02970 { 02971 // Update effected parents 02972 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,OriginalShape,this); 02973 Failed = !UpdateChangedNodes(&ObjChange); 02974 } 02975 } 02976 else 02977 { 02978 // Set up the flags that say it all went wrong 02979 Failed = TRUE; 02980 } 02981 02982 delete (EditShape); 02983 delete (EditEdge); 02984 02985 if (Failed) 02986 FailAndExecute(); 02987 End(); 02988 }
|
|
This is called every time the mouse moves, during a drag.
Reimplemented from Operation. Definition at line 2853 of file shapeops.cpp. 02854 { 02855 // If drag has moved onto a different spread, convert the coord to be relative to the 02856 // original spread. 02857 if (pSpread != StartSpread) 02858 PointerPos = MakeRelativeToSpread(StartSpread, pSpread, PointerPos); 02859 02860 // Now snap it to the current grid 02861 DocView::SnapCurrent(StartSpread,&PointerPos); 02862 02863 // Rub out the old EORed version of the path 02864 RenderDragBlobs( EditShape->GetBoundingRect(), StartSpread, bSolidDrag ); 02865 02866 // This is the bit where we go off and re-calculate the edge path, 02867 // based on how much the mouse has moved. We need to work in untransfomed coordinates 02868 DocCoord Offset = PointerPos; 02869 Matrix TransMat; 02870 EditShape->GetTransformMatrix(&TransMat); 02871 TransMat = TransMat.Inverse(); 02872 TransMat.transform(&Offset); 02873 Offset = Offset-UTStartMousePos; 02874 02875 RecalculateEdge( Offset ); 02876 if (!BuildEditShape(ClickMods.Constrain || !OriginalShape->IsStellated(), ClickMods.Adjust)) 02877 { 02878 InformError(); 02879 End(); 02880 } 02881 02882 // Draw in the new version of the path and update the Last Mouse Position 02883 RenderDragBlobs( EditShape->GetBoundingRect(), StartSpread, bSolidDrag ); 02884 }
|
|
Find out the state of the operation at the specific time.
Definition at line 3320 of file shapeops.cpp. 03321 { 03322 OpState Blobby; 03323 03324 return Blobby; 03325 }
|
|
Adds the operation to the list of all known operations.
Reimplemented from SimpleCCObject. Definition at line 3295 of file shapeops.cpp. 03296 { 03297 return (RegisterOpDescriptor( 0, 03298 _R(IDS_EDITREGULARSHAPEOP), 03299 CC_RUNTIME_CLASS(OpReformShapeEdge), 03300 OPTOKEN_RESHAPESHAPEEDGE, 03301 OpReformShapeEdge::GetState)); 03302 }
|
|
Will reshape the edge being edited using Jims curve distorting method.
Definition at line 3198 of file shapeops.cpp. 03199 { 03200 const double factor = 0.656875; 03201 PathVerb* Verbs = EditEdge->GetVerbArray(); 03202 DocCoord* Coords = EditEdge->GetCoordArray(); 03203 if (Verbs[Index] == PT_BEZIERTO) // first ctrl pt won't have closefigure set 03204 { 03205 DocCoord ControlOffset; 03206 ControlOffset.x = (INT32)(OrigControl1.x + (Offset.x) * factor / paramdist); 03207 ControlOffset.y = (INT32)(OrigControl1.y + (Offset.y) * factor / paramdist); 03208 03209 ControlOffset.x -= Coords[Index].x; 03210 ControlOffset.y -= Coords[Index].y; 03211 03212 Coords[Index].x += ControlOffset.x; 03213 Coords[Index].y += ControlOffset.y; 03214 03215 ControlOffset.x = (INT32)(OrigControl2.x + (Offset.x) * factor / (1.0-paramdist)); 03216 ControlOffset.y = (INT32)(OrigControl2.y + (Offset.y) * factor / (1.0-paramdist)); 03217 03218 ControlOffset.x -= Coords[Index+1].x; 03219 ControlOffset.y -= Coords[Index+1].y; 03220 03221 Coords[Index+1].x += ControlOffset.x; 03222 Coords[Index+1].y += ControlOffset.y; 03223 } 03224 }
|
|
Renders the drag blobs of this operation.
Reimplemented from Operation. Definition at line 3343 of file shapeops.cpp. 03344 { 03345 // If being called from DocView::RenderView, then the spread could be wrong - so 03346 // convert the rectangle if necessary. 03347 if (pSpread != StartSpread) 03348 { 03349 Rect.lo = MakeRelativeToSpread(StartSpread, pSpread, Rect.lo); 03350 Rect.hi = MakeRelativeToSpread(StartSpread, pSpread, Rect.hi); 03351 } 03352 03353 ERROR3IF(EditShape == NULL, "Can't render a non-existant shape!"); 03354 if (EditShape == NULL) 03355 return; 03356 03357 // start a rendering loop 03358 RenderRegion* pRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR); 03359 while (pRegion) 03360 { 03361 // Set the line colour 03362 pRegion -> SetFillColour(COLOUR_NONE); 03363 pRegion -> SetLineColour(COLOUR_XOREDIT); 03364 03365 // Draw the outline 03366 EditShape->RenderEorDrag(pRegion); 03367 03368 // Get the Next render region 03369 pRegion = DocView::GetNextOnTop(NULL); 03370 } 03371 }
|
|
Use to reverse an edit path before copying it to the other edge path NOTE: This function assumes that the edge path consists of a MoveTo-BezierTo.
Definition at line 3244 of file shapeops.cpp. 03245 { 03246 const INT32 NumCoords = EditEdge->GetNumCoords(); 03247 ERROR3IF(NumCoords != 4, "Edit edge was not a single Bezier section"); 03248 03249 if (!( NewPath->Initialise(NumCoords,4) && NewPath->CopyPathDataFrom(EditEdge) )) 03250 return FALSE; 03251 03252 if (!ShouldMirror) 03253 NewPath->Reverse(); 03254 03255 /* if (ShouldMirror) 03256 { 03257 DocCoord* Points = NewPath->GetCoordArray(); 03258 // Transform point 1 03259 double angle1 = atan2((double)Points[3].y-Points[0].y, (double)Points[3].x-Points[0].x) * (180/PI); 03260 double angle2 = atan2((double)Points[1].y-Points[0].y, (double)Points[1].x-Points[0].x) * (180/PI); 03261 03262 Matrix Trans(-Points[0].x, -Points[0].x); 03263 Trans *= Matrix(-ANGLE((angle2-angle1))); 03264 Trans *= Matrix(Points[0].x, Points[0].x); 03265 03266 Trans.transform(&(Points[1])); 03267 03268 // Transform point 2 03269 angle1 = atan2((double)Points[0].y-Points[3].y, (double)Points[0].x-Points[3].x) * (180/PI); 03270 angle2 = atan2((double)Points[2].y-Points[3].y, (double)Points[2].x-Points[3].x) * (180/PI); 03271 03272 Trans = Matrix(-Points[3].x, -Points[3].x); 03273 Trans *= Matrix(-ANGLE((angle2-angle1))); 03274 Trans *= Matrix(Points[3].x, Points[3].x); 03275 03276 Trans.transform(&(Points[2])); 03277 }*/ 03278 03279 return TRUE; 03280 }
|
|
Definition at line 352 of file shapeops.h. |
|
Definition at line 349 of file shapeops.h. |
|
Definition at line 342 of file shapeops.h. |
|
Definition at line 350 of file shapeops.h. |
|
Definition at line 346 of file shapeops.h. |
|
Definition at line 347 of file shapeops.h. |
|
Definition at line 343 of file shapeops.h. |
|
Definition at line 351 of file shapeops.h. |
|
Definition at line 344 of file shapeops.h. |
|
Definition at line 348 of file shapeops.h. |
|
Definition at line 345 of file shapeops.h. |