#include <oprshape.h>
Inheritance diagram for OpNewRegShape:
Public Types | |
enum | CreateMode { RADIUS, DIAMETER, BOUNDS } |
Public Member Functions | |
OpNewRegShape () | |
Constructor. This simply sets a few of the operation flags. | |
void | DoDrag (Spread *pSpread, DocCoord Anchor, INT32 NumSides, CreateMode DragMode, BOOL Circular, BOOL Stellated, BOOL Curved) |
Starts dragging from the coordinate passed in. For RADIUS mode you are dragging the major axes from a fixed centre point For DIAMETER mode you are dragging the major axes, the centre point is the midpoint of the line between the start and current points. For BOUNDS mode you are dragging a bounding box. The major and minor axes just touch the edge of the box. | |
virtual void | DragPointerMove (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL bSolidDrag) |
Takes the pointer position of the corner of the shape being dragged and redisplays the outline. | |
virtual void | DragFinished (DocCoord PointerPos, ClickModifiers ClickMods, Spread *, BOOL Success, BOOL bSolidDrag) |
Ends the drag and creates a rectangle using the dimensions and position of the outline rectangle produced by the dragging system. It also ends the operation. | |
void | RenderDragBlobs (DocRect, Spread *, BOOL bSolidDrag) |
Draws an EORed version of the current shape. | |
Static Public Member Functions | |
static BOOL | Declare () |
Adds the operation to the list of all known operations. | |
static OpState | GetState (String_256 *Description, OpDescriptor *) |
Find out the state of the new regular shape at the specific time. | |
Private Member Functions | |
BOOL | CompleteOperation () |
Does all the work in building the undo etc. It builds a shape and inserts it into the tree. | |
void | InflateShape (DocRect *Bounds, DocCoord *NewCentre, DocCoord *NewMajor, DocCoord *NewMinor) |
NewMajor and NewMinor are initially positioned half way along the top and halfway down the righthand side of the Bounds rect respectivly, Their positions are then increased so that the shape path passes through their previous positions. | |
Private Attributes | |
NodeRegularShape * | NewShape |
Spread * | StartSpread |
DocCoord | StartPoint |
DocCoord | LastPoint |
CreateMode | CreationMode |
Cursor * | pCursor |
BOOL | IsShiftDown |
DocCoord | RecentrePoint |
Definition at line 122 of file oprshape.h.
|
Definition at line 128 of file oprshape.h.
|
|
Constructor. This simply sets a few of the operation flags.
Definition at line 142 of file oprshape.cpp. 00143 { 00144 pCursor = NULL; 00145 IsShiftDown = FALSE; 00146 }
|
|
Does all the work in building the undo etc. It builds a shape and inserts it into the tree.
Definition at line 455 of file oprshape.cpp. 00456 { 00457 // We will only create the shape if it is bigger than a blob rect at the current scale 00458 DocRect temp; 00459 GetApplication()->GetBlobManager()->GetBlobRect(StartPoint, &temp); 00460 if (temp.ContainsCoord(LastPoint)) 00461 { 00462 return FALSE; 00463 } 00464 00465 // Find the document for this operation. 00466 Document* pDoc = GetWorkingDoc(); 00467 if (pDoc==NULL) 00468 { 00469 TRACEALL( _T("OpNewRegShape::CompleteOperation has no working document.")); 00470 return FALSE; 00471 } 00472 00473 // Apply a few attributes 00474 if (!(pDoc->GetAttributeMgr().ApplyCurrentAttribsToNode((NodeRenderableInk*)NewShape))) 00475 return FALSE; 00476 00477 // Delete any applied join attribute 00478 NodeAttribute* pAppliedJoin = NewShape->GetChildAttrOfType(CC_RUNTIME_CLASS(AttrJoinType)); 00479 if (pAppliedJoin != NULL) 00480 { 00481 pAppliedJoin->CascadeDelete(); 00482 delete pAppliedJoin; 00483 } 00484 00485 // Apparently all shapes should have mitre joins. 00486 AttrJoinType* pMitreJoin = new AttrJoinType(NewShape, LASTCHILD); 00487 if (pMitreJoin == NULL) 00488 return FALSE; 00489 pMitreJoin->Value.JoinType = MitreJoin; 00490 00491 // Try and start the the operation 00492 if (!DoStartSelOp(FALSE)) 00493 return FALSE; 00494 00495 // Ok, add it in and invalidate the region 00496 if (!DoInsertNewNode(NewShape, StartSpread, TRUE)) 00497 return FALSE; 00498 00499 // Finally, make sure we haven't added the new object partially off the spread 00500 StartSpread->ExpandPasteboardToInclude(NewShape->GetBoundingRect()); 00501 00502 // all worked 00503 return TRUE; 00504 }
|
|
Adds the operation to the list of all known operations.
Definition at line 614 of file oprshape.cpp. 00615 { 00616 return (RegisterOpDescriptor( 00617 0, 00618 _R(IDS_NEWREGULARSHAPEOP), 00619 CC_RUNTIME_CLASS(OpNewRegShape), 00620 OPTOKEN_NEWREGSHAPE, 00621 OpNewRegShape::GetState)); 00622 00623 }
|
|
Starts dragging from the coordinate passed in. For RADIUS mode you are dragging the major axes from a fixed centre point For DIAMETER mode you are dragging the major axes, the centre point is the midpoint of the line between the start and current points. For BOUNDS mode you are dragging a bounding box. The major and minor axes just touch the edge of the box.
Definition at line 172 of file oprshape.cpp. 00174 { 00175 DocView::SnapCurrent(pSpread, &Anchor); 00176 00177 // We had better take a note of the starting point of the drag. 00178 StartSpread = pSpread; 00179 StartPoint = Anchor; 00180 LastPoint = Anchor; 00181 CreationMode = DragMode; 00182 00183 // Create the shape that is to be dragged around. 00184 NewShape = new (NodeRegularShape); 00185 00186 if ((NewShape == NULL) || !NewShape->SetUpShape() ) 00187 { 00188 InformError(_R(IDS_OUT_OF_MEMORY), _R(IDS_OK)); 00189 return; 00190 } 00191 00192 // And make sure it is filled in 00193 NewShape->SetNumSides(NumSides); 00194 00195 const DocCoord Origin(0,0); 00196 NewShape->SetCentrePoint(Origin); 00197 NewShape->SetMajorAxes(Origin); 00198 NewShape->SetMinorAxes(Origin); 00199 00200 NewShape->SetCircular(Circular); 00201 NewShape->SetStellated(Stellated); 00202 NewShape->SetPrimaryCurvature(Curved); 00203 NewShape->SetStellationCurvature(Curved); 00204 00205 Matrix InitialMat(StartPoint.x, StartPoint.y); 00206 NewShape->SetTransformMatrix(&InitialMat); 00207 00208 // Eor the rectangle on for the first time 00209 DocRect EditPathBBox = NewShape->GetBoundingRect(); 00210 RenderDragBlobs(EditPathBBox, StartSpread, FALSE); 00211 00212 // And tell the Dragging system that we need drags to happen 00213 StartDrag( DRAGTYPE_AUTOSCROLL, NULL, &Anchor, FALSE ); 00214 }
|
|
Ends the drag and creates a rectangle using the dimensions and position of the outline rectangle produced by the dragging system. It also ends the operation.
Reimplemented from Operation. Definition at line 409 of file oprshape.cpp. 00411 { 00412 // Start a slow job 00413 BeginSlowJob(); 00414 00415 // End the Drag 00416 EndDrag(); 00417 00418 // First Rub out the old box 00419 DocRect EditPathBBox = NewShape->GetBoundingRect(); 00420 RenderDragBlobs(EditPathBBox, StartSpread, bSolidDrag); 00421 00422 // If we should carry on, then do it 00423 BOOL Worked = FALSE; 00424 if ( Success && (StartPoint != PointerPos) ) 00425 Worked = CompleteOperation(); 00426 00427 // if it did not work or the user pressed ESCAPE then fail 00428 if (!Worked) 00429 { 00430 // It did not work, so we had better recover 00431 NewShape->CascadeDelete(); 00432 delete NewShape; 00433 00434 FailAndExecute(); 00435 } 00436 00437 End(); 00438 }
|
|
Takes the pointer position of the corner of the shape being dragged and redisplays the outline.
Reimplemented from Operation. Definition at line 234 of file oprshape.cpp. 00236 { 00237 // Rub out the old shape 00238 DocRect EditPathBBox = NewShape->GetBoundingRect(); 00239 RenderDragBlobs(DocRect(0,0,0,0), StartSpread, bSolidDrag); 00240 00241 // make sure the rect does not wrap around the edge of the spread 00242 if (pSpread != StartSpread) 00243 PointerPos = MakeRelativeToSpread(StartSpread, pSpread, PointerPos); 00244 00245 // If the SHIFT key is down then drop into RADIUS mode 00246 CreateMode TempCreationMode = CreationMode; 00247 if (ClickMods.Adjust && CreationMode == DIAMETER) 00248 TempCreationMode = RADIUS; 00249 if (ClickMods.Adjust && ClickMods.Constrain && CreationMode == BOUNDS) 00250 TempCreationMode = RADIUS; 00251 00252 // Now see if we should constrain the point 00253 if (ClickMods.Constrain) 00254 { 00255 // If we are in bounds creation mode then we want to restrict to 45, 135 225, and 315 degrees 00256 // This stops thin shapes (ie zero wdith or height) 00257 if (TempCreationMode == BOUNDS) 00258 { 00259 double length = StartPoint.Distance(PointerPos); 00260 00261 if (length != 0.0) 00262 { 00263 DocCoord Offset = PointerPos - StartPoint; 00264 double rotangle = atan2((double)Offset.y, (double)Offset.x); 00265 00266 if ((rotangle >= 0) && (rotangle <= PI/2)) 00267 rotangle = PI/4; 00268 if (rotangle > PI/2) 00269 rotangle = 3*(PI/4); 00270 if ((rotangle < 0) && (rotangle >= -PI/2)) 00271 rotangle = -PI/4; 00272 if (rotangle < -PI/2) 00273 rotangle = -3*(PI/4); 00274 00275 PointerPos.x = StartPoint.x + (INT32)length; 00276 PointerPos.y = StartPoint.y; 00277 00278 Trans2DMatrix Trans(StartPoint, rotangle*(180/PI)); 00279 Trans.Transform(&PointerPos, 1); 00280 } 00281 } 00282 else 00283 { 00284 DocCoord Centre = NewShape->GetCentrePoint(); 00285 if (TempCreationMode == DIAMETER) 00286 Centre = StartPoint; 00287 DocView::ConstrainToAngle(Centre, &PointerPos); 00288 } 00289 } 00290 00291 // snap to the grid too 00292 DocView::SnapCurrent(pSpread, &PointerPos); 00293 00294 // Change our shape to fit the current mouse position 00295 switch (TempCreationMode) 00296 { 00297 case RADIUS: 00298 { // The major axes point is the current mouse pos rotated around the centre point by 00299 // 180 degrees. The minor point is the same point rotated by a further 90 degrees 00300 DocCoord OldCentre = NewShape->GetCentrePoint(); 00301 DocCoord NewMajor = PointerPos - OldCentre; 00302 DocCoord NewMinor = PointerPos - OldCentre; 00303 Trans2DMatrix Trans1(DocCoord(0,0), -180); 00304 Trans1.Transform(&NewMajor, 1); 00305 Trans2DMatrix Trans2(DocCoord(0,0), -270); 00306 Trans2.Transform(&NewMinor, 1); 00307 NewShape->SetMajorAxes(NewMajor); 00308 NewShape->SetMinorAxes(NewMinor); 00309 NewShape->SetCentrePoint(DocCoord(0,0)); 00310 Matrix InitialMat(OldCentre.x, OldCentre.y); 00311 NewShape->SetTransformMatrix(&InitialMat); 00312 break; 00313 } 00314 case DIAMETER: 00315 { // The centre point is the midpoint of the line from the start point to the current point. 00316 // The major axes is positioned so that a vertex is on the starting position. 00317 // The minor axes is the major axes rotated by -90 degrees. 00318 DocCoord NewCentre; 00319 NewCentre.x = (StartPoint.x + PointerPos.x) / 2; 00320 NewCentre.y = (StartPoint.y + PointerPos.y) / 2; 00321 NewShape->SetCentrePoint(DocCoord(0,0)); 00322 DocCoord NewMajor = PointerPos - NewCentre; 00323 Trans2DMatrix Trans1(DocCoord(0,0), 180-(180.0/NewShape->GetNumSides())); 00324 Trans1.Transform(&NewMajor, 1); 00325 NewShape->SetMajorAxes(NewMajor); 00326 DocCoord NewMinor = NewMajor; 00327 Trans2DMatrix Trans2(DocCoord(0,0), -90); 00328 Trans2.Transform(&NewMinor, 1); 00329 NewShape->SetMinorAxes(NewMinor); 00330 Matrix InitialMat(NewCentre.x, NewCentre.y); 00331 NewShape->SetTransformMatrix(&InitialMat); 00332 break; 00333 } 00334 case BOUNDS: 00335 { 00336 DocCoord NewCentre; 00337 DocCoord NewMajor; 00338 DocCoord NewMinor; 00339 // If SHIFT is down then we need to reposition the shape in a similar way to the old 00340 // rectangle tool 00341 if (ClickMods.Adjust) 00342 { 00343 if (!IsShiftDown) 00344 { 00345 IsShiftDown = TRUE; 00346 RecentrePoint.x = (StartPoint.x + PointerPos.x) / 2; 00347 RecentrePoint.y = (StartPoint.y + PointerPos.y) / 2; 00348 } 00349 DocRect BoundsRect(RecentrePoint, RecentrePoint); 00350 BoundsRect.IncludePoint(PointerPos); 00351 BoundsRect.IncludePoint(RecentrePoint + (RecentrePoint - PointerPos)); 00352 InflateShape(&BoundsRect, &NewCentre, &NewMajor, &NewMinor); 00353 } 00354 else 00355 { 00356 if (IsShiftDown) 00357 { 00358 IsShiftDown = FALSE; 00359 StartPoint = RecentrePoint + (RecentrePoint - PointerPos); 00360 } 00361 00362 DocRect BoundsRect(StartPoint, StartPoint); 00363 BoundsRect.IncludePoint(PointerPos); 00364 InflateShape(&BoundsRect, &NewCentre, &NewMajor, &NewMinor); 00365 } 00366 00367 NewShape->SetCentrePoint(DocCoord(0,0)); 00368 NewShape->SetMajorAxes(NewMajor - NewCentre); 00369 NewShape->SetMinorAxes(NewMinor - NewCentre); 00370 Matrix InitialMat(NewCentre.x, NewCentre.y); 00371 NewShape->SetTransformMatrix(&InitialMat); 00372 break; 00373 } 00374 default: 00375 ERROR3("Unknown creation type"); 00376 } 00377 00378 // Put the Eor back on again for the new shape 00379 EditPathBBox = NewShape->GetBoundingRect(); 00380 RenderDragBlobs(EditPathBBox, StartSpread, bSolidDrag); 00381 00382 BROADCAST_TO_ALL(ShapeEditedMsg(NewShape, pSpread)); 00383 00384 LastPoint = PointerPos; 00385 }
|
|
Find out the state of the new regular shape at the specific time.
Definition at line 638 of file oprshape.cpp. 00639 { 00640 OpState Blobby; 00641 00642 return Blobby; 00643 }
|
|
NewMajor and NewMinor are initially positioned half way along the top and halfway down the righthand side of the Bounds rect respectivly, Their positions are then increased so that the shape path passes through their previous positions.
Definition at line 526 of file oprshape.cpp. 00527 { 00528 // Set their initial positions 00529 NewCentre->x = (Bounds->lo.x + Bounds->hi.x) / 2; 00530 NewCentre->y = (Bounds->lo.y + Bounds->hi.y) / 2; 00531 NewMajor->x = (Bounds->lo.x + Bounds->hi.x) / 2; 00532 NewMajor->y = Bounds->hi.y; 00533 NewMinor->x = Bounds->hi.x; 00534 NewMinor->y = (Bounds->lo.y + Bounds->hi.y) / 2; 00535 00536 // Move them if required 00537 if (!NewShape->IsCircular()) 00538 { 00539 DocCoord MajorRender = *NewMajor; 00540 DocCoord MinorRender = *NewMinor; 00541 double radius = NewCentre->Distance(*NewMajor); 00542 double SideA = cos(PI/NewShape->GetNumSides())*radius; 00543 if (SideA != 0.0) 00544 { 00545 DocCoord Update = DocCoord::PositionPointFromRatio(*NewCentre, *NewMajor, radius/SideA); 00546 NewMajor->y = Update.y; 00547 } 00548 00549 if ( ((NewShape->GetNumSides() % 2) == 0) && (((NewShape->GetNumSides()/2) % 2) == 0) ) 00550 { 00551 radius = NewCentre->Distance(*NewMinor); 00552 SideA = cos(PI/NewShape->GetNumSides())*radius; 00553 if (SideA != 0.0) 00554 { 00555 DocCoord Update = DocCoord::PositionPointFromRatio(*NewCentre, *NewMinor, radius/SideA); 00556 NewMinor->x = Update.x; 00557 } 00558 } 00559 } 00560 }
|
|
Draws an EORed version of the current shape.
Reimplemented from Operation. Definition at line 576 of file oprshape.cpp. 00577 { 00578 // If being called from DocView::RenderView, then the spread could be wrong - so 00579 // convert the rectangle if necessary. 00580 if (pSpread != StartSpread) 00581 { 00582 Rect.lo = MakeRelativeToSpread(StartSpread, pSpread, Rect.lo); 00583 Rect.hi = MakeRelativeToSpread(StartSpread, pSpread, Rect.hi); 00584 } 00585 00586 // start a rendering loop 00587 RenderRegion* pRegion = DocView::RenderOnTop(NULL, pSpread, ClippedEOR); 00588 while (pRegion) 00589 { 00590 // Set the line colour 00591 pRegion -> SetFillColour(COLOUR_NONE); 00592 pRegion -> SetLineColour(COLOUR_XORNEW); 00593 00594 // Draw the outline 00595 NewShape->RenderEorDrag(pRegion); 00596 00597 // Get the Next render region 00598 pRegion = DocView::GetNextOnTop(NULL); 00599 } 00600 }
|
|
Definition at line 161 of file oprshape.h. |
|
Definition at line 163 of file oprshape.h. |
|
Definition at line 160 of file oprshape.h. |
|
Definition at line 157 of file oprshape.h. |
|
Definition at line 162 of file oprshape.h. |
|
Definition at line 164 of file oprshape.h. |
|
Definition at line 159 of file oprshape.h. |
|
Definition at line 158 of file oprshape.h. |