From bd9b40058a376c946318a444dd6c77737ec6ac98 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Sun, 25 Sep 2011 23:45:20 +0000 Subject: [PATCH] Added glue layer to Qt painting, to properly render cartesian coordinates. --- architektonas.pro | 2 ++ src/arc.cpp | 54 ++++++++++++++++++++++++++++----------------- src/arc.h | 2 +- src/circle.cpp | 14 +++++++----- src/circle.h | 2 +- src/container.cpp | 2 +- src/container.h | 2 +- src/dimension.cpp | 29 +++++++++++++++--------- src/dimension.h | 2 +- src/drawingview.cpp | 36 ++++++++++++++++-------------- src/line.cpp | 24 ++++++++++++-------- src/line.h | 2 +- src/main.cpp | 6 ----- src/object.cpp | 3 ++- src/object.h | 4 ++-- 15 files changed, 108 insertions(+), 76 deletions(-) diff --git a/architektonas.pro b/architektonas.pro index cf3254c..5d00725 100644 --- a/architektonas.pro +++ b/architektonas.pro @@ -53,6 +53,7 @@ HEADERS = \ src/main.h \ src/mathconstants.h \ src/object.h \ + src/painter.h \ src/settingsdialog.h \ src/vector.h @@ -68,6 +69,7 @@ SOURCES = \ src/line.cpp \ src/main.cpp \ src/object.cpp \ + src/painter.cpp \ src/settingsdialog.cpp \ src/vector.cpp diff --git a/src/arc.cpp b/src/arc.cpp index adccd21..925676d 100644 --- a/src/arc.cpp +++ b/src/arc.cpp @@ -16,6 +16,7 @@ #include #include "mathconstants.h" +#include "painter.h" Arc::Arc(Vector p1, double r, double a1, double a2, Object * p/*= NULL*/): Object(p1, p), @@ -27,8 +28,10 @@ Arc::~Arc() { } -/*virtual*/ void Arc::Draw(QPainter * painter) +/*virtual*/ void Arc::Draw(Painter * painter) { + QPen pen; + if (state == OSSelected) { Point p1(cos(startAngle), sin(startAngle)); @@ -44,23 +47,25 @@ Arc::~Arc() // moving it from. Point p3(cos(oldAngle), sin(oldAngle)); Vector oldLine = (p3 * (radius * 1.25)) + position; - painter->setPen(QPen(QColor(0x80, 0x80, 0x80), 1.0, Qt::DashLine)); - painter->drawLine((int)position.x, (int)position.y, (int)oldLine.x, (int)oldLine.y); + 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); } // In rotating and setting the span, we draw a line showing where // we angle/span is that we're setting. - painter->setPen(QPen(QColor(0x00, 0xC0, 0x80), 1.0, Qt::DashLine)); - painter->drawLine((int)position.x, (int)position.y, (int)oldPoint.x, (int)oldPoint.y); + 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); } // Draw the center point of the arc - painter->setPen(QPen(Qt::red, 2.0, Qt::DotLine)); - painter->drawEllipse(QPointF(position.x, position.y), 4.0, 4.0); + painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine)); + painter->DrawEllipse(position, 4.0, 4.0); // Draw the rotation & span setting handles - painter->drawEllipse(QPointF(handle2.x, handle2.y), 4.0, 4.0); - painter->drawEllipse(QPointF(handle3.x, handle3.y), 4.0, 4.0); + painter->DrawEllipse(handle2, 4.0, 4.0); + painter->DrawEllipse(handle3, 4.0, 4.0); // If we're rotating or setting the span, draw an information panel // showing both absolute and relative angles being set. @@ -70,13 +75,13 @@ Arc::~Arc() double relAngle = (startAngle >= oldAngle ? startAngle - oldAngle : startAngle - oldAngle + (2.0 * PI)) * RADIANS_TO_DEGREES; - painter->save(); +// painter->save(); //close, but no cigar. we need to "invert" our transformation to make this work properly // return QPoint(-offsetX + x, (size().height() - (-offsetY + y)) * +1.0); // painter->translate(0, viewportHeight); // painter->scale(1.0, -1.0); // Give up for now; just paint the info panel in the upper left corner of the screen - painter->resetTransform(); +// painter->resetTransform(); QString text; if (hitHandle2) @@ -97,28 +102,37 @@ Arc::~Arc() text = text.arg(radius, 0, 'd', 4).arg(radius / oldRadius * 100.0, 0, 'd', 0); } - painter->setPen(QPen(QColor(0x00, 0xFF, 0x00), 1.0, Qt::SolidLine)); - painter->setBrush(QBrush(QColor(0x40, 0xFF, 0x40, 0x9F))); + 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, 220.0, 60.0); // x, y, w, h - painter->drawRoundedRect(textRect, 7.0, 7.0); + painter->DrawRoundedRect(textRect, 7.0, 7.0); textRect.setLeft(textRect.left() + 14); - painter->setFont(*Object::font); - painter->setPen(QPen(QColor(0xDF, 0x5F, 0x00), 1.0, Qt::SolidLine)); - painter->drawText(textRect, Qt::AlignVCenter, text); - painter->restore(); + painter->SetFont(*Object::font); + pen = QPen(QColor(0xDF, 0x5F, 0x00), 1.0, Qt::SolidLine); + painter->SetPen(pen); + painter->DrawText(textRect, Qt::AlignVCenter, text); +// painter->Restore(); } // painter->setPen(QPen(Qt::red, 2.0, Qt::DotLine)); } else - painter->setPen(QPen(Qt::black, 1.0, Qt::SolidLine)); + { + pen = QPen(Qt::black, 1.0, Qt::SolidLine); + painter->SetPen(pen); + } +#if 0 QRectF rectangle(QPointF(position.x - radius, position.y - radius), QPointF(position.x + radius, position.y + radius)); int angle1 = (int)(startAngle * RADIANS_TO_DEGREES * 16.0); int angle2 = (int)(angleSpan * RADIANS_TO_DEGREES * 16.0); - painter->drawArc(rectangle, -angle1, -angle2); + painter->DrawArc(rectangle, -angle1, -angle2); +#else + painter->DrawArc(position, radius, startAngle, angleSpan); +#endif } /*virtual*/ Vector Arc::Center(void) diff --git a/src/arc.h b/src/arc.h index f6cb717..ee9c567 100644 --- a/src/arc.h +++ b/src/arc.h @@ -9,7 +9,7 @@ class Arc: public Object Arc(Vector, double, double, double, Object * p = 0); ~Arc(); - virtual void Draw(QPainter *); + virtual void Draw(Painter *); virtual Vector Center(void); virtual bool Collided(Vector); virtual void PointerMoved(Vector); diff --git a/src/circle.cpp b/src/circle.cpp index d395b68..a8902cc 100644 --- a/src/circle.cpp +++ b/src/circle.cpp @@ -14,6 +14,8 @@ #include "circle.h" #include +#include "painter.h" + Circle::Circle(Vector p1, double r, Object * p/*= NULL*/): Object(p1, p), radius(r), dragging(false), draggingHandle1(false), draggingHandle2(false)//, needUpdate(false) @@ -24,24 +26,24 @@ Circle::~Circle() { } -/*virtual*/ void Circle::Draw(QPainter * painter) +/*virtual*/ void Circle::Draw(Painter * painter) { if (state == OSSelected) - painter->setPen(QPen(Qt::red, 2.0, Qt::DotLine)); + painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine)); else - painter->setPen(QPen(Qt::black, 1.0, Qt::SolidLine)); + painter->SetPen(QPen(Qt::black, 1.0, Qt::SolidLine)); // if (draggingHandle1) if (state == OSSelected) - painter->drawEllipse(QPointF(position.x, position.y), 4.0, 4.0); + painter->DrawEllipse(position, 4.0, 4.0); // if (draggingHandle2) // if (state == OSSelected) // painter->drawEllipse(QPointF(endpoint.x, endpoint.y), 4.0, 4.0); if (state == OSSelected && dragging) - painter->drawEllipse(QPointF(oldPoint.x, oldPoint.y), 4.0, 4.0); + painter->DrawEllipse(oldPoint, 4.0, 4.0); - painter->drawEllipse(QPointF(position.x, position.y), radius, radius); + painter->DrawEllipse(position, radius, radius); } /*virtual*/ Vector Circle::Center(void) diff --git a/src/circle.h b/src/circle.h index e4b3845..cc5159f 100644 --- a/src/circle.h +++ b/src/circle.h @@ -9,7 +9,7 @@ class Circle: public Object Circle(Vector, double, Object * p = 0); ~Circle(); - virtual void Draw(QPainter *); + virtual void Draw(Painter *); virtual Vector Center(void); virtual bool Collided(Vector); virtual void PointerMoved(Vector); diff --git a/src/container.cpp b/src/container.cpp index a565334..b69a6e3 100644 --- a/src/container.cpp +++ b/src/container.cpp @@ -33,7 +33,7 @@ Container::~Container() } } -/*virtual*/ void Container::Draw(QPainter * painter) +/*virtual*/ void Container::Draw(Painter * painter) { for(int i=0; i<(int)objects.size(); i++) objects[i]->Draw(painter); diff --git a/src/container.h b/src/container.h index ac9c51d..7801c8f 100644 --- a/src/container.h +++ b/src/container.h @@ -10,7 +10,7 @@ class Container: public Object Container(Vector, Object * p = 0); ~Container(); - virtual void Draw(QPainter *); + virtual void Draw(Painter *); virtual Vector Center(void); virtual bool Collided(Vector); virtual void PointerMoved(Vector); diff --git a/src/dimension.cpp b/src/dimension.cpp index b9fc976..4ccd48e 100644 --- a/src/dimension.cpp +++ b/src/dimension.cpp @@ -15,6 +15,7 @@ #include #include "mathconstants.h" +#include "painter.h" Dimension::Dimension(Vector p1, Vector p2, Object * p/*= NULL*/): Object(p1, p), endpoint(p2), @@ -34,7 +35,7 @@ Dimension::~Dimension() { } -/*virtual*/ void Dimension::Draw(QPainter * painter) +/*virtual*/ void Dimension::Draw(Painter * painter) { // If there are valid Vector pointers in here, use them to update the internal // positions. Otherwise, we just use the internal positions by default. @@ -45,9 +46,9 @@ Dimension::~Dimension() endpoint = *point2; if (state == OSSelected) - painter->setPen(QPen(Qt::red, 2.0, Qt::DotLine)); + painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine)); else - painter->setPen(QPen(Qt::blue, 1.0, Qt::SolidLine)); + painter->SetPen(QPen(Qt::blue, 1.0, Qt::SolidLine)); // Draw an aligned dimension line double angle = Vector(endpoint - position).Angle(); @@ -60,7 +61,7 @@ Dimension::~Dimension() Point p2 = endpoint + (orthogonal * 10.0); // Draw main dimension line - painter->drawLine(QPointF(p1.x, p1.y), QPointF(p2.x, p2.y)); + painter->DrawLine(p1, p2); Point p3 = position + (orthogonal * 16.0); Point p4 = endpoint + (orthogonal * 16.0); @@ -68,16 +69,18 @@ Dimension::~Dimension() Point p6 = endpoint + (orthogonal * 4.0); // Draw extension lines - painter->drawLine(QPointF(p3.x, p3.y), QPointF(p5.x, p5.y)); - painter->drawLine(QPointF(p4.x, p4.y), QPointF(p6.x, p6.y)); + painter->DrawLine(p3, p5); + painter->DrawLine(p4, p6); // Draw length of dimension line... - painter->setFont(QFont("Arial", 10)); + painter->SetFont(QFont("Arial", 10)); Vector v1((p1.x - p2.x) / 2.0, (p1.y - p2.y) / 2.0); Point ctr = p2 + v1; + // This is in pixels, which isn't even remotely correct... !!! FIX !!! QString dimText = QString("%1\"").arg(Vector(endpoint - position).Magnitude()); - int textWidth = QFontMetrics(painter->font()).width(dimText); - int textHeight = QFontMetrics(painter->font()).height(); +// int textWidth = QFontMetrics(painter->font()).width(dimText); +// int textHeight = QFontMetrics(painter->font()).height(); +#if 0 //We have to do transformation voodoo to make the text come out readable and in correct orientation... //Some things to note here: if angle > 90 degrees, then we need to take the negative of the angle //for our text. @@ -98,11 +101,17 @@ painter->scale(1.0, -1.0); //painter->translate(-textWidth / 2, -24); // painter->drawText(0, 0, textWidth, 20, Qt::AlignCenter, dimText); // This version draws the y-coord from the baseline of the font - painter->drawText(-textWidth / 2, yOffset, dimText); + painter->DrawText(-textWidth / 2, yOffset, dimText); //painter->setPen(QPen(QColor(0xFF, 0x20, 0x20), 1.0, Qt::SolidLine)); //painter->drawLine(20, 0, -20, 0); //painter->drawLine(0, 20, 0, -20); painter->restore(); +#else +// painter->DrawText(QRectF(QPointF(ctr.x, ctr.y), QPointF(ctr.x + textWidth, ctr.y + textHeight)), Qt::AlignVCenter, dimText); +// Now that we've taken our own good advice, maybe we should have the painter class +// do a nice abstracted text draw routine? :-) + painter->DrawAngledText(ctr, angle, dimText); +#endif /* All of the preceeding makes me think that rather than try to compensate for Qt's unbelieveably diff --git a/src/dimension.h b/src/dimension.h index 301bcff..222675a 100644 --- a/src/dimension.h +++ b/src/dimension.h @@ -10,7 +10,7 @@ class Dimension: public Object Dimension(Vector *, Vector *, Object * p = 0); ~Dimension(); - virtual void Draw(QPainter *); + virtual void Draw(Painter *); virtual Vector Center(void); virtual bool Collided(Vector); virtual void PointerMoved(Vector); diff --git a/src/drawingview.cpp b/src/drawingview.cpp index e904bdb..148a34e 100644 --- a/src/drawingview.cpp +++ b/src/drawingview.cpp @@ -16,6 +16,8 @@ // // STILL TO BE DONE: // +// - Redo rendering code to *not* use Qt's transform functions, as they are tied +// to a left-handed system and we need a right-handed one. // // Uncomment this for debugging... @@ -32,14 +34,12 @@ #include "circle.h" #include "dimension.h" #include "line.h" +#include "painter.h" DrawingView::DrawingView(QWidget * parent/*= NULL*/): QWidget(parent), // The value in the settings file will override this. useAntialiasing(true), -// scale(1.0), offsetX(-10), offsetY(-10), tool(TOOLSelect), -// ptHighlight(-1), oldPtHighlight(-1), ptNextHighlight(-1), oldPtNextHighlight(-1), -// polyFirstPoint(true) scale(1.0), offsetX(-10), offsetY(-10), document(Vector(0, 0)), gridSpacing(32.0), collided(false), rotateTool(false), rx(150.0), ry(150.0) @@ -63,7 +63,6 @@ DrawingView::DrawingView(QWidget * parent/*= NULL*/): QWidget(parent), #if 1 Dimension * dimension = new Dimension(Vector(0, 0), Vector(0, 0), &document); line->SetDimensionOnLine(dimension); -// line->SetDimensionOnPoint2(dimension); document.Add(dimension); #else // Alternate way to do the above... @@ -95,11 +94,14 @@ QPoint DrawingView::GetAdjustedClientPosition(int x, int y) void DrawingView::paintEvent(QPaintEvent * /*event*/) { - QPainter painter(this); + QPainter qtPainter(this); + Painter painter(&qtPainter); if (useAntialiasing) - painter.setRenderHint(QPainter::Antialiasing); + qtPainter.setRenderHint(QPainter::Antialiasing); + Painter::screenSize = Vector(size().width(), size().height()); +#if 0 #if 0 painter.translate(QPoint(-offsetX, size.height() - (-offsetY))); painter.scale(1.0, -1.0); @@ -112,22 +114,23 @@ void DrawingView::paintEvent(QPaintEvent * /*event*/) transform.translate(-offsetX, -size().height() - offsetY); // transform.scale(0.25, 0.25); painter.setTransform(transform); +#endif #endif Object::SetViewportHeight(size().height()); // Draw coordinate axes - painter.setPen(QPen(Qt::blue, 1.0, Qt::DotLine)); - painter.drawLine(0, -16384, 0, 16384); - painter.drawLine(-16384, 0, 16384, 0); + painter.SetPen(QPen(Qt::blue, 1.0, Qt::DotLine)); + painter.DrawLine(0, -16384, 0, 16384); + painter.DrawLine(-16384, 0, 16384, 0); // Draw supplemental (tool related) points if (rotateTool) { - painter.setPen(QPen(QColor(0, 200, 0), 2.0, Qt::SolidLine)); - painter.drawLine(rx - 10, ry, rx + 10, ry); - painter.drawLine(rx, ry - 10, rx, ry + 10); + painter.SetPen(QPen(QColor(0, 200, 0), 2.0, Qt::SolidLine)); + painter.DrawLine(rx - 10, ry, rx + 10, ry); + painter.DrawLine(rx, ry - 10, rx, ry + 10); } // Maybe we can make the grid into a background brush instead, and let Qt deal @@ -138,18 +141,19 @@ void DrawingView::paintEvent(QPaintEvent * /*event*/) painter.setPen(QPen(QColor(90, 90, 90), 1.0, Qt::DotLine)); //these two loops kill performance! + // Also, these overwrite our coordinate axes for(double x=0; x #include "dimension.h" +#include "painter.h" + Line::Line(Vector p1, Vector p2, Object * p/*= NULL*/): Object(p1, p), endpoint(p2), draggingLine(false), draggingHandle1(false), draggingHandle2(false), //needUpdate(false), @@ -42,18 +44,18 @@ Line::~Line() // detached. } -/*virtual*/ void Line::Draw(QPainter * painter) +/*virtual*/ void Line::Draw(Painter * painter) { - painter->setPen(QPen(Qt::red, 2.0, Qt::DotLine)); + painter->SetPen(QPen(Qt::red, 2.0, Qt::DotLine)); if ((state == OSSelected) || ((state == OSInactive) && hitPoint1)) - painter->drawEllipse(QPointF(position.x, position.y), 4.0, 4.0); + painter->DrawEllipse(position, 4.0, 4.0); if ((state == OSSelected) || ((state == OSInactive) && hitPoint2)) - painter->drawEllipse(QPointF(endpoint.x, endpoint.y), 4.0, 4.0); + painter->DrawEllipse(endpoint, 4.0, 4.0); if ((state == OSInactive) && !hitLine) - painter->setPen(QPen(Qt::black, 1.0, Qt::SolidLine)); + painter->SetPen(QPen(Qt::black, 1.0, Qt::SolidLine)); if (Object::fixedLength && (draggingHandle1 || draggingHandle2)) { @@ -63,16 +65,16 @@ Line::~Line() Vector current(point2 - point1); Vector v = current.Unit() * length; Vector v2 = point1 + v; - painter->drawLine((int)point1.x, (int)point1.y, (int)v2.x, (int)v2.y); + painter->DrawLine((int)point1.x, (int)point1.y, (int)v2.x, (int)v2.y); if (current.Magnitude() > length) { - painter->setPen(QPen(QColor(128, 0, 0), 1.0, Qt::DashLine)); - painter->drawLine((int)v2.x, (int)v2.y, (int)point2.x, (int)point2.y); + painter->SetPen(QPen(QColor(128, 0, 0), 1.0, Qt::DashLine)); + painter->DrawLine((int)v2.x, (int)v2.y, (int)point2.x, (int)point2.y); } } else - painter->drawLine((int)position.x, (int)position.y, (int)endpoint.x, (int)endpoint.y); + painter->DrawLine((int)position.x, (int)position.y, (int)endpoint.x, (int)endpoint.y); } /*virtual*/ Vector Line::Center(void) @@ -273,6 +275,10 @@ software currently out there: the GUI will try to do the right thing, most of th // 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); diff --git a/src/line.h b/src/line.h index ab26225..5e1430c 100644 --- a/src/line.h +++ b/src/line.h @@ -11,7 +11,7 @@ class Line: public Object Line(Vector, Vector, Object * p = 0); ~Line(); - virtual void Draw(QPainter *); + virtual void Draw(Painter *); virtual Vector Center(void); virtual bool Collided(Vector); virtual void PointerMoved(Vector); diff --git a/src/main.cpp b/src/main.cpp index 684ccf3..3a1e633 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,15 +29,9 @@ int main(int argc, char * argv[]) { Q_INIT_RESOURCE(architektonas); // This must the same name as the exe filename -// QApplication app(argc, argv); -//printf("TTEdit app(argc, argv);\n"); Architektonas app(argc, argv); -//printf("TTEMainWindow mainWindow;\n"); ApplicationWindow mainWindow; -//printf("mainWindow.show();\n"); mainWindow.show(); -//OK, it gets to here at least... -//printf("return app.exec();\n"); return app.exec(); } diff --git a/src/object.cpp b/src/object.cpp index 3820d7e..ae20db6 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -13,6 +13,7 @@ // 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" @@ -39,7 +40,7 @@ Object::~Object() { } -/*virtual*/ void Object::Draw(QPainter *) +/*virtual*/ void Object::Draw(Painter *) { } diff --git a/src/object.h b/src/object.h index 8b047be..0c89654 100644 --- a/src/object.h +++ b/src/object.h @@ -4,7 +4,7 @@ #include // This is a container #include "vector.h" // This is the mathematical construct -class QPainter; +class Painter; class QFont; class Dimension; @@ -17,7 +17,7 @@ class Object Object(Vector, Object * passedInParent = 0); ~Object(); - virtual void Draw(QPainter *); + virtual void Draw(Painter *); virtual Vector Center(void); virtual bool Collided(Vector); virtual void PointerMoved(Vector); -- 2.37.2