OpEditRectangle Class Reference

This operation edits a NodeRect already in the tree. It is normally started when the Rect detects a drag on one of its selected blobs. More...

#include <opsmpshp.h>

Inheritance diagram for OpEditRectangle:

SelOperation UndoableOperation Operation MessageHandler ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 OpEditRectangle ()
 Dummy Contrustor.
void DoDrag (DocCoord Anchor, Spread *, NodeRect *pRect, INT32 FixedCorner)
 Starts up a drag for editing a NodeEllipse. It records the start postion and start spread etc as well as copying the parallelogram of the NodeEllipse to change and creating a new NodeEllipse for the purpose of render EORed stuff.
virtual void DragPointerMove (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL bSolidDrag)
 Recalculates the ellipse according to the new position of the corner that is being dragged, EORs it to the screen and keeps the Parallelogram up to date.
virtual void DragFinished (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL Success, BOOL bSolidDrag)
 If the drag was a success then a copy of the original node in the tree is created and updated ellipse built. The original NodeEllipse is hidden and the new one if inserted into the tree. If any of these things fail then the operation will fail.
virtual void RenderDragBlobs (DocRect, Spread *, BOOL bSolidDrag)
 Renders the Ellipse as it will look if the drag were to end. If we failed to create the Ellipse earlier, it will draw a bounding rect.

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.

Protected Attributes

DocCoord Parallel [4]
INT32 FixedCorner
NodeRectOldRect
BOOL UseRect
NodeRectRectPath
SpreadStartSpread
DocCoord StartPoint
DocCoord LastMousePosition

Private Member Functions

 CC_DECLARE_DYNCREATE (OpEditRectangle)
BOOL CompleteOperation ()
 Builds all the undo and generally edits the rectangle.
BOOL TransformChildAttrs (NodeRect *pRect)
 This performs a bodge that Charles asked to be added that scales the attributes when the rectangle is edited.
void RebuildParallelogram (DocCoord PointerPos)
 Recalculates the parallelogram based on the corner being dragged and the fixed corner. The new parallelogram is copied into the Ellipse we are using for EORing and the Ellipse rebuilt to fit the parallelogram.

Detailed Description

This operation edits a NodeRect already in the tree. It is normally started when the Rect detects a drag on one of its selected blobs.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/6/94

Definition at line 123 of file opsmpshp.h.


Constructor & Destructor Documentation

OpEditRectangle::OpEditRectangle  ) 
 

Dummy Contrustor.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/6/94

Definition at line 142 of file opsmpshp.cpp.

00143 {
00144     RectPath = NULL;
00145 }


Member Function Documentation

OpEditRectangle::CC_DECLARE_DYNCREATE OpEditRectangle   )  [private]
 

BOOL OpEditRectangle::CompleteOperation  )  [private]
 

Builds all the undo and generally edits the rectangle.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/8/94
Returns:
TRUE if it worked, FALSE if it failed

Definition at line 338 of file opsmpshp.cpp.

00339 {
00340     // Start a slow job
00341     BeginSlowJob();
00342 
00343     // Get a node to copy the original into
00344     Node* pNode;
00345     if (!OldRect->NodeCopy(&pNode))
00346         return FALSE;
00347 
00348     // Get our new node as the correct type
00349     ENSURE(pNode->IsKindOf(CC_RUNTIME_CLASS(NodeRect)), "Node should have been a NodeRect");
00350     NodeRect* pRect = (NodeRect*) pNode;
00351 
00352     // Create an rect to fill the bounding rect
00353     pRect->Parallel[0] = RectPath->Parallel[0];
00354     pRect->Parallel[1] = RectPath->Parallel[1];
00355     pRect->Parallel[2] = RectPath->Parallel[2];
00356     pRect->Parallel[3] = RectPath->Parallel[3];
00357 
00358     pRect->UpdateShape();
00359     pRect->InkPath.IsFilled = TRUE;
00360 
00361     // Start building the undo
00362     if (!DoStartSelOp(FALSE))
00363         return FALSE;
00364 
00365     // Add the new rect to the tree
00366     if (!DoInsertNewNode(pRect, OldRect, NEXT, TRUE))
00367         return FALSE;
00368 
00369     // Invalidate the region of the old rect
00370     if (!DoInvalidateNodeRegion(OldRect, TRUE))
00371         return FALSE;
00372 
00373     // and remove the old Rect from the tree
00374     if (!DoHideNode(OldRect, TRUE))
00375         return FALSE;
00376 
00377     // Transform the Node Children according to bounding box changes
00378     if (!TransformChildAttrs(pRect))
00379         return FALSE;
00380 
00381     // everything has worked, so return TRUE
00382     return TRUE;
00383 }

