]> Shamusworld >> Repos - architektonas/blobdiff - src/line.cpp
Added new triangulation tool, ability to snap to endpoints/intersections.
[architektonas] / src / line.cpp
index 46a6d85860c8d598b8f76497f9ea4ace005bb20d..7841fa8a823e43720d327985e16bf44370eb0ce2 100644 (file)
@@ -131,7 +131,6 @@ Actually, this is done here to keep tools from selecting stuff inadvertantly...
 
        // Someone told us to fuck off, so we'll fuck off. :-)
        if (ignoreClicks)
-//             return false;
                return hit;
 
        // Now that we've done our hit testing on the non-snapped point, snap it if
@@ -139,6 +138,9 @@ Actually, this is done here to keep tools from selecting stuff inadvertantly...
        if (snapToGrid)
                point = SnapPointToGrid(point);
 
+       if (snapPointIsValid)
+               point = snapPoint;
+
 // this is shite. this should be checked for in the Container, not here!
 #warning "!!! This should be checked for in Container, not here !!!"
        // If we're part of a non-top-level container, send this signal to it
@@ -149,87 +151,6 @@ Actually, this is done here to keep tools from selecting stuff inadvertantly...
                return true;
        }
 
-/*
-There's a small problem here with the implementation: You can have a dimension tied
-to only one point while at the same time you can have a dimension sitting on this line.
-Since there's only *one* dimPoint for each point, this can be problematic...
-
-We solve this by allowing only *one* Dimension object to be attached to the Line,
-Arc, etc. and by giving the Dimension object a pointer to our endpoints.
-
-Problem still arises when we delete this object; The attached Dimension object will
-then have bad pointers! What it *should* do is delete the object if and only if this
-line is not attached to any other object. If it is, then one of those attachment
-points should be sent to the dimension object (done for position & endpoint).
-
-NOTE: The STL vector<T> *does not* take ownership of pointers, therefore is suitable
-      for our purposes
-
-Also: It would be nice to have a preview of the dimension being drawn, with a modifier
-key to make it draw/show on the other side...
-
-TODO: Make Dimension preview with modifier keys for showing on other side
-*/
-/*
-
-N.B.: This no longer works, as the DrawDimension object takes precedence over this code.
-      THIS DOES NOTHING ANYMORE!!!
-
-*/
-#if 0
-       // Is the dimension tool active? Let's use it:
-       if (dimensionActive)
-       {
-               // User clicked on the line itself (endpoint checks should preceed this one):
-               // (Priorities are taken care of in HitTest()...)
-               if (hitLine)
-               {
-#if 0
-                       if (attachedDimension == NULL)
-                       {
-                               // How to get this object into the top level container???
-/*
-The real question is do we care. I think so, because if this isn't in the top
-level container, it won't get drawn...
-But we can fix that by making this object call any attached object's (like
-a dimension only) Draw() function... :-/
-*/
-                               attachedDimension = new Dimension(&position, &endpoint, DTLinear, this);
-
-                               if (parent != NULL)
-                                       parent->Add(attachedDimension);
-                       }
-                       else
-                       {
-                               // If there's one already there, tell it to flip sides...
-                               attachedDimension->FlipSides();
-                       }
-#else
-                       // New approach here: We look for connected objects.
-                       Object * attachedDimension = FindAttachedDimension();
-
-                       if (attachedDimension)
-                       {
-                               // If there's an attached Dimension, tell it to switch sides...
-                               ((Dimension *)attachedDimension)->FlipSides();
-                       }
-                       else
-                       {
-                               // Otherwise, we make a new one and attach it here.
-                               attachedDimension = new Dimension(Connection(this, 0), Connection(this, 1.0), DTLinear, this);
-                               connected.push_back(Connection(attachedDimension, 0));
-                               connected.push_back(Connection(attachedDimension, 1.0));
-
-                               if (parent != NULL)
-                                       parent->Add(attachedDimension);
-                       }
-#endif
-
-                       return true;
-               }
-       }
-#endif
-
        if (state == OSInactive)
        {
 //How to translate this into pixels from Document space???
@@ -313,12 +234,17 @@ a dimension only) Draw() function... :-/
                return false;
        }
 
-       // Hit test tells us what we hit (if anything) through boolean variables. (It
-       // also tells us whether or not the state changed. --not any more)
+       // Hit test tells us what we hit (if anything) through boolean variables.
        SaveHitState();
        bool hovered = HitTest(point);
        needUpdate = HitStateChanged();
 
+       if (snapToGrid)
+               point = SnapPointToGrid(point);
+
+       if (snapPointIsValid)
+               point = snapPoint;
+
        objectWasDragged = (draggingLine | draggingHandle1 | draggingHandle2);
 
        if (objectWasDragged)
@@ -469,6 +395,7 @@ the horizontal line or vertical line that intersects from the current mouse posi
        Vector lineSegment = endpoint - position;
        Vector v1 = point - position;
        Vector v2 = point - endpoint;
+       Vector v3 = point - Center();   // Midpoint, for snapping...
        double t = Geometry::ParameterOfLineAndPoint(position, endpoint, point);
        double distance;
 
@@ -500,12 +427,27 @@ the horizontal line or vertical line that intersects from the current mouse posi
                        / lineSegment.Magnitude());
 
        if ((v1.Magnitude() * Painter::zoom) < 8.0)
+       {
                hitPoint1 = true;
+               snapPoint = position;
+               snapPointIsValid = true;
+       }
        else if ((v2.Magnitude() * Painter::zoom) < 8.0)
+       {
                hitPoint2 = true;
+               snapPoint = endpoint;
+               snapPointIsValid = true;
+       }
        else if ((distance * Painter::zoom) < 5.0)
                hitLine = true;
 
+       // Not a manipulation point, but a snapping point:
+       if ((v3.Magnitude() * Painter::zoom) < 8.0)
+       {
+               snapPoint = Center();
+               snapPointIsValid = true;
+       }
+
        return (hitPoint1 || hitPoint2 || hitLine ? true : false);
 }