CSnap Class Reference

Performs the snapping required by Camelot. More...

#include <snap.h>

List of all members.

Public Member Functions

 CSnap (DocView *pThisDocView, Spread *pThisSpread)
 The constructor. At the moment, snapping is controlled on a per-view basis, so a DocView has to be supplied. Also, snapping to objects happens on a per-spread basis, hence the need to supply a spread.
BOOL Snap (DocCoord *pDocCoord, BOOL TryMagSnap=TRUE, BOOL TryGridSnap=TRUE)
 Allows you to easily snap a coord to something relevant in the given spread (e.g. to a grid, magnetic object, etc).
BOOL Snap (DocRect *pDocRect, const DocCoord &PrevCoord, const DocCoord &CurCoord)
 Allows you to easily snap a rectangle to objects.
BOOL TryToSnapToObject (Node *pNode, DocCoord *pDocCoord)
 Allows a test to see if a particular node snaps to a particaular coord.
BOOL SnapToGrids (DocCoord *pDocCoord)
 Allows you to easily snap a coord to a grid in a spread.
BOOL SnapToGuidelines (DocCoord *pDocCoord, GuidelineType Type=GUIDELINE_NOTYPE)
 Allows you to easily snap a coord to a guideline in a spread.
void SetSpread (Spread *pThisSpread)

Static Public Member Functions

static MILLIPOINT GetSnapDist ()
static MILLIPOINT GetSnapToCoordDist ()
static BOOL SnapCoordToPath (DocCoord *pDocCoord, Path *pPath)
 Common code called by a number of Nodes Snap(DocCoord*) functions. Attempts to snap a coord onto a path.
static BOOL SnapRectToRect (DocRect *pSnappedRect, const DocRect &RefRect)
 Snap a rectangle so that it lines up with one or more sides of another rectangle. This will only happen if the first rectangle is close to the second rectangle.

Private Member Functions

 CC_DECLARE_MEMDUMP (CSnap)
BOOL SnapToGrids (DocRect *pDocRect, const DocCoord &PrevCoord, const DocCoord &CurCoord)
 Allows you to easily snap a coord to a grid in a spread.
BOOL SnapToObjects (Node *pRootNode, DocCoord *pDocCoord, BOOL Magnetic, BOOL GuideLayersOnly)
 Allows you to snap a coord to an object in a spread. This will try and snap the coord to NodeRenderableBounded nodes in the sub-tree in the reverse order in which they are rendered. Each eligable node is firstly checked to see if the bounds contain the coord. If the Magnetic param is TRUE, only NodeRend nodes with their Man.
BOOL SnapToObjects (DocRect *pDocRect, const DocCoord &PrevCoord, const DocCoord &CurCoord, BOOL Magnetic, BOOL GuideLayersOnly)
 Allows you to easily snap a coord to an object in a spread.
BOOL SnapToGuidelines (DocRect *pDocRect, const DocCoord &PrevCoord, const DocCoord &CurCoord)
 Allows you to easily snap a rect to a guideline in a spread.
BOOL SnapToGuidesInLayer (Layer *pLayer, DocCoord *pDocCoord, GuidelineType Type)
 Helper function that will snap one component of the DocCoord to one type of guideline.
BOOL SnapToGuideObjects (DocCoord *pDocCoord)
 Allows you to easily snap a coord to objects in guide layers.
BOOL SnapToGuideObjects (DocRect *pDocRect, const DocCoord &PrevCoord, const DocCoord &CurCoord)
 Allows you to easily snap a rect to objects in guide layers.
BOOL SnapToPages (DocCoord *pDocCoord)
 Allows you to easily snap a coord to a page in a spread.
BOOL SnapToPages (DocRect *pDocRect, const DocCoord &PrevCoord, const DocCoord &CurCoord)
 Allows you to easily snap a coord to a page in a spread.
void CalcSnapDist ()
 Calculates the snapping distance to objects for this CSnap object's DocView. Uses the DocView's scale factor as a parameter, so this should be called every time the DocView's scale factor changes.

Static Private Member Functions

static BOOL SnapToValue (const INT32 RefValue, INT32 *pTestValue, INT32 *pLockedValue)
 Given a reference and pointers to two variable values, this function attempts to snap the first variable value to the reference, and if successful adjusts the second variable value by the same amount as the first.

Private Attributes

DocViewpDocView
SpreadpSpread
NodepLastSnappingObject

Static Private Attributes

static MILLIPOINT SnapDist = 1
static MILLIPOINT SnapToCoordDist = 1
static BOOL TrySnapToPages = TRUE


Detailed Description

Performs the snapping required by Camelot.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94

Definition at line 123 of file snap.h.


Constructor & Destructor Documentation

CSnap::CSnap DocView pThisDocView,
Spread pThisSpread
 

The constructor. At the moment, snapping is controlled on a per-view basis, so a DocView has to be supplied. Also, snapping to objects happens on a per-spread basis, hence the need to supply a spread.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
pThisDocView - the view in which this snapping is occuring [INPUTS] pThisSpread - the spread that constains the objects (grids, guides, etc) to snap to
See also:

Definition at line 150 of file snap.cpp.

00151 {
00152     pDocView = pThisDocView;
00153     pSpread  = pThisSpread;
00154     pLastSnappingObject = NULL;
00155 
00156     CalcSnapDist();
00157 }


Member Function Documentation

void CSnap::CalcSnapDist  )  [private]
 

Calculates the snapping distance to objects for this CSnap object's DocView. Uses the DocView's scale factor as a parameter, so this should be called every time the DocView's scale factor changes.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
22/9/94

Definition at line 1076 of file snap.cpp.