void OpEditRectangle::DoDrag DocCoord  Anchor,
Spread pSpread,
NodeRect pRect,
INT32  Corner
 

Starts up a drag for editing a NodeEllipse. It records the start postion and start spread etc as well as copying the parallelogram of the NodeEllipse to change and creating a new NodeEllipse for the purpose of render EORed stuff.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/6/94
Parameters:
Anchor - The starting position of the drag [INPUTS] pSpread - The spread that the drag started over pElip - The NodeEllipse that is being edited Corner - The corner of the Parallelogram that is fixed

Definition at line 167 of file opsmpshp.cpp.

00168 {
00169     // Various starting positions
00170     StartSpread = pSpread;
00171     StartPoint = Anchor;
00172     LastMousePosition = Anchor;
00173 
00174     // The original shape in the tree
00175     OldRect = pRect;
00176 
00177     // Make a copy of the bounding parallelogram
00178     Parallel[0] = pRect->Parallel[0];
00179     Parallel[1] = pRect->Parallel[1];
00180     Parallel[2] = pRect->Parallel[2];
00181     Parallel[3] = pRect->Parallel[3];
00182 
00183     // Which corner of the parallelogram is not moving
00184     FixedCorner = Corner;
00185 
00186     // We will make a rect for the drag blobs
00187     UseRect = FALSE;
00188     RectPath = new NodeRect;
00189     if (RectPath!=NULL)
00190     {   
00191         if (RectPath->SetUpPath(12,12))
00192         {
00193             // Mark the Ellipse as being valid
00194             UseRect = TRUE;
00195 
00196             // Give the ellipse a valid path
00197             RectPath->CreateShape(pRect->GetBoundingRect());
00198             RectPath->Parallel[Corner] = Parallel[Corner];
00199 
00200             // Build a rect from the parallel ready for the Eor blobs
00201             RebuildParallelogram(Anchor);
00202 
00203             // and draw the blobs in
00204             RenderDragBlobs(DocRect(0,0,0,0), StartSpread, FALSE);
00205 
00206             // And tell the Dragging system that we need drags to happen
00207             StartDrag( DRAGTYPE_AUTOSCROLL );
00208         }
00209     }
00210 
00211     // If we do not have a path, then report the error
00212     if (UseRect == FALSE)
00213         InformError(_R(IDS_OUT_OF_MEMORY), _R(IDS_OK));
00214 }

void OpEditRectangle::DragFinished DocCoord  PointerPos,
ClickModifiers  ClickMods,
Spread ,
BOOL  Success,
BOOL  bSolidDrag
[virtual]
 

If the drag was a success then a copy of the original node in the tree is created and updated ellipse built. The original NodeEllipse is hidden and the new one if inserted into the tree. If any of these things fail then the operation will fail.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/6/94
Parameters:
PointerPos - The current position of the mouse [INPUTS] ClickMods - Which buttons and modifiers are held down pSpread - The Spread that the mouse is over now. Success - TRUE if the drag was completed sucessfully.

Reimplemented from Operation.

Definition at line 283 of file opsmpshp.cpp.

