]> Shamusworld >> Repos - architektonas/blobdiff - src/line.cpp
Added bounding calcs to Arc, more fixes for groups.
[architektonas] / src / line.cpp
index da9717c1af65810bbe2975e33b9c8048c3798610..156b55e6b6b05a812a83cb247e3c0d275e93ac9c 100644 (file)
@@ -19,7 +19,9 @@
 #include "line.h"
 
 #include <QtGui>
+#include "container.h"
 #include "dimension.h"
+#include "mathconstants.h"
 #include "painter.h"
 
 
@@ -88,6 +90,35 @@ Line::~Line()
        else
 //             painter->DrawLine((int)position.x, (int)position.y, (int)endpoint.x, (int)endpoint.y);
                painter->DrawLine(position, endpoint);
+
+       // If we're rotating or setting the span, draw an information panel
+       // showing both absolute and relative angles being set.
+       if (draggingHandle1 || draggingHandle2)
+       {
+               double absAngle = (Vector(endpoint - position).Angle()) * RADIANS_TO_DEGREES;
+//             double relAngle = (startAngle >= oldAngle ? startAngle - oldAngle :
+//                     startAngle - oldAngle + (2.0 * PI)) * RADIANS_TO_DEGREES;
+               double absLength = Vector(position - endpoint).Magnitude();
+
+               QString text;
+
+               text = QObject::tr("Length: %1 in.\n") + QChar(0x2221) + QObject::tr(": %2");
+               text = text.arg(absLength).arg(absAngle);
+
+               QPen pen = QPen(QColor(0x00, 0xFF, 0x00), 1.0, Qt::SolidLine);
+               painter->SetPen(pen);
+               painter->SetBrush(QBrush(QColor(0x40, 0xFF, 0x40, 0x9F)));
+               QRectF textRect(10.0, 10.0, 270.0, 70.0);       // x, y, w, h
+               painter->DrawRoundedRect(textRect, 7.0, 7.0);
+
+               textRect.setLeft(textRect.left() + 14);
+               painter->SetFont(*Object::font);
+//                     pen = QPen(QColor(0xDF, 0x5F, 0x00), 1.0, Qt::SolidLine);
+               pen = QPen(QColor(0x00, 0x5F, 0xDF));
+               painter->SetPen(pen);
+               painter->DrawText(textRect, Qt::AlignVCenter, text);
+//             painter->SetPen(QPen(QColor(0xDF, 0x5F, 0x00)));
+       }
 }
 
 /*virtual*/ Vector Line::Center(void)
@@ -103,6 +134,14 @@ Line::~Line()
        objectWasDragged = false;
        HitTest(point);
 
+       // If we're part of a non-top-level container, send this signal to it
+       if (parent->type == OTContainer && !((Container *)parent)->isTopLevelContainer
+               && (hitLine || hitPoint1 || hitPoint2))
+       {
+               parent->state = OSSelected;
+               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.
@@ -255,6 +294,22 @@ Like so:
 
 /*virtual*/ void Line::PointerMoved(Vector point)
 {
+       if (selectionInProgress)
+       {
+               // Check for whether or not the rect contains this line
+#if 0
+               if (selection.normalized().contains(Extents()))
+#else
+               if (selection.normalized().contains(position.x, position.y)
+                       && selection.normalized().contains(endpoint.x, endpoint.y))
+#endif
+                       state = OSSelected;
+               else
+                       state = OSInactive;
+
+               return;
+       }
+
        // Hit test tells us what we hit (if anything) through boolean variables. It
        // also tells us whether or not the state changed.
        needUpdate = HitTest(point);
@@ -406,6 +461,61 @@ about keeping track of old states...
 }
 
 
+bool Line::HitTest(Point point)
+{
+       SaveState();
+
+       hitPoint1 = hitPoint2 = hitLine = false;
+       Vector lineSegment = endpoint - position;
+       Vector v1 = point - position;
+       Vector v2 = point - endpoint;
+       double parameterizedPoint = lineSegment.Dot(v1) / lineSegment.Magnitude(), distance;
+
+       // Geometric interpretation:
+       // The parameterized point on the vector lineSegment is where the perpendicular
+       // intersects lineSegment. If pp < 0, then the perpendicular lies beyond the 1st
+       // endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd endpoint.
+
+       if (parameterizedPoint < 0.0)
+               distance = v1.Magnitude();
+       else if (parameterizedPoint > lineSegment.Magnitude())
+               distance = v2.Magnitude();
+       else
+               // distance = ?Det?(ls, v1) / |ls|
+               distance = fabs((lineSegment.x * v1.y - v1.x * lineSegment.y) / lineSegment.Magnitude());
+
+       // Geometric interpretation of the above:
+       // If the segment endpoints are s and e, and the point is p, then the test
+       // for the perpendicular intercepting the segment is equivalent to insisting
+       // that the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
+       // Perpendicular distance from the point to the segment is computed by first
+       // computing the area of the triangle the three points form, then dividing by
+       // the length of the segment.  Distances are done just by the Pythagorean
+       // theorem. Twice the area of the triangle formed by three points is the
+       // determinant of the following matrix:
+       //
+       // sx sy 1       0  0  1       0  0  0
+       // ex ey 1  ==>  ex ey 1  ==>  ex ey 0
+       // px py 1       px py 1       px py 0
+       //
+       // By translating the start point to the origin, and subtracting row 1 from
+       // all other rows, we end up with the matrix on the right which greatly
+       // simplifies the calculation of the determinant.
+
+//How do we determine distance here? Especially if zoomed in or out???
+//#warning "!!! Distances tested for may not be valid if zoomed in or out !!!"
+// [FIXED]
+       if ((v1.Magnitude() * Painter::zoom) < 8.0)
+               hitPoint1 = true;
+       else if ((v2.Magnitude() * Painter::zoom) < 8.0)
+               hitPoint2 = true;
+       else if ((distance * Painter::zoom) < 5.0)
+               hitLine = true;
+
+       return StateChanged();
+}
+
+
 // Check to see if the point passed in coincides with any we have. If so, return a
 // pointer to it; otherwise, return NULL.
 /*virtual*/ Vector * Line::GetPointAt(Vector v)
@@ -469,14 +579,6 @@ you then *definitely* do not want them to have the same reference number.
 }
 
 