01077 {
01078     // Find out the Magnetic Line Radius preference from its owner
01079     INT32 MagneticRad = NodeRenderableBounded::MagneticLineRadius;
01080     INT32 PointRad = NodeRenderableBounded::MagneticPointRadius;
01081 
01082     // Scale it according to the ScaleFactor.
01083     if (pDocView!=NULL)
01084     {
01085         // Get the Scale factor and modify the magnetic radius
01086         double Scale = pDocView->GetViewScale().MakeDouble();
01087 
01088         MagneticRad = (INT32) ((double)MagneticRad / Scale);
01089         PointRad = (INT32) ((double)PointRad / Scale);
01090     }
01091 
01092     // Set the snapping distance to the (hopefully) modified magnetic radius
01093     SnapDist = MagneticRad;
01094     SnapToCoordDist = PointRad;
01095 }

CSnap::CC_DECLARE_MEMDUMP CSnap   )  [private]
 

static MILLIPOINT CSnap::GetSnapDist  )  [inline, static]
 

Definition at line 142 of file snap.h.

00142 { return SnapDist; }

static MILLIPOINT CSnap::GetSnapToCoordDist  )  [inline, static]
 

Definition at line 143 of file snap.h.

00143 { return SnapToCoordDist; }

void CSnap::SetSpread Spread pThisSpread  )  [inline]
 

Definition at line 140 of file snap.h.

00140 { pSpread = pThisSpread; }

BOOL CSnap::Snap DocRect pDocRect,
const DocCoord PrevCoord,
const DocCoord CurCoord
 

Allows you to easily snap a rectangle to objects.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
pDocRect = a rectangle is spread coords [INPUTS] PrevCoord = Used to determine how rect is snapped CurCoord = As above
Returns:
TRUE - The rect has been snapped to something FALSE - The rect is untouched by man and beast
See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 267 of file snap.cpp.

00268 {
00269     ERROR3IF(pDocView == NULL || pSpread == NULL,"Invalid DocView and/or spread");
00270     if (pDocView == NULL || pSpread == NULL) return FALSE;
00271 
00272     // This has to be called here so that the static SnapDist member var is
00273     // correct for this CSnap's DocView
00274     CalcSnapDist();
00275 
00276     BOOL Snapped = FALSE;
00277 
00278     if (!Snapped && pDocView->GetSnapToGuidesState())
00279         Snapped = SnapToGuidelines(pDocRect,PrevCoord,CurCoord);
00280 
00281     if (!Snapped && pDocView->GetSnapToGuidesState())
00282         Snapped = SnapToGuideObjects(pDocRect,PrevCoord,CurCoord);
00283 
00284     BOOL SnapToAllObjs = pDocView->GetSnapToObjectsState();     // "Snap to all objects" state
00285     BOOL SnapToMagObjs = pDocView->GetSnapToMagObjectsState();  // "Snap to magnetic objects" state
00286 
00287     if (!Snapped)
00288     {
00289         // Only try and snap to objects if either the "snap to all objects" OR "snap to magnetic objects"
00290         // flags are set
00291 
00292         if (SnapToAllObjs || SnapToMagObjs)
00293         {
00294             // Only check magnetic objects if the "snap to magnetic objects" flag is TRUE and the 
00295             // "Snap to all objects" flag is FALSE
00296 
00297             BOOL Magnetic = (SnapToMagObjs && !SnapToAllObjs);
00298 
00299             Snapped = SnapToObjects(pDocRect,PrevCoord,CurCoord,Magnetic,FALSE);
00300         }
00301     }
00302 
00303     // Try snapping to the page boundaries
00304     if (!Snapped && TrySnapToPages && SnapToAllObjs)
00305         Snapped = SnapToPages(pDocRect,PrevCoord,CurCoord);
00306 
00307     // Try and snap to the grids
00308     if (!Snapped && pDocView->GetSnapToGridState())
00309         Snapped = SnapToGrids(pDocRect,PrevCoord,CurCoord);
00310 
00311     return (Snapped);
00312 }

BOOL CSnap::Snap DocCoord pDocCoord,
BOOL  TryMagSnap = TRUE,
BOOL  TryGridSnap = TRUE
 

Allows you to easily snap a coord to something relevant in the given spread (e.g. to a grid, magnetic object, etc).

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
pDocCoord = a coord relative to the given spread [INPUTS]
Returns:
TRUE - The coord has been snapped to something FALSE - The coord is untouched by man and beast
See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 179 of file snap.cpp.

00182 {
00183     ERROR2IF(pDocView==NULL,FALSE,"CSnap::Snap() - pDocView==NULL");
00184     ERROR2IF( pSpread==NULL,FALSE,"CSnap::Snap() - pSpread==NULL");
00185     // This has to be called here so that the static SnapDist member var is
00186     // correct for this CSnap's DocView
00187     CalcSnapDist();
00188 
00189     BOOL Snapped=FALSE;
00190 
00191     // Try snapping to the guidelines on the guide layers
00192     if (!Snapped && pDocView->GetSnapToGuidesState())
00193         Snapped = SnapToGuidelines(pDocCoord);
00194 
00195     // Try snapping to the objects on the guide layers
00196     if (!Snapped && pDocView->GetSnapToGuidesState())
00197         Snapped = SnapToGuideObjects(pDocCoord);
00198 
00199     // Find the state of the snapping flags
00200     BOOL SnapToAllObjs = TryMagSnap && pDocView->GetSnapToObjectsState();       // "Snap to all objects" state
00201     BOOL SnapToMagObjs = TryMagSnap && pDocView->GetSnapToMagObjectsState();    // "Snap to magnetic objects" state
00202 
00203     // Only try and snap to objects if either the flags are set
00204     if (!Snapped && (SnapToAllObjs || SnapToMagObjs))
00205     {
00206         // try and snap to the last object we snapped to
00207         if ((pLastSnappingObject!=NULL)                         &&  // Do we have a last snapped object?
00208             (pLastSnappingObject->FindParent() != NULL)         &&  // Does it have a parent (i.e. not been hidden)?
00209             (TryToSnapToObject(pLastSnappingObject, pDocCoord))
00210            )    
00211         {
00212             Snapped=TRUE;
00213         }
00214         else
00215         {
00216             // We failed to snap to the last object we snapped to, so set the pointer to NULL
00217             pLastSnappingObject = NULL;
00218 
00219             // Only check magnetic objects if the "snap to magnetic objects" flag is TRUE and the 
00220             // "Snap to all objects" flag is FALSE
00221             BOOL Magnetic = (SnapToMagObjs && !SnapToAllObjs);
00222             if (SnapToObjects(pSpread->FindLastChild(), pDocCoord, Magnetic, FALSE))
00223                 Snapped=TRUE;
00224         }
00225     }
00226 
00227     // Try snapping to the page boundaries
00228     if (!Snapped && TrySnapToPages && SnapToAllObjs)
00229         Snapped = SnapToPages(pDocCoord);
00230 
00231     // set a flag to indicate if snapped to an object but not the grid
00232     // for update of magnetic snap indicator
00233     BOOL NonGridSnapped=Snapped;
00234     
00235     // if not already snapped to an object, try to snap to grid
00236     if (!Snapped)
00237         if (TryGridSnap && (pDocView->GetSnapToGridState()) && (SnapToGrids(pDocCoord)))
00238             Snapped=TRUE;
00239 
00240 #if !defined(EXCLUDE_FROM_RALPH)
00241     // update mouse position in StatusLine (with snapped mouse position)
00242     StatusLine* pStatusLine=GetApplication()->GetpStatusLine();
00243     if (pStatusLine)
00244         pStatusLine->UpdateMousePosAndSnap(pDocCoord,pSpread,pDocView,NonGridSnapped);
00245 #endif
00246 
00247     return Snapped;
00248 }

