]> Shamusworld >> Repos - architektonas/commitdiff
Trim tool now works for Lines, but inaccurate.
authorShamus Hammons <jlhamm@acm.org>
Mon, 17 Feb 2014 03:15:20 +0000 (21:15 -0600)
committerShamus Hammons <jlhamm@acm.org>
Mon, 17 Feb 2014 03:15:20 +0000 (21:15 -0600)
15 files changed:
src/arc.cpp
src/arc.h
src/circle.cpp
src/circle.h
src/container.cpp
src/container.h
src/dimension.cpp
src/dimension.h
src/line.cpp
src/line.h
src/object.cpp
src/object.h
src/text.h
src/trimaction.cpp
src/trimaction.h

index 36245b43dc70a2f3cdf160ca80155384bfcddfe2..6aefc1c52bc663d1070e8b8e252f175962266737 100644 (file)
@@ -216,7 +216,7 @@ so let's do like this:
 }
 
 
-/*virtual*/ void Arc::PointerMoved(Vector point)
+/*virtual*/ bool Arc::PointerMoved(Vector point)
 {
 // one other thing to check here for is if a modifier key is being held as well,
 // to allow for multi-selection
@@ -229,7 +229,7 @@ so let's do like this:
                else
                        state = OSInactive;
 
-               return;
+               return false;
        }
 
        // The TLC will send these messages if the object is selected but not clicked on.
@@ -239,7 +239,7 @@ so let's do like this:
 //     objectWasDragged = true;
 //     needUpdate = false;
        SaveHitState();
-       HitTest(point);
+       bool hovered = HitTest(point);
        needUpdate = HitStateChanged();
        objectWasDragged = (draggingCenter | draggingEdge | draggingRotate | draggingSpan);
 
@@ -271,6 +271,7 @@ so let's do like this:
        // Why save this? For rendering code?
        oldPoint = point;
 //     needUpdate = true;
+       return hovered;
 }
 
 
index bb707768b24eb2695de4af5f0281926d0ba630ef..ec3c600132966f472566ff78add11cf12f43cd87 100644 (file)
--- a/src/arc.h
+++ b/src/arc.h
@@ -12,7 +12,7 @@ class Arc: public Object
                virtual void Draw(Painter *);
                virtual Vector Center(void);
                virtual bool Collided(Vector);
-               virtual void PointerMoved(Vector);
+               virtual bool PointerMoved(Vector);
                virtual void PointerReleased(void);
                virtual bool HitTest(Point);
                virtual void Enumerate(FILE *);
index 88cdaa714684be3272265a3ffaae7c08f1d6dc70..94a9ec8f807b47b5e867bb3e5fab79b951c46c3a 100644 (file)
@@ -118,7 +118,7 @@ Circle::~Circle()
 }
 
 
-/*virtual*/ void Circle::PointerMoved(Vector point)
+/*virtual*/ bool Circle::PointerMoved(Vector point)
 {
        if (selectionInProgress)
        {
@@ -129,13 +129,13 @@ Circle::~Circle()
                else
                        state = OSInactive;
 
-               return;
+               return false;
        }
 
        // Hit test tells us what we hit (if anything) through boolean variables. It
        // also tells us whether or not the state changed.
        SaveHitState();
-       HitTest(point);
+       bool hovered = HitTest(point);
        needUpdate = HitStateChanged();
        objectWasDragged = (draggingEdge | draggingCenter);
 
@@ -149,6 +149,7 @@ Circle::~Circle()
 
        // Save this point so the rendering code knows where to draw the handle...
        dragPoint = point;
+       return hovered;
 }
 
 
index 3cf6a44f41ae4a1d28041bc06344d45a2f66ddca..43b297cfe74701eb1bb8c3c3812286db247a20e2 100644 (file)
@@ -14,7 +14,7 @@ class Circle: public Object
                virtual void Draw(Painter *);
                virtual Vector Center(void);
                virtual bool Collided(Vector);
-               virtual void PointerMoved(Vector);
+               virtual bool PointerMoved(Vector);
                virtual void PointerReleased(void);
                virtual bool HitTest(Point);
                virtual void Enumerate(FILE *);
