]> Shamusworld >> Repos - architektonas/commitdiff
Fixes for the Layer widget.
authorShamus Hammons <jlhamm@acm.org>
Tue, 25 Aug 2015 14:49:25 +0000 (09:49 -0500)
committerShamus Hammons <jlhamm@acm.org>
Tue, 25 Aug 2015 14:49:25 +0000 (09:49 -0500)
All buttons are hooked up and working now, but there is still much to do
to get the Drawing working properly with it, such as putting objects into
the correct layer, hiding layers that the user set as hidden, disallow
editing for layers the user set as locked, & etc.

19 files changed:
src/arc.cpp [deleted file]
src/arc.h [deleted file]
src/circle.cpp [deleted file]
src/circle.h [deleted file]
src/connection.h
src/drawingview.cpp
src/drawingview.h
src/fileio.cpp
src/geometry.cpp
src/geometry.h
src/global.cpp
src/global.h
src/layerwidget.cpp
src/layerwidget.h
src/line.cpp [deleted file]
src/line.h [deleted file]
src/object.cpp [deleted file]
src/object.h [deleted file]
src/settingsdialog.cpp

diff --git a/src/arc.cpp b/src/arc.cpp
deleted file mode 100644 (file)
index 6391eae..0000000
+++ /dev/null
@@ -1,527 +0,0 @@
-// arc.cpp: Arc object
-//
-// Part of the Architektonas Project
-// (C) 2011 Underground Software
-// See the README and GPLv3 files for licensing and warranty information
-//
-// JLH = James Hammons <jlhamm@acm.org>
-//
-// WHO  WHEN        WHAT
-// ---  ----------  ------------------------------------------------------------
-// JLH  03/30/2011  Created this file
-// JLH  04/03/2011  Added information panel (angles) rendering
-// JLH  08/16/2013  Added continuous user feedack like for Line and Circle
-//
-
-#include "arc.h"
-
-#include <QtGui>
-#include "geometry.h"
-#include "mathconstants.h"
-#include "painter.h"
-
-
-Arc::Arc(Vector p1, double r, double a1, double a2, Object * p/*= NULL*/):
-       Object(p1, p), /*type(OTArc),*/ radius(r), startAngle(a1), angleSpan(a2),
-       draggingCenter(false), draggingEdge(false), draggingRotate(false),
-       draggingSpan(false),
-       hitCenter(false), hitArc(false), hitRotate(false), hitSpan(false)
-{
-       // This is in the base class, why can't we use the contructor to fill it???
-       type = OTArc;
-       state = OSInactive;
-}
-
-
-Arc::~Arc()
-{
-}
-
-
-/*virtual*/ void Arc::Draw(Painter * painter)
-{
-       QPen pen;
-       painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine));
-
-       Point p1(cos(startAngle), sin(startAngle));
-       Point p2(cos(startAngle + angleSpan), sin(startAngle + angleSpan));
-       Vector handle2 = (p1 * radius) + position;
-       Vector handle3 = (p2 * radius) + position;
-
-       if ((state == OSSelected) || ((state == OSInactive) && hitRotate))
-               painter->DrawHandle(handle2);
-
-       if ((state == OSSelected) || ((state == OSInactive) && hitSpan))
-               painter->DrawHandle(handle3);
-
-       if ((state == OSSelected) || ((state == OSInactive) && hitCenter))
-               painter->DrawHandle(position);
-
-       if ((state == OSInactive) && !hitArc)
-               painter->SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
-
-       painter->DrawArc(position, radius, startAngle, angleSpan);
-
-       if (draggingRotate || draggingSpan)
-       {
-               if (draggingRotate)
-               {
-                       // If we rotating, we draw a guideline showing the angle we're
-                       // moving it from.
-                       Point p3(cos(oldAngle), sin(oldAngle));
-                       Vector oldLine = (p3 * (radius * 1.25)) + position;
-                       pen = QPen(QColor(0x80, 0x80, 0x80), 1.0, Qt::DashLine);
-                       painter->SetPen(pen);
-//                     painter->DrawLine((int)position.x, (int)position.y, (int)oldLine.x, (int)oldLine.y);
-                       painter->DrawLine(position, oldLine);
-               }
-
-               // In rotating and setting the span, we draw a line showing where
-               // we angle/span is that we're setting.
-               pen = QPen(QColor(0x00, 0xC0, 0x80), 1.0, Qt::DashLine);
-               painter->SetPen(pen);
-               painter->DrawLine((int)position.x, (int)position.y, (int)oldPoint.x, (int)oldPoint.y);
-       }
-
-       // If we're rotating or setting the span, draw an information panel
-       // showing both absolute and relative angles being set.
-       if (draggingRotate || draggingSpan || draggingEdge)
-       {
-               double absAngle = (Vector(oldPoint - position).Angle()) * RADIANS_TO_DEGREES;
-               double relAngle = (startAngle >= oldAngle ? startAngle - oldAngle :
-                       startAngle - oldAngle + (2.0 * PI)) * RADIANS_TO_DEGREES;
-
-               QString text;
-
-               if (draggingRotate)
-               {
-                       text = QObject::tr("Abs ") + QChar(0x2221) + ": %1" + QChar(0x00B0)
-                               + QObject::tr("\nRel ") + QChar(0x2221) + ": %2" + QChar(0x00B0);
-                       text = text.arg(absAngle, 0, 'd', 4).arg(relAngle, 0, 'd', 4);
-               }
-               else if (draggingSpan)
-               {
-                       text = QObject::tr("Abs ") + QChar(0x2221) + ": %1" + QChar(0x00B0)
-                               + QObject::tr("\nSpan: %2") + QChar(0x00B0);
-                       text = text.arg(absAngle, 0, 'd', 4).arg(angleSpan * RADIANS_TO_DEGREES, 0, 'd', 4);
-               }
-               else if (draggingEdge)
-               {
-                       text = QObject::tr("Radius: %1\nScale: %2%");
-                       text = text.arg(radius, 0, 'd', 4).arg(radius / oldRadius * 100.0, 0, 'd', 0);
-               }
-
-#if 0
-               pen = QPen(QColor(0x00, 0xFF, 0x00), 1.0, Qt::SolidLine);
-               painter->SetPen(pen);
-               painter->SetBrush(QBrush(QColor(0x40, 0xFF, 0x40, 0x9F)));
-               QRectF textRect(10.0, 10.0, 270.0, 70.0);       // x, y, w, h
-               painter->DrawRoundedRect(textRect, 7.0, 7.0);
-
-               textRect.setLeft(textRect.left() + 14);
-               painter->SetFont(*Object::font);
-               pen = QPen(QColor(0x00, 0x5F, 0xDF));
-               painter->SetPen(pen);
-               painter->DrawText(textRect, Qt::AlignVCenter, text);
-#else
-               painter->DrawInformativeText(text);
-#endif
-       }
-}
-
-
-/*virtual*/ Vector Arc::Center(void)
-{
-       return position;
-}
-
-
-/*
- We need at least *four* handles for this object:
- - one for moving
- - one for resizing
- - one for rotation
- - one for setting the span of the arc
-
-We need to think about the intuitive way (if there is any) to grab and
-manipulate a complex object like this... Need to think, "What should happen when
-I click here and drag there?"
-
-Also: should put the snap logic into the Object base class (as a static method)...
-*/
-
-/*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;
-       draggingEdge   = hitArc;
-       draggingRotate = hitRotate;
-       draggingSpan   = hitSpan;
-
-       // Now that we've done our hit testing on the non-snapped point, snap it if
-       // necessary...
-       if (snapToGrid)
-               point = SnapPointToGrid(point);
-
-       if (snapPointIsValid)
-               point = snapPoint;
-
-/*
-State Management:
-We want the arc to go into OSSelected mode if we click on it but don't drag.
-If we don't click anywhere on the arc, then we want it to go into OSInactive mode.
-Otherwise, we hit a handle and we want to modify the object whether it's in
-OSSelected mode or not.
-
-If I, go to S. Can drag, but only handles 2, 3, & 4 (since the center is not highlighted
-until we select it.
-       However, if dragging, revert to I once finished.
-
-If S, stay in S. Can drag all.
-
-So, we know this. If wasDragged is true, then there's a chance we need to revert to I.
-How can we be sure?
-
-So. We have a matrix that looks like this:
-
-        |Was I|Was S
---------+-----+-----
-Inactive|     |   
---------+-----+-----
-Selected|     |   
-
-        |h1|h2|h3|h4
---------+--+--+--+--
-Inactive|  |  |  |
---------+--+--+--+--
-Selected|  |  |  |
-
-so let's do like this:
-*/
-       if (hitSomething)
-       {
-               oldState = state;
-               state = OSSelected;
-//             oldPoint = point;
-               oldPoint = position;
-               oldAngle = startAngle;
-               oldRadius = radius;
-               return true;
-       }
-
-       state = OSInactive;
-       return false;
-}
-
-
-/*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
-       if (selectionInProgress)
-       {
-               // Check for whether or not the rect contains this circle
-//             if (selection.normalized().contains(Extents()))
-               if (selection.contains(Extents()))
-                       state = OSSelected;
-               else
-                       state = OSInactive;
-
-               return false;
-       }
-
-       // The TLC will send these messages if the object is selected but not clicked on.
-       // So we have to be careful with our assumptions here.
-       // This is actually untrue in that case, we need to come up with something better
-       // here...
-//     objectWasDragged = true;
-//     needUpdate = false;
-       SaveHitState();
-       bool hovered = HitTest(point);
-       needUpdate = HitStateChanged();
-
-       if (snapToGrid)
-               point = SnapPointToGrid(point);
-
-       if (snapPointIsValid)
-               point = snapPoint;
-
-       objectWasDragged = (draggingCenter | draggingEdge | draggingRotate | draggingSpan);
-
-       if (objectWasDragged)
-               needUpdate = true;
-//     if (!(hitHandle1 || hitHandle2 || hitHandle3 || hitHandle4))
-//             return;
-
-//     Vector delta = point - oldPoint;
-
-       if (draggingCenter)
-               position = point;
-       else if (draggingEdge)
-               radius = Vector::Magnitude(point, position);
-       else if (draggingRotate)
-       {
-               startAngle = Vector(point - position).Angle();
-       }
-       else if (draggingSpan)
-       {
-               double angle = Vector(point - position).Angle();
-
-               if (angle < startAngle)
-                       angle += 2.0 * PI;
-
-               angleSpan = angle - startAngle;
-       }
-
-       // Why save this? For rendering code?
-       oldPoint = point;
-//     needUpdate = true;
-       return hovered;
-}
-
-
-/*virtual*/ void Arc::PointerReleased(void)
-{
-       // Mouse went up, so our dragging is done (if any *was* done, that is)
-//     hitHandle1 = hitHandle2 = hitHandle3 = hitHandle4 = false;
-       draggingCenter = draggingEdge = draggingRotate = draggingSpan = false;
-       hitCenter = hitArc = hitRotate = hitSpan = false;
-
-       // If the object was dragged, then revert to the old state.
-       // Otherwise, we were probably just clicked, and want to stay in the selected state.
-       if (objectWasDragged)
-               state = oldState;
-}
-
-
-/*virtual*/ bool Arc::HitTest(Point point)
-{
-       hitCenter = hitArc = hitRotate = hitSpan = false;
-
-/*
-What we have:
-the center of the arc
-the starting angle
-the span of the arc
-The point on a unit circle given an angle a is x = cos(a), y = sin(a)
-This vector is already unitized, so all we need to do to get our point is to
-multiply it by radius (to get the length correct) and add it to the center
-point (to get the correct position).
-*/
-//     Vector v1(point, position);     // Head minus tail (vector points at "point")
-       Vector v1(position, point);     // Head minus tail (vector points at "point")
-       Point p1(cos(startAngle), sin(startAngle));
-       Point p2(cos(startAngle + angleSpan), sin(startAngle + angleSpan));
-       Vector handle2 = (p1 * radius) + position;
-       Vector handle3 = (p2 * radius) + position;
-       double pointerAngle = v1.Angle();
-       double length = v1.Magnitude();
-
-#if 0
-       if (v1.Magnitude() < 10.0)
-               hitCenter = true;
-       else if (Vector(handle3 - point).Magnitude() < 10.0)
-               hitSpan = true;
-       else if (Vector(handle2 - point).Magnitude() < 10.0)
-               hitRotate = true;
-       else if ((v1.Magnitude() < radius + 3.0) && (v1.Magnitude() > radius - 3.0)
-               && AngleInArcSpan(pointerAngle))
-               hitArc = true;
-#else
-       if ((length * Painter::zoom) < 8.0)
-       {
-               hitCenter = true;
-               snapPoint = position;
-               snapPointIsValid = true;
-       }
-       else if (((fabs(length - radius) * Painter::zoom) < 2.0)
-               && AngleInArcSpan(pointerAngle))
-               hitArc = true;
-       else if ((Vector::Magnitude(handle2, point) * Painter::zoom) < 8.0)
-       {
-               hitRotate = true;
-               snapPoint = handle2;
-               snapPointIsValid = true;
-       }
-       else if ((Vector::Magnitude(handle3, point) * Painter::zoom) < 8.0)
-       {
-               hitSpan = true;
-               snapPoint = handle3;
-               snapPointIsValid = true;
-       }
-#endif
-
-       return (hitCenter || hitArc || hitRotate || hitSpan ? true : false);
-}
-
-
-/*virtual*/ QRectF Arc::Extents(void)
-{
-       double start = startAngle;
-       double end = start + angleSpan;
-       QPointF p1(cos(start), sin(start));
-       QPointF p2(cos(end), sin(end));
-       QRectF bounds(p1, p2);
-
-#if 0
-       // Swap X/Y coordinates if they're backwards...
-       if (bounds.left() > bounds.right())
-       {
-               double temp = bounds.left();
-               bounds.setLeft(bounds.right());
-               bounds.setRight(temp);
-       }
-
-       if (bounds.bottom() > bounds.top())
-       {
-               double temp = bounds.bottom();
-               bounds.setBottom(bounds.top());
-               bounds.setTop(temp);
-       }
-#else
-       bounds = bounds.normalized();
-#endif
-
-       // If the end of the arc is before the beginning, add 360 degrees to it
-       if (end < start)
-               end += 2.0 * PI;
-
-       // Adjust the bounds depending on which axes are crossed
-       if ((start < PI_OVER_2) && (end > PI_OVER_2))
-               bounds.setTop(1.0);
-
-       if ((start < PI) && (end > PI))
-               bounds.setLeft(-1.0);
-
-       if ((start < (PI + PI_OVER_2)) && (end > (PI + PI_OVER_2)))
-               bounds.setBottom(-1.0);
-
-       if ((start < (2.0 * PI)) && (end > (2.0 * PI)))
-               bounds.setRight(1.0);
-
-       if ((start < ((2.0 * PI) + PI_OVER_2)) && (end > ((2.0 * PI) + PI_OVER_2)))
-               bounds.setTop(1.0);
-
-       if ((start < (3.0 * PI)) && (end > (3.0 * PI)))
-               bounds.setLeft(-1.0);
-
-       if ((start < ((3.0 * PI) + PI_OVER_2)) && (end > ((3.0 * PI) + PI_OVER_2)))
-               bounds.setBottom(-1.0);
-
-       bounds.setTopLeft(QPointF(bounds.left() * radius, bounds.top() * radius));
-       bounds.setBottomRight(QPointF(bounds.right() * radius, bounds.bottom() * radius));
-       bounds.translate(position.x, position.y);
-       return bounds;
-}
-
-
-/*
-start = 350, span = 20, end = 10, angle = 5
-angle < start, so angle = 365
-*/
-bool Arc::AngleInArcSpan(double angle)
-{
-       // This should be simple except for a small complication: The start angle plus
-       // the angle span can end up being less than the start angle! So, to check
-       // for this possibility, we check to see if the angle passed in is less than
-       // the start angle and if so, add 2PI to the angle passed in. Then we take the
-       // difference between our start angle and this adjusted angle and see if it
-       // falls within our span.
-       if (angle < startAngle)
-               angle += 2.0 * PI;
-
-       double passedInSpan = angle - startAngle;
-
-       return (passedInSpan <= angleSpan ?  true : false);
-}
-
-
-void Arc::SaveHitState(void)
-{
-       oldHitCenter = hitCenter;
-       oldHitArc    = hitArc;
-       oldHitRotate = hitRotate;
-       oldHitSpan   = hitSpan;
-}
-
-
-bool Arc::HitStateChanged(void)
-{
-       if ((hitCenter != oldHitCenter)
-               || (hitArc != oldHitArc)
-               || (hitRotate != oldHitRotate)
-               || (hitSpan != oldHitSpan))
-               return true;
-
-       return false;
-}
-
-
-/*virtual*/ void Arc::Enumerate(FILE * file)
-{
-       fprintf(file, "ARC %i (%lf,%lf) %lf, %lf, %lf\n", layer, position.x, position.y, radius, startAngle, angleSpan);
-}
-
-
-/*virtual*/ Object * Arc::Copy(void)
-{
-#warning "!!! This doesn't take care of attached Dimensions !!!"
-/*
-This is a real problem. While having a pointer in the Dimension to this line's points
-is fast & easy, it creates a huge problem when trying to replicate an object like this.
-
-Maybe a way to fix that then, is to have reference numbers instead of pointers. That
-way, if you copy them, ... you might still have problems. Because you can't be sure if
-a copy will be persistant or not, you then *definitely* do not want them to have the
-same reference number.
-*/
-       return new Arc(position, radius, startAngle, angleSpan, parent);
-}
-
-
-/*virtual*/ void Arc::Rotate(Point point, double angle)
-{
-       Point c1 = Geometry::RotatePointAroundPoint(position, point, angle);
-       Point ap1(cos(startAngle), sin(startAngle));
-       Point angleStartPoint = (ap1 * radius) + position;
-       Point c2 = Geometry::RotatePointAroundPoint(angleStartPoint, point, angle);
-
-       position = c1;
-       startAngle = Vector(c1, c2).Angle();
-}
-
-
-/*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;
-}
-
diff --git a/src/arc.h b/src/arc.h
deleted file mode 100644 (file)
index ec3c600..0000000
--- a/src/arc.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef __ARC_H__
-#define __ARC_H__
-
-#include "object.h"
-
-class Arc: public Object
-{
-       public:
-               Arc(Vector, double, double, double, Object * p = 0);
-               ~Arc();
-
-               virtual void Draw(Painter *);
-               virtual Vector Center(void);
-               virtual bool Collided(Vector);
-               virtual bool PointerMoved(Vector);
-               virtual void PointerReleased(void);
-               virtual bool HitTest(Point);
-               virtual void Enumerate(FILE *);
-               virtual Object * Copy(void);
-               virtual QRectF Extents(void);
-               virtual void Rotate(Point, double);
-               virtual void Mirror(Point, Point);
-               virtual void Save(void);
-               virtual void Restore(void);
-
-       private:
-               bool AngleInArcSpan(double angle);
-
-       protected:
-               void SaveHitState(void);
-               bool HitStateChanged(void);
-
-       protected:
-               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
-//             bool hitHandle2;        // Rotation
-//             bool hitHandle3;        // Setting span of the arc
-//             bool hitHandle4;        // Resizing
-               bool draggingCenter;
-               bool draggingEdge;
-               bool draggingRotate;
-               bool draggingSpan;
-               bool objectWasDragged;
-               Vector oldPoint;                                        // Used for dragging
-               double oldAngle;                                        // Used for user feedback
-               double oldRadius;                                       // Used for user feedback
-               bool hitCenter, hitArc, hitRotate, hitSpan;
-               bool oldHitCenter, oldHitArc, oldHitRotate, oldHitSpan;
-};
-
-#endif // __ARC_H__
diff --git a/src/circle.cpp b/src/circle.cpp
deleted file mode 100644 (file)
index ed37be3..0000000
+++ /dev/null
@@ -1,297 +0,0 @@
-// circle.cpp: Circle object
-//
-// Part of the Architektonas Project
-// (C) 2011 Underground Software
-// See the README and GPLv3 files for licensing and warranty information
-//
-// JLH = James Hammons <jlhamm@acm.org>
-//
-// WHO  WHEN        WHAT
-// ---  ----------  ------------------------------------------------------------
-// JLH  03/28/2011  Created this file
-// JLH  09/26/2011  Added hover effects
-// JLH  09/26/2011  Major cleanup of this class
-//
-
-#include "circle.h"
-
-#include <QtGui>
-#include "geometry.h"
-#include "painter.h"
-
-
-Circle::Circle(Vector p1, double r, Object * p/*= NULL*/): Object(p1, p), radius(r),
-       draggingEdge(false), draggingCenter(false), hitCenter(false), hitCircle(false)
-{
-       type = OTCircle;
-}
-
-
-Circle::~Circle()
-{
-}
-
-
-/*virtual*/ void Circle::Draw(Painter * painter)
-{
-       if (state == OSSelected || hitCircle || hitCenter)
-               painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine));
-       else
-               painter->SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
-
-       // Hatch/Fill...
-//     QBrush brush(Qt::DiagCrossPattern);
-//     brush.setColor(QColor(255, 255, 0));
-//     painter->SetBrush(brush);
-       painter->SetBrush(QBrush(Qt::NoBrush));
-
-       // Draw the object...
-       painter->DrawEllipse(position, radius, radius);
-
-       // & draw handles (if needed)
-       if (state == OSSelected || hitCenter)
-               painter->DrawHandle(position);
-
-       if (state == OSSelected && draggingEdge && objectWasDragged)
-               painter->DrawHandle(dragPoint);
-
-       // If resizing the circle, draw an information panel showing the new radius.
-       if (draggingEdge)
-       {
-               QString text = QObject::tr("Radius: %1\nScale: %2%");
-               text = text.arg(radius, 0, 'd', 4).arg(radius / oldRadius * 100.0, 0, 'd', 0);
-#if 0
-               QPen pen = QPen(QColor(0x00, 0xFF, 0x00), 1.0, Qt::SolidLine);
-               painter->SetPen(pen);
-               painter->SetBrush(QBrush(QColor(0x40, 0xFF, 0x40, 0x9F)));
-               QRectF textRect(10.0, 10.0, 270.0, 70.0);       // x, y, w, h
-               painter->DrawRoundedRect(textRect, 7.0, 7.0);
-
-               textRect.setLeft(textRect.left() + 14);
-               painter->SetFont(*Object::font);
-               pen = QPen(QColor(0x00, 0x5F, 0xDF));
-               painter->SetPen(pen);
-               painter->DrawText(textRect, Qt::AlignVCenter, text);
-#else
-               painter->DrawInformativeText(text);
-#endif
-       }
-}
-
-
-/*virtual*/ Vector Circle::Center(void)
-{
-       return position;
-}
-
-
-/*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);
-
-       // Now that we've done our hit testing on the non-snapped point, snap it if
-       // necessary...
-       if (snapToGrid)
-               point = SnapPointToGrid(point);
-
-       if (snapPointIsValid)
-               point = snapPoint;
-
-       draggingCenter = hitCenter;
-       draggingEdge = hitCircle;
-
-       if (hitCenter || hitCircle)
-       {
-               dragPoint = point;
-               oldState = state;
-               state = OSSelected;
-               oldRadius = radius;
-               return true;
-       }
-
-       // We didn't hit anything, so deselect this object and report failure to hit
-       state = OSInactive;
-       return false;
-}
-
-
-/*virtual*/ bool Circle::PointerMoved(Vector point)
-{
-       if (selectionInProgress)
-       {
-               // Check for whether or not the rect contains this circle
-//             if (selection.normalized().contains(Extents()))
-               if (selection.contains(Extents()))
-                       state = OSSelected;
-               else
-                       state = OSInactive;
-
-               return false;
-       }
-
-/*
-Note that we can separate this out in the TLC, and it would probably make more sense
-to do it there as then we can be assured that all hit testing is done before we do
-any snapping. !!! FIX !!!
-*/
-       // Hit test tells us what we hit (if anything) through boolean variables. It
-       // also tells us whether or not the state changed.
-       SaveHitState();
-       bool hovered = HitTest(point);
-       needUpdate = HitStateChanged();
-
-       if (snapToGrid)
-               point = SnapPointToGrid(point);
-
-       if (snapPointIsValid)
-               point = snapPoint;
-
-       objectWasDragged = (draggingEdge | draggingCenter);
-
-       if (objectWasDragged)
-               needUpdate = true;
-
-       if (draggingEdge)
-               radius = Vector::Magnitude(point, position);
-       else if (draggingCenter)
-               position = point;
-
-       // Save this point so the rendering code knows where to draw the handle...
-       dragPoint = point;
-       return hovered;
-}
-
-
-/*virtual*/ void Circle::PointerReleased(void)
-{
-       // Mouse went up, so our dragging is done (if any *was* done, that is)
-       draggingEdge = draggingCenter = false;
-       hitCenter = hitCircle = false;
-
-       // If the object was dragged, then revert to the old state.
-       // Otherwise, we were probably just clicked, and want to stay in the selected state.
-       if (objectWasDragged)
-               state = oldState;
-}
-
-
-/*virtual*/ bool Circle::HitTest(Point point)
-{
-//     SaveHitState();
-       hitCenter = hitCircle = false;
-       double length = Vector::Magnitude(position, point);
-//printf("Circle::length = %lf, radius = %lf\n", length, radius);
-//How to translate this into pixels from Document space???
-//Maybe we need to pass a scaling factor in here from the caller? That would make
-//sense, as the caller knows about the zoom factor and all that good kinda crap
-/*
-Document passes in the correct Cartesian coordinates being pointed to by the mouse.
-So all we have to be concerned with is properly scaling our hot zones/handle sizes,
-since we generally *don't* want those to scale with the zoom level. ;-)
-
-What is going on here?
-If we're zoomed out to, say, 50%, & our radius is 10.0 (absolute), then on screen
-the radius will be 5.0. By multiplying the length by the zoom factor, we align our
-pointed at length with our on screen length.
-*/
-       if ((length * Painter::zoom) < 8.0)
-       {
-               hitCenter = true;
-
-               // Make sure we don't try to snap to ourselves...!
-               if (!draggingCenter)
-               {
-                       snapPoint = position;
-                       snapPointIsValid = true;
-               }
-       }
-//wrong:       else if ((length < (radius + 2.0)) && (length > (radius - 2.0)))
-/*NB: The following should be identical to what we have down below, but it doesn't work out that way... :-P */
-//close, but no        else if (((length * Painter::zoom) < ((radius * Painter::zoom) + 2.0)) && ((length * Painter::zoom) > ((radius * Painter::zoom) - 2.0)))
-//really wrong!        else if (((length * Painter::zoom) < (radius + 2.0)) && ((length * Painter::zoom) > (radius - 2.0)))
-// close again, but sill no    else if (((length * Painter::zoom) < ((radius + 2.0) * Painter::zoom)) && ((length * Painter::zoom) > ((radius - 2.0) * Painter::zoom)))
-       else if ((fabs(length - radius) * Painter::zoom) < 2.0)
-               hitCircle = true;
-
-//     return HitStateChanged();
-       return (hitCenter || hitCircle ? true : false);
-}
-
-
-/*virtual*/ QRectF Circle::Extents(void)
-{
-       return QRectF(QPointF(position.x - radius, position.y - radius), QPointF(position.x + radius, position.y + radius));
-}
-
-
-void Circle::SaveHitState(void)
-{
-       oldHitCenter = hitCenter;
-       oldHitCircle = hitCircle;
-}
-
-
-bool Circle::HitStateChanged(void)
-{
-       if ((hitCenter != oldHitCenter) || (hitCircle != oldHitCircle))
-               return true;
-
-       return false;
-}
-
-
-/*virtual*/ void Circle::Enumerate(FILE * file)
-{
-       fprintf(file, "CIRCLE %i (%lf,%lf) %lf\n", layer, position.x, position.y, radius);
-}
-
-
-/*virtual*/ Object * Circle::Copy(void)
-{
-#warning "!!! This doesn't take care of attached Dimensions !!!"
-/*
-This is a real problem. While having a pointer in the Dimension to this line's points
-is fast & easy, it creates a huge problem when trying to replicate an object like this.
-
-Maybe a way to fix that then, is to have reference numbers instead of pointers. That
-way, if you copy them, ... you might still have problems. Because you can't be sure if
-a copy will be persistant or not, you then *definitely* do not want them to have the
-same reference number.
-*/
-       return new Circle(position, radius, parent);
-}
-
-
-/*virtual*/ void Circle::Rotate(Point point, double angle)
-{
-       Point c1 = Geometry::RotatePointAroundPoint(position, point, angle);
-       position = c1;
-}
-
-
-/*virtual*/ void Circle::Mirror(Point p1, Point p2)
-{
-       Point c1 = Geometry::MirrorPointAroundLine(position, p1, p2);
-       position = c1;
-}
-
-
-/*virtual*/ void Circle::Save(void)
-{
-       Object::Save();
-       oldRadius2 = radius;
-}
-
-
-/*virtual*/ void Circle::Restore(void)
-{
-       Object::Restore();
-       radius = oldRadius2;
-}
-
diff --git a/src/circle.h b/src/circle.h
deleted file mode 100644 (file)
index 43b297c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#ifndef __CIRCLE_H__
-#define __CIRCLE_H__
-
-#include "object.h"
-
-class Circle: public Object
-{
-       friend class Geometry;
-
-       public:
-               Circle(Vector, double, Object * p = 0);
-               ~Circle();
-
-               virtual void Draw(Painter *);
-               virtual Vector Center(void);
-               virtual bool Collided(Vector);
-               virtual bool PointerMoved(Vector);
-               virtual void PointerReleased(void);
-               virtual bool HitTest(Point);
-               virtual void Enumerate(FILE *);
-               virtual Object * Copy(void);
-               virtual QRectF Extents(void);
-               virtual void Rotate(Point, double);
-               virtual void Mirror(Point, Point);
-               virtual void Save(void);
-               virtual void Restore(void);
-
-       protected:
-               void SaveHitState(void);
-               bool HitStateChanged(void);
-
-       protected:
-               double radius;                                          // Center is Object::position
-               Vector dragPoint;                                       // Used for rendering edge dragging
-               double oldRadius2;
-
-       private:
-               bool draggingEdge;
-               bool draggingCenter;
-               bool objectWasDragged;
-               bool hitCenter, hitCircle;
-               bool oldHitCenter, oldHitCircle;
-               double oldRadius;
-};
-
-#endif // __CIRCLE_H__
index 09ce49922c54aa8e1d7d53007bcf327a39961e8d..89c2396de3cdc015d618fb7c739d8d11709cb197 100644 (file)
@@ -3,7 +3,6 @@
 
 //#include "object.h"
 
