+ painter.DrawRect(Global::selection);
+ }
+#endif
+}
+
+
+void DrawingView::RenderObjects(Painter * painter, Container * c)
+{
+ std::vector<void *>::iterator i;
+
+ for(i=c->objects.begin(); i!=c->objects.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);
+
+ switch (obj->type)
+ {
+ case OTLine:
+ {
+ Line * l = (Line *)obj;
+ painter->DrawLine(l->p1, l->p2);
+
+ if (l->hitPoint[0])
+ painter->DrawHandle(l->p1);
+
+ if (l->hitPoint[1])
+ painter->DrawHandle(l->p2);
+
+ break;
+ }
+ case OTCircle:
+ {
+ Circle * ci = (Circle *)obj;
+ painter->SetBrush(QBrush(Qt::NoBrush));
+ painter->DrawEllipse(ci->p1, ci->radius, ci->radius);
+ break;
+ }
+ case OTArc:
+ {
+ Arc * a = (Arc *)obj;
+ painter->DrawArc(a->p1, a->radius, a->angle1, a->angle2);
+ break;
+ }
+ case OTDimension:
+ {
+ Dimension * d = (Dimension *)obj;
+
+ Vector v(d->p1, d->p2);
+ double angle = v.Angle();
+ Vector unit = v.Unit();
+ Vector linePt1 = d->p1, linePt2 = d->p2;
+ Vector ortho;
+ double x1, y1, length;
+
+ if (d->subtype == DTLinearVert)
+ {
+ 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);
+ 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);
+ ortho = Vector(-1.0, 0);
+ angle = PI_OVER_2;
+ }
+
+ linePt1.x = linePt2.x = x1;
+ length = fabs(d->p1.y - d->p2.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);
+ 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);
+ ortho = Vector(0, -1.0);
+ angle = PI;
+ }
+
+ linePt1.y = linePt2.y = y1;
+ length = fabs(d->p1.x - d->p2.x);
+ }
+ else if (d->subtype == DTLinear)
+ {
+ angle = Vector(linePt1, linePt2).Angle();
+ ortho = Vector::Normal(linePt1, linePt2);
+ length = v.Magnitude();
+ }
+
+ unit = Vector(linePt1, linePt2).Unit();
+
+ Point p1 = linePt1 + (ortho * 10.0 * scaledThickness);
+ 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);
+
+ /*
+ The numbers hardcoded into here, what are they?
+ I believe they are pixels.
+ */
+ // Draw extension lines (if certain type)
+ painter->DrawLine(p3, p5);
+ painter->DrawLine(p4, p6);
+
+ // Calculate whether or not the arrowheads are too crowded to put inside
+ // the extension lines. 9.0 is the length of the arrowhead.
+ double t = Geometry::ParameterOfLineAndPoint(linePt1, linePt2, linePt2 - (unit * 9.0 * scaledThickness));
+ //printf("Dimension::Draw(): t = %lf\n", t);
+
+ // On the screen, it's acting like this is actually 58%...
+ // This is correct, we want it to happen at > 50%
+ if (t > 0.58)
+ {
+ // Draw main dimension line + arrowheads
+ painter->DrawLine(p1, p2);
+ painter->DrawArrowhead(p1, p2, scaledThickness);
+ painter->DrawArrowhead(p2, p1, scaledThickness);
+ }
+ else
+ {
+ // Draw outside arrowheads
+ Point p7 = p1 - (unit * 9.0 * scaledThickness);
+ Point p8 = p2 + (unit * 9.0 * scaledThickness);
+ painter->DrawArrowhead(p1, p7, scaledThickness);
+ painter->DrawArrowhead(p2, p8, scaledThickness);
+ painter->DrawLine(p1, p1 - (unit * 14.0 * scaledThickness));
+ painter->DrawLine(p2, p2 + (unit * 14.0 * scaledThickness));
+ }
+
+ // Draw length of dimension line...
+ painter->SetFont(QFont("Arial", 8.0 * Global::zoom * scaledThickness));
+ Point ctr = p2 + (Vector(p2, p1) / 2.0);
+
+ #if 0
+ QString dimText = QString("%1\"").arg(Vector(endpoint - position).Magnitude());
+ #else
+ QString dimText;
+
+ if (length < 12.0)
+ dimText = QString("%1\"").arg(length);
+ else
+ {
+ double feet = (double)((int)length / 12);
+ double inches = length - (feet * 12.0);
+
+ if (inches == 0)
+ dimText = QString("%1'").arg(feet);
+ else
+ dimText = QString("%1' %2\"").arg(feet).arg(inches);
+ }
+ #endif
+
+ painter->DrawAngledText(ctr, angle, dimText, scaledThickness);
+
+ break;
+ }
+ case OTText:
+ {
+ Text * t = (Text *)obj;
+ painter->DrawTextObject(t->p1, t->s.c_str(), scaledThickness);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+
+void DrawingView::DeleteSelectedItems(void)
+{
+ std::vector<void *>::iterator i = document.objects.begin();
+
+ while (i != document.objects.end())
+ {
+ Object * obj = (Object *)(*i);
+
+ if (obj->selected)
+ {
+ delete obj;
+ document.objects.erase(i);
+ }
+ else
+ i++;
+ }
+}
+
+
+void DrawingView::ClearSelection(void)
+{
+ std::vector<void *>::iterator i;
+
+ for(i=document.objects.begin(); i!=document.objects.end(); i++)
+ ((Object *)(*i))->selected = false;
+}
+
+
+void DrawingView::AddHoveredToSelection(void)
+{
+ std::vector<void *>::iterator i;
+
+ for(i=document.objects.begin(); i!=document.objects.end(); i++)
+ {
+ if (((Object *)(*i))->hovered)
+ ((Object *)(*i))->selected = true;
+ }
+}
+
+
+void DrawingView::GetSelection(std::vector<void *> & v)
+{
+ v.clear();
+ std::vector<void *>::iterator i;
+
+ for(i=document.objects.begin(); i!=document.objects.end(); i++)
+ {
+ if (((Object *)(*i))->selected)
+ v.push_back(*i);
+ }
+}
+
+
+void DrawingView::GetHovered(std::vector<void *> & v)
+{
+ v.clear();
+ std::vector<void *>::iterator i;
+
+ for(i=document.objects.begin(); i!=document.objects.end(); i++)
+ {
+ if (((Object *)(*i))->hovered)
+// {
+//printf("GetHovered: adding object (%X) to hover... hp1=%s, hp2=%s, hl=%s\n", (*i), (((Line *)(*i))->hitPoint[0] ? "true" : "false"), (((Line *)(*i))->hitPoint[1] ? "true" : "false"), (((Line *)(*i))->hitObject ? "true" : "false"));
+ v.push_back(*i);
+// }
+ }
+}
+
+
+void DrawingView::resizeEvent(QResizeEvent * /*event*/)
+{
+ Global::screenSize = Vector(size().width(), size().height());
+ UpdateGridBackground();
+}
+
+
+void DrawingView::ToolMouse(int mode, Point p)
+{
+ if (Global::tool == TTLine)
+ LineHandler(mode, p);
+}
+
+
+void DrawingView::ToolDraw(Painter * painter)
+{
+ if (Global::tool == TTLine)
+ {
+ if (Global::toolState == TSNone)
+ {
+ painter->DrawHandle(toolPoint[0]);
+ }
+ else if ((Global::toolState == TSPoint2) && shiftDown)
+ {
+ painter->DrawHandle(toolPoint[1]);
+ }
+ else
+ {
+ painter->DrawLine(toolPoint[0], toolPoint[1]);
+ painter->DrawHandle(toolPoint[1]);
+
+ Vector v(toolPoint[0], toolPoint[1]);
+ 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);
+ }
+ }
+}
+
+
+void DrawingView::LineHandler(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
+ {
+ Line * l = new Line(toolPoint[0], toolPoint[1]);
+ document.objects.push_back(l);
+ toolPoint[0] = toolPoint[1];
+ }