index 9cda1fa38b95e6c10d1af0659326a69af61c5501..2eca9f4573473c0c772a4efd96060836e6bc15ec 100644 (file)
@@ -201,9 +201,10 @@ class so that we can leverage that stuff here as well.
 // into parts and keep subdividing until an acceptable number of objects lie within
 // the slice. This way, the GUI will still be responsive and *not* have to test
 // every object for collision.
-/*virtual*/ void Container::PointerMoved(Vector point)
+/*virtual*/ bool Container::PointerMoved(Vector point)
 {
        std::vector<Object *>::iterator i;
+       lastObjectHovered = NULL;
 
        if (!isTopLevelContainer)
        {
@@ -215,7 +216,7 @@ class so that we can leverage that stuff here as well.
                        else
                                state = OSInactive;
 
-                       return;
+                       return false;
                }
 
                // No need to do any checking if we're already selected...
@@ -253,17 +254,19 @@ class so that we can leverage that stuff here as well.
                        needUpdate = true;
                }
 
-               return;
+               return false;
        }
 
        for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
        {
 //             if (objects[i]->GetState() == OSSelected)
-               (*i)->PointerMoved(point);
+               if ((*i)->PointerMoved(point))
+                       lastObjectHovered = *i;
        }
 
        // Generic container doesn't need this???
 //     needUpdate = false;
+       return (lastObjectHovered == NULL ? false : true);
 }
 
 
index a9066d659116cf461d636dfcac0f89e30a45168a..7de5d8918c175e2e08a221eae603005ceed5d001 100644 (file)
@@ -16,7 +16,7 @@ class Container: public Object
                virtual void Draw(Painter *);
                virtual Vector Center(void);
                virtual bool Collided(Vector);
-               virtual void PointerMoved(Vector);
+               virtual bool PointerMoved(Vector);
                virtual void PointerReleased(void);
                virtual bool NeedsUpdate(void);
                virtual void Add(Object *);
@@ -49,6 +49,7 @@ class Container: public Object
                std::vector<Object *> objects;
                bool isTopLevelContainer;
                Object * lastObjectClicked;
+               Object * lastObjectHovered;
        private:
                bool dragging;
                bool draggingHandle1;
index 01d7ec3d9d1e601f6312b8172b977ba92539bc3e..675afaff89c7c7a3cef7e4f98df0233a51fcaa91 100644 (file)
@@ -243,7 +243,7 @@ I believe they are pixels.
 }
 
 
-/*virtual*/ void Dimension::PointerMoved(Vector point)
+/*virtual*/ bool Dimension::PointerMoved(Vector point)
 {
        if (selectionInProgress)
        {
@@ -254,13 +254,13 @@ I believe they are pixels.
                else
                        state = OSInactive;
 
-               return;
+               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)
        SaveHitState();
-       HitTest(point);
+       bool hovered = HitTest(point);
        needUpdate = HitStateChanged();
 
        objectWasDragged = (/*draggingLine |*/ draggingHandle1 | draggingHandle2);
@@ -278,6 +278,8 @@ I believe they are pixels.
                oldPoint = point;
                needUpdate = true;
        }
+
+       return hovered;
 }
 
 
index 9a9b3d48c024e4e4f35666304f281a4e19492f74..dfbfd1d95dc3fa978cf0781bfe4c4ccc8faa34f8 100644 (file)
@@ -19,7 +19,7 @@ class Dimension: public Object
                virtual void Draw(Painter *);
                virtual Vector Center(void);
                virtual bool Collided(Vector);
-               virtual void PointerMoved(Vector);
+               virtual bool PointerMoved(Vector);
                virtual void PointerReleased(void);
                virtual bool HitTest(Point);
                virtual void Enumerate(FILE *);
index efd92e50900088804ef25b9ee6eed570ea8a7f4e..46a6d85860c8d598b8f76497f9ea4ace005bb20d 100644 (file)
@@ -299,7 +299,7 @@ a dimension only) Draw() function... :-/
 }
 
 
