}
-/*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
else
state = OSInactive;
- return;
+ return false;
}
// The TLC will send these messages if the object is selected but not clicked on.
// objectWasDragged = true;
// needUpdate = false;
SaveHitState();
- HitTest(point);
+ bool hovered = HitTest(point);
needUpdate = HitStateChanged();
objectWasDragged = (draggingCenter | draggingEdge | draggingRotate | draggingSpan);
// Why save this? For rendering code?
oldPoint = point;
// needUpdate = true;
+ return hovered;
}
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 *);
}
-/*virtual*/ void Circle::PointerMoved(Vector point)
+/*virtual*/ bool Circle::PointerMoved(Vector point)
{
if (selectionInProgress)
{
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);
// Save this point so the rendering code knows where to draw the handle...
dragPoint = point;
+ return hovered;
}
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 *);
// 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)
{
else
state = OSInactive;
- return;
+ return false;
}
// No need to do any checking if we're already selected...
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);
}
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 *);
std::vector<Object *> objects;
bool isTopLevelContainer;
Object * lastObjectClicked;
+ Object * lastObjectHovered;
private:
bool dragging;
bool draggingHandle1;
}
-/*virtual*/ void Dimension::PointerMoved(Vector point)
+/*virtual*/ bool Dimension::PointerMoved(Vector point)
{
if (selectionInProgress)
{
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);
oldPoint = point;
needUpdate = true;
}
+
+ return hovered;
}
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 *);
}
-/*virtual*/ void Line::PointerMoved(Vector point)
+/*virtual*/ bool Line::PointerMoved(Vector point)
{
if (selectionInProgress)
{
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);
dimPoint2->SetPoint2(draggingHandle2 ? v2 : endpoint);
#endif
}
+
+ return hovered;
}
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);
void SaveHitState(void);
bool HitStateChanged(void);
- protected:
+ public:
Vector endpoint; // Starting point is Object::position
+ protected:
Vector oldPoint; // Used for dragging
Point oldEndpoint;
}
-/*virtual*/ void Object::PointerMoved(Vector)
+/*virtual*/ bool Object::PointerMoved(Vector)
{
+ return false;
}
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);
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;
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 *);
#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)
{
- // 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)
{
+#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)
{
+#if 0
if ((key == Qt::Key_Shift) && shiftWasPressedOnNextPoint)
{
shiftWasPressedOnNextPoint = false;
ctrlWasPressed = false;
emit NeedRefresh();
}
+#endif
}
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__