BOOL CSnap::SnapCoordToPath DocCoord pDocCoord,
Path pPath
[static]
 

Common code called by a number of Nodes Snap(DocCoord*) functions. Attempts to snap a coord onto a path.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/10/95
Parameters:
pDocCoord = a coord in Spread coords [INPUTS] pPath - the path it should be snapped to
pDocCoord will hiold the snapped coodinate, if snapped [OUTPUTS]
Returns:
TRUE - the DocCoord has been snapped to the path. FALSE - the DocCoord has not been snapped

Definition at line 1112 of file snap.cpp.

01113 {
01114     BOOL Snapped = FALSE;
01115 
01116     MILLIPOINT SnapDist    = CSnap::GetSnapDist();
01117     MILLIPOINT SqrSnapDist = SnapDist*SnapDist;
01118 
01119     INT32 NearEl = 0;
01120     double mu = 0;
01121     double SqrDist = pPath->SqrDistanceToPoint(*pDocCoord, &NearEl, &mu);
01122 
01123     if (SqrDist <= SqrSnapDist)
01124     {
01125         *pDocCoord = pPath->ClosestPointTo(mu, NearEl);
01126         Snapped = TRUE;
01127     }
01128 
01129     return (Snapped);
01130 }

BOOL CSnap::SnapRectToRect DocRect pSnappedRect,
const DocRect RefRect
[static]
 

Snap a rectangle so that it lines up with one or more sides of another rectangle. This will only happen if the first rectangle is close to the second rectangle.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/10/1999
Parameters:
pSnappedRect pointer to the rectangle which will be snapped. [INPUTS] RefRect the reference rectangle, to snap to.
pSnappedRect may be snapped to RefRect. [OUTPUTS]
Returns:
TRUE if pSnappedRect was snapped, FALSE otherwise.

Errors: ERROR2 if pSnappedRect is NULL. See also:

Definition at line 1152 of file snap.cpp.

01153 {
01154     // validate input.
01155     ERROR2IF(pSnappedRect == NULL, FALSE, "CSnap::SnapRectToRect- NULL pSnappedRect.");
01156 
01157     // before we start doing loads of snap-testing, we need to check that the two rectangles
01158     // are close enough together.
01159     DocRect TestIntersect = *pSnappedRect;
01160     TestIntersect.Inflate(SnapDist);
01161     if (!TestIntersect.IsIntersectedWith(RefRect))
01162         return FALSE;
01163 
01164     // try to snap the y-coordinates of pSnappedRect to those of RefRect.
01165     // order of snap-attempts goes:
01166     //
01167     //      top-to-top, bottom-to-bottom, bottom-to-top, top-to-bottom
01168     //
01169     // ,where we are snapping y-values in pSnappedRect-to-RefRect.
01170     BOOL bSnappedY = FALSE;
01171     if (!bSnappedY) bSnappedY = SnapToValue(RefRect.hi.y, &(pSnappedRect->hi.y), &(pSnappedRect->lo.y));
01172     if (!bSnappedY) bSnappedY = SnapToValue(RefRect.lo.y, &(pSnappedRect->lo.y), &(pSnappedRect->hi.y));
01173     if (!bSnappedY) bSnappedY = SnapToValue(RefRect.hi.y, &(pSnappedRect->lo.y), &(pSnappedRect->hi.y));
01174     if (!bSnappedY) bSnappedY = SnapToValue(RefRect.lo.y, &(pSnappedRect->hi.y), &(pSnappedRect->lo.y));
01175 
01176     // try to snap the x-coordinates of pSnappedRect to those of RefRect.
01177     // order of snap-attempts goes:
01178     //
01179     //      left-to-left, right-to-right, left-to-right, right-to-left
01180     //
01181     // ,where we are snapping x-values in pSnappedRect-to-RefRect.
01182     BOOL bSnappedX = FALSE;
01183     if (!bSnappedX) bSnappedX = SnapToValue(RefRect.lo.x, &(pSnappedRect->lo.x), &(pSnappedRect->hi.x));
01184     if (!bSnappedX) bSnappedX = SnapToValue(RefRect.hi.x, &(pSnappedRect->hi.x), &(pSnappedRect->lo.x));
01185     if (!bSnappedX) bSnappedX = SnapToValue(RefRect.hi.x, &(pSnappedRect->lo.x), &(pSnappedRect->hi.x));
01186     if (!bSnappedX) bSnappedX = SnapToValue(RefRect.lo.x, &(pSnappedRect->hi.x), &(pSnappedRect->lo.x));
01187 
01188     // return the result.
01189     return bSnappedY || bSnappedX;
01190 }