00284 {
00285     // First Rub out the old Drag blobs and end the drag
00286     RenderDragBlobs(DocRect(0,0,0,0), StartSpread, bSolidDrag);
00287     EndDrag();
00288 
00289     // Flag to say if everything has worked
00290     BOOL IsOk = FALSE;
00291 
00292     // if the drag was a sucess then start to build undo etc
00293     if (Success)
00294     {
00295         // Will the ellipse allow the op?
00296         ObjChangeFlags cFlags;
00297         cFlags.ReplaceNode = TRUE;
00298         ObjChangeParam ObjChange(OBJCHANGE_STARTING,cFlags,OldRect,this);
00299         IsOk = OldRect->AllowOp(&ObjChange);    
00300 
00301         // build all the undo and complete the edit
00302         if (IsOk) IsOk = CompleteOperation();
00303 
00304         if (IsOk)
00305         {
00306             // Update all the effected parents
00307             ObjChange.Define(OBJCHANGE_FINISHED,cFlags,OldRect,this);
00308             IsOk = UpdateChangedNodes(&ObjChange);
00309         }
00310     }
00311 
00312     // If something went wrong, then fail
00313     if (IsOk==FALSE)
00314         FailAndExecute();
00315 
00316     // If we have an rect to work with then get rid of it
00317     if (UseRect)
00318         delete RectPath;
00319 
00320     // always call end
00321     End();
00322 }

void OpEditRectangle::DragPointerMove DocCoord  PointerPos,
ClickModifiers  ClickMods,
Spread pSpread,
BOOL  bSolidDrag
[virtual]
 

Recalculates the ellipse according to the new position of the corner that is being dragged, EORs it to the screen and keeps the Parallelogram up to date.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/6/94
Parameters:
PointerPos - The current position of the mouse [INPUTS] ClickMods - Which buttons and modifiers are held down pSpread - The Spread that the mouse is over now.

Reimplemented from Operation.

Definition at line 234 of file opsmpshp.cpp.

00235 {
00236     // Snap the actual mouse position to the grid if needed
00237     DocView::SnapCurrent(pSpread, &PointerPos);
00238 
00239     // Constrain the mouse motion if needed
00240     if (ClickMods.Constrain)
00241         DocView::ConstrainToAngle(StartPoint, &PointerPos);
00242 
00243     // If the mouse is in a different position then do something
00244     if (PointerPos != LastMousePosition)
00245     {
00246         // First Rub out the old Drag blobs
00247         RenderDragBlobs(DocRect(0,0,0,0), StartSpread, bSolidDrag);
00248 
00249         // Make sure that the coords are relative to the coorect spread
00250         if (pSpread != StartSpread)
00251             PointerPos = MakeRelativeToSpread(StartSpread, pSpread, PointerPos);
00252 
00253         // Build an ellipse ready for the Eor blobs
00254         RebuildParallelogram(PointerPos);
00255 
00256         // Update the last mouse position and re-calc the bounding rect
00257         LastMousePosition = PointerPos;
00258         RenderDragBlobs(DocRect(0,0,0,0), StartSpread, bSolidDrag);
00259     }
00260 }

OpState OpEditRectangle::GetState String_256 Description,
OpDescriptor
[static]
 

Find out the state of the operation at the specific time.

Author:
Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/11/93
Parameters:
Description - GetState fills this string with an approriate description [OUTPUTS] of the current state of the push tool
Returns:
The state of the operation, so that menu items (ticks and greying can be done properly

Definition at line 605 of file opsmpshp.cpp.

00606 {
00607     OpState Blobby;
00608     
00609     return Blobby;
00610 }

BOOL OpEditRectangle::Init void   )  [static]
 

Adds the operation to the list of all known operations.

Author:
Mario_Shamtani (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/9/93
Returns:
TRUE if all went OK, False otherwise

Reimplemented from SimpleCCObject.

Definition at line 577 of file opsmpshp.cpp.

00578 {
00579     return (RegisterOpDescriptor(
00580                                 0, 
00581                                 _R(IDS_RECTANGLE_TOOL),
00582                                 CC_RUNTIME_CLASS(OpEditRectangle), 
00583                                 OPTOKEN_EDITRECT,
00584                                 OpEditRectangle::GetState,
00585                                 0,  /* help ID */
00586                                 _R(IDBBL_EDITRECTOP),
00587                                 0   /* bitmap ID */));
00588 }

void OpEditRectangle::RebuildParallelogram DocCoord  PointerPos  )  [private]
 

