#include <shapeops.h>
Inheritance diagram for OpDragRegularShape:
Public Member Functions | |
OpDragRegularShape () | |
Constructor. This sets a few of the operation variables. | |
void | DoStartDragEdit (NodeRegularShape *, DocCoord, Spread *, DragType, BOOL QuickShape) |
void | DoStartDragEditCurve (NodeRegularShape *, DocCoord, Spread *, DragType, DocCoord Start, DocCoord End) |
This is called to start a drag operation on a regular shape. | |
virtual BOOL | SnappingDrag () |
virtual void | DragPointerMove (DocCoord Pos, ClickModifiers Mods, Spread *pSpread, BOOL bSolidDrag) |
This is called every time the mouse moves, during a drag. We need to render off the shape in its current position, calculate any changes to apply to it then render it back on. | |
virtual void | DragFinished (DocCoord Pos, ClickModifiers Mods, Spread *pSpread, BOOL Success, BOOL bSolidDrag) |
This is called when a drag operation finishes. If the drag was sucessful then the OriginalShape in the document is updated. | |
virtual void | RenderDragBlobs (DocRect, Spread *, BOOL bSolidDrag) |
Renders the current version of the shape to the window. | |
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_CENTRE, DRAG_ELLIPSE, DRAG_PRIMARY, DRAG_STELLATION, DRAG_PRIMARYCURVE, DRAG_STELLATIONCURVE } |
Private Member Functions | |
BOOL | ProcessCentre (DocCoord Pos, ClickModifiers Mods) |
This is called to update the EditShape after a mouse movement in a centre point drag. The shape is being translated. Constrain works from angles from the original centre point of the shape. | |
BOOL | ProcessPrimary (DocCoord Pos, ClickModifiers Mods) |
This is called to update the EditShape after a mouse movement in a primary point drag. | |
BOOL | ProcessRectangle (DocCoord Pos, ClickModifiers Mods) |
This is called to update a rectangular EditShape after a mouse movement during a drag on one if its corners. | |
BOOL | ProcessRectangleDiagonal (DocCoord Pos, ClickModifiers Mods) |
This is called to update a rectangular EditShape after a mouse movement during a drag on one if its corners. The rectangle is resized about the opposite corner to the drag corner. | |
BOOL | ProcessRectangleEdge (DocCoord Pos, DocCoord OtherEnd) |
This is called during a rectangle drag to resize the rectangle about either edge. | |
BOOL | ProcessEllipse (DocCoord Pos, ClickModifiers Mods) |
This is called to update the ellipitical EditShape after a mouse movement during a drag. | |
BOOL | ProcessStellation (DocCoord Pos, ClickModifiers Mods) |
This is called to update the EditShape after a mouse movement in a stellation point drag. | |
BOOL | ProcessRadius (DocCoord Pos, ClickModifiers Mods) |
This is called to process drags on the primary points and on the major axes. | |
BOOL | ProcessPrimaryCurve (DocCoord Pos) |
This is called to update the EditShape after a mouse movement in a primary curvature point drag. | |
BOOL | ProcessStellationCurve (DocCoord Pos) |
This is called to update the EditShape after a mouse movement in a stellation curvature point drag. | |
void | WheelConstrain (DocCoord *PointerPos, const DocCoord StartPos) |
This is called to constrain a point to a steering-wheel shape. The wheel is centred on the centre of OriginalShape. It has radius of the distance from the centre to StartPos. The other constrain line is the line passing through the centre point and StartPos. | |
DocCoord | GetUTPosition (DocCoord TransedPos) |
This is called to convert a current mouse postion to untransform back to the coordinates used by the untranslated OriginalShape. | |
BOOL | IsJoinAcute (const DocCoord *pJoin, const DocCoord *pOtherEndOfJoin, const DocCoord *pOtherPoint) |
For seeing the perpendicual distance from pOtherPoint to the line pJoin-pOtherEndOfJoin end on the line or before pJoin. Used when dragging along a line to see if the drag point has gon back beyond the start of the line. | |
Private Attributes | |
DocCoord | LastMousePos |
DocCoord | StartMousePos |
Spread * | StartSpread |
NodeRegularShape * | OriginalShape |
NodeRegularShape * | EditShape |
Cursor * | pCursor |
INT32 | CurrentCursorID |
DragType | DragObject |
DocCoord | LineStart |
DocCoord | LineEnd |
Matrix | transMat |
DocCoord | RectangleArray [4] |
BOOL | DragAroundCentre |
Definition at line 235 of file shapeops.h.
|
Definition at line 240 of file shapeops.h. 00240 {DRAG_CENTRE, DRAG_ELLIPSE, DRAG_PRIMARY, DRAG_STELLATION, 00241 DRAG_PRIMARYCURVE, DRAG_STELLATIONCURVE};
|
|
Constructor. This sets a few of the operation variables.
Definition at line 1532 of file shapeops.cpp. 01533 { 01534 pCursor = NULL; 01535 StartSpread = NULL; 01536 OriginalShape = NULL; 01537 EditShape = NULL; 01538 }
|
|
Definition at line 1563 of file shapeops.cpp. 01565 { 01566 // Adjust anchor point so this is the actual point on the shape that the drag starts from 01567 INT32 DragPointNumber = -1; 01568 pShape->DetermineClickEffect(&Anchor, pSpread, &DragPointNumber); 01569 01570 // Take note of the drag parameters 01571 DragObject = DragThing; 01572 LastMousePos = Anchor; 01573 StartMousePos = Anchor; 01574 StartSpread = pSpread; 01575 OriginalShape = pShape; 01576 DragAroundCentre = QuickShape; 01577 01578 // We also need to make a version of the shape that we can change 01579 EditShape = (NodeRegularShape*) OriginalShape->SimpleCopy(); 01580 BOOL Success = (EditShape != NULL); 01581 01582 if (Success) 01583 { 01584 // Create the cursors and display it (if it was created ok) 01585 pCursor = new Cursor(TOOLID_BEZTOOL, _R(IDC_MOVEBEZIERCURSOR)); 01586 01587 if ( pCursor != NULL && pCursor->IsValid()) 01588 { // Select the cursor 01589 CurrentCursorID = CursorStack::GPush(pCursor); 01590 } 01591 else 01592 { // Set cursor pointer to NULL to indicate its non appearence 01593 if (pCursor != NULL) 01594 delete pCursor; 01595 pCursor = NULL; 01596 } 01597 01598 // And tell the Dragging system that we need drags to happen 01599 Success = StartDrag(DRAGTYPE_AUTOSCROLL, NULL, &LastMousePos, FALSE); 01600 01601 // Render the initial shape 01602 if (Success) 01603 RenderDragBlobs(DocRect(), pSpread, FALSE); 01604 } 01605 01606 // Do special rectangle setup 01607 if (Success && (DragObject == DRAG_PRIMARY) && OriginalShape->IsARectangle()) 01608 { 01609 if (DragPointNumber == -1) 01610 { 01611 ERROR3("Couldn't find the rectangle drag point"); 01612 Success = FALSE; 01613 } 01614 01615 // Get the significant points 01616 DocCoord* PointsArray = NULL; 01617 INT32 NumberPoints = 0; 01618 Success = OriginalShape->BuildPolygonPoints(&PointsArray, &NumberPoints); 01619 01620 // Transform the significant points to document space 01621 if (Success) 01622 { 01623 // Get the shape matrix and its inverse 01624 Matrix ShapeMat; 01625 OriginalShape->GetTransformMatrix(&ShapeMat); 01626 ShapeMat.transform((Coord*)PointsArray,NumberPoints); 01627 } 01628 01629 // Get the points opposite to the drag point, the stationary point 01630 INT32 Opposite = 0; 01631 if (Success) 01632 Opposite = (DragPointNumber + ((NumberPoints-2)/2)) % (NumberPoints-2); 01633 01634 // Copy the points into the array. ) is the opposite point, 2 is the drag point 01635 if (Success) 01636 { 01637 INT32 Increment = (NumberPoints-2)/4; 01638 INT32 Copy = 0; 01639 for (INT32 i = Opposite; Copy < 4; i+=Increment) 01640 RectangleArray[Copy++] = PointsArray[i%(NumberPoints-2)]; 01641 01642 // Make the array go clockwise 01643 DocCoord temp = RectangleArray[1]; 01644 RectangleArray[1] = RectangleArray[3]; 01645 RectangleArray[3] = temp; 01646 } 01647 01648 delete PointsArray; 01649 } 01650 01651 if (!Success) 01652 { 01653 InformError(); 01654 FailAndExecute(); 01655 End(); 01656 } 01657 }
|
|
This is called to start a drag operation on a regular shape.
Definition at line 1680 of file shapeops.cpp. 01682 { 01683 DoStartDragEdit(pShape, Anchor, pSpread, DragThing, TRUE); 01684 01685 // Take note of the additional drag parameters 01686 LineStart = Start; 01687 LineEnd = End; 01688 }
|
|
This is called when a drag operation finishes. If the drag was sucessful then the OriginalShape in the document is updated.
Reimplemented from Operation. Definition at line 1819 of file shapeops.cpp. 01821 { 01822 // Do some tidying up 01823 RenderDragBlobs( DocRect(), StartSpread, bSolidDrag ); 01824 if (pCursor != NULL) 01825 { 01826 CursorStack::GPop(CurrentCursorID); 01827 delete pCursor; 01828 CurrentCursorID = 0; 01829 pCursor = NULL; 01830 } 01831 EndDrag(); 01832 BeginSlowJob(); 01833 01834 if ( Success ) 01835 { 01836 BOOL Failed = !DoStartSelOp(FALSE, TRUE, FALSE, TRUE); 01837 01838 //DocView* pDocView = DocView::GetSelected(); 01839 //ERROR3IF( pDocView == NULL, "There was no selected docview when editing a shape" ); 01840 01841 // Will the original shape allow the op to happen? 01842 ObjChangeFlags cFlags; 01843 cFlags.TransformNode = TRUE; 01844 ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,OriginalShape,this); 01845 Failed = !OriginalShape->AllowOp(&ObjChange); 01846 01847 if (!Failed) 01848 Failed = (RecalcBoundsAction::DoRecalc(this, &UndoActions, OriginalShape) == AC_FAIL); 01849 01850 // Now update the shape depending on the dragtype 01851 if (!Failed) 01852 { 01853 switch (DragObject) 01854 { 01855 case DRAG_CENTRE: 01856 { 01857 // Construct a transformation matrix to move the shape 01858 Trans2DMatrix* TransMat = new Trans2DMatrix(EditShape->GetCentrePoint().x - OriginalShape->GetCentrePoint().x, 01859 EditShape->GetCentrePoint().y - OriginalShape->GetCentrePoint().y); 01860 DoTransformNode(OriginalShape, TransMat); 01861 break; 01862 } 01863 case DRAG_ELLIPSE: 01864 case DRAG_PRIMARY: 01865 { // Transform shape using the matrix 01866 Trans2DMatrix* tm = new Trans2DMatrix(transMat); 01867 Failed = ! DoTransformNode(OriginalShape, tm) ; 01868 Failed |= !ChangeShapePointAction::DoToggle(this, &UndoActions, OriginalShape, 01869 ChangeShapePointAction::CHANGE_CENTRE, 01870 OriginalShape->GetUTCentrePoint()); 01871 OriginalShape->SetCentrePoint(EditShape->GetUTCentrePoint()); 01872 Failed |= !ChangeShapePointAction::DoToggle(this, &UndoActions, OriginalShape, 01873 ChangeShapePointAction::CHANGE_MINOR, 01874 OriginalShape->GetUTMinorAxes()); 01875 OriginalShape->SetMinorAxes(EditShape->GetUTMinorAxes()); 01876 Failed |= !ChangeShapePointAction::DoToggle(this, &UndoActions, OriginalShape, 01877 ChangeShapePointAction::CHANGE_MAJOR, 01878 OriginalShape->GetUTMajorAxes()); 01879 OriginalShape->SetMajorAxes(EditShape->GetUTMajorAxes()); 01880 break; 01881 } 01882 case DRAG_STELLATION: 01883 Failed = !ChangeShapeDataAction::DoToggle(this, &UndoActions, OriginalShape, 01884 ChangeShapeDataAction::CHANGE_STELLRADIUSTOPRIMARY, 01885 OriginalShape->GetStellRadiusToPrimary() ); 01886 OriginalShape->SetStellRadiusToPrimary(EditShape->GetStellRadiusToPrimary()); 01887 Failed = !ChangeShapeDataAction::DoToggle(this, &UndoActions, OriginalShape, 01888 ChangeShapeDataAction::CHANGE_STELLATIONOFFSET, 01889 OriginalShape->GetStellationRatio() ); 01890 OriginalShape->SetStellationRatio(EditShape->GetStellationRatio()); 01891 break; 01892 case DRAG_PRIMARYCURVE: 01893 Failed = !ChangeShapeDataAction::DoToggle(this, &UndoActions, OriginalShape, 01894 ChangeShapeDataAction::CHANGE_PRIMARYCURVETOPRIMARY, 01895 OriginalShape->GetPrimaryCurveToPrimary() ); 01896 OriginalShape->SetPrimaryCurveToPrimary(EditShape->GetPrimaryCurveToPrimary()); 01897 break; 01898 case DRAG_STELLATIONCURVE: 01899 Failed = !ChangeShapeDataAction::DoToggle(this, &UndoActions, OriginalShape, 01900 ChangeShapeDataAction::CHANGE_STELLCURVETOSTELL, 01901 OriginalShape->GetStellCurveToStell() ); 01902 OriginalShape->SetStellCurveToStell(EditShape->GetStellCurveToStell()); 01903 break; 01904 default: 01905 ERROR3("What was that drag type?"); 01906 break; 01907 } 01908 } 01909 01910 // Recalculate the path's bounding box 01911 OriginalShape->InvalidateBoundingRect(); 01912 OriginalShape->InvalidateCache(); 01913 01914 // tell the world that something in the selection has changed so that selection bounds are updated 01915 SelRange *Sel = GetApplication()->FindSelection(); 01916 Sel->Update(); 01917 01918 // Try to expand the pasteboard if necessary to include the new bounds of the object 01919 DocRect NewBounds = Sel->GetBoundingRect(); 01920 ERROR3IF(pSpread == NULL, "Unexpectedly NULL Spread pointer"); 01921 pSpread->ExpandPasteboardToInclude(NewBounds); 01922 01923 if (!Failed) 01924 { 01925 // Update effected parents 01926 ObjChange.Define(OBJCHANGE_FINISHED,cFlags,OriginalShape,this); 01927 Failed = !UpdateChangedNodes(&ObjChange); 01928 } 01929 01930 if (!Failed && OriginalShape->FindParentSpread()!=NULL) 01931 Failed = (RecordBoundsAction::DoRecord(this, &UndoActions, OriginalShape) == AC_FAIL) ; 01932 01933 // If any of the above failed the kill the op 01934 if (Failed) 01935 { 01936 // PATRACE( _T("An action failed!\n")); 01937 FailAndExecute(); 01938 } 01939 } 01940 else 01941 { 01942 // Set up the flags that say it all went wrong 01943 FailAndExecute(); 01944 } 01945 01946 delete (EditShape); 01947 End(); 01948 }
|
|
This is called every time the mouse moves, during a drag. We need to render off the shape in its current position, calculate any changes to apply to it then render it back on.
Reimplemented from Operation. Definition at line 1722 of file shapeops.cpp. 01723 { 01724 // If the PointerPois is the same as the last one, then dont bother doing anything 01725 if (PointerPos == LastMousePos) 01726 return; 01727 01728 // If drag has moved onto a different spread, convert the coord to be relative to the 01729 // original spread. 01730 if (pSpread != StartSpread) 01731 PointerPos = MakeRelativeToSpread(StartSpread, pSpread, PointerPos); 01732 01733 // Rub out the old EORed version of the path 01734 RenderDragBlobs( DocRect(), StartSpread, bSolidDrag); 01735 01736 // Now apply the changes to the EditShape, depending on the drag type 01737 BOOL Success = FALSE; 01738 switch (DragObject) 01739 { 01740 case DRAG_CENTRE: 01741 { 01742 Success = ProcessCentre(PointerPos, ClickMods); 01743 break; 01744 } 01745 case DRAG_ELLIPSE: 01746 { 01747 if (DragAroundCentre) 01748 Success = ProcessPrimary(PointerPos, ClickMods); 01749 else 01750 Success = ProcessEllipse(PointerPos, ClickMods); 01751 break; 01752 } 01753 case DRAG_PRIMARY: 01754 { 01755 if (EditShape->IsARectangle() && !DragAroundCentre) 01756 Success = ProcessRectangle(PointerPos, ClickMods); 01757 else 01758 Success = ProcessPrimary(PointerPos, ClickMods); 01759 break; 01760 } 01761 case DRAG_STELLATION: 01762 { 01763 Success = ProcessStellation(PointerPos, ClickMods); 01764 break; 01765 } 01766 case DRAG_PRIMARYCURVE: 01767 { 01768 Success = ProcessPrimaryCurve(PointerPos); 01769 break; 01770 } 01771 case DRAG_STELLATIONCURVE: 01772 { 01773 Success = ProcessStellationCurve(PointerPos); 01774 break; 01775 } 01776 default: 01777 ERROR3("What was the drag type?"); 01778 break; 01779 } 01780 01781 if (Success) 01782 { 01783 // Draw in the new version of the path 01784 RenderDragBlobs( DocRect(), StartSpread, bSolidDrag); 01785 01786 // Update the Last Mouse Position 01787 LastMousePos = PointerPos; 01788 01789 // Tell anyone that's interested 01790 BROADCAST_TO_ALL(ShapeEditedMsg(EditShape, pSpread)); 01791 } 01792 else 01793 { 01794 InformError(); 01795 EndDrag(); 01796 FailAndExecute(); 01797 End(); 01798 } 01799 }
|
|
Find out the state of the operation at the specific time.
Definition at line 2757 of file shapeops.cpp. 02758 { 02759 OpState Blobby; 02760 02761 return Blobby; 02762 }
|
|
This is called to convert a current mouse postion to untransform back to the coordinates used by the untranslated OriginalShape.
Definition at line 2660 of file shapeops.cpp. 02661 { 02662 Matrix TransMat; 02663 OriginalShape->GetTransformMatrix(&TransMat); 02664 TransMat = TransMat.Inverse(); 02665 TransMat.transform(&TransedPos); 02666 02667 return TransedPos; 02668 }
|
|
Adds the operation to the list of all known operations.
Reimplemented from SimpleCCObject. Definition at line 2734 of file shapeops.cpp. 02735 { 02736 return (RegisterOpDescriptor( 0, 02737 _R(IDS_EDITREGULARSHAPEOP), 02738 CC_RUNTIME_CLASS(OpDragRegularShape), 02739 OPTOKEN_DRAGREGULARSHAPE, 02740 OpDragRegularShape::GetState)); 02741 }
|
|
For seeing the perpendicual distance from pOtherPoint to the line pJoin-pOtherEndOfJoin end on the line or before pJoin. Used when dragging along a line to see if the drag point has gon back beyond the start of the line.
Definition at line 2716 of file shapeops.cpp. 02717 { 02718 return DocCoord::IsJoinAcute(pJoin, pOtherEndOfJoin, pOtherPoint); 02719 }
|
|
This is called to update the EditShape after a mouse movement in a centre point drag. The shape is being translated. Constrain works from angles from the original centre point of the shape.
Definition at line 2493 of file shapeops.cpp. 02494 { 02495 // Constrain and snap the mouse point if required 02496 DocCoord OldCentre = OriginalShape->GetCentrePoint(); 02497 if (ClickMods.Constrain) 02498 DocView::ConstrainToAngle(OldCentre, &PointerPos); 02499 DocView::SnapCurrent(StartSpread,&PointerPos); 02500 02501 // Translate shape based on the movement. 02502 DocCoord Offset = PointerPos - EditShape->GetCentrePoint(); 02503 Trans2DMatrix Trans(Offset.x, Offset.y); 02504 EditShape->Transform(Trans); 02505 02506 return TRUE; 02507 }
|
|
This is called to update the ellipitical EditShape after a mouse movement during a drag.
Definition at line 2184 of file shapeops.cpp. 02185 { 02186 // If this is an adjust drag then work around the centre 02187 if (Mods.Adjust) 02188 { 02189 if (Mods.Constrain) 02190 WheelConstrain(&PointerPos, StartMousePos); 02191 02192 return ProcessRadius(PointerPos, Mods); 02193 } 02194 02195 // Snap the mouse point to the active grid 02196 DocView::SnapCurrent(StartSpread,&PointerPos); 02197 02198 // Untransform the current pointer pos 02199 DocCoord UTPointerPos = GetUTPosition(PointerPos); 02200 const DocCoord UTCentre = OriginalShape->GetUTCentrePoint(); 02201 const DocCoord Centre = OriginalShape->GetCentrePoint(); 02202 Matrix OriginalMat; 02203 OriginalShape->GetTransformMatrix(&OriginalMat); 02204 DocCoord UTStartPos = GetUTPosition(StartMousePos); 02205 DocCoord UTOppositePos = DocCoord::PositionPointFromRatio(UTCentre, UTStartPos, -1.0); 02206 DocCoord OppositePos = UTOppositePos; 02207 OriginalMat.transform(&OppositePos); 02208 02209 // Get rotation of original and current dragging points 02210 DocCoord StartDragPoint = StartMousePos - OppositePos; 02211 double OrigRotation = atan2((double)StartDragPoint.y, (double)StartDragPoint.x); 02212 02213 // Get the scaling factor 02214 const double OriginalLength = OppositePos.Distance(StartMousePos); 02215 const double Ax = (StartMousePos.x-OppositePos.x); 02216 const double Ay = (StartMousePos.y-OppositePos.y); 02217 const double Bx = (PointerPos.x-OppositePos.x); 02218 const double By = (PointerPos.y-OppositePos.y); 02219 const double NewLength = ((Ax*Bx) + (Ay*By)) / sqrt((Ax*Ax) + (Ay*Ay)); 02220 double ScaleFactor = NewLength/OriginalLength; 02221 02222 // Transform to origin, rotate so drag point to opposite lies on the origin, 02223 // scale, rotate back to current rotation, then transform back 02224 Matrix Transform(-OppositePos.x, -OppositePos.y); 02225 Transform*= Matrix(ANGLE(-(OrigRotation*(180/PI)))); 02226 Transform*= Matrix(fixed16(ScaleFactor),fixed16(1.0)); 02227 Transform*= Matrix(ANGLE(OrigRotation*(180/PI))); 02228 Transform*= Matrix(OppositePos.x, OppositePos.y); 02229 Trans2DMatrix Trans(Transform); 02230 02231 // Copy the original shape then apply the transform 02232 delete EditShape; 02233 EditShape = (NodeRegularShape*)OriginalShape->SimpleCopy(); 02234 if (EditShape != NULL) 02235 { 02236 EditShape->Transform(Trans); 02237 transMat = Transform; 02238 return TRUE; 02239 } 02240 else 02241 return FALSE; 02242 }
|
|
This is called to update the EditShape after a mouse movement in a primary point drag.
Definition at line 2158 of file shapeops.cpp. 02159 { 02160 if (Mods.Constrain) 02161 { 02162 WheelConstrain(&PointerPos, StartMousePos); 02163 } 02164 02165 return ProcessRadius(PointerPos, Mods); 02166 }
|
|
This is called to update the EditShape after a mouse movement in a primary curvature point drag.
Definition at line 1965 of file shapeops.cpp. 01966 { 01967 // Untransform the various things 01968 Matrix Mat; 01969 EditShape->GetTransformMatrix(&Mat); 01970 Mat = Mat.Inverse(); 01971 DocCoord UTLineStart = LineStart; 01972 DocCoord UTLineEnd = LineEnd; 01973 DocCoord UTPointerPos = PointerPos; 01974 Mat.transform(&UTLineStart); 01975 Mat.transform(&UTLineEnd); 01976 Mat.transform(&UTPointerPos); 01977 01978 // Move the point along the edge line to get new ratio 01979 double c = UTLineStart.Distance(UTPointerPos); 01980 double b = fabs(DocCoord::DistanceFromLine(UTLineStart, UTLineEnd, UTPointerPos)); 01981 double a = sqrt(c*c - b*b); 01982 double NewRatio = a/EditShape->GetUTMajorAxes().Distance(EditShape->GetUTCentrePoint()); 01983 01984 // Detect a zero ratio case (otherwise the point moves back along the line) 01985 if (!IsJoinAcute(&UTLineStart, &UTLineEnd, &UTPointerPos)) 01986 { 01987 NewRatio = 0.0; 01988 } 01989 else 01990 { 01991 // Restrict to fit with along the edge 01992 if (EditShape->IsStellated()) 01993 { 01994 // Get the position of the stellation curvature point and its distance 01995 const double OuterMajorLength = OriginalShape->GetMajorRadiusSize(); 01996 const double StellationCurvatureLength = OuterMajorLength * OriginalShape->GetStellCurveToStell(); 01997 const double AvailableLength = (UTLineStart.Distance(UTLineEnd)) - StellationCurvatureLength; 01998 01999 double top = a; 02000 if ( (AvailableLength - a) < 1.0) 02001 top = AvailableLength; 02002 02003 NewRatio = top/EditShape->GetUTMajorAxes().Distance(EditShape->GetUTCentrePoint()); 02004 } 02005 else 02006 { 02007 // We need to limit the drag to halfway along the drag line 02008 const double MaxLength = UTLineStart.Distance(UTLineEnd)/2.0; 02009 if (a > MaxLength) 02010 NewRatio = MaxLength/EditShape->GetUTMajorAxes().Distance(EditShape->GetUTCentrePoint()); 02011 } 02012 } 02013 02014 EditShape->SetPrimaryCurveToPrimary(NewRatio); 02015 02016 return TRUE; 02017 }
|
|
This is called to process drags on the primary points and on the major axes.
Definition at line 2524 of file shapeops.cpp. 02525 { 02526 // Snap the mouse point to the active grid 02527 DocView::SnapCurrent(StartSpread,&Pos); 02528 02529 // Untransform the current pointer pos 02530 DocCoord UTPointerPos = GetUTPosition(Pos); 02531 const DocCoord UTCentre = OriginalShape->GetUTCentrePoint(); 02532 const DocCoord Centre = OriginalShape->GetCentrePoint(); 02533 02534 // Get rotation of original and current primary points 02535 DocCoord CurrentPrimary = StartMousePos - Centre; 02536 DocCoord NewPrimary = Pos - Centre; 02537 double OrigPrimaryRotation = atan2((double)CurrentPrimary.y, (double)CurrentPrimary.x); 02538 double NewPrimaryRotation = atan2((double)NewPrimary.y, (double)NewPrimary.x); 02539 ANGLE RotBy(-(OrigPrimaryRotation - NewPrimaryRotation)*(180/PI)); 02540 02541 // Get the scaling factor 02542 double NewLength = Pos.Distance(Centre); 02543 double CurrentLength = StartMousePos.Distance(Centre); 02544 double ScaleFactor = (CurrentLength != 0.0) ? (NewLength/CurrentLength) : 0.001; 02545 02546 // Transform to origin, scale, rotate then transform back 02547 Matrix Transform(-Centre.x, -Centre.y); 02548 Transform*= Matrix(RotBy); 02549 Transform*= Matrix(fixed16(ScaleFactor),fixed16(ScaleFactor)); 02550 Transform*= Matrix(Centre.x, Centre.y); 02551 Trans2DMatrix Trans(Transform); 02552 02553 // Copy the original shape then apply the transform 02554 delete EditShape; 02555 EditShape = (NodeRegularShape*)OriginalShape->SimpleCopy(); 02556 if (EditShape != NULL) 02557 { 02558 EditShape->Transform(Trans); 02559 transMat = Transform; 02560 return TRUE; 02561 } 02562 else 02563 return FALSE; 02564 }
|
|
This is called to update a rectangular EditShape after a mouse movement during a drag on one if its corners.
Definition at line 2260 of file shapeops.cpp. 02261 { 02262 // If this is an adjust drag then work around the centre 02263 if (Mods.Adjust) 02264 { 02265 if (Mods.Constrain) 02266 WheelConstrain(&PointerPos, StartMousePos); 02267 02268 return ProcessRadius(PointerPos, Mods); 02269 } 02270 02271 // See which line the mouse is nearest to determine the type of the drag 02272 if (Mods.Constrain) 02273 { 02274 double Diagonal = DocCoord::DistanceFromLine(RectangleArray[2], RectangleArray[0], PointerPos); 02275 double Prev = DocCoord::DistanceFromLine(RectangleArray[2], RectangleArray[1], PointerPos); 02276 double Next = DocCoord::DistanceFromLine(RectangleArray[2], RectangleArray[3], PointerPos); 02277 02278 if ((Diagonal <= Prev) && (Diagonal <= Next)) 02279 return ProcessRectangleDiagonal(PointerPos, Mods); 02280 else 02281 { 02282 if (Prev <= Next) 02283 return ProcessRectangleEdge(PointerPos, RectangleArray[1]); 02284 else 02285 return ProcessRectangleEdge(PointerPos, RectangleArray[3]); 02286 } 02287 } 02288 else 02289 return ProcessRectangleDiagonal(PointerPos, Mods); 02290 }
|
|
This is called to update a rectangular EditShape after a mouse movement during a drag on one if its corners. The rectangle is resized about the opposite corner to the drag corner.
Definition at line 2306 of file shapeops.cpp. 02307 { 02308 // Constrain the mouse so the aspect of the shape is maintained 02309 if (Mods.Constrain) 02310 { 02311 // Get the scaling factor 02312 const double RectDiagonal = RectangleArray[0].Distance(RectangleArray[2]); 02313 const double Ax = (RectangleArray[2].x-RectangleArray[0].x); 02314 const double Ay = (RectangleArray[2].y-RectangleArray[0].y); 02315 const double Bx = (PointerPos.x-RectangleArray[0].x); 02316 const double By = (PointerPos.y-RectangleArray[0].y); 02317 const double NewLength = ((Ax*Bx) + (Ay*By)) / sqrt((Ax*Ax) + (Ay*Ay)); 02318 double ratio = NewLength/RectDiagonal; 02319 02320 // reposition the pointer 02321 PointerPos = DocCoord::PositionPointFromRatio(RectangleArray[0], RectangleArray[2], ratio); 02322 } 02323 02324 // Snap the mouse point to the active grid 02325 DocView::SnapCurrent(StartSpread,&PointerPos); 02326 02327 // Get the shape matrix and its inverse 02328 Matrix ShapeMat; 02329 OriginalShape->GetTransformMatrix(&ShapeMat); 02330 Matrix InvShapeMat = ShapeMat; 02331 InvShapeMat = InvShapeMat.Inverse(); 02332 02333 // Copy the vertext array for changing 02334 DocCoord VertexArray[4]; 02335 for (INT32 loop = 0; loop < 4; loop++) 02336 VertexArray[loop] = RectangleArray[loop]; 02337 02338 // Get the matrix to take the original shape down to the unit square 02339 double OrigA = RectangleArray[3].x - RectangleArray[0].x; 02340 double OrigB = RectangleArray[3].y - RectangleArray[0].y; 02341 double OrigC = RectangleArray[1].x - RectangleArray[0].x; 02342 double OrigD = RectangleArray[1].y - RectangleArray[0].y; 02343 double OrigE = RectangleArray[0].x; 02344 double OrigF = RectangleArray[0].y; 02345 02346 // Invert this 02347 double Det = OrigA*OrigD - OrigB*OrigC; 02348 ERROR2IF(Det==0.0, FALSE, "Matrix Inversion Failed"); 02349 double InvertA = OrigD / Det; 02350 double InvertB = -OrigB / Det; 02351 double InvertC = -OrigC / Det; 02352 double InvertD = OrigA / Det; 02353 double InvertE = ((OrigC*OrigF) - (OrigE*OrigD))/Det; 02354 double InvertF = -(((OrigA*OrigF) - (OrigE*OrigB))/Det); 02355 02356 // Now transform the vertex points 02357 // Calculate the offsets from the old point and the fixed point 02358 double dx0 = PointerPos.x - RectangleArray[2].x; 02359 double dy0 = PointerPos.y - RectangleArray[2].y; 02360 02361 double dx3 = RectangleArray[1].x - RectangleArray[0].x; 02362 double dy3 = RectangleArray[1].y - RectangleArray[0].y; 02363 02364 double dx4 = RectangleArray[3].x - RectangleArray[0].x; 02365 double dy4 = RectangleArray[3].y - RectangleArray[0].y; 02366 02367 // Calculate the bits that we need to know 02368 double dx1 = dx3 * ((dy0*dx4-dy4*dx0) / (dx4*dy3-dy4*dx3)); 02369 double dy1 = dy3 * ((dy0*dx4-dy4*dx0) / (dx4*dy3-dy4*dx3)); 02370 double dx2 = dx4 * ((dx3*dy0-dy3*dx0) / (dy4*dx3-dx4*dy3)); 02371 double dy2 = dy4 * ((dx3*dy0-dy3*dx0) / (dy4*dx3-dx4*dy3)); 02372 02373 // Change the parallelogram 02374 VertexArray[1].x = RectangleArray[1].x + (INT32)dx1; 02375 VertexArray[1].y = RectangleArray[1].y + (INT32)dy1; 02376 VertexArray[3].x = RectangleArray[3].x + (INT32)dx2; 02377 VertexArray[3].y = RectangleArray[3].y + (INT32)dy2; 02378 VertexArray[2] = PointerPos; 02379 02380 // Get the array from unit to the new position 02381 double NewA = VertexArray[3].x - VertexArray[0].x; 02382 double NewB = VertexArray[3].y - VertexArray[0].y; 02383 double NewC = VertexArray[1].x - VertexArray[0].x; 02384 double NewD = VertexArray[1].y - VertexArray[0].y; 02385 double NewE = VertexArray[0].x; 02386 double NewF = VertexArray[0].y; 02387 02388 // multiply the two matrices 02389 double FinalA = (InvertA * NewA) + (InvertB * NewC); 02390 double FinalB = (InvertA * NewB) + (InvertB * NewD); 02391 double FinalC = (InvertC * NewA) + (InvertD * NewC); 02392 double FinalD = (InvertC * NewB) + (InvertD * NewD); 02393 INT32 FinalE = (INT32)(NewA*InvertE + NewC*InvertF + NewE); 02394 INT32 FinalF = (INT32)(NewB*InvertE + NewD*InvertF + NewF); 02395 02396 // apply to the rectangle 02397 Trans2DMatrix Transform(Matrix(FinalA, FinalB, FinalC, FinalD, FinalE, FinalF)); 02398 02399 delete EditShape; 02400 EditShape = new (NodeRegularShape); 02401 if (NULL == EditShape) 02402 return FALSE; 02403 02404 OriginalShape->CopyNodeContents(EditShape); 02405 EditShape->TransformCentreAndAxes(Transform); 02406 02407 return TRUE; 02408 }
|
|
This is called during a rectangle drag to resize the rectangle about either edge.
Definition at line 2424 of file shapeops.cpp. 02425 { 02426 // Work in untransformed space to remove skew 02427 const DocCoord DraggingEnd = GetUTPosition(RectangleArray[2]); 02428 OtherEnd = GetUTPosition(OtherEnd); 02429 PointerPos = GetUTPosition(PointerPos); 02430 02431 Matrix TransMat; 02432 OriginalShape->GetTransformMatrix(&TransMat); 02433 TransMat = TransMat.Inverse(); 02434 02435 // Translate rectangle so other (stationary) corner is on origin 02436 TransMat *= Matrix(-OtherEnd.x, -OtherEnd.y); 02437 02438 // Rotate rectangle so drag edge lies along x-axis 02439 double RotAngle = atan2((double)DraggingEnd.y-OtherEnd.y, (double)DraggingEnd.x-OtherEnd.x); 02440 TransMat *= Matrix(ANGLE(-RotAngle*(180/PI))); 02441 02442 // Scale along x-axis 02443 double OrigDragEdgeLength = OtherEnd.Distance(DraggingEnd); 02444 double c = OtherEnd.Distance(PointerPos); 02445 double a = DocCoord::DistanceFromLine(OtherEnd, DraggingEnd, PointerPos); 02446 double NewDragEdgeLength = sqrt((c*c) - (a*a)); 02447 double ScaleFactor = (OrigDragEdgeLength == 0.0) ? 1.0 : NewDragEdgeLength/OrigDragEdgeLength; 02448 if (!IsJoinAcute(&OtherEnd, &DraggingEnd, &PointerPos)) 02449 ScaleFactor = -ScaleFactor; 02450 TransMat *= Matrix (FIXED16(ScaleFactor), FIXED16(1.0)); 02451 02452 // Rotate back 02453 TransMat *= Matrix(ANGLE(RotAngle*(180/PI))); 02454 02455 // Translate back 02456 TransMat *= Matrix(OtherEnd.x, OtherEnd.y); 02457 02458 // And finally apply the original transform back 02459 Matrix OrigMatrix; 02460 OriginalShape->GetTransformMatrix(&OrigMatrix); 02461 TransMat *= OrigMatrix; 02462 02463 // Apply this to the edit shape 02464 delete EditShape; 02465 EditShape = new (NodeRegularShape); 02466 if (NULL == EditShape) 02467 return FALSE; 02468 02469 OriginalShape->CopyNodeContents(EditShape); 02470 Trans2DMatrix Trans2dMatrix(TransMat); 02471 EditShape->TransformCentreAndAxes( Trans2dMatrix ); 02472 02473 return TRUE; 02474 }
|
|
This is called to update the EditShape after a mouse movement in a stellation point drag.
Definition at line 2092 of file shapeops.cpp. 02093 { 02094 // Constrain the mouse movement 02095 if (Mods.Constrain) 02096 { 02097 WheelConstrain(&PointerPos, StartMousePos); 02098 } 02099 02100 // Snap the mouse point to the active grid 02101 DocView::SnapCurrent(StartSpread,&PointerPos); 02102 02103 // Untransform the current pointer pos 02104 DocCoord UTPointerPos = GetUTPosition(PointerPos); 02105 DocCoord UTStartPos = GetUTPosition(StartMousePos); 02106 02107 // Set the new stellation radius length 02108 double PrimaryRadiusLength = OriginalShape->GetUTMajorAxes().Distance(OriginalShape->GetUTCentrePoint()); 02109 double CurrentRadiusLength = UTPointerPos.Distance(OriginalShape->GetUTCentrePoint()); 02110 double NewRadius = min( CurrentRadiusLength / PrimaryRadiusLength, 1.0 ); 02111 EditShape->SetStellRadiusToPrimary(NewRadius); 02112 02113 // Now set the new stellation point offset 02114 // Get angle between the Major axes point and the pointer pos 02115 DocCoord OldPos = UTStartPos - OriginalShape->GetUTCentrePoint(); 02116 DocCoord NewPos = UTPointerPos - OriginalShape->GetUTCentrePoint(); 02117 02118 if (NewPos != DocCoord(0,0)) 02119 { 02120 double OrigAngle = atan2((double)OldPos.y, (double)OldPos.x); 02121 double NewAngle = atan2((double)NewPos.y, (double)NewPos.x); 02122 double OppositeRatio = 180.0/(360.0/EditShape->GetNumSides()) ; 02123 double SettingRatio = ((NewAngle-OrigAngle) / ((2*PI)/EditShape->GetNumSides()) ) + OriginalShape->GetStellationRatio(); 02124 02125 while (SettingRatio > OppositeRatio*2) 02126 SettingRatio -= OppositeRatio*2; 02127 while (SettingRatio < -OppositeRatio*2) 02128 SettingRatio += OppositeRatio*2; 02129 02130 if (SettingRatio > OppositeRatio) 02131 SettingRatio = -OppositeRatio + (SettingRatio-OppositeRatio); 02132 if (SettingRatio < -OppositeRatio) 02133 SettingRatio = OppositeRatio + (SettingRatio+OppositeRatio); 02134 02135 EditShape->SetStellationRatio(SettingRatio); 02136 } 02137 else 02138 EditShape->SetStellationRatio(0.0); 02139 02140 return TRUE; 02141 }
|
|
This is called to update the EditShape after a mouse movement in a stellation curvature point drag.
Definition at line 2034 of file shapeops.cpp. 02035 { 02036 // Untransform the various things 02037 Matrix Mat; 02038 EditShape->GetTransformMatrix(&Mat); 02039 Mat = Mat.Inverse(); 02040 DocCoord UTLineStart = LineStart; 02041 DocCoord UTLineEnd = LineEnd; 02042 DocCoord UTPointerPos = PointerPos; 02043 Mat.transform(&UTLineStart); 02044 Mat.transform(&UTLineEnd); 02045 Mat.transform(&UTPointerPos); 02046 02047 // Move the point along the edge line to get new ratio 02048 double c = UTLineStart.Distance(UTPointerPos); 02049 double b = fabs(DocCoord::DistanceFromLine(UTLineStart, UTLineEnd, UTPointerPos)); 02050 double a = sqrt(c*c - b*b); 02051 double NewRatio = a/EditShape->GetUTMajorAxes().Distance(EditShape->GetUTCentrePoint()); 02052 02053 // Detect a zero ratio case (otherwise the point moves back along the line) 02054 if (!IsJoinAcute(&UTLineStart, &UTLineEnd, &UTPointerPos)) 02055 { 02056 NewRatio = 0.0; 02057 } 02058 else 02059 { 02060 // Restrict to fit with along the edge 02061 const double OuterMajorLength = OriginalShape->GetMajorRadiusSize(); 02062 const double PrimaryCurvatureLength = OuterMajorLength * OriginalShape->GetPrimaryCurveToPrimary(); 02063 const double AvailableLength = (UTLineStart.Distance(UTLineEnd)) - PrimaryCurvatureLength; 02064 02065 double top = a; 02066 if ( (AvailableLength - a) < 1.0) 02067 top = AvailableLength; 02068 02069 NewRatio = top/EditShape->GetUTMajorAxes().Distance(EditShape->GetUTCentrePoint()); 02070 } 02071 02072 EditShape->SetStellCurveToStell(NewRatio); 02073 02074 return TRUE; 02075 }
|
|
Renders the current version of the shape to the window.
Reimplemented from Operation. Definition at line 2682 of file shapeops.cpp. 02683 { 02684 RenderRegion* pRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR ); 02685 while ( pRegion ) 02686 { 02687 // Set the line colour 02688 pRegion -> SetFillColour(COLOUR_NONE); 02689 pRegion -> SetLineColour(COLOUR_XOREDIT); 02690 02691 // And draw an EORed version of how the shape will turn out 02692 EditShape->RenderEorDrag( pRegion ); 02693 02694 // Get the Next render region 02695 pRegion = DocView::GetNextOnTop(NULL); 02696 } 02697 }
|
|
Reimplemented from Operation. Definition at line 1699 of file shapeops.cpp. 01700 { 01701 BOOL NonSnappingDrag = (DragObject==DRAG_PRIMARYCURVE || DragObject==DRAG_STELLATIONCURVE); 01702 return !NonSnappingDrag; 01703 }
|
|
This is called to constrain a point to a steering-wheel shape. The wheel is centred on the centre of OriginalShape. It has radius of the distance from the centre to StartPos. The other constrain line is the line passing through the centre point and StartPos.
Definition at line 2586 of file shapeops.cpp. 02587 { 02588 // Obtain perpendicular distance from StartPos 02589 DocCoord LineConstrainPoint = StartPos; 02590 DocCoord RotStartPos = StartPos; 02591 Matrix Mat(-OriginalShape->GetCentrePoint().x, -OriginalShape->GetCentrePoint().y); 02592 Mat *= Matrix(ANGLE(90)); 02593 Mat *= Matrix(OriginalShape->GetCentrePoint().x, OriginalShape->GetCentrePoint().y); 02594 Mat.transform(&RotStartPos); 02595 double LineDistance1 = DocCoord::DistanceFromLine(OriginalShape->GetCentrePoint(), StartPos, *PointerPos); 02596 double LineDistance2 = DocCoord::DistanceFromLine(OriginalShape->GetCentrePoint(), RotStartPos, *PointerPos); 02597 BOOL UseRotated = FALSE; 02598 double LineDistance = LineDistance1; 02599 if (LineDistance2 < LineDistance) 02600 { 02601 UseRotated = TRUE; 02602 LineDistance = LineDistance2; 02603 } 02604 02605 // Now obtain distance the pointer position is from the circumference of the circle 02606 double Radius = OriginalShape->GetCentrePoint().Distance(StartPos); 02607 const double CurrentRadius = OriginalShape->GetCentrePoint().Distance(*PointerPos); 02608 const double CircleDistance = fabs(Radius - CurrentRadius); 02609 02610 Radius = OriginalShape->GetCentrePoint().Distance(StartPos); 02611 02612 /* // Now if the pointer is past the centre point on the other side of the shape from StartPos 02613 // then we want the distance from the centre point 02614 if (!OriginalShape->IsCircular()) 02615 { 02616 DocCoord StartOrig = StartPos - OriginalShape->GetCentrePoint(); 02617 DocCoord PointerOrig = *PointerPos - OriginalShape->GetCentrePoint(); 02618 double StartAngle = atan2((double)StartOrig.y, (double)StartOrig.x); 02619 double PointerAngle = atan2((double)PointerOrig.y, (double)PointerOrig.x); 02620 if ((PointerAngle < StartAngle-(PI/2)) || (PointerAngle > StartAngle+(PI/2)) ) 02621 LineDistance = CircleDistance*2; 02622 }*/ 02623 02624 // Now constrain to either the line or the circumference 02625 if ((CircleDistance < LineDistance) && (CurrentRadius >= 0.0001)) 02626 { 02627 // Constrain to the circle circumference 02628 *PointerPos = DocCoord::PositionPointFromRatio(OriginalShape->GetCentrePoint(), *PointerPos, Radius/CurrentRadius); 02629 } 02630 else 02631 { 02632 // Constrain to the line 02633 if (UseRotated) 02634 *PointerPos = DocCoord::PositionPointFromRatio(OriginalShape->GetCentrePoint(), RotStartPos, CurrentRadius/Radius); 02635 else 02636 *PointerPos = DocCoord::PositionPointFromRatio(OriginalShape->GetCentrePoint(), StartPos, CurrentRadius/Radius); 02637 } 02638 }
|
|
Definition at line 286 of file shapeops.h. |
|
Definition at line 293 of file shapeops.h. |
|
Definition at line 287 of file shapeops.h. |
|
Definition at line 284 of file shapeops.h. |
|
Definition at line 280 of file shapeops.h. |
|
Definition at line 290 of file shapeops.h. |
|
Definition at line 289 of file shapeops.h. |
|
Definition at line 283 of file shapeops.h. |
|
Definition at line 285 of file shapeops.h. |
|
Definition at line 292 of file shapeops.h. |
|
Definition at line 281 of file shapeops.h. |
|
Definition at line 282 of file shapeops.h. |
|
Definition at line 291 of file shapeops.h. |