X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=src%2Fdrawingview.cpp;h=8c581bfc1df8e904ccb41bd2b724b26b3c3ae7d5;hb=4a979ddae8aa6b3556f24e8b961f7787c4b40cbe;hp=9e1b56c784e02698733c85cd205c1bc913db372f;hpb=84fc4387b9a6051819da5c9ed688de1ec372c7f7;p=architektonas diff --git a/src/drawingview.cpp b/src/drawingview.cpp index 9e1b56c..8c581bf 100644 --- a/src/drawingview.cpp +++ b/src/drawingview.cpp @@ -376,6 +376,16 @@ void DrawingView::RenderObjects(Painter * painter, std::vector & v) break; case OTArc: painter->DrawArc(obj->p[0], obj->radius[0], obj->angle[0], obj->angle[1]); + + if (obj->hitPoint[0]) + painter->DrawHandle(obj->p[0]); + + if (obj->hitPoint[1]) + painter->DrawHandle(obj->p[0] + (Vector(cos(obj->angle[0]), sin(obj->angle[0])) * obj->radius[0])); + + if (obj->hitPoint[2]) + painter->DrawHandle(obj->p[0] + (Vector(cos(obj->angle[0] + obj->angle[1]), sin(obj->angle[0] + obj->angle[1])) * obj->radius[0])); + break; case OTDimension: { @@ -575,6 +585,8 @@ void DrawingView::ToolHandler(int mode, Point p) ArcHandler(mode, p); else if (Global::tool == TTRotate) RotateHandler(mode, p); + else if (Global::tool == TTMirror) + MirrorHandler(mode, p); } @@ -677,7 +689,7 @@ void DrawingView::ToolDraw(Painter * painter) { if (toolPoint[0] == toolPoint[1]) return; - + painter->DrawLine(toolPoint[0], toolPoint[1]); // Likely we need a tool container for this... (now we do!) #if 0 @@ -692,14 +704,49 @@ void DrawingView::ToolDraw(Painter * painter) #endif double absAngle = (Vector(toolPoint[1] - toolPoint[0]).Angle()) * RADIANS_TO_DEGREES; - QString text = QChar(0x2221) + QObject::tr(": %1"); informativeText = text.arg(absAngle); if (ctrlDown) informativeText += " (Copy)"; + } + } + else if (Global::tool == TTMirror) + { + if ((Global::toolState == TSNone) || (Global::toolState == TSPoint1)) + painter->DrawHandle(toolPoint[0]); + else if ((Global::toolState == TSPoint2) && shiftDown) + painter->DrawHandle(toolPoint[1]); + else + { + if (toolPoint[0] == toolPoint[1]) + return; + + Point mirrorPoint = toolPoint[0] + Vector(toolPoint[1], toolPoint[0]); +// painter->DrawLine(toolPoint[0], toolPoint[1]); + painter->DrawLine(mirrorPoint, toolPoint[1]); + // Likely we need a tool container for this... (now we do!) +#if 0 + if (ctrlDown) + { + painter->SetPen(0x00FF00, 2.0, LSSolid); + overrideColor = true; + } + + RenderObjects(painter, toolObjects); + overrideColor = false; +#endif + + double absAngle = (Vector(toolPoint[1] - toolPoint[0]).Angle()) * RADIANS_TO_DEGREES; -// painter->DrawInformativeText(text); + if (absAngle > 180.0) + absAngle -= 180.0; + + QString text = QChar(0x2221) + QObject::tr(": %1"); + informativeText = text.arg(absAngle); + + if (ctrlDown) + informativeText += " (Copy)"; } } } @@ -960,6 +1007,109 @@ void DrawingView::RotateHandler(int mode, Point p) } +void DrawingView::MirrorHandler(int mode, Point p) +{ + switch (mode) + { + case ToolMouseDown: + if (Global::toolState == TSNone) + { + toolPoint[0] = p; + SavePointsFrom(select, toolScratch); + Global::toolState = TSPoint1; + } + else if (Global::toolState == TSPoint1) + toolPoint[0] = p; + else + toolPoint[1] = p; + + break; + case ToolMouseMove: + if ((Global::toolState == TSPoint1) || (Global::toolState == TSNone)) + toolPoint[0] = p; + else if (Global::toolState == TSPoint2) + { + toolPoint[1] = p; + + if (shiftDown) + return; + + double angle = Vector(toolPoint[0], toolPoint[1]).Angle(); + std::vector::iterator j = select.begin(); + std::vector::iterator i = toolScratch.begin(); + + for(; i!=toolScratch.end(); i++, j++) + { + Object obj = *i; + Point p1 = Geometry::MirrorPointAroundLine(obj.p[0], toolPoint[0], toolPoint[1]); + Point p2 = Geometry::MirrorPointAroundLine(obj.p[1], toolPoint[0], toolPoint[1]); + Object * obj2 = (Object *)(*j); + obj2->p[0] = p1; + obj2->p[1] = p2; + + if (obj.type == OTArc) + { + // This is 2*mirror angle - obj angle - obj span + obj2->angle[0] = (2.0 * angle) - obj.angle[0] - obj.angle[1]; + + if (obj2->angle[0] > PI_TIMES_2) + obj2->angle[0] -= PI_TIMES_2; + } + } + } + + break; + case ToolMouseUp: + if (Global::toolState == TSPoint1) + { + Global::toolState = TSPoint2; + // Prevent spurious line from drawing... + toolPoint[1] = toolPoint[0]; + } + else if ((Global::toolState == TSPoint2) && shiftDown) + { + // Key override is telling us to make a new line, not continue the + // previous one. + toolPoint[0] = toolPoint[1]; + } + else + { + // Either we're finished with our rotate, or we're stamping a copy. + if (ctrlDown) + { + // Stamp a copy of the selection at the current rotation & bail + std::vector temp; + CopyObjects(select, temp); + ClearSelected(temp); + AddObjectsTo(document.objects, temp); + RestorePointsTo(select, toolScratch); + return; + } + + toolPoint[0] = p; + Global::toolState = TSPoint1; + SavePointsFrom(select, toolScratch); + } + + break; + case ToolKeyDown: + // Reset the selection if shift held down... + if (shiftDown) + RestorePointsTo(select, toolScratch); + + break; + case ToolKeyUp: + // Reset selection when key is let up + if (!shiftDown) + MirrorHandler(ToolMouseMove, toolPoint[1]); + + break; + case ToolCleanup: + RestorePointsTo(select, toolScratch); + } +} + + void DrawingView::mousePressEvent(QMouseEvent * event) { if (event->button() == Qt::LeftButton) @@ -1066,6 +1216,21 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event) // Do object hit testing... bool needUpdate = HitTestObjects(point); + // Check for multi-hover... + if (numHovered > 1) + { + GetHovered(hover); + + double t, u; + int numIntersecting = Geometry::Intersects((Object *)hover[0], (Object *)hover[1], &t, &u); + + if (numIntersecting > 0) + { + QString text = tr("Intersection t=%1, u=%2"); + informativeText = text.arg(t).arg(u); + } + } + // Do tool handling, if any are active... if (Global::tool) { @@ -1391,8 +1556,8 @@ bool DrawingView::HitTestObjects(Point point) } case OTArc: { - bool oldHP = obj->hitPoint[0], oldHO = obj->hitObject; - obj->hitPoint[0] = obj->hitObject = false; + bool oldHP0 = obj->hitPoint[0], oldHP1 = obj->hitPoint[1], oldHP2 = obj->hitPoint[2], oldHO = obj->hitObject; + obj->hitPoint[0] = obj->hitPoint[1] = obj->hitPoint[2] = obj->hitObject = false; double length = Vector::Magnitude(obj->p[0], point); double angle = Vector::Angle(obj->p[0], point); @@ -1404,15 +1569,24 @@ bool DrawingView::HitTestObjects(Point point) double span = angle - obj->angle[0]; // N.B.: Still need to hit test the arc start & arc span handles... + double spanAngle = obj->angle[0] + obj->angle[1]; + Point handle1 = obj->p[0] + (Vector(cos(obj->angle[0]), sin(obj->angle[0])) * obj->radius[0]); + Point handle2 = obj->p[0] + (Vector(cos(spanAngle), sin(spanAngle)) * obj->radius[0]); + double length2 = Vector::Magnitude(point, handle1); + double length3 = Vector::Magnitude(point, handle2); if ((length * Global::zoom) < 8.0) obj->hitPoint[0] = true; + else if ((length2 * Global::zoom) < 8.0) + obj->hitPoint[1] = true; + else if ((length3 * Global::zoom) < 8.0) + obj->hitPoint[2] = true; else if (((fabs(length - obj->radius[0]) * Global::zoom) < 2.0) && (span < obj->angle[1])) obj->hitObject = true; - obj->hovered = (obj->hitPoint[0] || obj->hitObject ? true : false); + obj->hovered = (obj->hitPoint[0] || obj->hitPoint[1] || obj->hitPoint[2] || obj->hitObject ? true : false); - if ((oldHP != obj->hitPoint[0]) || (oldHO != obj->hitObject)) + if ((oldHP0 != obj->hitPoint[0]) || (oldHP1 != obj->hitPoint[1]) || (oldHP2 != obj->hitPoint[2]) || (oldHO != obj->hitObject)) needUpdate = true; break; @@ -1467,6 +1641,74 @@ void DrawingView::HandleObjectMovement(Point point) informativeText = text.arg(obj->radius[0], 0, 'd', 4);//.arg(obj->radius[0] / oldRadius * 100.0, 0, 'd', 0); } + break; + case OTArc: + if (obj->hitPoint[0]) + obj->p[0] = point; + else if (obj->hitPoint[1]) + { + // Change the Arc's span (handle #1) + if (shiftDown) + { + double angle = Vector::Angle(obj->p[0], point); + double delta = angle - obj->angle[0]; + + if (delta < 0) + delta += PI_TIMES_2; + + obj->angle[1] -= delta; + obj->angle[0] = angle; + + if (obj->angle[1] < 0) + obj->angle[1] += PI_TIMES_2; + + QString text = QObject::tr("Span: %1") + QChar(0x00B0) + QObject::tr("\n%2") + QChar(0x00B0) + QObject::tr(" - %3") + QChar(0x00B0); + informativeText = text.arg(obj->angle[1] * RADIANS_TO_DEGREES, 0, 'd', 4).arg(obj->angle[0] * RADIANS_TO_DEGREES, 0, 'd', 2).arg((obj->angle[0] + obj->angle[1]) * RADIANS_TO_DEGREES, 0, 'd', 2); + return; + } + + double angle = Vector::Angle(obj->p[0], point); + obj->angle[0] = angle; + QString text = QObject::tr("Start angle: %1") + QChar(0x00B0); + informativeText = text.arg(obj->angle[0] * RADIANS_TO_DEGREES, 0, 'd', 4); + } + else if (obj->hitPoint[2]) + { + // Change the Arc's span (handle #2) + if (shiftDown) + { + double angle = Vector::Angle(obj->p[0], point); + obj->angle[1] = angle - obj->angle[0]; + + if (obj->angle[1] < 0) + obj->angle[1] += PI_TIMES_2; + + QString text = QObject::tr("Span: %1") + QChar(0x00B0) + QObject::tr("\n%2") + QChar(0x00B0) + QObject::tr(" - %3") + QChar(0x00B0); + informativeText = text.arg(obj->angle[1] * RADIANS_TO_DEGREES, 0, 'd', 4).arg(obj->angle[0] * RADIANS_TO_DEGREES, 0, 'd', 2).arg((obj->angle[0] + obj->angle[1]) * RADIANS_TO_DEGREES, 0, 'd', 2); + return; + } + + double angle = Vector::Angle(obj->p[0], point); + obj->angle[0] = angle - obj->angle[1]; + + if (obj->angle[0] < 0) + obj->angle[0] += PI_TIMES_2; + + QString text = QObject::tr("End angle: %1") + QChar(0x00B0); + informativeText = text.arg((obj->angle[0] + obj->angle[1]) * RADIANS_TO_DEGREES, 0, 'd', 4); + } + else if (obj->hitObject) + { + if (shiftDown) + { + return; + } + + obj->radius[0] = Vector::Magnitude(obj->p[0], point); + QString text = QObject::tr("Radius: %1"); + informativeText = text.arg(obj->radius[0], 0, 'd', 4); + } + break; default: break;