]> Shamusworld >> Repos - architektonas/blobdiff - src/trimaction.cpp
Trim tool now works for Lines, but inaccurate.
[architektonas] / src / trimaction.cpp
index ea8e9eb5a1eb1a4a65c80377b023319462e908e1..40ae9fe9b61388848f795d81e85c8053022733c4 100644 (file)
@@ -15,6 +15,7 @@
 #include "applicationwindow.h"
 #include "container.h"
 #include "drawingview.h"
+#include "geometry.h"
 #include "line.h"
 #include "mathconstants.h"
 #include "painter.h"
 enum { FIRST_POINT, NEXT_POINT };
 
 
-TrimAction::TrimAction(): state(FIRST_POINT), line(NULL),
-       shiftWasPressedOnNextPoint(false), ctrlWasPressed(false),
-       mirror(new Container(Vector()))
+TrimAction::TrimAction(): state(FIRST_POINT), t(0), u(1.0),
+       doc(&(ApplicationWindow::drawing->document))
+//, line(NULL),
+//     shiftWasPressedOnNextPoint(false), ctrlWasPressed(false),
+//     mirror(new Container(Vector()))
 {
-       ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror);
-       mirror->Save();
+//     ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror);
+//     mirror->Save();
 }
 
 
@@ -39,8 +42,18 @@ TrimAction::~TrimAction()
 
 /*virtual*/ void TrimAction::Draw(Painter * painter)
 {
-       painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine));
+       Object * obj = doc->lastObjectHovered;
 
+       if (obj == NULL)
+               return;
+
+       // This assumes a Line, but it might not be!
+       painter->SetPen(QPen(Qt::black, 2.0, Qt::DotLine));
+       Vector v(((Line *)obj)->position, ((Line *)obj)->endpoint);
+       Point p1 = ((Line *)obj)->position + (v * t);
+       Point p2 = ((Line *)obj)->position + (v * u);
+       painter->DrawLine(p1, p2);
+#if 0
        if (state == FIRST_POINT)
        {
                painter->DrawHandle(p1);
@@ -70,36 +83,111 @@ TrimAction::~TrimAction()
                if (p1 != p2)
                        mirror->Draw(painter);
        }
+#endif
 }
 
 
 /*virtual*/ void TrimAction::MouseDown(Vector point)
 {
-       // Clear our override...
-       shiftWasPressedOnNextPoint = false;
+// this is not accurate enough. need to use the actual intersection point, not
+// just the parameter(s).
+       Object * toTrim = doc->lastObjectHovered;
 
-       if (state == FIRST_POINT)
-               p1 = point;
+       if (toTrim == NULL)
+               return;
+
+//it would be nice to do it like this, but if we bisect the object, we have to
+//create an extra one...
+//     toTrim->Trim(t, u);
+
+       Vector v(((Line *)toTrim)->position, ((Line *)toTrim)->endpoint);
+
+       // Check to see which case we have...
+       // We're trimming point #1...
+       if (t == 0)
+       {
+               ((Line *)toTrim)->position = ((Line *)toTrim)->position + (v * u);
+//             u = 1.0;
+       }
+       else if (u == 1.0)
+       {
+               ((Line *)toTrim)->endpoint = ((Line *)toTrim)->position + (v * t);
+//             t = 0;
+       }
        else
-               p2 = point;
+       {
+               Point p1 = ((Line *)toTrim)->position + (v * t);
+               Point p2 = ((Line *)toTrim)->position + (v * u);
+               Point p3 = ((Line *)toTrim)->endpoint;
+               ((Line *)toTrim)->endpoint = p1;
+               Line * line = new Line(p2, p3);
+               emit ObjectReady(line);
+//             t = 0, u = 1.0;
+       }
+
+       doc->lastObjectHovered = NULL;
 }
 
 
 /*virtual*/ void TrimAction::MouseMoved(Vector point)
 {
+#if 0
        if (state == FIRST_POINT)
                p1 = point;
-       else
+//     else
+//     {
+//             p2 = point;
+//             mirror->Restore();
+//             mirror->Mirror(p1, p2);
+//     }
+#endif
+//     Container & doc = ApplicationWindow::drawing->document;
+//     int items = doc.ItemsSelected();
+       Object * toTrim = doc->lastObjectHovered;
+//     double closestPt1 = 0, closestPt2 = 1.0;
+       t = 0, u = 1.0;
+
+       if (toTrim == NULL)
+               return;
+
+       if (toTrim->type != OTLine)
+               return;
+
+       double pointHoveredT = Geometry::ParameterOfLineAndPoint(((Line *)toTrim)->position, ((Line *)toTrim)->endpoint, point);
+
+       std::vector<Object *>::iterator i;
+
+       for(i=doc->objects.begin(); i!=doc->objects.end(); i++)
        {
-               p2 = point;
-               mirror->Restore();
-               mirror->Mirror(p1, p2);
+               // Can't trim against yourself... :-P
+               if (*i == toTrim)
+                       continue;
+
+               Object * trimAgainst = *i;
+               double t1;//, u1;
+
+               if ((toTrim->type != OTLine) || (trimAgainst->type != OTLine))
+                       continue;
+
+               int intersects = Geometry::Intersects((Line *)toTrim, (Line *)trimAgainst, &t1);//, &u1);
+
+               if (intersects)
+               {
+                       // Now what? We don't know which side to trim!
+                       // ... now we do, we know which side of the Line we're on!
+                       if ((t1 > t) && (t1 < pointHoveredT))
+                               t = t1;
+
+                       if ((t1 < u) && (t1 > pointHoveredT))
+                               u = t1;
+               }
        }
 }
 
 
 /*virtual*/ void TrimAction::MouseReleased(void)
 {
+#if 0
        if (state == FIRST_POINT)
        {
                p2 = p1;
@@ -121,11 +209,13 @@ TrimAction::~TrimAction()
                        mirror->CopyContentsTo(&(ApplicationWindow::drawing->document));
                }
        }
+#endif
 }
 
 
 /*virtual*/ void TrimAction::KeyDown(int key)
 {
+#if 0
        if ((key == Qt::Key_Shift) && (state == NEXT_POINT))
        {
                shiftWasPressedOnNextPoint = true;
@@ -139,11 +229,17 @@ TrimAction::~TrimAction()
                ctrlWasPressed = true;
                emit NeedRefresh();
        }
+#endif
+       if ((t == 0) && (u == 1.0))
+               return;
+
+       t = 0, u = 1.0;
 }
 
 
 /*virtual*/ void TrimAction::KeyReleased(int key)
 {
+#if 0
        if ((key == Qt::Key_Shift) && shiftWasPressedOnNextPoint)
        {
                shiftWasPressedOnNextPoint = false;
@@ -157,5 +253,6 @@ TrimAction::~TrimAction()
                ctrlWasPressed = false;
                emit NeedRefresh();
        }
+#endif
 }