]> Shamusworld >> Repos - architektonas/blobdiff - src/drawingview.cpp
Add ability to add Arcs to document.
[architektonas] / src / drawingview.cpp
index 15579c9ab7dd5a8ef6790e408652fdc22b58dd00..9e1b56c784e02698733c85cd205c1bc913db372f 100644 (file)
@@ -323,6 +323,9 @@ void DrawingView::paintEvent(QPaintEvent * /*event*/)
                painter.SetBrush(QBrush(QColor(255, 127, 0, 100)));
                painter.DrawRect(Global::selection);
        }
+
+       if (!informativeText.isEmpty())
+               painter.DrawInformativeText(informativeText);
 }
 
 
@@ -566,6 +569,10 @@ void DrawingView::ToolHandler(int mode, Point p)
 {
        if (Global::tool == TTLine)
                LineHandler(mode, p);
+       else if (Global::tool == TTCircle)
+               CircleHandler(mode, p);
+       else if (Global::tool == TTArc)
+               ArcHandler(mode, p);
        else if (Global::tool == TTRotate)
                RotateHandler(mode, p);
 }
@@ -592,8 +599,72 @@ void DrawingView::ToolDraw(Painter * painter)
                        double absAngle = v.Angle() * RADIANS_TO_DEGREES;
                        double absLength = v.Magnitude();
                        QString text = tr("Length: %1 in.\n") + QChar(0x2221) + tr(": %2");
-                       text = text.arg(absLength).arg(absAngle);
-                       painter->DrawInformativeText(text);
+                       informativeText = text.arg(absLength).arg(absAngle);
+               }
+       }
+       else if (Global::tool == TTCircle)
+       {
+               if (Global::toolState == TSNone)
+               {
+                       painter->DrawHandle(toolPoint[0]);
+               }
+               else if ((Global::toolState == TSPoint2) && shiftDown)
+               {
+                       painter->DrawHandle(toolPoint[1]);
+               }
+               else
+               {
+                       double length = Vector::Magnitude(toolPoint[0], toolPoint[1]);
+//                     painter->DrawLine(toolPoint[0], toolPoint[1]);
+//                     painter->DrawHandle(toolPoint[1]);
+                       painter->SetBrush(QBrush(Qt::NoBrush));
+                       painter->DrawEllipse(toolPoint[0], length, length);
+                       QString text = tr("Radius: %1 in.");//\n") + QChar(0x2221) + tr(": %2");
+                       informativeText = text.arg(length);//.arg(absAngle);
+               }
+       }
+       else if (Global::tool == TTArc)
+       {
+               if (Global::toolState == TSNone)
+               {
+                       painter->DrawHandle(toolPoint[0]);
+               }
+               else if (Global::toolState == TSPoint2)
+               {
+                       double length = Vector::Magnitude(toolPoint[0], toolPoint[1]);
+                       painter->SetBrush(QBrush(Qt::NoBrush));
+                       painter->DrawEllipse(toolPoint[0], length, length);
+                       painter->DrawLine(toolPoint[0], toolPoint[1]);
+                       painter->DrawHandle(toolPoint[1]);
+                       QString text = tr("Radius: %1 in.");
+                       informativeText = text.arg(length);
+               }
+               else if (Global::toolState == TSPoint3)
+               {
+                       double angle = Vector::Angle(toolPoint[0], toolPoint[2]);
+                       painter->DrawLine(toolPoint[0], toolPoint[2]);
+                       painter->SetBrush(QBrush(Qt::NoBrush));
+                       painter->DrawEllipse(toolPoint[0], toolPoint[1].x, toolPoint[1].x);
+                       painter->DrawHandle(toolPoint[0] + (Vector(cos(angle), sin(angle)) * toolPoint[1].x));
+                       QString text = tr("Angle start: %1") + QChar(0x00B0);
+                       informativeText = text.arg(RADIANS_TO_DEGREES * angle);
+               }
+               else
+               {
+                       double angle = Vector::Angle(toolPoint[0], toolPoint[3]);
+                       double span = angle - toolPoint[2].x;
+
+                       if (span < 0)
+                               span += PI_TIMES_2;
+
+                       painter->DrawLine(toolPoint[0], toolPoint[3]);
+                       painter->SetBrush(QBrush(Qt::NoBrush));
+                       painter->DrawEllipse(toolPoint[0], toolPoint[1].x, toolPoint[1].x);
+                       painter->SetPen(0xFF00FF, 2.0, LSSolid);
+                       painter->DrawArc(toolPoint[0], toolPoint[1].x, toolPoint[2].x, span);
+                       painter->DrawHandle(toolPoint[0] + (Vector(cos(angle), sin(angle)) * toolPoint[1].x));
+                       QString text = tr("Arc span: %1") + QChar(0x00B0);
+                       informativeText = text.arg(RADIANS_TO_DEGREES * span);
                }
        }
        else if (Global::tool == TTRotate)
