X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdrawingview.cpp;h=f3cac0db04a00f44aa71934bfac4e6b21f122165;hb=deb5512a6b35e73dc2c19ac4d2800cff87dd2e71;hp=21c85dd48236cacb7d1cac4904ab5403af51ff77;hpb=e06428cc60e07d9ef33af8b559d60f23894130fb;p=architektonas diff --git a/src/drawingview.cpp b/src/drawingview.cpp index 21c85dd..f3cac0d 100644 --- a/src/drawingview.cpp +++ b/src/drawingview.cpp @@ -35,6 +35,7 @@ #include "mathconstants.h" #include "painter.h" #include "structs.h" +#include "utils.h" #define BACKGROUND_MAX_SIZE 512 @@ -48,7 +49,7 @@ enum { ToolMouseDown, ToolMouseMove, ToolMouseUp }; DrawingView::DrawingView(QWidget * parent/*= NULL*/): QWidget(parent), // The value in the settings file will override this. useAntialiasing(true), numSelected(0), numHovered(0), shiftDown(false), - ctrlDown(false), + ctrlDown(false), overrideColor(false), gridBackground(BACKGROUND_MAX_SIZE, BACKGROUND_MAX_SIZE), scale(1.0), offsetX(-10), offsetY(-10),// document(Vector(0, 0)), gridPixels(0), collided(false)//, toolAction(NULL) @@ -79,8 +80,8 @@ DrawingView::DrawingView(QWidget * parent/*= NULL*/): QWidget(parent), #endif #else Line * line = new Line;//(Vector(5, 5), Vector(50, 40), &document); - line->p1 = Vector(5, 5); - line->p2 = Vector(50, 40); + line->p[0] = Vector(5, 5); + line->p[1] = Vector(50, 40); line->type = OTLine; line->thickness = 2.0; line->style = LSDash; @@ -324,64 +325,60 @@ void DrawingView::paintEvent(QPaintEvent * /*event*/) painter.DrawLine(0, -16384, 0, 16384); painter.DrawLine(-16384, 0, 16384, 0); - // The top level document takes care of rendering for us... -// document.Draw(&painter); - // Not any more it doesn't... - RenderObjects(&painter, &document); + // Do object rendering... + RenderObjects(&painter, document.objects); -#if 0 - if (toolAction) - { - painter.SetPen(QPen(QColor(200, 100, 0, 255), 1.0, Qt::DashLine)); - painter.DrawCrosshair(oldPoint); - toolAction->Draw(&painter); - } -#else + // Do tool rendering, if any... if (Global::tool) { painter.SetPen(QPen(QColor(200, 100, 0, 255), 1.0, Qt::DashLine)); painter.DrawCrosshair(oldPoint); ToolDraw(&painter); } -#endif -#if 1 + // Do selection rectangle rendering, if any if (Global::selectionInProgress) { painter.SetPen(QPen(QColor(255, 127, 0, 255))); painter.SetBrush(QBrush(QColor(255, 127, 0, 100))); painter.DrawRect(Global::selection); } -#endif } -void DrawingView::RenderObjects(Painter * painter, Container * c) +// +// Renders objects in the passed in vector +// +void DrawingView::RenderObjects(Painter * painter, std::vector & v) { std::vector::iterator i; - for(i=c->objects.begin(); i!=c->objects.end(); i++) + for(i=v.begin(); i!=v.end(); i++) { Object * obj = (Object *)(*i); float scaledThickness = Global::scale * obj->thickness; - painter->SetPen(obj->color, Global::zoom * scaledThickness, obj->style); - painter->SetBrush(obj->color); - if (obj->selected || obj->hitObject) - painter->SetPen(0xFF0000, Global::zoom * scaledThickness, LSDash); + if (!overrideColor) + { + painter->SetPen(obj->color, Global::zoom * scaledThickness, obj->style); + painter->SetBrush(obj->color); + + if (obj->selected || obj->hitObject) + painter->SetPen(0xFF0000, Global::zoom * scaledThickness, LSDash); + } switch (obj->type) { case OTLine: { Line * l = (Line *)obj; - painter->DrawLine(l->p1, l->p2); + painter->DrawLine(l->p[0], l->p[1]); if (l->hitPoint[0]) - painter->DrawHandle(l->p1); + painter->DrawHandle(l->p[0]); if (l->hitPoint[1]) - painter->DrawHandle(l->p2); + painter->DrawHandle(l->p[1]); break; } @@ -389,23 +386,23 @@ void DrawingView::RenderObjects(Painter * painter, Container * c) { Circle * ci = (Circle *)obj; painter->SetBrush(QBrush(Qt::NoBrush)); - painter->DrawEllipse(ci->p1, ci->radius, ci->radius); + painter->DrawEllipse(ci->p[0], ci->radius, ci->radius); break; } case OTArc: { Arc * a = (Arc *)obj; - painter->DrawArc(a->p1, a->radius, a->angle1, a->angle2); + painter->DrawArc(a->p[0], a->radius, a->angle1, a->angle2); break; } case OTDimension: { Dimension * d = (Dimension *)obj; - Vector v(d->p1, d->p2); + Vector v(d->p[0], d->p[1]); double angle = v.Angle(); Vector unit = v.Unit(); - Vector linePt1 = d->p1, linePt2 = d->p2; + Vector linePt1 = d->p[0], linePt2 = d->p[1]; Vector ortho; double x1, y1, length; @@ -413,41 +410,41 @@ void DrawingView::RenderObjects(Painter * painter, Container * c) { if ((angle < 0) || (angle > PI)) { - x1 = (d->p1.x > d->p2.x ? d->p1.x : d->p2.x); - y1 = (d->p1.y > d->p2.y ? d->p1.y : d->p2.y); + x1 = (d->p[0].x > d->p[1].x ? d->p[0].x : d->p[1].x); + y1 = (d->p[0].y > d->p[1].y ? d->p[0].y : d->p[1].y); ortho = Vector(1.0, 0); angle = PI3_OVER_2; } else { - x1 = (d->p1.x > d->p2.x ? d->p2.x : d->p1.x); - y1 = (d->p1.y > d->p2.y ? d->p2.y : d->p1.y); + x1 = (d->p[0].x > d->p[1].x ? d->p[1].x : d->p[0].x); + y1 = (d->p[0].y > d->p[1].y ? d->p[1].y : d->p[0].y); ortho = Vector(-1.0, 0); angle = PI_OVER_2; } linePt1.x = linePt2.x = x1; - length = fabs(d->p1.y - d->p2.y); + length = fabs(d->p[0].y - d->p[1].y); } else if (d->subtype == DTLinearHorz) { if ((angle < PI_OVER_2) || (angle > PI3_OVER_2)) { - x1 = (d->p1.x > d->p2.x ? d->p1.x : d->p2.x); - y1 = (d->p1.y > d->p2.y ? d->p1.y : d->p2.y); + x1 = (d->p[0].x > d->p[1].x ? d->p[0].x : d->p[1].x); + y1 = (d->p[0].y > d->p[1].y ? d->p[0].y : d->p[1].y); ortho = Vector(0, 1.0); angle = 0; } else { - x1 = (d->p1.x > d->p2.x ? d->p2.x : d->p1.x); - y1 = (d->p1.y > d->p2.y ? d->p2.y : d->p1.y); + x1 = (d->p[0].x > d->p[1].x ? d->p[1].x : d->p[0].x); + y1 = (d->p[0].y > d->p[1].y ? d->p[1].y : d->p[0].y); ortho = Vector(0, -1.0); angle = PI; } linePt1.y = linePt2.y = y1; - length = fabs(d->p1.x - d->p2.x); + length = fabs(d->p[0].x - d->p[1].x); } else if (d->subtype == DTLinear) { @@ -462,8 +459,8 @@ void DrawingView::RenderObjects(Painter * painter, Container * c) Point p2 = linePt2 + (ortho * 10.0 * scaledThickness); Point p3 = linePt1 + (ortho * 16.0 * scaledThickness); Point p4 = linePt2 + (ortho * 16.0 * scaledThickness); - Point p5 = d->p1 + (ortho * 4.0 * scaledThickness); - Point p6 = d->p2 + (ortho * 4.0 * scaledThickness); + Point p5 = d->p[0] + (ortho * 4.0 * scaledThickness); + Point p6 = d->p[1] + (ortho * 4.0 * scaledThickness); /* The numbers hardcoded into here, what are they? @@ -528,7 +525,7 @@ void DrawingView::RenderObjects(Painter * painter, Container * c) case OTText: { Text * t = (Text *)obj; - painter->DrawTextObject(t->p1, t->s.c_str(), scaledThickness); + painter->DrawTextObject(t->p[0], t->s.c_str(), scaledThickness); break; } default: @@ -618,6 +615,8 @@ void DrawingView::ToolMouse(int mode, Point p) { if (Global::tool == TTLine) LineHandler(mode, p); + else if (Global::tool == TTRotate) + RotateHandler(mode, p); } @@ -646,6 +645,41 @@ void DrawingView::ToolDraw(Painter * painter) painter->DrawInformativeText(text); } } + else if (Global::tool == TTRotate) + { + 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; + + painter->DrawLine(toolPoint[0], 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; + + QString text = QChar(0x2221) + QObject::tr(": %1"); + text = text.arg(absAngle); + + if (ctrlDown) + text += " (Copy)"; + + painter->DrawInformativeText(text); + } + } } @@ -690,6 +724,88 @@ void DrawingView::LineHandler(int mode, Point p) } +void DrawingView::RotateHandler(int mode, Point p) +{ + switch (mode) + { + case ToolMouseDown: + if (Global::toolState == TSNone) + { + toolPoint[0] = p; + toolObjects.clear(); + CopyObjects(select, toolObjects); +// ClearSelected(toolObjects); + Global::toolState = TSPoint1; + } + else if (Global::toolState == TSPoint1) + toolPoint[0] = p; + else + toolPoint[1] = p; + + break; + case ToolMouseMove: +/* +There's two approaches to this that we can do: + + -- Keep a copy of selected objects & rotate those (drawing rotated + selected) + -- Rotate the selected (drawing selected only) + +Either way, we need to have a copy of the points before we change them; we also need +to know whether or not to discard any changes made--maybe with a ToolCleanup() +function. +*/ + if ((Global::toolState == TSPoint1) || (Global::toolState == TSNone)) + toolPoint[0] = p; + else if (Global::toolState == TSPoint2) + { +// need to reset the selected points to their non-rotated state in this case... + if (shiftDown) + return; + + toolPoint[1] = p; + + double angle = Vector(toolPoint[1], toolPoint[0]).Angle(); + std::vector::iterator j = select.begin(); + std::vector::iterator i = toolObjects.begin(); + +// for(; i!=select.end(); i++, j++) + for(; i!=toolObjects.end(); i++, j++) + { + Object * obj = (Object *)(*i); + Point p1 = Geometry::RotatePointAroundPoint(obj->p[0], toolPoint[0], angle); + Point p2 = Geometry::RotatePointAroundPoint(obj->p[1], toolPoint[0], angle); + Object * obj2 = (Object *)(*j); + obj2->p[0] = p1; + obj2->p[1] = p2; + } + } + + 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 + { +#if 0 + Line * l = new Line(toolPoint[0], toolPoint[1]); + document.objects.push_back(l); + toolPoint[0] = toolPoint[1]; +#endif + } + } +} + + void DrawingView::mousePressEvent(QMouseEvent * event) { if (event->button() == Qt::LeftButton) @@ -780,38 +896,9 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event) } // Handle object movement (left button down & over an object) - if ((event->buttons() & Qt::LeftButton) && numHovered) + if ((event->buttons() & Qt::LeftButton) && numHovered && !Global::tool) { - if (Global::snapToGrid) - point = SnapPointToGrid(point); - - Point delta = point - oldPoint; - 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")); - - switch (obj->type) - { - case OTLine: - { - Line * l = (Line *)obj; - - if (l->hitPoint[0]) - l->p1 = point; - else if (l->hitPoint[1]) - l->p2 = point; - else if (l->hitObject) - { - l->p1 += delta; - l->p2 += delta; - } - - break; - } - default: - break; - } - + HandleObjectMovement(point); update(); oldPoint = point; return; @@ -841,29 +928,20 @@ void DrawingView::mouseReleaseEvent(QMouseEvent * event) { if (event->button() == Qt::LeftButton) { -#if 0 - document.PointerReleased(); -#endif - //We need to update especially if nothing collided and the state needs to change. !!! FIX !!! //could set it up to use the document's update function (assumes that all object updates //are being reported correctly: // if (document.NeedsUpdate()) + // 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 0 - if (toolAction) - toolAction->MouseReleased(); -#else if (Global::tool) { Vector point = Painter::QtToCartesianCoords(Vector(event->x(), event->y())); -// ToolMouseUp(point); ToolMouse(ToolMouseUp, point); return; } -#endif if (Global::selectionInProgress) { @@ -1000,7 +1078,7 @@ void DrawingView::CheckObjectBounds(void) { Line * l = (Line *)obj; - if (Global::selection.contains(l->p1.x, l->p1.y) && Global::selection.contains(l->p2.x, l->p2.y)) + if (Global::selection.contains(l->p[0].x, l->p[0].y) && Global::selection.contains(l->p[1].x, l->p[1].y)) l->selected = true; break; @@ -1009,7 +1087,7 @@ void DrawingView::CheckObjectBounds(void) { Circle * c = (Circle *)obj; - if (Global::selection.contains(c->p1.x - c->radius, c->p1.y - c->radius) && Global::selection.contains(c->p1.x + c->radius, c->p1.y + c->radius)) + if (Global::selection.contains(c->p[0].x - c->radius, c->p[0].y - c->radius) && Global::selection.contains(c->p[0].x + c->radius, c->p[0].y + c->radius)) c->selected = true; break; @@ -1072,7 +1150,7 @@ void DrawingView::CheckObjectBounds(void) bounds.setTopLeft(QPointF(bounds.left() * a->radius, bounds.top() * a->radius)); bounds.setBottomRight(QPointF(bounds.right() * a->radius, bounds.bottom() * a->radius)); - bounds.translate(a->p1.x, a->p1.y); + bounds.translate(a->p[0].x, a->p[0].y); if (Global::selection.contains(bounds)) a->selected = true; @@ -1106,10 +1184,10 @@ bool DrawingView::HitTestObjects(Point point) Line * l = (Line *)obj; bool oldHP0 = l->hitPoint[0], oldHP1 = l->hitPoint[1], oldHO = l->hitObject; l->hitPoint[0] = l->hitPoint[1] = l->hitObject = false; - Vector lineSegment = l->p2 - l->p1; - Vector v1 = point - l->p1; - Vector v2 = point - l->p2; - double t = Geometry::ParameterOfLineAndPoint(l->p1, l->p2, point); + Vector lineSegment = l->p[1] - l->p[0]; + Vector v1 = point - l->p[0]; + Vector v2 = point - l->p[1]; + double t = Geometry::ParameterOfLineAndPoint(l->p[0], l->p[1], point); double distance; if (t < 0.0) @@ -1168,6 +1246,41 @@ bool DrawingView::HitTestObjects(Point point) } +void DrawingView::HandleObjectMovement(Point point) +{ + if (Global::snapToGrid) + point = SnapPointToGrid(point); + + Point delta = point - oldPoint; + 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")); + + switch (obj->type) + { + case OTLine: + { + Line * l = (Line *)obj; + + if (l->hitPoint[0]) + l->p[0] = point; + else if (l->hitPoint[1]) + l->p[1] = point; + else if (l->hitObject) + { + l->p[0] += delta; + l->p[1] += delta; + } + + break; + } + default: + break; + } +} + + + #if 0 // This returns true if we've moved over an object... if (document.PointerMoved(point)) // <-- This