BOOL CSnap::SnapToGrids DocRect pDocRect,
const DocCoord PrevCoord,
const DocCoord CurCoord
[private]
 

Allows you to easily snap a coord to a grid in a spread.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
pDocRect = a rectangle is spread coords [INPUTS] PrevCoord = Used to determine how rect is snapped CurCoord = As above
Returns:
TRUE - The rect has been snapped to something FALSE - The rect is untouched by man and beast
See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 782 of file snap.cpp.

00783 {
00784     // Make sure that we can and should be snapping to grids
00785     ERROR3IF(pDocView == NULL || pSpread == NULL,"Invalid DocView and/or spread");
00786     if (pDocView == NULL || pSpread == NULL) return FALSE;
00787     if (!pDocView->GetSnapToGridState()) return (FALSE);
00788 
00789     BOOL Snapped = FALSE;
00790 
00791     // find the first grid in this layer
00792     Node* pNode = pSpread->FindFirstChild();
00793     if (!pNode->IS_KIND_OF(NodeGrid))
00794         pNode = pNode->FindNext(CC_RUNTIME_CLASS(NodeGrid));
00795 
00796     DocRect SnappedRect,ClosestSnappedRect;
00797 
00798     while (pNode != NULL)
00799     {
00800         NodeGrid* pNodeGrid = (NodeGrid *)pNode;
00801 
00802         SnappedRect = *pDocRect;
00803         if (pNodeGrid->Snap(&SnappedRect,PrevCoord,CurCoord))
00804         {
00805             if (Snapped)
00806             {
00807                 if (pDocRect->lo.Distance(SnappedRect.lo) < pDocRect->lo.Distance(ClosestSnappedRect.lo))
00808                     ClosestSnappedRect = SnappedRect;
00809             }
00810             else
00811             {
00812                 ClosestSnappedRect = SnappedRect;
00813                 Snapped = TRUE;
00814             }
00815         }
00816         pNode = pNode->FindNext(CC_RUNTIME_CLASS(NodeGrid));
00817     }
00818 
00819     if (Snapped)
00820         *pDocRect = ClosestSnappedRect;
00821 
00822     return (Snapped);
00823 }

BOOL CSnap::SnapToGrids DocCoord pDocCoord  ) 
 

Allows you to easily snap a coord to a grid in a spread.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
pDocCoord = a spread coord [INPUTS]
Returns:
TRUE - The coord has been snapped to a grid FALSE - The coord is untouched by man and beast
See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 712 of file snap.cpp.

00713 {
00714     // Make sure that we can and should be snapping to grids
00715     ERROR3IF(pDocView == NULL || pSpread == NULL,"Invalid DocView and/or spread");
00716     if (pDocView == NULL || pSpread == NULL) return FALSE;
00717 // >>>> Phil says: This isn't needed because the caller always checks this
00718 // >>>> if necessary.
00719 //  if (!pDocView->GetSnapToGridState()) return (FALSE);
00720 
00721     // We haven't snapped yet
00722     BOOL Snapped = FALSE;
00723 
00724     // find the first grid in this layer
00725     Node* pNode = pSpread->FindFirstChild();
00726     if (!pNode->IS_KIND_OF(NodeGrid))
00727         pNode = pNode->FindNext(CC_RUNTIME_CLASS(NodeGrid));
00728 
00729     // Get some DocCoords ready
00730     DocCoord SnappedCoord,ClosestSnappedCoord;
00731 
00732     while (pNode != NULL)
00733     {
00734         // We've got a kind of grid
00735         NodeGrid* pNodeGrid = (NodeGrid *)pNode;
00736 
00737         SnappedCoord = *pDocCoord;
00738         if (pNodeGrid->Snap(&SnappedCoord))
00739         {
00740             // We've now got a snapped version of the coord
00741             // Keep the snapped coord that is closest to the original point
00742 
00743             if (Snapped)
00744             {
00745                 if (pDocCoord->Distance(SnappedCoord) < pDocCoord->Distance(ClosestSnappedCoord))
00746                     ClosestSnappedCoord = SnappedCoord;
00747             }
00748             else
00749             {
00750                 ClosestSnappedCoord = SnappedCoord;
00751                 Snapped = TRUE;
00752             }
00753         }
00754         // Get the next node, it could be a grid!
00755         pNode = pNode->FindNext(CC_RUNTIME_CLASS(NodeGrid));
00756     }
00757 
00758     if (Snapped)
00759         *pDocCoord = ClosestSnappedCoord;
00760 
00761     return (Snapped);
00762 }

BOOL CSnap::SnapToGuidelines DocRect pDocRect,
const DocCoord PrevCoord,
const DocCoord CurCoord
[private]
 

Allows you to easily snap a rect to a guideline in a spread.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/9/95
Parameters:
pDocRect = a spread rect [INPUTS] PrevCoord = Prev coord of mouse pointer CurCoord = Current coord of mouse pointer
Returns:
TRUE - The rect has been snapped to something FALSE - The rect is untouched by man and beast
This will snap the sides of the rect closest to the guidelines on the page.

It snaps the H & V sides of the rect independantly, so that the corner of the rect will snap into H & V guideline intersection points correctly/

See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 545 of file snap.cpp.