-#if 0
-/*virtual*/ ObjectType Line::Type(void)
-{
-       return OTLine;
-}
-#endif
-
-
 void Line::SetDimensionOnLine(Dimension * dimension/*=NULL*/)
 {
        // If they don't pass one in, create it for the caller.
@@ -530,60 +632,6 @@ Object * Line::FindAttachedDimension(void)
 }
 
 
-bool Line::HitTest(Point point)
-{
-       SaveState();
-
-       hitPoint1 = hitPoint2 = hitLine = false;
-       Vector lineSegment = endpoint - position;
-       Vector v1 = point - position;
-       Vector v2 = point - endpoint;
-       double parameterizedPoint = lineSegment.Dot(v1) / lineSegment.Magnitude(), distance;
-
-       // Geometric interpretation:
-       // The parameterized point on the vector lineSegment is where the perpendicular
-       // intersects lineSegment. If pp < 0, then the perpendicular lies beyond the 1st
-       // endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd endpoint.
-
-       if (parameterizedPoint < 0.0)
-               distance = v1.Magnitude();
-       else if (parameterizedPoint > lineSegment.Magnitude())
-               distance = v2.Magnitude();
-       else
-               // distance = ?Det?(ls, v1) / |ls|
-               distance = fabs((lineSegment.x * v1.y - v1.x * lineSegment.y) / lineSegment.Magnitude());
-
-       // Geometric interpretation of the above:
-       // If the segment endpoints are s and e, and the point is p, then the test
-       // for the perpendicular intercepting the segment is equivalent to insisting
-       // that the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
-       // Perpendicular distance from the point to the segment is computed by first
-       // computing the area of the triangle the three points form, then dividing by
-       // the length of the segment.  Distances are done just by the Pythagorean
-       // theorem. Twice the area of the triangle formed by three points is the
-       // determinant of the following matrix:
-       //
-       // sx sy 1       0  0  1       0  0  0
-       // ex ey 1  ==>  ex ey 1  ==>  ex ey 0
-       // px py 1       px py 1       px py 0
-       //
-       // By translating the start point to the origin, and subtracting row 1 from
-       // all other rows, we end up with the matrix on the right which greatly
-       // simplifies the calculation of the determinant.
-
-//How do we determine distance here? Especially if zoomed in or out???
-//#warning "!!! Distances tested for may not be valid if zoomed in or out !!!"
-// [FIXED]
-       if ((v1.Magnitude() * Painter::zoom) < 8.0)
-               hitPoint1 = true;
-       else if ((v2.Magnitude() * Painter::zoom) < 8.0)
-               hitPoint2 = true;
-       else if ((distance * Painter::zoom) < 5.0)
-               hitLine = true;
-
-       return StateChanged();
-}
-
 void Line::SaveState(void)
 {
        oldHitPoint1 = hitPoint1;
@@ -591,6 +639,7 @@ void Line::SaveState(void)
        oldHitLine = hitLine;
 }
 
+
 bool Line::StateChanged(void)
 {
        if ((hitPoint1 != oldHitPoint1) || (hitPoint2 != oldHitPoint2) || (hitLine != oldHitLine))
@@ -599,6 +648,7 @@ bool Line::StateChanged(void)
        return false;
 }
 
+
 /*
 Intersection of two lines: