*.ui
pix/*
res/*.xcf
+dxflib/
+fparser/
+architektonas
- Add Spline
- Add Text
- Manipulate Dimension
- - Object connections
+ - Object connections (two types: flexible and rigid)
- Group selection (kind done, needs more work though)
- Take movement code out of Objects and put it into top level Container (actually
I think this should be more of the state code handling. Have to see.)
#include "arc.h"
#include <QtGui>
+#include "geometry.h"
#include "mathconstants.h"
#include "painter.h"
/*virtual*/ bool Arc::Collided(Vector point)
{
+ // Someone told us to fuck off, so we'll fuck off. :-)
+ if (ignoreClicks)
+ return false;
+
objectWasDragged = false;
bool hitSomething = HitTest(point);
draggingCenter = hitCenter;
return new Arc(position, radius, startAngle, angleSpan, parent);
}
+
+/*virtual*/ void Arc::Mirror(Point p1, Point p2)
+{
+ Point c1 = Geometry::MirrorPointAroundLine(position, p1, p2);
+ Point ap1(cos(startAngle + angleSpan), sin(startAngle + angleSpan));
+ Point angleEndPoint = (ap1 * radius) + position;
+ Point c2 = Geometry::MirrorPointAroundLine(angleEndPoint, p1, p2);
+
+ position = c1;
+ startAngle = Vector(c2, c1).Angle();
+}
+
+
+/*virtual*/ void Arc::Save(void)
+{
+ Object::Save();
+ oldRadius2 = radius;
+ oldStartAngle = startAngle;
+ oldAngleSpan = angleSpan;
+}
+
+
+/*virtual*/ void Arc::Restore(void)
+{
+ Object::Restore();
+ radius = oldRadius2;
+ startAngle = oldStartAngle;
+ angleSpan = oldAngleSpan;
+}
+
virtual void Enumerate(FILE *);
virtual Object * Copy(void);
virtual QRectF Extents(void);
+ virtual void Mirror(Point, Point);
+ virtual void Save(void);
+ virtual void Restore(void);
private:
bool AngleInArcSpan(double angle);
double radius; // Center is Object::position
double startAngle; // Starting angle in radians
double angleSpan; // # of degrees the arc spans in radians
+ double oldRadius2;
+ double oldStartAngle;
+ double oldAngleSpan;
private:
// bool hitHandle1; // Moving
#include "circle.h"
#include <QtGui>
+#include "geometry.h"
#include "painter.h"
/*virtual*/ bool Circle::Collided(Vector point)
{
+ // Someone told us to fuck off, so we'll fuck off. :-)
+ if (ignoreClicks)
+ return false;
+
// We can assume this, since this is a mouse down event here.
objectWasDragged = false;
HitTest(point);
return new Circle(position, radius, parent);
}
+
+/*virtual*/ void Circle::Mirror(Point p1, Point p2)
+{
+ Point c1 = Geometry::MirrorPointAroundLine(position, p1, p2);
+// return new Circle(c1, radius);
+ position = c1;
+}
+
+
+/*virtual*/ void Circle::Save(void)
+{
+ Object::Save();
+ oldRadius2 = radius;
+}
+
+
+/*virtual*/ void Circle::Restore(void)
+{
+ Object::Restore();
+ radius = oldRadius2;
+}
+
virtual void Enumerate(FILE *);
virtual Object * Copy(void);
virtual QRectF Extents(void);
+ virtual void Mirror(Point, Point);
+ virtual void Save(void);
+ virtual void Restore(void);
protected:
void SaveHitState(void);
protected:
double radius; // Center is Object::position
Vector dragPoint; // Used for rendering edge dragging
+ double oldRadius2;
private:
bool draggingEdge;
Container::Container(Vector p1, Object * p/*= NULL*/): Object(p1, p),
isTopLevelContainer(false),
- dragging(false), draggingHandle1(false), draggingHandle2(false)//, needUpdate(false)
+ dragging(false), draggingHandle1(false), draggingHandle2(false),
+ hit(false)//, needUpdate(false)
{
type = OTContainer;
state = OSInactive;
}
+void Container::CopySelectedContentsTo(Container * newContainer)
+{
+ // Sanity check
+ if (newContainer == NULL)
+ return;
+
+ // Shuffle the contents of this container to the new one
+ for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
+ {
+ if ((*i)->state == OSSelected)
+ newContainer->Add((*i)->Copy());
+ }
+}
+
+
void Container::ResizeAllDimensions(double newSize)
{
for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
return c;
}
+
+/*virtual*/ void Container::Mirror(Point p1, Point p2)
+{
+ for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
+ (*i)->Mirror(p1, p2);
+}
+
+
+/*virtual*/ void Container::Save(void)
+{
+ Object::Save();
+
+ for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
+ (*i)->Save();
+}
+
+
+/*virtual*/ void Container::Restore(void)
+{
+ Object::Restore();
+
+ for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
+ (*i)->Restore();
+}
+
virtual QRectF Extents(void);
virtual void Enumerate(FILE *);
virtual Object * Copy(void);
+ virtual void Mirror(Point, Point);
+ virtual void Save(void);
+ virtual void Restore(void);
void Delete(Object *);
void DeleteSelectedItems(void);
void Clear(void);
Object * SelectedItem(unsigned int);
void MoveContentsTo(Container *);
void MoveSelectedContentsTo(Container *);
+ void CopySelectedContentsTo(Container *);
void ResizeAllDimensions(double);
protected:
}
-/*virtual*/ Object * Line::Mirror(Vector p1, Vector p2)
+/*virtual*/ void Line::Mirror(Point p1, Point p2)
{
-#if 1
Point l1 = Geometry::MirrorPointAroundLine(position, p1, p2);
Point l2 = Geometry::MirrorPointAroundLine(endpoint, p1, p2);
- return new Line(l1, l2);
-#else
- Vector normal = Vector::Normal(p1, p2);
- Vector p4 = position + normal;
-
- // Find the intersection of the line and position + normal to the line
- double px = (((p1.x * p2.y) - (p1.y * p2.x)) * (position.x - p4.x))
- - ((p1.x - p2.x) * ((position.x * p4.y) - (position.y * p4.x)));
- double py = (((p1.x * p2.y) - (p1.y * p2.x)) * (position.y - p4.y))
- - ((p1.y - p2.y) * ((position.x * p4.y) - (position.y * p4.x)));
- double d = ((p1.x - p2.x) * (position.y - p4.y))
- - ((p1.y - p2.y) * (position.x - p4.x));
-
- // px = (x1y2 - y1x2)(x3 - x4) - (x1 - x2)(x3y4 - y3x4)
- // py = (x1y2 - y1x2)(y3 - y4) - (y1 - y2)(x3y4 - y3x4)
- // d = (x1 - x2)(y3 - y4) - (y1 - y2)(x3 - x4) = 0 if lines are parallel
- // Intersection is (px / d, py / d)
-
- Vector v1(px / d, py / d);
-
-// Vector normal = Vector::Normal(p1, p2);
- p4 = endpoint + normal;
-
- // Find the intersection of the line and endpoint + normal to the line
- px = (((p1.x * p2.y) - (p1.y * p2.x)) * (endpoint.x - p4.x))
- - ((p1.x - p2.x) * ((endpoint.x * p4.y) - (endpoint.y * p4.x)));
- py = (((p1.x * p2.y) - (p1.y * p2.x)) * (endpoint.y - p4.y))
- - ((p1.y - p2.y) * ((endpoint.x * p4.y) - (endpoint.y * p4.x)));
- d = ((p1.x - p2.x) * (endpoint.y - p4.y))
- - ((p1.y - p2.y) * (endpoint.x - p4.x));
+ position = l1;
+ endpoint = l2;
+}
- Vector v2(px / d, py / d);
-#if 0
- Vector v3 = position - v1;
- Vector v4 = endpoint - v2;
+/*virtual*/ void Line::Save(void)
+{
+ Object::Save();
+ oldEndpoint = endpoint;
+}
- Vector v5 = v1 + -v3;
- Vector v6 = v2 + -v4;
-#else
- Vector v5 = v1 + v1 - position;
- Vector v6 = v2 + v2 - endpoint;
-#endif
- return new Line(v5, v6);
-#endif
+/*virtual*/ void Line::Restore(void)
+{
+ Object::Restore();
+ endpoint = oldEndpoint;
}
virtual Object * Copy(void);
virtual Vector GetPointAtParameter(double parameter);
virtual QRectF Extents(void);
-// virtual ObjectType Type(void);
virtual void Translate(Vector);
virtual void Rotate(Vector, double);
virtual void Scale(Vector, double);
- virtual Object * Mirror(Vector, Vector);
+ virtual void Mirror(Point, Point);
+ virtual void Save(void);
+ virtual void Restore(void);
void SetDimensionOnLine(Dimension * d = 0);
Object * FindAttachedDimension(void);
protected:
Vector endpoint; // Starting point is Object::position
Vector oldPoint; // Used for dragging
+ Point oldEndpoint;
private:
bool draggingLine;
MirrorAction::MirrorAction(): state(FIRST_POINT), line(NULL),
shiftWasPressedOnNextPoint(false), mirror(new Container(Vector()))
{
+// ApplicationWindow::drawing->document.CopySelectedContentsTo(selected);
+ ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror);
+
+// for(std::vector<Object *>::iterator i=mirror->objects.begin(); i!=mirror->objects.end(); i++)
+// (*i)->Save();
+ mirror->Save();
}
}
else
{
- painter->DrawLine(p1, p2);
- painter->DrawHandle(p2);
+ Vector reflectedP2 = -(p2 - p1);
+ Point newP2 = p1 + reflectedP2;
+ painter->DrawLine(newP2, p2);
+ painter->DrawHandle(p1);
double absAngle = (Vector(p2 - p1).Angle()) * RADIANS_TO_DEGREES;
-// double absLength = Vector(position - endpoint).Magnitude();
+
+ // Keep the angle between 0 and 180 degrees
+ if (absAngle > 180.0)
+ absAngle -= 180.0;
QString text = QChar(0x2221) + QObject::tr(": %1");
text = text.arg(absAngle);
// text = text.arg(Vector::Magnitude(p1, p2));
painter->DrawInformativeText(text);
- mirror->Draw(painter);
+ // Draw the mirror only if there's been a line to mirror around
+ if (p1 != p2)
+ mirror->Draw(painter);
}
}
{
p2 = point;
- mirror->Clear();
- int itemsSelected = ApplicationWindow::drawing->document.ItemsSelected();
-
- if (itemsSelected == 0)
- return;
-
- for(int i=0; i<itemsSelected; i++)
+ for(std::vector<Object *>::iterator i=mirror->objects.begin(); i!=mirror->objects.end(); i++)
{
- Object * object = ApplicationWindow::drawing->document.SelectedItem(i);
- Object * mirrored = object->Mirror(p1, p2);
- mirror->Add(mirrored);
+ (*i)->Restore();
+ (*i)->Mirror(p1, p2);
}
}
}
}
else if (state == NEXT_POINT)
{
- // We create the new object here, and then pass it off to the
- // DrawingView which stuffs it into the document.
-// line = new Line(p1, p2);
- // We don't need no stinkin' sentinels, when we have signals & slots!
-// emit ObjectReady(line);
+ state = FIRST_POINT;
- p1 = p2;
- state = NEXT_POINT;
+ std::vector<Object *> & objs = ApplicationWindow::drawing->document.objects;
+
+ for(std::vector<Object *>::iterator i=objs.begin(); i!=objs.end(); i++)
+ {
+ if ((*i)->state == OSSelected)
+ (*i)->Mirror(p1, p2);
+ }
+
+ mirror->Clear();
+ ApplicationWindow::drawing->document.CopySelectedContentsTo(mirror);
+ mirror->Save();
}
}
Line * line;
Vector p1, p2, p1Save;
bool shiftWasPressedOnNextPoint;
+// Container * selected;
Container * mirror;
};
}
-/*virtual*/ Object * Object::Mirror(Vector, Vector)
+/*virtual*/ void Object::Mirror(Point, Point)
{
- return NULL;
+}
+
+
+/*virtual*/ void Object::Save(void)
+{
+ oldPosition = position;
+}
+
+
+/*virtual*/ void Object::Restore(void)
+{
+ position = oldPosition;
}
virtual void Translate(Vector);
virtual void Rotate(Vector, double);
virtual void Scale(Vector, double);
- virtual Object * Mirror(Vector, Vector);
+ virtual void Mirror(Point, Point);
+ virtual void Save(void);
+ virtual void Restore(void);
ObjectState GetState(void);
void Reparent(Object *);
// Dimension * GetAttachedDimension(void);
Object * parent;
// Pen pen;
// Fill fill;
+ Point oldPosition;
public:
ObjectType type;
ObjectState state;