@@ -623,12 +694,12 @@ void DrawingView::ToolDraw(Painter * painter)
                        double absAngle = (Vector(toolPoint[1] - toolPoint[0]).Angle()) * RADIANS_TO_DEGREES;
 
                        QString text = QChar(0x2221) + QObject::tr(": %1");
-                       text = text.arg(absAngle);
+                       informativeText = text.arg(absAngle);
 
                        if (ctrlDown)
-                               text += " (Copy)";
+                               informativeText += " (Copy)";
 
-                       painter->DrawInformativeText(text);
+//                     painter->DrawInformativeText(text);
                }
        }
 }
@@ -675,6 +746,118 @@ void DrawingView::LineHandler(int mode, Point p)
 }
 
 
+void DrawingView::CircleHandler(int mode, Point p)
+{
+       switch (mode)
+       {
+       case ToolMouseDown:
+               if (Global::toolState == TSNone)
+                       toolPoint[0] = p;
+               else
+                       toolPoint[1] = p;
+
+               break;
+       case ToolMouseMove:
+               if (Global::toolState == TSNone)
+                       toolPoint[0] = p;
+               else
+                       toolPoint[1] = p;
+
+               break;
+       case ToolMouseUp:
+               if (Global::toolState == TSNone)
+               {
+                       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
+               {
+                       double length = Vector::Magnitude(toolPoint[0], toolPoint[1]);
+                       Circle * c = new Circle(toolPoint[0], length);
+                       document.objects.push_back(c);
+                       toolPoint[0] = toolPoint[1];
+                       Global::toolState = TSNone;
+               }
+       }
+}
+
+
+void DrawingView::ArcHandler(int mode, Point p)
+{
+       switch (mode)
+       {
+       case ToolMouseDown:
+               if (Global::toolState == TSNone)
+                       toolPoint[0] = p;
+               else if (Global::toolState == TSPoint2)
+                       toolPoint[1] = p;
+               else if (Global::toolState == TSPoint3)
+                       toolPoint[2] = p;
+               else
+                       toolPoint[3] = p;
+
+               break;
+       case ToolMouseMove:
+               if (Global::toolState == TSNone)
+                       toolPoint[0] = p;
+               else if (Global::toolState == TSPoint2)
+                       toolPoint[1] = p;
+               else if (Global::toolState == TSPoint3)
+                       toolPoint[2] = p;
+               else
+                       toolPoint[3] = p;
+
+               break;
+       case ToolMouseUp:
+               if (Global::toolState == TSNone)
+               {
+                       // Prevent spurious line from drawing...
+                       toolPoint[1] = toolPoint[0];
+                       Global::toolState = TSPoint2;
+               }
+               else if (Global::toolState == TSPoint2)
+               {
+                       if (shiftDown)
+                       {
+                               // Key override is telling us to start circle at new center, not
+                               // continue the current one.
+                               toolPoint[0] = toolPoint[1];
+                               return;
+                       }
+
+                       // Set the radius in toolPoint[1].x
+                       toolPoint[1].x = Vector::Magnitude(toolPoint[0], toolPoint[1]);
+                       Global::toolState = TSPoint3;
+               }
+               else if (Global::toolState == TSPoint3)
+               {
+                       // Set the angle in toolPoint[2].x
+                       toolPoint[2].x = Vector::Angle(toolPoint[0], toolPoint[2]);
+                       Global::toolState = TSPoint4;
+               }
+               else
+               {
+                       double endAngle = Vector::Angle(toolPoint[0], toolPoint[3]);
+                       double span = endAngle - toolPoint[2].x;
+
+                       if (span < 0)
+                               span += PI_TIMES_2;
+
+                       Arc * arc = new Arc(toolPoint[0], toolPoint[1].x, toolPoint[2].x, span);
+                       document.objects.push_back(arc);
+                       Global::toolState = TSNone;
+               }
+       }
+}
+
+
 void DrawingView::RotateHandler(int mode, Point p)
 {
        switch (mode)
@@ -717,7 +900,6 @@ void DrawingView::RotateHandler(int mode, Point p)
 
                                if (obj.type == OTArc)
                                {
-//printf("Obj2->angle[0] = %f, obj.angle[0] = %f, angle = %f\n", obj2->angle[0], obj.angle[0], angle);
                                        obj2->angle[0] = obj.angle[0] + angle;
 
                                        if (obj2->angle[0] > PI_TIMES_2)
@@ -814,6 +996,7 @@ void DrawingView::mousePressEvent(QMouseEvent * event)
                        GetHovered(hover);      // prolly needed
 
                        // Needed for grab & moving objects
+                       // We do it *after*... why? (doesn't seem to confer any advantage...)
                        if (Global::snapToGrid)
                                oldPoint = SnapPointToGrid(point);
 
@@ -871,6 +1054,9 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event)
        // Handle object movement (left button down & over an object)
        if ((event->buttons() & Qt::LeftButton) && numHovered && !Global::tool)
        {
+               if (Global::snapToGrid)
+                       point = SnapPointToGrid(point);
+
                HandleObjectMovement(point);
                update();
                oldPoint = point;
@@ -919,7 +1105,8 @@ void DrawingView::mouseReleaseEvent(QMouseEvent * event)
                if (Global::selectionInProgress)
                        Global::selectionInProgress = false;
 
-// Should be we do this automagically? Hmm...
+               informativeText.clear();
+// Should we be doing this automagically? Hmm...
                // Clear our vectors
                select.clear();
                hover.clear();
@@ -933,9 +1120,8 @@ void DrawingView::mouseReleaseEvent(QMouseEvent * event)
                                select.push_back(*i);
 
 //hmm, this is no good, too late to do any good :-P
-//                             if ((*i)->hovered)
-//                                     hover.push_back(*i);
-//                     }
+//                     if ((*i)->hovered)
+//                             hover.push_back(*i);
                }
        }
        else if (event->button() == Qt::MiddleButton)
@@ -967,13 +1153,11 @@ void DrawingView::wheelEvent(QWheelEvent * event)
                Global::zoom /= zoomFactor;
        }
 