Recalculates the parallelogram based on the corner being dragged and the fixed corner. The new parallelogram is copied into the Ellipse we are using for EORing and the Ellipse rebuilt to fit the parallelogram.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/6/94
Parameters:
PointerPos - The coords of the Parallelograms corner that is being dragged [INPUTS]

Definition at line 472 of file opsmpshp.cpp.

00473 {
00474     // Lets number the coordinates. 0 is the fixed one and go clockwise from there
00475     INT32 pos0, pos1, pos2, pos3;
00476     pos0 = FixedCorner;
00477 
00478     if (pos0>1)
00479         pos2 = pos0-2;
00480     else
00481         pos2 = pos0+2;
00482 
00483     if (pos0==3)
00484         pos1 = 0;
00485     else
00486         pos1 = pos0+1;
00487 
00488     if (pos0==0)
00489         pos3 = 3;
00490     else
00491         pos3 = pos0-1;
00492 
00493     // Calculate the offsets from the old point and the fixed point
00494     double dx0 = PointerPos.x - Parallel[pos2].x;
00495     double dy0 = PointerPos.y - Parallel[pos2].y;
00496 
00497     double dx3 = Parallel[pos1].x - Parallel[pos0].x;
00498     double dy3 = Parallel[pos1].y - Parallel[pos0].y;
00499 
00500     double dx4 = Parallel[pos3].x - Parallel[pos0].x;
00501     double dy4 = Parallel[pos3].y - Parallel[pos0].y;
00502     
00503     // Calculate the bits that we need to know
00504     double dx1 = dx3 * ((dy0*dx4-dy4*dx0) / (dx4*dy3-dy4*dx3));
00505     double dy1 = dy3 * ((dy0*dx4-dy4*dx0) / (dx4*dy3-dy4*dx3));
00506     double dx2 = dx4 * ((dx3*dy0-dy3*dx0) / (dy4*dx3-dx4*dy3));
00507     double dy2 = dy4 * ((dx3*dy0-dy3*dx0) / (dy4*dx3-dx4*dy3));
00508 
00509     // Change the parallelogram
00510     RectPath->Parallel[pos1].x = Parallel[pos1].x + (INT32)dx1;
00511     RectPath->Parallel[pos1].y = Parallel[pos1].y + (INT32)dy1;
00512 
00513     RectPath->Parallel[pos3].x = Parallel[pos3].x + (INT32)dx2;
00514     RectPath->Parallel[pos3].y = Parallel[pos3].y + (INT32)dy2;
00515     
00516     RectPath->Parallel[pos2] = PointerPos;
00517 
00518     // Build an ellipse in this parallelogram
00519     RectPath->UpdateShape();
00520 }

void OpEditRectangle::RenderDragBlobs DocRect  Rect,
Spread pSpread,
BOOL  bSolidDrag
[virtual]
 

Renders the Ellipse as it will look if the drag were to end. If we failed to create the Ellipse earlier, it will draw a bounding rect.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
1/6/94
Parameters:
Rect - the rect that needs redrawing [INPUTS] pSpread - the spread that is being rendered

Reimplemented from Operation.

Definition at line 537 of file opsmpshp.cpp.

00538 {
00539     // If being called from DocView::RenderView, then the spread could be wrong
00540     if (pSpread != StartSpread)
00541         return;
00542 
00543     // Decide what to area to redraw
00544     DocRect* pRect = NULL;
00545     if (!Rect.IsEmpty())
00546         pRect = &Rect;
00547 
00548     // Start an eor render session
00549     RenderRegion* pRegion = DocView::RenderOnTop(pRect, pSpread, ClippedEOR);
00550     while (pRegion)
00551     {
00552         // Set the line colour 
00553         pRegion->SetLineColour(COLOUR_XORNEW);
00554 
00555         // Draw the Rectangle
00556         RectPath->RenderEorDrag(pRegion);
00557 
00558         // Get the Next render region
00559         pRegion = DocView::GetNextOnTop(pRect);
00560     }
00561 }