00546 {
00547     ERROR2IF(pDocRect == NULL,FALSE,"pDocRect is NULL");
00548 
00549     // This is the amount we will be translating pDocRect by in order to get it to snap
00550     INT32 DeltaX = 0, DeltaY = 0;
00551 
00552     // Copy of the original pDocRect to preserve the original coords
00553     DocRect SnappedRect = *pDocRect;
00554 
00555     //----
00556     // Snap the left or right hand side of the rect
00557     //----
00558 
00559     BOOL SnappedLoX = SnapToGuidelines(&SnappedRect.lo,GUIDELINE_VERT);     // Snap the left hand side
00560     BOOL SnappedHiX = SnapToGuidelines(&SnappedRect.hi,GUIDELINE_VERT);     // Snap the right hand side
00561     
00562     if (SnappedLoX && SnappedHiX)
00563     {
00564         // Did both sides snap? I.e. are both sides very close to a vertical guideline?
00565         // If so, choose to snap the side that's closest to a guideline
00566 
00567         BOOL DeltaLoX = SnappedRect.lo.x - pDocRect->lo.x;
00568         BOOL DeltaHiX = SnappedRect.hi.x - pDocRect->hi.x;
00569 
00570         if (abs(DeltaLoX) < abs(DeltaHiX))
00571             DeltaX = DeltaLoX;
00572         else
00573             DeltaX = DeltaHiX;
00574     }
00575     else if (SnappedLoX)
00576         DeltaX = SnappedRect.lo.x - pDocRect->lo.x;     // Only the left hand side snapped
00577     else if (SnappedHiX)
00578         DeltaX = SnappedRect.hi.x - pDocRect->hi.x;     // Only the right hand side snapped
00579 
00580     //----
00581     // Snap the top or bottom of the rect
00582     //----
00583 
00584     BOOL SnappedLoY = SnapToGuidelines(&SnappedRect.lo,GUIDELINE_HORZ);     // Snap the bottom
00585     BOOL SnappedHiY = SnapToGuidelines(&SnappedRect.hi,GUIDELINE_HORZ);     // Snap the top
00586     
00587     if (SnappedLoY && SnappedHiY)
00588     {
00589         // Did both sides snap? I.e. are both sides very close to a horizontal guideline?
00590         // If so, choose to snap the side that's closest to a guideline
00591 
00592         BOOL DeltaLoY = SnappedRect.lo.y - pDocRect->lo.y;
00593         BOOL DeltaHiY = SnappedRect.hi.y - pDocRect->hi.y;
00594 
00595         if (abs(DeltaLoY) < abs(DeltaHiY))
00596             DeltaY = DeltaLoY;
00597         else
00598             DeltaY = DeltaHiY;
00599     }
00600     else if (SnappedLoY)
00601         DeltaY = SnappedRect.lo.y - pDocRect->lo.y;     // Only the bottom snapped
00602     else if (SnappedHiY)
00603         DeltaY = SnappedRect.hi.y - pDocRect->hi.y;     // Only the top snapped
00604 
00605 
00606     // Did any snapping occur?
00607     BOOL Snapped = (SnappedLoX || SnappedHiX || SnappedLoY || SnappedHiY);
00608 
00609     // If it did, translate pDocRect by the required amount
00610     if (Snapped)
00611         pDocRect->Translate(DeltaX,DeltaY);
00612 
00613     return (Snapped);
00614 }

BOOL CSnap::SnapToGuidelines DocCoord pDocCoord,
GuidelineType  Type = GUIDELINE_NOTYPE
 

Allows you to easily snap a coord to a guideline in a spread.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/9/95
Parameters:
pDocCoord = a spread coord [INPUTS] Type = type of guideline to snap to (GUIDELINE_NOTYPE means snap to all types)
Returns:
TRUE - The coord has been snapped to a guideline FALSE - The coord is untouched by man and beast
When Type == GUIDELINE_NOTYPE: It snaps the X ordinate to the vertical rulers, and the Y ordinate to horizontal rulers. This also creates the desired effect of making H & V guideline intersection points hot.

When Type != GUIDELINE_NOTYPE: It snaps the given coord to this type of guideline only. (Used by the DocRect snapping version of this func)

See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 410 of file snap.cpp.

00411 {
00412     ERROR3IF(pDocView == NULL || pSpread == NULL,"Invalid DocView and/or spread");
00413     if (pDocView == NULL || pSpread == NULL) return FALSE;
00414 
00415     // We haven't snapped yet
00416     BOOL Snapped = FALSE;
00417 
00418     // Scan all layers in the spread
00419     Layer* pLayer = pSpread->FindFirstLayer();
00420     while (pLayer != NULL && !Snapped)
00421     {
00422         if (pLayer->IsGuide() && pLayer->IsVisible())
00423         {
00424             // Only guide layers can contain guidelines
00425 
00426             if (Type == GUIDELINE_NOTYPE)
00427             {
00428                 // OK, try to snap to both H & V guidelines
00429                 Snapped  = SnapToGuidesInLayer(pLayer,pDocCoord,GUIDELINE_HORZ);
00430                 Snapped |= SnapToGuidesInLayer(pLayer,pDocCoord,GUIDELINE_VERT);
00431             }
00432             else
00433                 // Only Snap to guidelines of the given type.
00434                 Snapped  = SnapToGuidesInLayer(pLayer,pDocCoord,Type);
00435         }
00436 
00437         pLayer = pLayer->FindNextLayer();
00438     }
00439 
00440     return Snapped;
00441 }

BOOL CSnap::SnapToGuideObjects DocRect pDocRect,
const DocCoord PrevCoord,
const DocCoord CurCoord
[private]
 

Allows you to easily snap a rect to objects in guide layers.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/9/95
Parameters:
pDocRect = a spread rect [INPUTS] PrevCoord = Prev coord of mouse pointer CurCoord = Current coord of mouse pointer
Returns:
TRUE - The rect has been snapped to a guideline FALSE - The rect is untouched by man and beast
See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 673 of file snap.cpp.