-//enum DimensionType { DTLinear, DTRadial, DTDiametric, DTCircumferential, DTLeader };
 class Object;
 
 class Connection
index 8c581bfc1df8e904ccb41bd2b724b26b3c3ae7d5..54e3b342daf6c26b45fd5214f72c92d3a1bcb8db 100644 (file)
@@ -49,8 +49,8 @@ DrawingView::DrawingView(QWidget * parent/*= NULL*/): QWidget(parent),
        useAntialiasing(true), numSelected(0), numHovered(0), shiftDown(false),
        ctrlDown(false),
        gridBackground(BACKGROUND_MAX_SIZE, BACKGROUND_MAX_SIZE),
-       scale(1.0), offsetX(-10), offsetY(-10),// document(Vector(0, 0)),
-       gridPixels(0), collided(false)//, toolAction(NULL)
+       scale(1.0), offsetX(-10), offsetY(-10),
+       gridPixels(0), collided(false), hoveringIntersection(false)
 {
 //     document.isTopLevelContainer = true;
 //wtf? doesn't work except in c++11??? document = { 0 };
@@ -324,6 +324,9 @@ void DrawingView::paintEvent(QPaintEvent * /*event*/)
                painter.DrawRect(Global::selection);
        }
 
+       if (hoveringIntersection)
+               painter.DrawHandle(intersectionPoint);
+
        if (!informativeText.isEmpty())
                painter.DrawInformativeText(informativeText);
 }
@@ -1174,6 +1177,7 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event)
        Global::selection.setBottomRight(QPointF(point.x, point.y));
        // Only needs to be done here, as mouse down is always preceded by movement
        Global::snapPointIsValid = false;
+       hoveringIntersection = false;
 
        // Scrolling...
        if (event->buttons() & Qt::MiddleButton)
@@ -1226,8 +1230,13 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event)
 
                if (numIntersecting > 0)
                {
-                       QString text = tr("Intersection t=%1, u=%2");
-                       informativeText = text.arg(t).arg(u);
+                       Vector v1 = Geometry::GetPointForParameter((Object *)hover[0], t);
+                       Vector v2 = Geometry::GetPointForParameter((Object *)hover[1], u);
+                       QString text = tr("Intersection t=%1 (%3, %4), u=%2 (%5, %6)");
+                       informativeText = text.arg(t).arg(u).arg(v1.x).arg(v1.y).arg(v2.x).arg(v2.y);
+
+                       hoveringIntersection = true;
+                       intersectionPoint = v1;
                }
        }
 
index 849ce76b2c943a1d2a07070d1585c54107434b60..518301a8e43cddc2b1b304d677ff324bc2e5af8a 100644 (file)
@@ -78,6 +78,8 @@ class DrawingView: public QWidget
                std::vector<void *> toolObjects;
                std::vector<Object> toolScratch;
                Point toolPoint[32];
+               Point intersectionPoint;
+               bool hoveringIntersection;
 
 //     public:
 //             static Container document;
index 101f0701f0059f98eca014ec36e1507bdc1bbb05..503ccc109322dcd41f68b6cc629ad38abc663484 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <vector>
-//#include "arc.h"
-//#include "circle.h"
-//#include "container.h"
-//#include "dimension.h"
-//#include "line.h"
 #include "structs.h"
 
 /*
index 11e633f380aef100a282cda4eeb5bf52410f34e7..b67c64e30e6211d8cd9dafefbd1204671101f02b 100644 (file)
@@ -90,7 +90,6 @@ Point Geometry::MirrorPointAroundLine(Point point, Point tail, Point head)
 //
 Point Geometry::RotatePointAroundPoint(Point point, Point rotationPoint, double angle)
 {
-//     Vector v = Vector(point, rotationPoint);
        Vector v = Vector(rotationPoint, point);
        double px = (v.x * cos(angle)) - (v.y * sin(angle));
        double py = (v.x * sin(angle)) + (v.y * cos(angle));
@@ -422,6 +421,17 @@ void Geometry::FindAnglesForSides(double s1, double s2, double s3, double * a1,
        // Use law of sines to find 2nd & 3rd angles
 // sin A / a = sin B / b
 // sin B = (sin A / a) * b
+// B = arcsin( sin A * (b / a))
+// ??? ==> B = A * arcsin(b / a)
+/*
+Well, look here:
+sin B = sin A * (b / a)
+sin B / sin A = b / a
+arcsin( sin B / sin A ) = arcsin( b / a )
+
+hmm... dunno...
+*/
+
        double angle2 = asin(s2 * (sin(angle1) / s1));
        double angle3 = asin(s3 * (sin(angle1) / s1));
 
@@ -435,3 +445,17 @@ void Geometry::FindAnglesForSides(double s1, double s2, double s3, double * a1,
                *a3 = angle3;
 }
 
+
+Point Geometry::GetPointForParameter(Object * obj, double t)
+{
+       if (obj->type == OTLine)
+       {
+               // Translate line vector to the origin, then add the scaled vector to
+               // initial point of the line.
+               Vector v = obj->p[1] - obj->p[0];
+               return obj->p[0] + (v * t);
+       }
+
+       return Point(0, 0);
+}
+
index 865dc6d0f6b36ed3a6050bcdde45d3c7e0912d78..02cfada77dee1c68b9e658adf335b6a7c9110d45 100644 (file)
@@ -20,6 +20,7 @@ class Geometry
 //             static int Intersects(Line * l, Circle * c, double * tp = 0, double * up = 0, double * vp = 0, double * wp = 0);
 //             static int Intersects(Circle * c1, Circle * c2, double * tp = 0, double * up = 0, double * vp = 0, double * wp = 0, Point * p1 = 0, Point * p2 = 0);
                static void FindAnglesForSides(double s1, double s2, double s3, double * a1, double * a2, double * a3);
+               static Point GetPointForParameter(Object *, double);
 };
 
 #endif         // __GEOMETRY_H__
index fe758560726cf71c55c9d84009b9b600aac66f40..013f795eff2c32027457b9ab00fe7ef98318a7d8 100644 (file)
@@ -37,3 +37,7 @@ double Global::zoom = 1.0;
 Vector Global::screenSize(200.0, 200.0);
 
 float Global::scale = 0.5;
+
+int Global::activeLayer = 0;
+bool Global::layerIsLocked = false;
+
index d59155e5a0c0d1e8c8b74c124ef75859e435b202..d66f93badd104b65bdc02cba8a1967e479665769 100644 (file)
@@ -42,6 +42,9 @@ class Global
                static Vector screenSize;
 
                static float scale;
+
+               static int activeLayer;
+               static bool layerIsLocked;
 };
 
 #endif // __GLOBALS_H__
index 33221206a456172f62d28cebfb9b7a3374d1a941..faaf5b999854423f546b39724f854e7419900fa3 100644 (file)
 //
 
 #include "layerwidget.h"
+#include "global.h"
 #include "layeritemwidget.h"
 
 
 LayerWidget::LayerWidget(void): QWidget(),
-       list(new QListWidget)
+       addLayer(new QToolButton), removeLayer(new QToolButton),
+       editLayer(new QToolButton), layerUp(new QToolButton),
+       layerDown(new QToolButton), list(new QListWidget)
 {
        LayerItemWidget * liw = new LayerItemWidget("Background");
        QListWidgetItem * qlwi = new QListWidgetItem(list);
        list->setItemWidget(qlwi, liw);
 
-#if 0
-       QPushButton * pb1 = new QPushButton("+");
-       QPushButton * pb2 = new QPushButton("-");
-       QPushButton * pb3 = new QPushButton("Edit");
-       QPushButton * pb4 = new QPushButton("^");
-       QPushButton * pb5 = new QPushButton("v");
-#else
-       QToolButton * pb1 = new QToolButton;
-       QToolButton * pb2 = new QToolButton;
-       QToolButton * pb3 = new QToolButton;
-       QToolButton * pb4 = new QToolButton;
-       QToolButton * pb5 = new QToolButton;
-
-       pb1->setIcon(QIcon(":/res/layer-add.png"));
-       pb2->setIcon(QIcon(":/res/layer-delete.png"));
-       pb3->setIcon(QIcon(":/res/layer-edit.png"));
-       pb4->setIcon(QIcon(":/res/layer-up.png"));
-       pb5->setIcon(QIcon(":/res/layer-down.png"));
-
-       pb1->setToolTip(tr("Add layer"));
-       pb2->setToolTip(tr("Remove layer"));
-       pb3->setToolTip(tr("Edit layer"));
-       pb4->setToolTip(tr("Move layer up"));
-       pb5->setToolTip(tr("Move layer down"));
-#endif
+//     QToolButton * pb1 = new QToolButton;
+//     QToolButton * pb2 = new QToolButton;
+//     QToolButton * pb3 = new QToolButton;
+//     QToolButton * pb4 = new QToolButton;
+//     QToolButton * pb5 = new QToolButton;
+
+       addLayer->setIcon(QIcon(":/res/layer-add.png"));
+       removeLayer->setIcon(QIcon(":/res/layer-delete.png"));
+       editLayer->setIcon(QIcon(":/res/layer-edit.png"));
+       layerUp->setIcon(QIcon(":/res/layer-up.png"));
+       layerDown->setIcon(QIcon(":/res/layer-down.png"));
+
+       addLayer->setToolTip(tr("Add layer"));
+       removeLayer->setToolTip(tr("Remove layer"));
+       editLayer->setToolTip(tr("Edit layer"));
+       layerUp->setToolTip(tr("Move layer up"));
+       layerDown->setToolTip(tr("Move layer down"));
 
        QHBoxLayout * hbox1 = new QHBoxLayout;
-       hbox1->addWidget(pb1);
-       hbox1->addWidget(pb2);
-       hbox1->addWidget(pb3);
-       hbox1->addWidget(pb4);
-       hbox1->addWidget(pb5);
+       hbox1->addWidget(addLayer);
+       hbox1->addWidget(removeLayer);
+       hbox1->addWidget(editLayer);
+       hbox1->addWidget(layerUp);
+       hbox1->addWidget(layerDown);
        hbox1->addStretch();
 
        QVBoxLayout * mainLayout = new QVBoxLayout;
@@ -63,12 +58,13 @@ LayerWidget::LayerWidget(void): QWidget(),
        setLayout(mainLayout);
 
        connect(list, SIGNAL(currentRowChanged(int)), this, SLOT(HandleLayerSelected(int)));
-       list->setCurrentRow(4);
-       connect(pb1, SIGNAL(clicked()), this, SLOT(AddLayer()));
-       connect(pb2, SIGNAL(clicked()), this, SLOT(DeleteLayer()));
-       connect(pb3, SIGNAL(clicked()), this, SLOT(EditLayer()));
-       connect(pb4, SIGNAL(clicked()), this, SLOT(MoveLayerUp()));
-       connect(pb5, SIGNAL(clicked()), this, SLOT(MoveLayerDown()));
+       connect(addLayer, SIGNAL(clicked()), this, SLOT(AddLayer()));
+       connect(removeLayer, SIGNAL(clicked()), this, SLOT(DeleteLayer()));
+       connect(editLayer, SIGNAL(clicked()), this, SLOT(EditLayer()));
+       connect(layerUp, SIGNAL(clicked()), this, SLOT(MoveLayerUp()));
+       connect(layerDown, SIGNAL(clicked()), this, SLOT(MoveLayerDown()));
+
+       list->setCurrentRow(0);
 }
 
 
@@ -80,7 +76,15 @@ LayerWidget::~LayerWidget()
 void LayerWidget::HandleLayerSelected(int currentRow)
 {
 //printf("LayerWidget::HandleLayerSelected(): currentRow = %i\n", currentRow);
-       emit(LayerSelected(currentRow));
+//     emit(LayerSelected(currentRow));
+
+       QListWidgetItem * qlwi = list->item(currentRow);
+       LayerItemWidget * li = (LayerItemWidget *)list->itemWidget(qlwi);
+       Global::activeLayer = currentRow;
+       Global::layerIsLocked = li->editibility->isChecked();
+
+       // Set button states to sane values
+       SetButtonStates();
 }
 
 
@@ -92,25 +96,91 @@ void LayerWidget::AddLayer(void)
        QListWidgetItem * qlwi = new QListWidgetItem();
        list->insertItem(0, qlwi);
        list->setItemWidget(qlwi, liw);
+
+       SetButtonStates();
 }
 
 
 void LayerWidget::DeleteLayer(void)
 {
+       int numItems = list->count();
+
+       if (numItems == 1)
+               return;
+
+       QListWidgetItem * qlwi = list->currentItem();
+       list->removeItemWidget(qlwi);
+       delete qlwi;
+
+       SetButtonStates();
+
+       // N.B.: Also, we need to delete the layer in the Drawing as well!
 }
 
 
 void LayerWidget::EditLayer(void)
 {
+       // Get the LayerItemWidget so we can edit it (its name, anyway)...
+       QListWidgetItem * qlwi = list->currentItem();
+       LayerItemWidget * li = (LayerItemWidget *)list->itemWidget(qlwi);
+       QString s = li->name->text();
+
+       bool ok;
+       QString result = QInputDialog::getText(this, tr("Edit Layer Name"), tr("Layer Name:"), QLineEdit::Normal, s, &ok);
+
+       if (ok && !result.isEmpty())
+               li->name->setText(result);
 }
 
 
 void LayerWidget::MoveLayerUp(void)
 {
+       // Get information out of the LayerItemWidget (& get it from the list!)
+       int currentRow = list->currentRow();
+       QListWidgetItem * qlwi = list->currentItem();
+       LayerItemWidget * li = (LayerItemWidget *)list->itemWidget(qlwi);
+       QString s = li->name->text();
+       bool visible = li->visibility->isChecked();
+       bool editible = li->editibility->isChecked();
+
+       // We have to make a new LayerItemWidget because it destroys the old one!
+       list->takeItem(currentRow);
+       list->insertItem(currentRow - 1, qlwi);
+       li = new LayerItemWidget(s, visible, editible);
+       list->setItemWidget(qlwi, li);
+       list->setCurrentItem(qlwi);
 }
 
 
 void LayerWidget::MoveLayerDown(void)
 {
+       // Get information out of the LayerItemWidget (& get it from the list!)
+       int currentRow = list->currentRow();
+       QListWidgetItem * qlwi = list->currentItem();
+       LayerItemWidget * li = (LayerItemWidget *)list->itemWidget(qlwi);
+       QString s = li->name->text();
+       bool visible = li->visibility->isChecked();
+       bool editible = li->editibility->isChecked();
+
+       // We have to make a new LayerItemWidget because it destroys the old one!
+       list->takeItem(currentRow);
+       list->insertItem(currentRow + 1, qlwi);
+       li = new LayerItemWidget(s, visible, editible);
+       list->setItemWidget(qlwi, li);
+       list->setCurrentItem(qlwi);
+}
+
+
+//
+// Set button states in this widget to sane values
+//
+void LayerWidget::SetButtonStates(void)
+{
+       int numItems = list->count();
+       int currentRow = list->currentRow();
+
+       layerDown->setEnabled(currentRow == (numItems - 1) ? false : true);
+       layerUp->setEnabled(currentRow == 0 ? false : true);
+       removeLayer->setEnabled(numItems == 1 ? false : true);
 }
 
index 914c29ca32c24063dc66e6eddfcd3dfddf69feb2..e515dcfd4a724f318f9cc326114f2f558324828e 100644 (file)
@@ -19,9 +19,19 @@ class LayerWidget: public QWidget
                void MoveLayerUp(void);
                void MoveLayerDown(void);
 
+       private:
+               void SetButtonStates(void);
+
        signals:
                void LayerSelected(int);
 
+       public:
+               QToolButton * addLayer;
+               QToolButton * removeLayer;
+               QToolButton * editLayer;
+               QToolButton * layerUp;
+               QToolButton * layerDown;
+
        private:
                QListWidget * list;
 };