BOOL OpEditRectangle::TransformChildAttrs NodeRect pRect  )  [private]
 

This performs a bodge that Charles asked to be added that scales the attributes when the rectangle is edited.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/8/94

Definition at line 398 of file opsmpshp.cpp.

00399 {
00400     DocRect OldBounds = OldRect->GetBoundingRect(TRUE);
00401     DocRect NewBounds = pRect->GetBoundingRect(TRUE);
00402 
00403     // Get the Width and Height of the two rectangles
00404     INT32 OldWidth  = OldBounds.Width();
00405     INT32 OldHeight = OldBounds.Height();
00406     INT32 NewWidth  = NewBounds.Width();
00407     INT32 NewHeight = NewBounds.Height();
00408 
00409     // Find the Centre of each rectangle
00410     OldBounds.Translate(OldWidth/2, OldHeight/2);
00411     NewBounds.Translate(NewWidth/2, NewHeight/2);
00412     DocCoord OldCentre = OldBounds.lo;
00413     DocCoord NewCentre = NewBounds.lo;
00414 
00415     // Calculate the difference in size between the two rectangles
00416     FIXED16 xscale = FIXED16(double(NewWidth)/double(OldWidth));
00417     FIXED16 yscale = FIXED16(double(NewHeight)/double(OldHeight));
00418 
00419     // And now make a transform for the attribute
00420     // First move the old attribute position to the origin
00421     Matrix AttrTrans = Matrix(-OldCentre.x, -OldCentre.y);
00422 
00423     // Now scale it
00424     AttrTrans *= Matrix(xscale, yscale);
00425 
00426     // And finally move it to the new position
00427     AttrTrans *= Matrix(NewCentre.x, NewCentre.y);
00428 
00429     // Now scan for all Attribute Children and Transform them
00430     Node* pNode = pRect->FindFirstChild();
00431     while (pNode != NULL)
00432     {
00433         if (pNode->IsKindOf(CC_RUNTIME_CLASS(AttrFillGeometry)))
00434         {
00435             // get the transform to use
00436             Trans2DMatrix* Trans = new Trans2DMatrix(AttrTrans);
00437 
00438             // get the node and transform it
00439             //NodeAttribute* NodeToTransform = (NodeAttribute*)pNode;
00440 //          RangeControl rc = {TRUE, TRUE, FALSE};
00441             Range temp(pNode, pNode, RangeControl(TRUE,TRUE,FALSE));
00442             if (!DoTransformNodes(temp, Trans))
00443             {
00444                 delete Trans;
00445                 return FALSE;
00446             }
00447         }
00448 
00449         // go get the next one
00450         pNode = pNode->FindNext();
00451     }
00452 
00453     return TRUE;
00454 }


Member Data Documentation

INT32 OpEditRectangle::FixedCorner [protected]
 

Definition at line 157 of file opsmpshp.h.

DocCoord OpEditRectangle::LastMousePosition [protected]
 

Definition at line 168 of file opsmpshp.h.

NodeRect* OpEditRectangle::OldRect [protected]
 

Definition at line 160 of file opsmpshp.h.

DocCoord OpEditRectangle::Parallel[4] [protected]
 

Definition at line 156 of file opsmpshp.h.

NodeRect* OpEditRectangle::RectPath [protected]
 

Definition at line 163 of file opsmpshp.h.

DocCoord OpEditRectangle::StartPoint [protected]
 

Definition at line 167 of file opsmpshp.h.

Spread* OpEditRectangle::StartSpread [protected]
 

Definition at line 164 of file opsmpshp.h.

BOOL OpEditRectangle::UseRect [protected]
 

Definition at line 162 of file opsmpshp.h.


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