# by James Hammons
# (C) 2012 Underground Software
#
-TARGET = architectonas
-echo "Cross compiling $(TARGET) for Win32..."
+TARGET=architektonas
+echo "Cross compiling ${TARGET} for Win32..."
export PATH=/opt/mxe/usr/bin:$PATH
rm Makefile
/opt/mxe/usr/i686-pc-mingw32/qt/bin/qmake
make
#make CROSS=i686-pc-mingw32-
#rel=`svn info | grep Revision | cut -f 2 -d ' '`
-#rel=`git log -1 --pretty=format:%ci | cut -d ' ' -f 1 | tr -d -`
-#cd release && upx -9v $(TARGET).exe && zip -9v $(TARGET)-$rel.zip $(TARGET).exe
+rel=`git log -1 --pretty=format:%ci | cut -d ' ' -f 1 | tr -d -`
+#echo ${TARGET}.exe
+cd release && upx -9v ${TARGET}.exe && zip -9v ${TARGET}-${rel}.zip ${TARGET}.exe
<file>file-save-as.png</file>
<file>settings.png</file>
<file>mirror-tool.png</file>
+ <file>layer-add.png</file>
+ <file>layer-delete.png</file>
+ <file>layer-edit.png</file>
+ <file>layer-up.png</file>
+ <file>layer-down.png</file>
+ <file>block-import.png</file>
</qresource>
</RCC>
signals:
void ObjectReady(Object *);
void NeedRefresh(void);
+
+ // Class variables
+// public:
+// static unsigned int currentLayer;
};
#endif // __ACTION_H__
dock2->setObjectName("Blocks");
// Create status bar
- zoomIndicator = new QLabel("Grid: 12.0\" Zoom: 12.5%");
+ zoomIndicator = new QLabel("Grid: 12.0\" BU: Inch");
statusBar()->addPermanentWidget(zoomIndicator);
statusBar()->showMessage(tr("Ready"));
{
QString filename = QFileDialog::getOpenFileName(this, tr("Open Drawing"),
"", tr("Architektonas files (*.drawing)"));
+
+ // User cancelled open
+ if (filename.isEmpty())
+ return;
+
FILE * file = fopen(filename.toAscii().data(), "r");
if (file == 0)
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(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;
qlw->setItemWidget(qli4, biw4);
qlw->setItemWidget(qli5, biw5);
+#if 0
QPushButton * pb1 = new QPushButton("+");
QPushButton * pb2 = new QPushButton("-");
QPushButton * pb3 = new QPushButton("Edit");
QPushButton * pb4 = new QPushButton("Import");
+#else
+ QToolButton * pb1 = new QToolButton;
+ QToolButton * pb2 = new QToolButton;
+ QToolButton * pb3 = new QToolButton;
+ QToolButton * pb4 = 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/block-import.png"));
+
+ pb1->setToolTip(tr("Add block"));
+ pb2->setToolTip(tr("Remove block"));
+ pb3->setToolTip(tr("Edit block"));
+ pb4->setToolTip(tr("Import block"));
+#endif
QHBoxLayout * hbox1 = new QHBoxLayout;
hbox1->addWidget(pb1);
/*virtual*/ bool Container::Collided(Vector point)
{
objectWasDragged = false;
-// Vector v1 = position - point;
-
bool collision = false;
+ lastObjectClicked = NULL;
- // NOTE that this deletes the object on mouse down instead of mouse up. Have to
- // check to see how it feels to do it that way...
+ // NOTE that this deletes the object on mouse down instead of mouse up.
+ // Have to check to see how it feels to do it that way...
+ // N.B.: This only works because the toolAction is not set, &
+ // Object::ignoreClicks isn't set either...
if (deleteActive)
{
for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end();)
for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
{
if ((*i)->Collided(point))
+ {
collision = true;
+ lastObjectClicked = *i;
+//printf("Container::Collided: lastObjectClicked = %X\n", lastObjectClicked);
+ }
}
}
public:
std::vector<Object *> objects;
bool isTopLevelContainer;
+ Object * lastObjectClicked;
private:
bool dragging;
bool draggingHandle1;
Dimension::Dimension(Vector p1, Vector p2, DimensionType dt/*= DTLinear*/, Object * p/*= NULL*/):
Object(p1, p), endpoint(p2),
dragging(false), draggingHandle1(false), draggingHandle2(false),
- length(p2.Magnitude()), dimensionType(dt), size(0.25), point1(NULL), point2(NULL)
+ length(p2.Magnitude()), dimensionType(dt), size(0.25)//, point1(NULL), point2(NULL)
{
// We set the size to 1/4 base unit. Could be anything.
type = OTDimension;
}
-
+#if 0
// This is bad, p1 & p2 could be NULL, causing much consternation...
Dimension::Dimension(Connection p1, Connection p2, DimensionType dt/*= DTLinear*/, Object * p/*= NULL*/):
dragging(false), draggingHandle1(false), draggingHandle2(false),
- length(0), dimensionType(dt), size(0.25), point1(p1), point2(p2)
+ length(0), dimensionType(dt), size(0.25)//, point1(p1), point2(p2)
{
type = OTDimension;
}
-
+#endif
Dimension::~Dimension()
{
painter->SetBrush(QBrush(QColor(Qt::blue)));
// Draw an aligned dimension line
- double angle = Vector(endpoint - position).Angle();
- double orthoAngle = angle + (PI / 2.0);
- Vector orthogonal = Vector(cos(orthoAngle), sin(orthoAngle));
- Vector unit = Vector(endpoint - position).Unit();
-
-// Arrowhead:
-// Point p1 = head - (unit * 9.0 * size);
-// Point p2 = p1 + (orthogonal * 3.0 * size);
-// Point p3 = p1 - (orthogonal * 3.0 * size);
+ Vector v(position, endpoint);
+ double angle = v.Angle();
+// double orthoAngle = angle + (PI / 2.0);
+// Vector orthogonal = Vector(cos(orthoAngle), sin(orthoAngle));
+ Vector orthogonal = Vector::Normal(position, endpoint);
+ Vector unit = v.Unit();
/*
The numbers hardcoded into here, what are they?
QString dimText = QString("%1\"").arg(Vector(endpoint - position).Magnitude());
#else
QString dimText;
- double length = Vector(endpoint - position).Magnitude();
+// double length = Vector(endpoint - position).Magnitude();
+ double length = v.Magnitude();
if (length < 12.0)
dimText = QString("%1\"").arg(length);
#endif
painter->DrawAngledText(ctr, angle, dimText, size);
+
+ if (hitLine)
+ {
+ Point p9 = ((position + endpoint) / 2.0) + (orthogonal * 14.0)
+ + (unit * 7.0);
+
+ Point p10 = p9 + (orthogonal * -7.0);
+ Point p11 = p10 + (unit * 7.0);
+ Point p12 = p11 + (orthogonal * 7.0);
+ Point p13 = p12 + (unit * -7.0);
+ painter->DrawLine(p10, p11);
+ painter->DrawLine(p11, p12);
+ painter->DrawLine(p12, p13);
+ painter->DrawLine(p13, p10);
+ }
}
/*virtual*/ bool Dimension::HitTest(Point point)
{
- hitPoint1 = hitPoint2 = false;
-// Vector lineSegment(position, endpoint);
+ Vector orthogonal = Vector::Normal(position, endpoint);
+ // Get our line parallel to our points
+ Point p1 = position + (orthogonal * 10.0 * size);
+ Point p2 = endpoint + (orthogonal * 10.0 * size);
+ Point p3(p1, point);
+
+ hitPoint1 = hitPoint2 = hitLine = hitFlipSwitch = false;
Vector v1(position, point);
Vector v2(endpoint, point);
+// Vector lineSegment(position, endpoint);
+ Vector lineSegment(p1, p2);
// double t = Geometry::ParameterOfLineAndPoint(position, endpoint, point);
-// double distance;
+ double t = Geometry::ParameterOfLineAndPoint(p1, p2, point);
+ double distance;
-// if (t < 0.0)
-// distance = v1.Magnitude();
-// else if (t > 1.0)
-// distance = v2.Magnitude();
-// else
+ 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());
+ distance = fabs((lineSegment.x * p3.y - p3.x * lineSegment.y)
+ / lineSegment.Magnitude());
if ((v1.Magnitude() * Painter::zoom) < 8.0)
hitPoint1 = true;
else if ((v2.Magnitude() * Painter::zoom) < 8.0)
hitPoint2 = true;
+ else if ((distance * Painter::zoom) < 5.0)
+ hitLine = true;
- return (hitPoint1 || hitPoint2 ? true : false);
+ return (hitPoint1 || hitPoint2 || hitLine ? true : false);
}
{
oldHitPoint1 = hitPoint1;
oldHitPoint2 = hitPoint2;
-// oldHitLine = hitLine;
+ oldHitLine = hitLine;
}
bool Dimension::HitStateChanged(void)
{
- if ((hitPoint1 != oldHitPoint1) || (hitPoint2 != oldHitPoint2))
+ if ((hitPoint1 != oldHitPoint1) || (hitPoint2 != oldHitPoint2) || (hitLine != oldHitLine))
return true;
return false;
{} // Not sure how to handle this case :-P
}
-
+#if 0
/*virtual*/ void Dimension::Connect(Object * obj, double param)
{
// There are four possibilities here...
if (point2.object == obj)
point2.object = NULL;
}
-
+#endif
/*virtual*/ QRectF Dimension::Extents(void)
{
Point p1 = position;
Point p2 = endpoint;
- if (point1.object)
- p1 = point1.object->GetPointAtParameter(point1.t);
-
- if (point2.object)
- p2 = point2.object->GetPointAtParameter(point2.t);
+// if (point1.object)
+// p1 = point1.object->GetPointAtParameter(point1.t);
+//
+// if (point2.object)
+// p2 = point2.object->GetPointAtParameter(point2.t);
return QRectF(QPointF(p1.x, p1.y), QPointF(p2.x, p2.y));
}
void Dimension::FlipSides(void)
{
-#if 0
+#if 1
Vector tmp = position;
position = endpoint;
endpoint = tmp;
+//Not sure this matters...
+//#warning "!!! May need to swap parameter values on connected objects !!!"
#else
Connection tmp = point1;
point1 = point2;
public:
Dimension(Vector, Vector, DimensionType dt = DTLinear, Object * p = 0);
- Dimension(Connection, Connection, DimensionType dt = DTLinear, Object * p = 0);
+// Dimension(Connection, Connection, DimensionType dt = DTLinear, Object * p = 0);
~Dimension();
virtual void Draw(Painter *);
virtual Object * Copy(void);
virtual Vector GetPointAtParameter(double parameter);
virtual void MovePointAtParameter(double parameter, Vector);
- virtual void Connect(Object *, double);
- virtual void Disconnect(Object *, double);
- virtual void DisconnectAll(Object *);
+// virtual void Connect(Object *, double);
+// virtual void Disconnect(Object *, double);
+// virtual void DisconnectAll(Object *);
virtual QRectF Extents(void);
void FlipSides(void);
DimensionType dimensionType;
bool hitPoint1;
bool hitPoint2;
- bool oldHitPoint1, oldHitPoint2;
+ bool hitLine;
+ bool hitFlipSwitch;
+ bool oldHitPoint1, oldHitPoint2, oldHitLine, oldHitFlipSwitch;
public:
double size; // Size of arrows/text in base units
private:
// We use these in lieu of the built-in connected[] array; no reason to
// do it this way especially
- Connection point1;
- Connection point2;
+// Connection point1;
+// Connection point2;
};
#endif // __DIMENSION_H__
/*virtual*/ void DrawArcAction::MouseDown(Vector point)
{
if (state == FIRST_POINT)
+ // How to check for hitting an object here?
p1 = point;
else if (state == SECOND_POINT)
{
//
#include "drawdimensionaction.h"
+#include "applicationwindow.h"
#include "dimension.h"
+#include "drawingview.h"
+#include "line.h"
#include "painter.h"
-enum { FIRST_POINT, NEXT_POINT };
+enum { FIRST_POINT, NEXT_POINT, NO_POINT };
DrawDimensionAction::DrawDimensionAction(): state(0), dimension(NULL)
{
painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine));
- // I think stuff like crosshairs should be done in the DrawingView, tho
if (state == FIRST_POINT)
{
painter->DrawHandle(p1);
}
- else
+ else if (state == NEXT_POINT)
{
painter->DrawLine(p1, p2);
painter->DrawHandle(p2);
/*virtual*/ void DrawDimensionAction::MouseDown(Vector point)
{
+ obj = ApplicationWindow::drawing->document.lastObjectClicked;
+
+ if (obj)
+ {
+ if (obj->type == OTLine)
+ {
+ // Make sure we didn't hit an endpoint...
+ if (!(((Line *) obj)->hitPoint1 || ((Line *)obj)->hitPoint2))
+ {
+ state = NO_POINT;
+ return;
+ }
+ }
+ }
+
if (state == FIRST_POINT)
p1 = point;
else
/*virtual*/ void DrawDimensionAction::MouseReleased(void)
{
- if (state == FIRST_POINT)
+ if (state == NO_POINT)
+ {
+ HandleAddDimensionToObject();//ApplicationWindow::drawing->document.lastObjectClicked);
+ state = FIRST_POINT;
+ }
+ else if (state == FIRST_POINT)
{
p2 = p1;
state = NEXT_POINT;
{
}
+
+void DrawDimensionAction::HandleAddDimensionToObject(void)//Object * obj)
+{
+//printf("Adding dimension to object...\n");
+ if (obj->type == OTLine)
+ {
+ Object * existing = ((Line *)obj)->FindAttachedDimension();
+
+ if (existing)
+ {
+ ((Dimension *)existing)->FlipSides();
+ }
+//printf("--> type == LINE\n");
+ // Should also check here to see if it hit the line proper or just hit
+ // an endpoint...
+ else
+ {
+ dimension = new Dimension(p1, p2);
+ ((Line *)obj)->SetDimensionOnLine(dimension);
+ emit ObjectReady(dimension);
+ }
+ }
+}
+
#include "action.h"
class Dimension;
+class Object;
class DrawDimensionAction: public Action
{
virtual void KeyDown(int);
virtual void KeyReleased(int);
+ private:
+// void HandleAddDimensionToObject(Object *);
+ void HandleAddDimensionToObject(void);
+
private:
int state;
Dimension * dimension;
Vector p1, p2;
+ Object * obj;
};
#endif // __DRAWDIMENSIONACTION_H__
// The value in the settings file will override this.
useAntialiasing(true),
gridBackground(BACKGROUND_MAX_SIZE, BACKGROUND_MAX_SIZE),
- scale(1.0), offsetX(-10), offsetY(-10),
- document(Vector(0, 0)),
- /*gridSpacing(12.0),*/ gridPixels(0), collided(false), //rotateTool(false),
-// rx(150.0), ry(150.0),
-// scrollDrag(false), addLineTool(false), addCircleTool(false),
-// addDimensionTool(false),
- toolAction(NULL)
+ scale(1.0), offsetX(-10), offsetY(-10), document(Vector(0, 0)),
+ gridPixels(0), collided(false), toolAction(NULL)
{
document.isTopLevelContainer = true;
setBackgroundRole(QPalette::Base);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- Object::gridSpacing = 12.0;
-// toolPalette = new ToolWindow();
-// CreateCursors();
-// setCursor(cur[TOOLSelect]);
-// setMouseTracking(true);
+ Object::gridSpacing = 12.0; // In base units (inch is default)
Line * line = new Line(Vector(5, 5), Vector(50, 40), &document);
document.Add(line);
we do! :-)
*/
- SetGridSize(12);
+ SetGridSize(12); // This is in pixels
}
if (event->button() == Qt::LeftButton)
{
Vector point = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
-
-// Problem with this: Can't select stuff very well with the snap grid on.
-// Completely screws things up, as sometimes things don't fall on the grid.
-/*
-So, how to fix this? Have the Object check itself?
-Maybe we can fix this by having the initial point not be snapped, but when there's
-a drag, we substitute the snapped point 'oldPoint' which the Object keeps track of
-internally to know how far it was dragged...
-
-Now we do... :-/
-*/
-#if 0
- if (Object::snapToGrid)
- point = Object::SnapPointToGrid(point);
-#endif
-
collided = document.Collided(point);
+ // Do an update if collided with at least *one* object in the document
if (collided)
- update(); // Do an update if collided with at least *one* object in the document
+ update();
if (toolAction)
{
QToolButton * pb4 = new QToolButton;
QToolButton * pb5 = new QToolButton;
- pb1->setIcon(QIcon(":/res/generic-tool.png"));
- pb2->setIcon(QIcon(":/res/generic-tool.png"));
- pb3->setIcon(QIcon(":/res/generic-tool.png"));
- pb4->setIcon(QIcon(":/res/generic-tool.png"));
- pb5->setIcon(QIcon(":/res/generic-tool.png"));
+ 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
QHBoxLayout * hbox1 = new QHBoxLayout;
QString text = QObject::tr("Length: %1 in.\n") + QChar(0x2221) + QObject::tr(": %2");
text = text.arg(absLength).arg(absAngle);
-#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 (in Qt coords)
- 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
}
}
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...
*/
- // 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);
+ bool hit = HitTest(point);
+
+ // Someone told us to fuck off, so we'll fuck off. :-)
+ if (ignoreClicks)
+// return false;
+ return hit;
// Now that we've done our hit testing on the non-snapped point, snap it if
// necessary...
void Line::SetDimensionOnLine(Dimension * dimension/*= NULL*/)
{
// If they don't pass one in, create it for the caller.
- if (dimension == NULL)
+ // 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, this);
- dimension = new Dimension(Connection(this, 0), Connection(this, 1.0), DTLinear, this);
+ dimension = new Dimension(position, endpoint, DTLinear, parent);
+// dimension = new Dimension(Connection(this, 0), Connection(this, 1.0), DTLinear, this);
- if (parent)
+ // THIS IS SERIOUS!!! WITHOUT A PARENT, THIS OBJECT IS IN LIMBO!!!
+// if (parent)
//{
//printf("Line::SetDimensionOnLine(): Adding to parent...\n");
- parent->Add(dimension);
+ parent->Add(dimension);
//}
}
- else
- {
- dimension->Connect(this, 0);
- dimension->Connect(this, 1.0);
- }
+
+ dimension->Connect(this, 0);
+ dimension->Connect(this, 1.0);
// Make sure the Dimension is connected to us...
Connect(dimension, 0);
bool objectWasDragged;
double length;
Vector angle;
+ public:
bool hitPoint1, hitPoint2, hitLine;
+ private:
bool oldHitPoint1, oldHitPoint2, oldHitLine;
};
#include "line.h"
#include "mathconstants.h"
#include "painter.h"
-//#include "vector.h"
-//#define FIRST_POINT 0
-//#define NEXT_POINT 1
enum { FIRST_POINT, NEXT_POINT };
{
painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine));
- // I think stuff like crosshairs should be done in the DrawingView, tho
- // (and it's done there now...)
if (state == FIRST_POINT)
{
painter->DrawHandle(p1);
else
{
mirror->CopyContentsTo(&(ApplicationWindow::drawing->document));
-// mirror->CopyContentsTo(&(DrawingView.document));
}
}
}
virtual void Disconnect(Object *, double);
virtual void DisconnectAll(Object *);
virtual QRectF Extents(void);
-// virtual ObjectType Type(void);// = 0; // Pure virtual, must be implemented
virtual void Translate(Vector);
virtual void Rotate(Point, double);
virtual void Scale(Point, double);
virtual void Restore(void);
ObjectState GetState(void);
void Reparent(Object *);
-// Dimension * GetAttachedDimension(void);
-//Hm. Object * Connect(Object *);
// Class methods
static void SetFixedAngle(bool state = true);
protected:
Vector position; // All objects have a position (doubles as reference point)
Object * parent;
+//this needs to be added eventually
// Pen pen;
// Fill fill;
Point oldPosition;
protected:
ObjectState oldState;
bool needUpdate;
-// Dimension * attachedDimension;
std::vector<Connection> connected;
// Class variables