diff --git a/src/line.cpp b/src/line.cpp
deleted file mode 100644 (file)
index 7841fa8..0000000
+++ /dev/null
@@ -1,743 +0,0 @@
-// line.cpp: Line object
-//
-// Part of the Architektonas Project
-// (C) 2011 Underground Software
-// See the README and GPLv3 files for licensing and warranty information
-//
-// JLH = James Hammons <jlhamm@acm.org>
-//
-// WHO  WHEN        WHAT
-// ---  ----------  ------------------------------------------------------------
-// JLH  03/22/2011  Created this file
-// JLH  04/11/2011  Fixed attached dimensions to stay at correct length when
-//                  "Fixed Length" button is down
-// JLH  04/27/2011  Fixed attached dimension to stay a correct length when
-//                  "Fixed Length" button is *not* down ;-)
-// JLH  05/29/2011  Added (some) mouseover hints
-//
-
-#include "line.h"
-
-#include <QtGui>
-#include "container.h"
-#include "dimension.h"
-#include "geometry.h"
-#include "mathconstants.h"
-#include "painter.h"
-
-
-Line::Line(Vector p1, Vector p2, Object * p/*= NULL*/): Object(p1, p),
-       /*type(OTLine),*/ endpoint(p2),
-       draggingLine(false), draggingHandle1(false), draggingHandle2(false), //needUpdate(false),
-       length(Vector::Magnitude(p2, p1)), angle(Vector(endpoint - position).Unit()),
-       hitPoint1(false), hitPoint2(false), hitLine(false)
-{
-       type = OTLine;
-}
-
-
-Line::~Line()
-{
-// Taking care of connections should be done by the Container, as we don't know
-// anything about any other object connected to this one.
-#if 0
-       // If there are any attached Dimensions, we must set the attachment points
-       // to NULL since they will no longer be valid.
-       if (attachedDimension)
-       {
-               attachedDimension->SetPoint1(NULL);
-               attachedDimension->SetPoint2(NULL);
-       }
-       // IT WOULD BE NICE to have any object points attached to this line automagically
-       // connect to this dimension object at this point, instead of just becoming
-       // detached.
-#endif
-//actually not true, we know the object pointer and parameter!
-//actuall, the Object base class does this for us...!
-#if 0
-       std::vector<Connection>::iterator i;
-
-       for(i=connected.begin(); i!=connected.end(); i++)
-       {
-               (*i).object->Disconnect(this, (*i).t);
-       }
-#endif
-}
-
-
-/*virtual*/ void Line::Draw(Painter * painter)
-{
-       painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine));
-
-       if ((state == OSSelected) || ((state == OSInactive) && hitPoint1))
-               painter->DrawHandle(position);
-
-       if ((state == OSSelected) || ((state == OSInactive) && hitPoint2))
-               painter->DrawHandle(endpoint);
-
-       if ((state == OSInactive) && !hitLine)
-               painter->SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
-
-       if (Object::fixedLength && (draggingHandle1 || draggingHandle2))
-       {
-               Vector point1 = (draggingHandle1 ? endpoint : position);
-               Vector point2 = (draggingHandle1 ? position : endpoint);
-
-               Vector current(point2 - point1);
-               Vector v = current.Unit() * length;
-               Vector v2 = point1 + v;
-               painter->DrawLine(point1, v2);
-
-               if (current.Magnitude() > length)
-               {
-                       painter->SetPen(QPen(QColor(128, 0, 0), 1.0, Qt::DashLine));
-                       painter->DrawLine(v2, point2);
-               }
-       }
-       else
-               painter->DrawLine(position, endpoint);
-
-       // If we're dragging an endpoint, draw an information panel showing both
-       // the length and angle being set.
-       if (draggingHandle1 || draggingHandle2)
-       {
-               double absAngle = (Vector(endpoint - position).Angle()) * RADIANS_TO_DEGREES;
-               double absLength = Vector(position - endpoint).Magnitude();
-
-               QString text = QObject::tr("Length: %1 in.\n") + QChar(0x2221) + QObject::tr(": %2");
-               text = text.arg(absLength).arg(absAngle);
-               painter->DrawInformativeText(text);
-       }
-}
-
-/*virtual*/ Vector Line::Center(void)
-{
-       // Technically, this is the midpoint but who are we to quibble? :-)
-       Vector v((position.x - endpoint.x) / 2.0, (position.y - endpoint.y) / 2.0);
-       return endpoint + v;
-}
-
-/*virtual*/ bool Line::Collided(Vector point)
-{
-/*
-what we can do here is set ignoreClicks to true to keep other objects that are
-selected from deselecting themselves. Will that fuck up something else? Not sure
-yet... :-/
-Actually, this is done here to keep tools from selecting stuff inadvertantly...
-*/
-       // We can assume this, since this is a mouse down event here.
-       objectWasDragged = false;
-       bool hit = HitTest(point);
-
-       // Someone told us to fuck off, so we'll fuck off. :-)
-       if (ignoreClicks)
-               return hit;
-
-       // Now that we've done our hit testing on the non-snapped point, snap it if
-       // necessary...
-       if (snapToGrid)
-               point = SnapPointToGrid(point);
-
-       if (snapPointIsValid)
-               point = snapPoint;
-
-// this is shite. this should be checked for in the Container, not here!
-#warning "!!! This should be checked for in Container, not here !!!"
-       // If we're part of a non-top-level container, send this signal to it
-       if (parent->type == OTContainer && !((Container *)parent)->isTopLevelContainer
-               && (hitLine || hitPoint1 || hitPoint2))
-       {
-               parent->state = OSSelected;
-               return true;
-       }
-
-       if (state == OSInactive)
-       {
-//How to translate this into pixels from Document space???
-//Maybe we need to pass a scaling factor in here from the caller? That would
-//make sense, as the caller knows about the zoom factor and all that good kinda
-//crap
-//I think what's needed is an Object class variable/method that can be changed
-//by the TLC and called in derived classes to properly scale the location to
-//the current zoom level. That *should* work.
-
-// ALSO: Need to code a global (read: Object class) variable that tells use
-//       whether a modifier key was pressed in addition to the mouse click, so
-//       we can do stuff like, say, hold down CTRL and be able to do multiple
-//       selecting of objects (in that case, we would keep the Object state
-//       from changing).
-               if (hitPoint1)
-               {
-                       oldState = state;
-                       state = OSSelected;
-                       oldPoint = position;
-                       draggingHandle1 = true;
-                       return true;
-               }
-               else if (hitPoint2)
-               {
-                       oldState = state;
-                       state = OSSelected;
-                       oldPoint = endpoint;
-                       draggingHandle2 = true;
-                       return true;
-               }
-               else if (hitLine)
-               {
-                       oldState = state;
-                       state = OSSelected;
-                       oldPoint = point;
-                       draggingLine = true;
-                       return true;
-               }
-       }
-       else if (state == OSSelected)
-       {
-               if (hitLine)
-               {
-                       oldState = state;
-//                     state = OSInactive;
-                       oldPoint = point;
-                       draggingLine = true;
-
-                       // Toggle selected state if CTRL held
-                       if (qApp->keyboardModifiers() == Qt::ControlModifier)
-                               state = OSInactive;
-
-                       return true;
-               }
-       }
-
-       // If CTRL is held, then we bypass the "turn off" code. Still didn't hit
-       // *this* object though. :-)
-       if (qApp->keyboardModifiers() == Qt::ControlModifier)
-               return false;
-
-       // If we got here, we clicked on nothing, so set the object to inactive.
-       // (Once we can read key modifiers, we can override this to allow multiple selection.)
-       state = OSInactive;
-       return false;
-}
-
-
-/*virtual*/ bool Line::PointerMoved(Vector point)
-{
-       if (selectionInProgress)
-       {
-               // Check for whether or not the rect contains this line
-               if (selection.contains(position.x, position.y)
-                       && selection.contains(endpoint.x, endpoint.y))
-                       state = OSSelected;
-               else
-                       state = OSInactive;
-
-               return false;
-       }
-
-       // Hit test tells us what we hit (if anything) through boolean variables.
-       SaveHitState();
-       bool hovered = HitTest(point);
-       needUpdate = HitStateChanged();
-
-       if (snapToGrid)
-               point = SnapPointToGrid(point);
-
-       if (snapPointIsValid)
-               point = snapPoint;
-
-       objectWasDragged = (draggingLine | draggingHandle1 | draggingHandle2);
-
-       if (objectWasDragged)
-       {
-               Vector delta = point - oldPoint;
-
-               if (draggingHandle1 || draggingLine)
-                       position += delta;
-
-               if (draggingHandle2 || draggingLine)
-                       endpoint += delta;
-
-               oldPoint = point;
-               needUpdate = true;
-
-//doesn't work         QMainWindow::statusBar()->setText("You are manipulating a line");
-
-               // Tell connected objects to move themselves...
-               if (draggingLine)
-               {
-                       std::vector<Connection>::iterator i;
-
-                       for(i=connected.begin(); i!=connected.end(); i++)
-                       {
-                               if ((*i).object->type == OTLine)
-                                       ((Line *)((*i).object))->MovePointAtParameter((*i).t, delta);
-                               else if ((*i).object->type == OTDimension)
-                                       ((Dimension *)((*i).object))->MovePointAtParameter((*i).t, delta);
-                       }
-               }
-       }
-
-/*
-We can't count on any coupling between the dimension object and us, so how do we do this???
-Also, there may be more than one Dimension object connected to a single endpoint!
-
-Ugly ways to do it:
- - Keep track of the state of the connected dimension
- - Pass the Dimension the point that's being changed and the delta
-
-More elegant ways:
- - Pass the point in a notification function (how?)
- - Pass the point as a reference to the class instance object (&endpoint). This
-   way, the line doesn't have to care about keeping track of Dimensions
-   connected to it. But still have to care about other connected entities
-   (other Lines, Circles, Arcs, Splines, Texts, etc). I think I'd be OK with
-   this. Since the Dimension has a pointer to our object, all we have to do is
-   update our coordinates and the Dimension object will adjust itself on the
-   next repaint. Problem solved, and we don't have to know anything about how
-   many Dimensions are connected to us, or where! \o/
-   The question then becomes, how do we do this kind of coupling???
-
-We need to know about connected entities so that we can have them either move
-in expected ways or constrain the movement of this Line object. This is how we
-will be a cut above all other CAD software currently out there: the GUI will
-try to do the right thing, most of the time. :-)
-*/
-       if (needUpdate)
-       {
-// should only do this if "Fixed Length" is set... !!! FIX !!! [DONE]
-               Vector point1 = (draggingHandle1 ? endpoint : position);
-               Vector point2 = (draggingHandle1 ? position : endpoint);
-
-               if (Object::fixedAngle)
-               {
-                       // Here we calculate the component of the current vector along the fixed angle.
-                       // A_compB = (A . Bu) * Bu
-                       double magnitudeAlongB = Vector::Dot(Vector(point2 - point1), angle);
-/*
-Actually, this isn't quite right. What we want to do is look for the intersection along either
-the horizontal line or vertical line that intersects from the current mouse position.
-*/
-
-                       if (draggingHandle1)
-                               position = endpoint + (angle * magnitudeAlongB);
-
-                       if (draggingHandle2)
-                               endpoint = position + (angle * magnitudeAlongB);
-               }
-//             else
-//                     v2 = point2;
-
-//If we tell the dimension to flip sides, this is no longer a valid
-//assumption. !!! FIX !!!
-//Ideally, we should just send the point that's changing to the Dimension object
-//and have it figure out which point needs to move... Or is it???
-// Ideally, we shouldn't have to fuck around with this shit. We need to fix the rendering code
-// so that we don't have to wait until the dragging is done to correct the position of the
-// point in question, but we'd need another variable tho.
-#if 0
-               if (dimPoint1)
-                       dimPoint1->SetPoint1(draggingHandle1 ? v2 : position);
-               
-               if (dimPoint2)
-                       dimPoint2->SetPoint2(draggingHandle2 ? v2 : endpoint);
-#endif
-       }
-
-       return hovered;
-}
-
-
-/*virtual*/ void Line::PointerReleased(void)
-{
-       if (draggingHandle1 || draggingHandle2)
-       {
-               // Set the length (in case the global state was set to fixed (or not))
-               if (Object::fixedLength)
-               {
-                       if (draggingHandle1)    // startpoint
-                       {
-                               Vector v = Vector(position - endpoint).Unit() * length;
-                               position = endpoint + v;
-                       }
-                       else                                    // endpoint
-                       {
-                               Vector v = Vector(endpoint - position).Unit() * length;
-                               endpoint = position + v;
-                       }
-               }
-               else
-               {
-                       // Otherwise, we calculate the new length, just in case on the next
-                       // move it turns out to have a fixed length. :-)
-                       length = Vector(endpoint - position).Magnitude();
-               }
-
-               if (!Object::fixedAngle)
-               {
-                       // Calculate the new angle, just in case on the next move it turns
-                       // out to be fixed. :-)
-                       angle = Vector(endpoint - position).Unit();
-               }
-       }
-
-       draggingLine = false;
-       draggingHandle1 = false;
-       draggingHandle2 = false;
-
-       if (objectWasDragged)
-               state = oldState;
-}
-
-
-/*virtual*/ bool Line::HitTest(Point point)
-{
-       hitPoint1 = hitPoint2 = hitLine = false;
-       Vector lineSegment = endpoint - position;
-       Vector v1 = point - position;
-       Vector v2 = point - endpoint;
-       Vector v3 = point - Center();   // Midpoint, for snapping...
-       double t = Geometry::ParameterOfLineAndPoint(position, endpoint, point);
-       double distance;
-
-       // Geometric interpretation of "distance = ?Det?(ls, v1) / |ls|":
-       // If the segment endpoints are s and e, and the point is p, then the test
-       // for the perpendicular intercepting the segment is equivalent to insisting
-       // that the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
-       // Perpendicular distance from the point to the segment is computed by first
-       // computing the area of the triangle the three points form, then dividing by
-       // the length of the segment.  Distances are done just by the Pythagorean
-       // theorem. Twice the area of the triangle formed by three points is the
-       // determinant of the following matrix:
-       //
-       // sx sy 1       0  0  1       0  0  0
-       // ex ey 1  ==>  ex ey 1  ==>  ex ey 0
-       // px py 1       px py 1       px py 0
-       //
-       // By translating the start point to the origin, and subtracting row 1 from
-       // all other rows, we end up with the matrix on the right which greatly
-       // simplifies the calculation of the determinant.
-
-       if (t < 0.0)
-               distance = v1.Magnitude();
-       else if (t > 1.0)
-               distance = v2.Magnitude();
-       else
-               // distance = ?Det?(ls, v1) / |ls|
-               distance = fabs((lineSegment.x * v1.y - v1.x * lineSegment.y)
-                       / lineSegment.Magnitude());
-
-       if ((v1.Magnitude() * Painter::zoom) < 8.0)
-       {
-               hitPoint1 = true;
-               snapPoint = position;
-               snapPointIsValid = true;
-       }
-       else if ((v2.Magnitude() * Painter::zoom) < 8.0)
-       {
-               hitPoint2 = true;
-               snapPoint = endpoint;
-               snapPointIsValid = true;
-       }
-       else if ((distance * Painter::zoom) < 5.0)
-               hitLine = true;
-
-       // Not a manipulation point, but a snapping point:
-       if ((v3.Magnitude() * Painter::zoom) < 8.0)
-       {
-               snapPoint = Center();
-               snapPointIsValid = true;
-       }
-
-       return (hitPoint1 || hitPoint2 || hitLine ? true : false);
-}
-
-
-// Check to see if the point passed in coincides with any we have. If so, return a
-// pointer to it; otherwise, return NULL.
-/*virtual*/ Vector * Line::GetPointAt(Vector v)
-{
-       if (v == position)
-               return &position;
-       else if (v == endpoint)
-               return &endpoint;
-
-       return 0;
-}
-
-
-/*virtual*/ void Line::Enumerate(FILE * file)
-{
-       fprintf(file, "LINE %i (%lf,%lf) (%lf,%lf)\n", layer, position.x, position.y, endpoint.x, endpoint.y);
-}
-
-
-/*virtual*/ Object * Line::Copy(void)
-{
-#warning "!!! This doesn't take care of attached Dimensions !!!"
-/*
-This is a real problem. While having a pointer in the Dimension to this line's points
-is fast & easy, it creates a huge problem when trying to replicate an object like this.
-
-Maybe a way to fix that then, is to have reference numbers instead of pointers. That
-way, if you copy them, ... you might still have problems. Because you can't be sure if
-a copy will be persistant or not, you then *definitely* do not want them to have the
-same reference number.
-*/
-       return new Line(position, endpoint, parent);
-}
-
-
-/*virtual*/ Vector Line::GetPointAtParameter(double parameter)
-{
-// Is there any real reason to clamp this to the endpoints?
-// (hey, whaddya know? this was masking a bug!)
-#if 0
-       if (parameter <= 0)
-               return position;
-       else if (parameter >= 1.0)
-               return endpoint;
-#endif
-
-       // The parameter is a percentage of the length of the vector, so all we
-       // have to do is scale the vector by it to find the point.
-       return position + (Vector(position, endpoint) * parameter);
-}
-
-
-/*virtual*/ void Line::MovePointAtParameter(double parameter, Vector v)
-{
-       if (parameter == 0)
-               position += v;
-       else if (parameter == 1.0)
-               endpoint += v;
-       else
-               {} // Not sure how to handle this case :-P
-}
-
-
-/*virtual*/ QRectF Line::Extents(void)
-{
-       QRectF rect(QPointF(position.x, position.y), QPointF(endpoint.x, endpoint.y));
-       return rect.normalized();
-}
-
-
-/*virtual*/ void Line::Translate(Vector amount)
-{
-       position += amount;
-       endpoint += amount;
-}
-
-
-/*virtual*/ void Line::Rotate(Point point, double angle)
-{
-       Point l1 = Geometry::RotatePointAroundPoint(position, point, angle);
-       Point l2 = Geometry::RotatePointAroundPoint(endpoint, point, angle);
-       position = l1;
-       endpoint = l2;
-}
-
-
-/*virtual*/ void Line::Scale(Point point, double amount)
-{
-}
-
-
-/*virtual*/ void Line::Mirror(Point p1, Point p2)
-{
-       Point l1 = Geometry::MirrorPointAroundLine(position, p1, p2);
-       Point l2 = Geometry::MirrorPointAroundLine(endpoint, p1, p2);
-       position = l1;
-       endpoint = l2;
-}
-
-
-/*virtual*/ void Line::Save(void)
-{
-       Object::Save();
-       oldEndpoint = endpoint;
-}
-
-
-/*virtual*/ void Line::Restore(void)
-{
-       Object::Restore();
-       endpoint = oldEndpoint;
-}
-
-
-void Line::SetDimensionOnLine(Dimension * dimension/*= NULL*/)
-{
-       // If they don't pass one in, create it for the caller.
-       // But ONLY if this line has a parent container!
-       // This is really bad to do here, it should be done in the parent container, always!
-#warning "!!! Parent container should be creating Dimension object !!!"
-       if ((dimension == NULL) && (parent != NULL))
-       {
-//printf("Line::SetDimensionOnLine(): Creating new dimension...\n");
-               dimension = new Dimension(position, endpoint, DTLinear, parent);
-//             dimension = new Dimension(Connection(this, 0), Connection(this, 1.0), DTLinear, this);
-
-               // THIS IS SERIOUS!!! WITHOUT A PARENT, THIS OBJECT IS IN LIMBO!!!
-//             if (parent)
-//{
-//printf("Line::SetDimensionOnLine(): Adding to parent...\n");
-               parent->Add(dimension);
-//}
-       }
-
-       dimension->Connect(this, 0);
-       dimension->Connect(this, 1.0);
-
-       // Make sure the Dimension is connected to us...
-       Connect(dimension, 0);
-       Connect(dimension, 1.0);
-
-       dimension->position = position;
-       dimension->endpoint = endpoint;
-}
-
-
-Object * Line::FindAttachedDimension(void)
-{
-       // Is there anything connected to this line? If not, return NULL
-       if (connected.size() < 2)
-               return NULL;
-
-       // Otherwise, we have to search our objects to see if there's a likely
-       // candidate. In this case, we're looking for a pointer to the same object
-       // with a parameter of 0 and 1 respectively. This is O((n^2)/2).
-       for(uint i=0; i<connected.size(); i++)
-       {
-               for(uint j=i+1; j<connected.size(); j++)
-               {
-//printf("Line: connected[i]=%X, connected[j]=%X, connected[i].t=%lf, connected[j].t=%lf\n", connected[i].object, connected[j].object, connected[i].t, connected[j].t);
-                       if ((connected[i].object == connected[j].object)
-                               && ((connected[i].t == 0 && connected[j].t == 1.0)
-                               || (connected[i].t == 1.0 && connected[j].t == 0)))
-                               return connected[i].object;
-               }
-       }
-
-       // Didn't find anything, so return NULL
-       return NULL;
-}
-
-
-void Line::SaveHitState(void)
-{
-       oldHitPoint1 = hitPoint1;
-       oldHitPoint2 = hitPoint2;
-       oldHitLine = hitLine;
-}
-
-
-bool Line::HitStateChanged(void)
-{
-       if ((hitPoint1 != oldHitPoint1) || (hitPoint2 != oldHitPoint2) || (hitLine != oldHitLine))
-               return true;
-
-       return false;
-}
-
-
-/*
-Intersection of two lines:
-
-Find where the lines with equations r = i + j + t (3i - j) and r = -i + s (j) intersect.
-
-When they intersect, we can set the equations equal to one another:
-
-i + j + t (3i - j) = -i + s (j)
-
-Equating coefficients:
-1 + 3t = -1 and 1 - t = s
-So t = -2/3 and s = 5/3
-
-The position vector of the intersection point is therefore given by putting t = -2/3 or s = 5/3 into one of the above equations. This gives -i +5j/3 .
-
-
-so, let's say we have two lines, l1 and l2. Points are v0(p0x, p0y), v1(p1x, p1y) for l1
-and v2(p2x, p2y), v3(p3x, p3y) for l2.
-
-d1 = v1 - v0, d2 = v3 - v2
-
-Our parametric equations for the line then are:
-
-r1 = v0 + t(d1)
-r2 = v2 + s(d2)
-
-Set r1 = r2, thus we have:
-
-v0 + t(d1) = v2 + s(d2)
-
-Taking coefficients, we have:
-
-p0x + t(d1x) = p2x + s(d2x)
-p0y + t(d1y) = p2y + s(d2y)
-
-rearranging we get:
-
-t(d1x) - s(d2x) = p2x - p0x
-t(d1y) - s(d2y) = p2y - p0y
-
-Determinant D is ad - bc where the matrix looks like:
-
-a b
-c d
-
-so D = (d1x)(d2y) - (d2x)(d1y)
-if D = 0, the lines are parallel.
-Dx = (p2x - p0x)(d2y) - (d2x)(p2y - p0y)
-Dy = (d1x)(p2y - p0y) - (p2x - p0x)(d1y)
-t = Dx/D, s = Dy/D
-
-We only need to calculate t, as we can then multiply it by d1 to get the intersection point.
-
----------------------------------------------------------------------------------------------------
-
-The first and most preferred method for intersection calculation is the perp-product calculation. There are two vectors, v1 and v2. Create a third vector vector between the starting points of these vectors, and calculate the perp product of v2 and the two other vectors. These two scalars have to be divided to get the mulitplication ratio of v1 to reach intersection point. So:
-
-v1 ( bx1 , by1 );
-v2 ( bx2 , by2 );
-v3 ( bx3 , by3 );
-
-Perp product is equal with dot product of normal of first vector and the second vector, so we need normals:
-
-n1 ( -by1 , bx1 );
-n3 ( -by3 , bx3 );
-
-Dot products:
-
-dp1 = n3 . v2 = -by3 * bx2 + bx3 * by2;
-dp2 = n1 . v2 = -by1 * bx2 + bx1 * by2;
-
-ratio = dp1 / dp2;
-crossing vector = v1 * ratio;
-
-And that's it.
-
------------------------------------
-
-So... to code this, let's say we have two Lines: l1 & l2.
-
-Vector v1 = l1.endpoint - l1.position;
-Vector v2 = l2.endpoint - l2.position;
-Vector v3 = v2 - v1;
-
-Vector normal1(-v1.y, v1.x);
-Vector normal3(-v3.y, v3.x);
-
-double dotProduct1 = v2.Dot(normal1);
-double dotProduct2 = v2.Dot(normal3);
-
-if (dotProduct2 == 0)
-       return ParallelLines;
-else
-{
-       // I think we'd still have to add the intersection to the position point to get the intersection...
-       Point intersection = v1 * (dotProduct1 / dotProduct2);
-       return intersection;
-}
-*/
-
diff --git a/src/line.h b/src/line.h
deleted file mode 100644 (file)
index 8c98924..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef __LINE_H__
-#define __LINE_H__
-
-#include "object.h"
-
-class Dimension;
-
-class Line: public Object
-{
-       friend class Geometry;
-
-       public:
-               Line(Vector, Vector, Object * p = 0);
-               ~Line();
-
-               virtual void Draw(Painter *);
-               virtual Vector Center(void);
-               virtual bool Collided(Vector);
-               virtual bool PointerMoved(Vector);
-               virtual void PointerReleased(void);
-               virtual bool HitTest(Point);
-               virtual Vector * GetPointAt(Vector);
-               virtual void Enumerate(FILE *);
-               virtual Object * Copy(void);
-               virtual Vector GetPointAtParameter(double parameter);
-               virtual void MovePointAtParameter(double parameter, Vector);
-               virtual QRectF Extents(void);
-               virtual void Translate(Vector);
-               virtual void Rotate(Point, double);
-               virtual void Scale(Vector, double);
-               virtual void Mirror(Point, Point);
-               virtual void Save(void);
-               virtual void Restore(void);
-               void SetDimensionOnLine(Dimension * d = 0);
-               Object * FindAttachedDimension(void);
-
-       protected:
-               void SaveHitState(void);
-               bool HitStateChanged(void);
-
-       public:
-               Vector endpoint;                                        // Starting point is Object::position
-       protected:
-               Vector oldPoint;                                        // Used for dragging
-               Point oldEndpoint;
-
-       private:
-               bool draggingLine;
-               bool draggingHandle1;
-               bool draggingHandle2;
-               bool objectWasDragged;
-               double length;
-               Vector angle;
-       public:
-               bool hitPoint1, hitPoint2, hitLine;
-       private:
-               bool oldHitPoint1, oldHitPoint2, oldHitLine;
-};
-
-#endif // __LINE_H__
diff --git a/src/object.cpp b/src/object.cpp
deleted file mode 100644 (file)
index 4cc8460..0000000
+++ /dev/null
@@ -1,325 +0,0 @@
-//
-// object.cpp: Base class for all CAD objects
-//
-// Part of the Architektonas Project
-// (C) 2011 Underground Software
-// See the README and GPLv3 files for licensing and warranty information
-//
-// JLH = James Hammons <jlhamm@acm.org>
-//
-// WHO  WHEN        WHAT
-// ---  ----------  ------------------------------------------------------------
-// JLH  03/22/2011  Created this file
-// JLH  04/01/2011  Added constructor to allow derived objects to have empty
-//                  constructor bodies, added state querying
-// JLH  04/02/2001  Added static methods for global states (fixed angle, etc)
-//
-
-#include "object.h"
-#include <stdlib.h>
-#include <math.h>
-
-// Initialize static variables
-bool Object::fixedAngle = false;
-bool Object::fixedLength = false;
-QFont * Object::font = 0;
-int Object::viewportHeight = 0;
-bool Object::deleteActive = false;
-bool Object::dimensionActive = false;
-bool Object::snapToGrid = true;
-//snapToPoints all well here?
-bool Object::ignoreClicks = false;
-bool Object::dontMove = false;
-bool Object::selectionInProgress = false;
-QRectF Object::selection;
-double Object::gridSpacing;
-int Object::currentLayer = 0;
-Point Object::snapPoint;
-bool Object::snapPointIsValid = false;
-
-
-Object::Object(): position(Vector(0, 0)), parent(0), type(OTObject),
-       state(OSInactive), layer(0), oldState(OSInactive), needUpdate(false)
-       //, attachedDimension(0)
-{
-}
-
-
-Object::Object(Vector v,  Object * passedInParent/*= 0*/): position(v),
-       parent(passedInParent), state(OSInactive), layer(0), oldState(OSInactive),
-       needUpdate(false)//, attachedDimension(0)
-{
-}
-
-
-Object::~Object()
-{
-printf("Object: Destroyed!\n");
-       for(uint i=0; i<connected.size(); i++)
-               connected[i].object->DisconnectAll(this);
-}
-
-
-/*virtual*/ void Object::Draw(Painter *)
-{
-}
-
-
-/*virtual*/ Vector Object::Center(void)
-{
-       return Vector();
-}
-
-
-/*virtual*/ bool Object::Collided(Vector)
-{
-       return false;
-}
-
-
-/*virtual*/ bool Object::PointerMoved(Vector)
-{
-       return false;
-}
-
-
-/*virtual*/ void Object::PointerReleased(void)
-{
-}
-
-
-/*virtual*/ bool Object::NeedsUpdate(void)
-{
-       return needUpdate;
-}
-
-
-/*virtual*/ bool Object::HitTest(Point)
-{
-       return false;
-}
-
-
-// This is intended to be overridden by the Container class, for object morphing
-/*virtual*/ void Object::Transmute(Object *, Object *)
-{
-}
-
-
-/*virtual*/ Object * Object::GetParent(void)
-{
-       return parent;
-}
-
-
-/*virtual*/ void Object::Add(Object *)
-{
-}
-
-
-// This returns a pointer to the point passed in, if it coincides. Otherwise returns NULL.
-/*virtual*/ Vector * Object::GetPointAt(Vector)
-{
-       return 0;
-}
-
-
-// This is meant for writing object data to a file.
-/*virtual*/ void Object::Enumerate(FILE *)
-{
-}
-
-
-/*virtual*/ Object * Object::Copy(void)
-{
-       return new Object(position, parent);
-}
-
-
-// This returns a point on the object at 'parameter', which is between 0 and 1.
-// Default is to return the object's position.
-/*virtual*/ Vector Object::GetPointAtParameter(double)
-{
-       return position;
-}
-
-
-// Since these functions are pretty much non-object specific, we can implement
-// them here. :-)
-/*virtual*/ void Object::Connect(Object * obj, double parameter)
-{
-       // Check to see if this connection is already in our list...
-       Connection c(obj, parameter);
-       std::vector<Connection>::iterator i;
-
-       for(i=connected.begin(); i!=connected.end(); i++)
-       {
-               // Bail out if this connection is already present...
-               if (*i == c)
-                       return;
-       }
-
-       // Connection is a new one, add it in...
-       connected.push_back(c);
-}
-
-
-/*virtual*/ void Object::Disconnect(Object * obj, double parameter)
-{
-       std::vector<Connection>::iterator i;
-
-       for(i=connected.begin(); i!=connected.end(); i++)
-       {
-               if (((*i).object == obj) && ((*i).t == parameter))
-               {
-                       connected.erase(i);
-                       return;
-               }
-       }
-}
-
-
-/*virtual*/ void Object::DisconnectAll(Object * obj)
-{
-       std::vector<Connection>::iterator i;
-
-       for(i=connected.begin(); i!=connected.end(); )
-       {
-               if ((*i).object == obj)
-                       connected.erase(i);
-               else
-                       i++;
-       }
-}
-
-
-/*virtual*/ QRectF Object::Extents(void)
-{
-       // Generic object returns an empty rect...
-       return QRectF();
-}
-
-
-#if 0
-/*virtual*/ ObjectType Object::Type(void)
-{
-       return OTObject;
-}
-#endif
-
-
-/*virtual*/ void Object::Translate(Vector amount)
-{
-       position += amount;
-}
-
-
-/*virtual*/ void Object::Rotate(Point, double)
-{
-}
-
-
-/*virtual*/ void Object::Scale(Point, double)
-{
-}
-
-
-/*virtual*/ void Object::Mirror(Point, Point)
-{
-}
-
-
-/*virtual*/ void Object::Save(void)
-{
-       oldPosition = position;
-}
-
-
-/*virtual*/ void Object::Restore(void)
-{
-       position = oldPosition;
-}
-
-
-ObjectState Object::GetState(void)
-{
-       return state;
-}
-
-
-void Object::Reparent(Object * newParent)
-{
-       parent = newParent;
-}
-
-
-/*Dimension * Object::GetAttachedDimension(void)
-{
-       return attachedDimension;
-}*/
-
-
-// Class methods...
-
-void Object::SetFixedAngle(bool state/*= true*/)
-{
-       fixedAngle = state;
-}
-
-
-void Object::SetFixedLength(bool state/*= true*/)
-{
-       fixedLength = state;
-}
-
-
-void Object::SetFont(QFont * f)
-{
-       font = f;
-}
-
-
-void Object::SetViewportHeight(int height)
-{
-       viewportHeight = height;
-}
-
-
-void Object::SetDeleteActive(bool state/*= true*/)
-{
-       deleteActive = state;
-}
-
-
-void Object::SetDimensionActive(bool state/*= true*/)
-{
-       dimensionActive = state;
-}
-
-
-void Object::SetSnapMode(bool state/*= true*/)
-{
-       snapToGrid = state;
-}
-
-
-//
-// This looks strange, but it's really quite simple: We want a point that's
-// more than half-way to the next grid point to snap there while conversely we
-// want a point that's less than half-way to to the next grid point then snap
-// to the one before it. So we add half of the grid spacing to the point, then
-// divide by it so that we can remove the fractional part, then multiply it
-// back to get back to the correct answer.
-//
-Vector Object::SnapPointToGrid(Vector point)
-{
-       point += gridSpacing / 2.0;             // *This* adds to Z!!!
-       point /= gridSpacing;
-       point.x = floor(point.x);//need to fix this for negative numbers...
-       point.y = floor(point.y);
-       point.z = 0;                                    // Make *sure* Z doesn't go anywhere!!!
-       point *= gridSpacing;
-       return point;
-}
-
-
diff --git a/src/object.h b/src/object.h
deleted file mode 100644 (file)
index ff29e1f..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef __OBJECT_H__
-#define __OBJECT_H__
-
-#include <stdio.h>
-#include <vector>                                                      // This is a container
-#include "vector.h"                                                    // This is the mathematical construct
-#include "connection.h"
-#include <QRectF>
-
-class Painter;
-class QFont;
-class Dimension;
-//class FILE;
-
-enum ObjectState { OSInactive, OSSelected };
-enum ObjectType { OTNone, OTObject, OTLine, OTCircle, OTArc, OTDimension, OTEllipse, OTContainer, OTSpline };
-
-class Object
-{
-       friend class Geometry;
-
-       public:
-               Object();
-               Object(Vector, Object * passedInParent = 0);
-               ~Object();
-
-               virtual void Draw(Painter *);
-               virtual Vector Center(void);
-               virtual bool Collided(Vector);
-               virtual bool PointerMoved(Vector);
-               virtual void PointerReleased(void);
-               virtual bool NeedsUpdate(void);
-               virtual bool HitTest(Point);
-               virtual void Transmute(Object *, Object *);
-               virtual Object * GetParent(void);
-               virtual void Add(Object *);
-               virtual Vector * GetPointAt(Vector);
-               virtual void Enumerate(FILE *);
-               virtual Object * Copy(void);
-               virtual Vector GetPointAtParameter(double parameter);
-//Not yet, soon though         virtual void MovePointAtParameter(double parameter, Vector);
-               virtual void Connect(Object *, double);
-               virtual void Disconnect(Object *, double);
-               virtual void DisconnectAll(Object *);
-               virtual QRectF Extents(void);
-               virtual void Translate(Vector);
-               virtual void Rotate(Point, double);
-               virtual void Scale(Point, double);
-               virtual void Mirror(Point, Point);
-               virtual void Save(void);
-               virtual void Restore(void);
-               ObjectState GetState(void);
-               void Reparent(Object *);
-
-               // Class methods
-               static void SetFixedAngle(bool state = true);
-               static void SetFixedLength(bool state = true);
-               static void SetFont(QFont *);
-               static void SetViewportHeight(int);
-               static void SetDeleteActive(bool state = true);
-               static void SetDimensionActive(bool state = true);
-               static void SetSnapMode(bool state = true);
-               static Vector SnapPointToGrid(Vector);
-
-       public:
-               Vector position;                                        // All objects have a position (doubles as reference point)
-       protected:
-               Object * parent;
-//this needs to be added eventually
-//             Pen pen;
-//             Fill fill;
-               Point oldPosition;
-       public:
-               ObjectType type;
-               ObjectState state;
-               unsigned int layer;
-       protected:
-               ObjectState oldState;
-               bool needUpdate;
-               std::vector<Connection> connected;
-
-               // Class variables
-       public:
-               static QFont * font;
-       protected:
-               static bool fixedAngle;
-               static bool fixedLength;
-               static int viewportHeight;
-               static bool deleteActive;
-               static bool dimensionActive;
-       public:
-               static bool snapToGrid;
-               static bool ignoreClicks;
-               static bool dontMove;
-       public:
-               static bool selectionInProgress;
-               static QRectF selection;
-               static double gridSpacing;                      // Grid spacing in base units
-               static int currentLayer;
-               static Point snapPoint;
-               static bool snapPointIsValid;
-};
-
-#endif // __OBJECT_H__
index 7b528c79308d1c79f7b7861a8a3454dc75d4b2a1..442fba8c6e5da60651eff1ae857d4fa761a986f7 100644 (file)
@@ -22,7 +22,7 @@ SettingsDialog::SettingsDialog(QWidget * parent/*= 0*/): QDialog(parent)
        generalTab = new GeneralTab(this);
        baseunitTab = new BaseUnitTab(this);
        tabWidget->addTab(generalTab, tr("General"));
-       tabWidget->addTab(baseunitTab, tr("Base Units"));
+       tabWidget->addTab(baseunitTab, tr("Base Unit"));
 //     tabWidget->addTab(new PermissionsTab(fileInfo), tr("Permissions"));
 //     tabWidget->addTab(new ApplicationsTab(fileInfo), tr("Applications"));