X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Farc.cpp;h=355d7a76f2b5b425ddc5b882f7e21e86a22d8dc4;hb=86caae9cadd6e1877a4e6226533521ef0d1c6389;hp=adccd21507f23c816110b031c45aa3450a0d9c2c;hpb=9f6ad3fe0b9cb30115a5d38e8af3aebed0d70c08;p=architektonas diff --git a/src/arc.cpp b/src/arc.cpp index adccd21..355d7a7 100644 --- a/src/arc.cpp +++ b/src/arc.cpp @@ -4,7 +4,7 @@ // (C) 2011 Underground Software // See the README and GPLv3 files for licensing and warranty information // -// JLH = James L. Hammons +// JLH = James Hammons // // WHO WHEN WHAT // --- ---------- ------------------------------------------------------------ @@ -16,19 +16,26 @@ #include #include "mathconstants.h" +#include "painter.h" -Arc::Arc(Vector p1, double r, double a1, double a2, Object * p/*= NULL*/): Object(p1, p), - radius(r), startAngle(a1), angleSpan(a2) +Arc::Arc(Vector p1, double r, double a1, double a2, Object * p/*= NULL*/): + Object(p1, p), /*type(OTArc),*/ radius(r), startAngle(a1), angleSpan(a2) { + // This is in the base class, why can't we use the contructor to fill it??? + type = OTArc; } + 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 +51,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->DrawHandle(position); // 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->DrawHandle(handle2); + painter->DrawHandle(handle3); // If we're rotating or setting the span, draw an information panel // showing both absolute and relative angles being set. @@ -70,13 +79,6 @@ Arc::~Arc() double relAngle = (startAngle >= oldAngle ? startAngle - oldAngle : startAngle - oldAngle + (2.0 * PI)) * RADIANS_TO_DEGREES; - 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(); QString text; if (hitHandle2) @@ -97,35 +99,38 @@ 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))); - QRectF textRect(10.0, 10.0, 220.0, 60.0); // x, y, w, h - painter->drawRoundedRect(textRect, 7.0, 7.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); - 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); + pen = QPen(QColor(0x00, 0x5F, 0xDF)); + painter->SetPen(pen); + painter->DrawText(textRect, Qt::AlignVCenter, text); + painter->SetPen(QPen(QColor(0xDF, 0x5F, 0x00))); } - -// 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); + } - 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(position, radius, startAngle, angleSpan); +// painter->DrawRect(Extents()); } + /*virtual*/ Vector Arc::Center(void) { return position; } + /* We need at least *four* handles for this object: - one for moving @@ -229,8 +234,20 @@ so let's do like this: return false; } + /*virtual*/ void Arc::PointerMoved(Vector point) { + if (selectionInProgress) + { + // Check for whether or not the rect contains this circle + if (selection.normalized().contains(Extents())) + state = OSSelected; + else + state = OSInactive; + + return; + } + // 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 @@ -269,16 +286,18 @@ so let's do like this: needUpdate = true; } + /*virtual*/ void Arc::PointerReleased(void) { hitHandle1 = hitHandle2 = hitHandle3 = hitHandle4 = false; // Here we check for just a click: If object was clicked and dragged, then // revert to the old state (OSInactive). Otherwise, keep the new state that // we set. -/*Maybe it would be better to just check for "object was dragged" state and not have to worry -about keeping track of old states... -Well, we can't know if it was dragged from Inactive or not, that's the problem. We could make -a variable called "needToRevertToInactive" instead +/* +Maybe it would be better to just check for "object was dragged" state and not +have to worry about keeping track of old states... +Well, we can't know if it was dragged from Inactive or not, that's the problem. +We could make a variable called "needToRevertToInactive" instead I mean, we could write like: if (objectWasDragged && oldState == OSInactive) @@ -290,6 +309,63 @@ but this is actually more compact and cleaner. state = oldState; } + +/*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); + + // 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); + } + + // 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; +} + + #if 0 /*virtual*/ bool Arc::NeedsUpdate(void) { @@ -297,6 +373,7 @@ but this is actually more compact and cleaner. } #endif + /* start = 350, span = 20, end = 10, angle = 5 angle < start, so angle = 365 @@ -316,3 +393,10 @@ bool Arc::AngleInArcSpan(double angle) return (passedInSpan <= angleSpan ? true : false); } + + +/*virtual*/ void Arc::Enumerate(FILE * file) +{ + fprintf(file, "ARC (%lf,%lf) %lf, %lf, %lf\n", position.x, position.y, radius, startAngle, angleSpan); +} +