-#if 1
 //     Global::gridSpacing = gridPixels / Painter::zoom;
 //     UpdateGridBackground();
        SetGridSize(Global::gridSpacing * Global::zoom);
        update();
 //     zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Global::gridSpacing));
-#endif
 }
 
 
@@ -1016,6 +1200,7 @@ void DrawingView::keyReleaseEvent(QKeyEvent * event)
        }
 }
 
+
 //
 // 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
@@ -1204,6 +1389,34 @@ bool DrawingView::HitTestObjects(Point point)
 
                        break;
                }
+               case OTArc:
+               {
+                       bool oldHP = obj->hitPoint[0], oldHO = obj->hitObject;
+                       obj->hitPoint[0] = obj->hitObject = false;
+                       double length = Vector::Magnitude(obj->p[0], point);
+                       double angle = Vector::Angle(obj->p[0], point);
+
+                       // Make sure we get the angle in the correct spot
+                       if (angle < obj->angle[0])
+                               angle += PI_TIMES_2;
+
+                       // Get the span that we're pointing at...
+                       double span = angle - obj->angle[0];
+
+                       // N.B.: Still need to hit test the arc start & arc span handles...
+
+                       if ((length * Global::zoom) < 8.0)
+                               obj->hitPoint[0] = 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);
+
+                       if ((oldHP != obj->hitPoint[0]) || (oldHO != obj->hitObject))
+                               needUpdate = true;
+
+                       break;
+               }
                default:
                        break;
                }
@@ -1221,10 +1434,8 @@ bool DrawingView::HitTestObjects(Point point)
 
 void DrawingView::HandleObjectMovement(Point point)
 {
-       if (Global::snapToGrid)
-               point = SnapPointToGrid(point);
-
        Point delta = point - oldPoint;
+//printf("HOM: old = (%f,%f), new = (%f, %f), delta = (%f, %f)\n", oldPoint.x, oldPoint.y, point.x, point.y, delta.x, delta.y);
        Object * obj = (Object *)hover[0];
 //printf("Object type = %i (size=%i), ", obj->type, hover.size());
 //printf("Object (%X) move: hp1=%s, hp2=%s, hl=%s\n", obj, (obj->hitPoint[0] ? "true" : "false"), (obj->hitPoint[1] ? "true" : "false"), (obj->hitObject ? "true" : "false"));
@@ -1232,9 +1443,6 @@ void DrawingView::HandleObjectMovement(Point point)
        switch (obj->type)
        {
        case OTLine:
-       {
-//             Line * l = (Line *)obj;
-
                if (obj->hitPoint[0])
                        obj->p[0] = point;
                else if (obj->hitPoint[1])
@@ -1246,7 +1454,20 @@ void DrawingView::HandleObjectMovement(Point point)
                }
 
                break;
-       }
+       case OTCircle:
+               if (obj->hitPoint[0])
+                       obj->p[0] = point;
+               else if (obj->hitObject)
+               {
+//this doesn't work. we need to save this on mouse down for this to work correctly!
+//                     double oldRadius = obj->radius[0];
+                       obj->radius[0] = Vector::Magnitude(obj->p[0], point);
+
+                       QString text = QObject::tr("Radius: %1");//\nScale: %2%");
+                       informativeText = text.arg(obj->radius[0], 0, 'd', 4);//.arg(obj->radius[0] / oldRadius * 100.0, 0, 'd', 0);
+               }
+
+               break;
        default:
                break;
        }