-// TrimAction.cpp: Action class for mirroring selected objects
+// trimaction.cpp: Action class for mirroring selected objects
//
// Part of the Architektonas Project
// (C) 2011 Underground Software
#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();
}
/*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);
if (p1 != p2)
mirror->Draw(painter);
}
+#endif
}
-/*virtual*/ void TrimAction::MouseDown(Vector point)
+/*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;
mirror->CopyContentsTo(&(ApplicationWindow::drawing->document));
}
}
+#endif
}
-/*virtual*/ void TrimAction::KeyDown(int key)
+/*virtual*/ void TrimAction::KeyDown(int /*key*/)
{
+#if 0
if ((key == Qt::Key_Shift) && (state == NEXT_POINT))
{
shiftWasPressedOnNextPoint = true;
ctrlWasPressed = true;
emit NeedRefresh();
}
+#endif
+ if ((t == 0) && (u == 1.0))
+ return;
+
+ t = 0, u = 1.0;
}
-/*virtual*/ void TrimAction::KeyReleased(int key)
+/*virtual*/ void TrimAction::KeyReleased(int /*key*/)
{
+#if 0
if ((key == Qt::Key_Shift) && shiftWasPressedOnNextPoint)
{
shiftWasPressedOnNextPoint = false;
ctrlWasPressed = false;
emit NeedRefresh();
}
+#endif
}