00674 {
00675     ERROR3IF(pDocView == NULL || pSpread == NULL,"Invalid DocView and/or spread");
00676     if (pDocView == NULL || pSpread == NULL) return FALSE;
00677 
00678     // We haven't snapped yet
00679     BOOL Snapped = FALSE;
00680 
00681     // Scan all layers in the spread
00682     Layer* pLayer = pSpread->FindFirstLayer();
00683     while (pLayer != NULL && !Snapped)
00684     {
00685         // Only snap to objects in visible guide layers
00686         if (pLayer->IsGuide() && pLayer->IsVisible())
00687             Snapped = SnapToObjects(pDocRect,PrevCoord,CurCoord,FALSE,TRUE);
00688 
00689         pLayer = pLayer->FindNextLayer();
00690     }
00691 
00692     return Snapped;
00693 }

BOOL CSnap::SnapToGuideObjects DocCoord pDocCoord  )  [private]
 

Allows you to easily snap a coord to objects in guide layers.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/9/95
Parameters:
pDocCoord = a spread coord [INPUTS]
Returns:
TRUE - The coord has been snapped to a guideline FALSE - The coord is untouched by man and beast
See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 634 of file snap.cpp.

00635 {
00636     ERROR3IF(pDocView == NULL || pSpread == NULL,"Invalid DocView and/or spread");
00637     if (pDocView == NULL || pSpread == NULL) return FALSE;
00638 
00639     // We haven't snapped yet
00640     BOOL Snapped = FALSE;
00641 
00642     // Scan all layers in the spread
00643     Layer* pLayer = pSpread->FindFirstLayer();
00644     while (pLayer != NULL && !Snapped)
00645     {
00646         // Only snap to objects in visible guide layers
00647         if (pLayer->IsGuide() && pLayer->IsVisible())
00648             Snapped = SnapToObjects(pLayer,pDocCoord,FALSE,TRUE);
00649 
00650         pLayer = pLayer->FindNextLayer();
00651     }
00652 
00653     return Snapped;
00654 }

BOOL CSnap::SnapToGuidesInLayer Layer pLayer,
DocCoord pDocCoord,
GuidelineType  Type
[private]
 

Helper function that will snap one component of the DocCoord to one type of guideline.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/9/95
Parameters:
pLayer = ptr to layer [INPUTS] pDocCoord = ptr to DocCoord to snap Type = the type of guide to snap to (HORZ or VERT)
Returns:
TRUE - The coord has been snapped to a guideline FALSE - The coord is untouched by man and beast
Only guidelines that are top-level children of pLayer are used

The following statements describe how the snapping is performed (though the code implements a more general method)

if Type == HORZ then the Y coord is snapped to the closest HORZ guideline if Type == VERT then the X coord is snapped to the closest VERT guideline

See also:
CSnap::SnapToGuidelines(DocCoord* pDocCoord)

Definition at line 469 of file snap.cpp.

00470 {
00471     ERROR2IF(pLayer    == NULL,FALSE,"pLayer is NULL");
00472     ERROR2IF(pDocCoord == NULL,FALSE,"pDocCoord is NULL");
00473 
00474     BOOL Snapped      = FALSE;
00475     BOOL FirstSnapped = TRUE;
00476 
00477     DocCoord SnappedCoord;          // Holds the snapped version of pDocCoord
00478     DocCoord ClosestSnappedCoord;   // The closest snapped coord to the original coord
00479 
00480     // Scan all top-level objects in the layer for guidelines
00481     Node* pNode = pLayer->FindFirstChild(CC_RUNTIME_CLASS(NodeGuideline));
00482     while (pNode != NULL && !Snapped)
00483     {
00484         NodeGuideline* pGuide = ((NodeGuideline*)pNode);
00485 
00486         if (pGuide->GetType() == Type)
00487         {
00488             // We've found a guideline of the correct type
00489 
00490             // Snap the coord
00491             SnappedCoord = *pDocCoord;
00492             Snapped = pGuide->Snap(&SnappedCoord);
00493 
00494             if (Snapped)
00495             {
00496                 // If it has snapped, make sure our idea of the closest snapped coord is correct
00497                 if (FirstSnapped)
00498                 {
00499                     // If it's the first time we have received a snapped coord, it must be the closest
00500                     ClosestSnappedCoord = SnappedCoord;
00501                     FirstSnapped = FALSE;
00502                 }
00503                 else
00504                 {
00505                     // Is this snapped coord closer to the original coord than the previous closest snapped coord?
00506                     if (pDocCoord->Distance(SnappedCoord) < pDocCoord->Distance(ClosestSnappedCoord))
00507                         ClosestSnappedCoord = SnappedCoord;
00508                 }
00509             }
00510         }
00511 
00512         pNode = pNode->FindNext(CC_RUNTIME_CLASS(NodeGuideline));
00513     }
00514 
00515     // Update the supplied coord if we have a snapped version.
00516     if (Snapped)
00517         *pDocCoord = ClosestSnappedCoord;
00518 
00519     return Snapped;
00520 }

BOOL CSnap::SnapToObjects DocRect pDocRect,
const DocCoord PrevCoord,
const DocCoord CurCoord,
BOOL  Magnetic,
BOOL  GuideLayersOnly
[private]
 

Allows you to easily snap a coord to an object in a spread.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
pDocRect = a rectangle is spread coords [INPUTS] PrevCoord = Used to determine how rect is snapped CurCoord = As above Magnetic = TRUE means only snap to magnetic objects FALSE means snap to all objects GuideLayersOnly = TRUE means ignore objects on guide layers FALSE means treat guide layers as standard layers
Returns:
TRUE - The rect has been snapped to an object FALSE - The rect is untouched by man and beast
See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 1056 of file snap.cpp.

01057 {
01058     return FALSE;
01059 }

BOOL CSnap::SnapToObjects Node pRootNode,
DocCoord pDocCoord,
BOOL  Magnetic,
BOOL  GuideLayersOnly
[private]
 