-/*virtual*/ void Line::PointerMoved(Vector point)
+/*virtual*/ bool Line::PointerMoved(Vector point)
 {
        if (selectionInProgress)
        {
@@ -310,13 +310,13 @@ a dimension only) Draw() function... :-/
                else
                        state = OSInactive;
 
-               return;
+               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)
        SaveHitState();
-       HitTest(point);
+       bool hovered = HitTest(point);
        needUpdate = HitStateChanged();
 
        objectWasDragged = (draggingLine | draggingHandle1 | draggingHandle2);
@@ -416,6 +416,8 @@ the horizontal line or vertical line that intersects from the current mouse posi
                        dimPoint2->SetPoint2(draggingHandle2 ? v2 : endpoint);
 #endif
        }
+
+       return hovered;
 }
 
 
index 70bf39861b41bf39817c16f5ee55e442419698a7..8c98924d648aeaa534bc1c7ec510efc5cd2e56e2 100644 (file)
@@ -16,7 +16,7 @@ class Line: public Object
                virtual void Draw(Painter *);
                virtual Vector Center(void);
                virtual bool Collided(Vector);
-               virtual void PointerMoved(Vector);
+               virtual bool PointerMoved(Vector);
                virtual void PointerReleased(void);
                virtual bool HitTest(Point);
                virtual Vector * GetPointAt(Vector);
@@ -38,8 +38,9 @@ class Line: public Object
                void SaveHitState(void);
                bool HitStateChanged(void);
 
-       protected:
+       public:
                Vector endpoint;                                        // Starting point is Object::position
+       protected:
                Vector oldPoint;                                        // Used for dragging
                Point oldEndpoint;
 
index 09d52bf3357b02165410e82e4200877421eddb7e..2e85bf2d3e57c0b9666099dfb81a5a796d2692ac 100644 (file)
@@ -75,8 +75,9 @@ printf("Object: Destroyed!\n");
 }
 
 
-/*virtual*/ void Object::PointerMoved(Vector)
+/*virtual*/ bool Object::PointerMoved(Vector)
 {
+       return false;
 }
 
 
index 08b7e9dc9f9324c79a3c9da6d6f6aedc0f287438..f7d5d7c0a493b02c31d07070ef7bcdcc511e0baf 100644 (file)
@@ -27,7 +27,7 @@ class Object
                virtual void Draw(Painter *);
                virtual Vector Center(void);
                virtual bool Collided(Vector);
-               virtual void PointerMoved(Vector);
+               virtual bool PointerMoved(Vector);
                virtual void PointerReleased(void);
                virtual bool NeedsUpdate(void);
                virtual bool HitTest(Point);
@@ -62,8 +62,9 @@ class Object
                static void SetSnapMode(bool state = true);
                static Vector SnapPointToGrid(Vector);
 
-       protected:
+       public:
                Vector position;                                        // All objects have a position (doubles as reference point)
+       protected:
                Object * parent;
 //this needs to be added eventually
 //             Pen pen;
index a075902a58a43a0b0c3f1dec431a85216e791d36..8bba9f82ac5915776c0b5fb2abc5e4d138d25dca 100644 (file)
@@ -13,7 +13,7 @@ class Text: public Object
                virtual void Draw(Painter *);
                virtual Vector Center(void);
                virtual bool Collided(Vector);
-               virtual void PointerMoved(Vector);
+               virtual bool PointerMoved(Vector);
                virtual void PointerReleased(void);
                virtual bool HitTest(Point);
                virtual void Enumerate(FILE *);
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
 }
 
index 02720deca6e03452faa2882cf221cd166a57025b..78f4425b61baca789583221647b4f9136f1dab6f 100644 (file)
@@ -21,11 +21,13 @@ class TrimAction: public Action
 
        private:
                int state;
-               Line * line;
+//             Line * line;
                Vector p1, p2, p1Save;
-               bool shiftWasPressedOnNextPoint;
-               bool ctrlWasPressed;
-               Container * mirror;
+//             bool shiftWasPressedOnNextPoint;
+//             bool ctrlWasPressed;
+//             Container * mirror;
+               double t, u;
+               Container * doc;
 };
 
 #endif // __TRIMACTION_H__