Allows you to snap a coord to an object in a spread. This will try and snap the coord to NodeRenderableBounded nodes in the sub-tree in the reverse order in which they are rendered. Each eligable node is firstly checked to see if the bounds contain the coord. If the Magnetic param is TRUE, only NodeRend nodes with their Man.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/9/94
Parameters:
pRootNode = ptr to root node of sub tree of objects to snap to [INPUTS] pDocCoord = a spread coord Magnetic = TRUE means only snap to magnetic objects FALSE means snap to all objects GuideLayersOnly = TRUE means objects on visible guide layers only FALSE means objects on visible layers EXCEPT visible guide layers
Returns:
TRUE - The coord has been snapped to an object FALSE - The coord is untouched by man and beast
See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 851 of file snap.cpp.

00852 {
00853     // were we passed rubbish
00854     if (pRootNode==NULL)
00855         return FALSE;
00856 
00857     // Got a real node here. It should be the last child node of the spread
00858     Node* pNode = pRootNode;
00859     BOOL  IsRising = FALSE;
00860 //  BOOL  Snapped = FALSE;
00861 
00862     // Find a DocView
00863     DocView* pDocView = DocView::GetCurrent();
00864     if (pDocView==NULL)
00865         return FALSE;
00866 
00867     // set up an interval timer so we can regularly check if we need to abort
00868     const UINT32 AbortDelay = 100;  // milliseconds
00869     MonotonicTime AbortTimer;
00870     AbortTimer.Sample();
00871 
00872     while (!pNode->IsSpread())
00873     {
00874         // at regular intervals, check to see if we should abort the snap test
00875         if (AbortTimer.Elapsed(AbortDelay))
00876         {
00877             // if mouse moved, abort
00878             if (pDocView->IsMouseMoved())
00879                 return FALSE;
00880 
00881             // also abort if the mouse is no longer of the docview
00882 PORTNOTE("Snap", "Removed use of GetMousePosAndWindowID to abort snap processing")
00883 #if !defined(EXCLUDE_FROM_XARALX)
00884             CWindowID WinID;
00885             WinCoord  WndPos;
00886             BOOL      MouseOK = CCamApp::GetMousePosAndWindowID( &WinID, &WndPos );
00887             if( MouseOK && WinID != NULL && 
00888                 pDocView != CCamView::GetDocViewFromWindowID( WinID ) )
00889                 return FALSE;
00890 #endif
00891 
00892             // resample timer
00893             AbortTimer.Sample();
00894         }
00895 
00896 
00897 //          while (pNode->IsLayer() &&
00898 //                 (!(((Layer *)pNode)->IsVisible()) || (GuideLayersOnly && ((Layer*)pNode)->IsGuide()))
00899 //                )
00900 
00901         // We need to skip ALL unsuitable layers, so repeat until we find a layer we can snap to
00902         // A suitable layer has to be visible.
00903         // If 'GuideLayersOnly' flag is set, it also has to be a guide layer
00904 
00905         // Assume the layer is not suitable
00906         BOOL SuitableLayer = FALSE;
00907 
00908         // If we have found a layer, and it's not suitable, keep searching until we find one we like
00909         while (pNode->IsLayer() && !SuitableLayer)
00910         {
00911             Layer* pLayer = (Layer*)pNode;
00912 
00913             BOOL Visible = pLayer->IsVisible();                 // Is layer visible?
00914 
00915             if (GuideLayersOnly)                                // Guide layers only?
00916                 SuitableLayer = Visible && pLayer->IsGuide();   // Suitable if visible & guide layer
00917             else
00918                 SuitableLayer = Visible && !pLayer->IsGuide();  // Else, suitable if visible & NOT guide layer
00919 
00920             if (!SuitableLayer)
00921             {
00922                 // This layer is not suitable, so skip it
00923                 if (pNode->FindPrevious() != NULL)
00924                     pNode = pNode->FindPrevious();
00925                 else
00926                 {
00927                     pNode = pNode->FindParent();
00928                     IsRising = TRUE;    // If we haven't hit a spread, then we'd better make sure
00929                                         // that the next if statement does the right thing
00930                 }
00931 
00932                 // See if we have come back to the spread
00933                 if (pNode == NULL || pNode->IsSpread())
00934                     return FALSE;
00935             }
00936         }
00937 
00938         if (!IsRising)
00939         {
00940             // Get the last most child from this node
00941             if (pNode->ShouldBeRendered())
00942             {
00943                 while (pNode->FindFirstChild()!=NULL)
00944                 {
00945                     // Get the last node in the sibling list
00946                     pNode = pNode->FindLastChild();
00947 
00948                     // If it was NULL then something odd has happened, so fail
00949                     if (pNode==NULL)
00950                         return FALSE;
00951                 }
00952             }
00953         }
00954 
00955         // Test this node for magnetic snapping
00956         if (pNode->ShouldBeRendered())
00957         {       
00958             if (TryToSnapToObject(pNode, pDocCoord))
00959             {
00960                 // This node snapped. Note the node so we can try again next time
00961                 pLastSnappingObject = pNode;
00962                 return TRUE;
00963             }
00964         }
00965 
00966         // It did not snap to that node, so find the previous one
00967         if (pNode->FindPrevious()!=NULL)
00968         {
00969             // find the node before this one
00970             pNode = pNode->FindPrevious();
00971             IsRising = FALSE;
00972         }
00973         else
00974         {
00975             // run out of nodes, so find the parent and flag that
00976             // we are going up in the tree
00977             pNode = pNode->FindParent();
00978             IsRising = TRUE;
00979         }
00980     } 
00981 
00982     // No nodes snapped to the coord
00983     return FALSE;
00984 }

BOOL CSnap::SnapToPages DocRect pDocRect,
const DocCoord PrevCoord,
const DocCoord CurCoord
[private]
 

Allows you to easily snap a coord to a page in a spread.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/12/95
Parameters:
pDocRect = a spread rect [INPUTS] PrevCoord = Prev coord of mouse pointer CurCoord = Current coord of mouse pointer
Returns:
TRUE - The rect has been snapped to a page FALSE - The coord is untouched by man and beast
See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 366 of file snap.cpp.

00367 {
00368     ERROR3IF(pDocView == NULL || pSpread == NULL,"Invalid DocView and/or spread");
00369     if (pDocView == NULL || pSpread == NULL) return FALSE;
00370 
00371     BOOL Snapped = FALSE;
00372 
00373     Page* pPage = pSpread->FindFirstPageInSpread();
00374     while (pPage != NULL && !Snapped)
00375     {
00376         Snapped = pPage->Snap(pDocRect,PrevCoord,CurCoord);
00377         pPage = pPage->FindNextPage();
00378     }
00379 
00380     return Snapped;
00381 }

BOOL CSnap::SnapToPages DocCoord pDocCoord  )  [private]
 

Allows you to easily snap a coord to a page in a spread.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/12/95
Parameters:
pDocCoord = a spread coord [INPUTS]
Returns:
TRUE - The coord has been snapped to a page FALSE - The coord is untouched by man and beast
See also:
All Snap member functions of all classes derived from NodeRenderableBounded.

Definition at line 332 of file snap.cpp.

00333 {
00334     ERROR3IF(pDocView == NULL || pSpread == NULL,"Invalid DocView and/or spread");
00335     if (pDocView == NULL || pSpread == NULL) return FALSE;
00336 
00337     BOOL Snapped = FALSE;
00338 
00339     Page* pPage = pSpread->FindFirstPageInSpread();
00340     while (pPage != NULL && !Snapped)
00341     {
00342         Snapped = pPage->Snap(pDocCoord);
00343         pPage = pPage->FindNextPage();
00344     }
00345 
00346     return Snapped;
00347 }

BOOL CSnap::SnapToValue const INT32  RefValue,
INT32 *  pTestValue,
INT32 *  pLockedValue
[static, private]
 

Given a reference and pointers to two variable values, this function attempts to snap the first variable value to the reference, and if successful adjusts the second variable value by the same amount as the first.

Author:
Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/10/1999
Parameters:
RefValue a reference INT32 to snap to. [INPUTS] pTestValue pointer to a INT32 to snap to RefValue. pLockedValue pointer to a INT32 whose behaviour is locked with pTestValue's
The values referred to by pTestValue, pLockedValue may be changed, in which [OUTPUTS] case this function will return TRUE.
Returns:
TRUE if the given variable values were sucessfully snapped to the reference, FALSE otherwise.

Errors: ERROR3 if either of the variable-value pointers is NULL. In release builds, just returns FALSE if this is the case. See also:

Definition at line 1215 of file snap.cpp.

01216 {
01217     if (pTestValue == NULL || pLockedValue == NULL)
01218     {
01219         ERROR3("CSnap::SnapValues- NULL parameters");
01220         return FALSE;
01221     }
01222 
01223     if ((*pTestValue) > RefValue && ((*pTestValue) - RefValue) <= SnapDist)
01224     {
01225         (*pLockedValue) -= ((*pTestValue) - RefValue);
01226         (*pTestValue) = RefValue;
01227         return TRUE;
01228     }
01229     else if ((*pTestValue) < RefValue && (RefValue - (*pTestValue)) <= SnapDist)
01230     {
01231         (*pLockedValue) += (RefValue - (*pTestValue));
01232         (*pTestValue) = RefValue;
01233         return TRUE;
01234     }
01235 
01236     return FALSE;
01237 }

BOOL CSnap::TryToSnapToObject Node pNode,
DocCoord pDocCoord
 

Allows a test to see if a particular node snaps to a particaular coord.

Author:
Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
Date:
31/1/95
Parameters:
pNode - The node to try and snap to [INPUTS] pDocCoord - The coord to snap
Returns:
TRUE if it snapped the object to the coord, FALSE if it failed to snap

Definition at line 1000 of file snap.cpp.

01001 {
01002     // Test this node for magnetic snapping
01003     if (pNode->IsBounded())
01004     {
01005         // Convert it to a RenderableBounded
01006         NodeRenderableBounded* pNodeRndBnd = (NodeRenderableBounded*) pNode;
01007 
01008         // Don't allow snapping to dragged nodes...
01009         if (pNodeRndBnd->IsDragged())
01010             return FALSE;
01011 
01012         // Firstly, inflate the bounds by the size of the snapping distance
01013         DocRect Bounds = pNodeRndBnd->GetBoundingRect();
01014         if (CSnap::SnapDist > CSnap::SnapToCoordDist)
01015             Bounds.Inflate(CSnap::SnapDist);
01016         else
01017             Bounds.Inflate(CSnap::SnapToCoordDist);
01018 
01019         // If the coord lies inside the inflated bounds of the node, try and snap to the object
01020         if (Bounds.ContainsCoord(*pDocCoord))
01021         {
01022             // Try to snap to the more significant points on the node
01023             if (pNodeRndBnd->SnapToCoords(pDocCoord))
01024                 return TRUE;
01025 
01026             // It failed, so try and snap to the outline of the shape
01027             if (pNodeRndBnd->Snap(pDocCoord))
01028                 return TRUE;
01029         }
01030     }
01031 
01032     // It did not snap to anything
01033     return FALSE;
01034 }


Member Data Documentation

DocView* CSnap::pDocView [private]
 

Definition at line 176 of file snap.h.

Node* CSnap::pLastSnappingObject [private]
 

Definition at line 178 of file snap.h.

Spread* CSnap::pSpread [private]
 

Definition at line 177 of file snap.h.

MILLIPOINT CSnap::SnapDist = 1 [static, private]
 

Definition at line 183 of file snap.h.

MILLIPOINT CSnap::SnapToCoordDist = 1 [static, private]
 

Definition at line 184 of file snap.h.

BOOL CSnap::TrySnapToPages = TRUE [static, private]
 

Definition at line 188 of file snap.h.


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