]> Shamusworld >> Repos - architektonas/blobdiff - src/drawingview.cpp
Added miscellaneous features.
[architektonas] / src / drawingview.cpp
index 943a9b9f4cd9edb088df0a5d8a75a9824512d4cd..f50fca562d11ce438a51c61d70ef16e689ba92e1 100644 (file)
@@ -45,7 +45,7 @@
 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), altDown(false),
        gridBackground(BACKGROUND_MAX_SIZE, BACKGROUND_MAX_SIZE),
        scale(1.0), offsetX(-10), offsetY(-10), document(true),
        gridPixels(0), collided(false), hoveringIntersection(false),
@@ -311,6 +311,42 @@ void DrawingView::HandleLayerSwap(int layer1, int layer2)
 }
 
 
+void DrawingView::HandlePenWidth(float width)
+{
+       std::vector<void *>::iterator i = select.begin();
+
+       for(; i!=select.end(); i++)
+       {
+               Object * obj = (Object *)(*i);
+               obj->thickness = width;
+       }
+}
+
+
+void DrawingView::HandlePenStyle(int style)
+{
+       std::vector<void *>::iterator i = select.begin();
+
+       for(; i!=select.end(); i++)
+       {
+               Object * obj = (Object *)(*i);
+               obj->style = style;
+       }
+}
+
+
+void DrawingView::HandlePenColor(uint32_t color)
+{
+       std::vector<void *>::iterator i = select.begin();
+
+       for(; i!=select.end(); i++)
+       {
+               Object * obj = (Object *)(*i);
+               obj->color = color;
+       }
+}
+
+
 QPoint DrawingView::GetAdjustedMousePosition(QMouseEvent * event)
 {
        // This is undoing the transform, e.g. going from client coords to local
@@ -607,7 +643,14 @@ void DrawingView::RenderObjects(Painter * painter, std::vector<void *> & v, int
                case OTText:
                {
                        Text * t = (Text *)obj;
-                       painter->DrawTextObject(t->p[0], t->s.c_str(), scaledThickness);
+
+                       if (t->measured == false)
+                       {
+                               t->extents = painter->MeasureTextObject(t->s.c_str(), scaledThickness);
+                               t->measured = true;
+                       }
+
+                       painter->DrawTextObject(t->p[0], t->s.c_str(), scaledThickness, t->angle[0]);
                        break;
                }
                case OTSpline:
@@ -704,6 +747,8 @@ void DrawingView::ToolHandler(int mode, Point p)
                RotateHandler(mode, p);
        else if (Global::tool == TTMirror)
                MirrorHandler(mode, p);
+       else if (Global::tool == TTDimension)
+               DimensionHandler(mode, p);
 }
 
 
@@ -826,7 +871,7 @@ void DrawingView::ToolDraw(Painter * painter)
                {
                        if (toolPoint[0] == toolPoint[1])
                                return;
-                       
+
                        Point mirrorPoint = toolPoint[0] + Vector(toolPoint[1], toolPoint[0]);
                        painter->DrawLine(mirrorPoint, toolPoint[1]);
 
@@ -842,6 +887,28 @@ void DrawingView::ToolDraw(Painter * painter)
                                informativeText += " (Copy)";
                }
        }
+       if (Global::tool == TTDimension)
+       {
+               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");
+                       informativeText = text.arg(absLength).arg(absAngle);
+               }
+       }
 }
 
 
@@ -878,7 +945,7 @@ void DrawingView::LineHandler(int mode, Point p)
                }
                else
                {
-                       Line * l = new Line(toolPoint[0], toolPoint[1]);
+                       Line * l = new Line(toolPoint[0], toolPoint[1], Global::penWidth, Global::penColor, Global::penStyle);
                        l->layer = Global::activeLayer;
                        document.objects.push_back(l);
                        toolPoint[0] = toolPoint[1];
@@ -921,7 +988,7 @@ void DrawingView::CircleHandler(int mode, Point p)
                else
                {
                        double length = Vector::Magnitude(toolPoint[0], toolPoint[1]);
-                       Circle * c = new Circle(toolPoint[0], length);
+                       Circle * c = new Circle(toolPoint[0], length, Global::penWidth, Global::penColor, Global::penStyle);
                        c->layer = Global::activeLayer;
                        document.objects.push_back(c);
                        toolPoint[0] = toolPoint[1];
@@ -998,7 +1065,7 @@ void DrawingView::ArcHandler(int mode, Point p)
                        if (span < 0)
                                span += TAU;
 
-                       Arc * arc = new Arc(toolPoint[0], toolPoint[1].x, toolPoint[2].x, span);
+                       Arc * arc = new Arc(toolPoint[0], toolPoint[1].x, toolPoint[2].x, span, Global::penWidth, Global::penColor, Global::penStyle);
                        arc->layer = Global::activeLayer;
                        document.objects.push_back(arc);
                        Global::toolState = TSNone;
@@ -1214,6 +1281,48 @@ void DrawingView::MirrorHandler(int mode, Point p)
 }
 
 
+void DrawingView::DimensionHandler(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
+               {
+                       Dimension * d = new Dimension(toolPoint[0], toolPoint[1], DTLinear);
+                       d->layer = Global::activeLayer;
+                       document.objects.push_back(d);
+                       Global::toolState = TSNone;
+               }
+       }
+}
+
+
 void DrawingView::mousePressEvent(QMouseEvent * event)
 {
        if (event->button() == Qt::LeftButton)
@@ -1253,6 +1362,9 @@ void DrawingView::mousePressEvent(QMouseEvent * event)
                        dragged = (Object *)hover[0];
                        draggingObject = true;
 
+                       // Alert the pen widget
+                       emit(ObjectSelected(dragged));
+
                        // See if anything is using just a straight click on a handle
                        if (HandleObjectClicked())
                        {
@@ -1293,9 +1405,10 @@ void DrawingView::mouseMoveEvent(QMouseEvent * event)
        // Only needs to be done here, as mouse down is always preceded by movement
        Global::snapPointIsValid = false;
        hoveringIntersection = false;
+       oldScrollPoint = Vector(event->x(), event->y());
 
        // Scrolling...
-       if (event->buttons() & Qt::MiddleButton)
+       if ((event->buttons() & Qt::MiddleButton) || scrollDrag)
        {
                point = Vector(event->x(), event->y());
                // Since we're using Qt coords for scrolling, we have to adjust them
@@ -1490,11 +1603,14 @@ void DrawingView::keyPressEvent(QKeyEvent * event)
 {
        bool oldShift = shiftDown;
        bool oldCtrl = ctrlDown;
+       bool oldAlt = altDown;
 
        if (event->key() == Qt::Key_Shift)
                shiftDown = true;
        else if (event->key() == Qt::Key_Control)
                ctrlDown = true;
+       else if (event->key() == Qt::Key_Alt)
+               altDown = true;
 
        if ((oldShift != shiftDown) || (oldCtrl != ctrlDown))
        {
@@ -1504,6 +1620,14 @@ void DrawingView::keyPressEvent(QKeyEvent * event)
                update();
        }
 
+       if (oldAlt != altDown)
+       {
+               scrollDrag = true;
+               setCursor(Qt::SizeAllCursor);
+//             oldPoint = Vector();
+               oldPoint = oldScrollPoint;
+       }
+
        if (select.size() > 0)
        {
                if (event->key() == Qt::Key_Up)
@@ -1534,11 +1658,14 @@ void DrawingView::keyReleaseEvent(QKeyEvent * event)
 {
        bool oldShift = shiftDown;
        bool oldCtrl = ctrlDown;
+       bool oldAlt = altDown;
 
        if (event->key() == Qt::Key_Shift)
                shiftDown = false;
        else if (event->key() == Qt::Key_Control)
                ctrlDown = false;
+       else if (event->key() == Qt::Key_Alt)
+               altDown = false;
 
        if ((oldShift != shiftDown) || (oldCtrl != ctrlDown))
        {
@@ -1547,6 +1674,12 @@ void DrawingView::keyReleaseEvent(QKeyEvent * event)
 
                update();
        }
+
+       if (oldAlt != altDown)
+       {
+               scrollDrag = false;
+               setCursor(Qt::ArrowCursor);
+       }
 }
 
 
@@ -1596,16 +1729,19 @@ Rect DrawingView::GetObjectExtents(Object * obj)
        switch (obj->type)
        {
        case OTLine:
+       case OTDimension:
        {
                rect = Rect(obj->p[0], obj->p[1]);
                break;
        }
+
        case OTCircle:
        {
                rect = Rect(obj->p[0], obj->p[0]);
                rect.Expand(obj->radius[0]);
                break;
        }
+
        case OTArc:
        {
                Arc * a = (Arc *)obj;
@@ -1642,9 +1778,16 @@ Rect DrawingView::GetObjectExtents(Object * obj)
 
                rect *= a->radius[0];
                rect.Translate(a->p[0]);
+               break;
+       }
 
+       case OTText:
+       {
+               Text * t = (Text *)obj;
+               rect = Rect(t->p[0], Point(t->p[0].x + t->extents.Width(), t->p[0].y - t->extents.Height()));
                break;
        }
+
        case OTContainer:
        {
                Container * c = (Container *)obj;
@@ -1655,6 +1798,7 @@ Rect DrawingView::GetObjectExtents(Object * obj)
                for(; i!=c->objects.end(); i++)
                        rect |= GetObjectExtents((Object *)*i);
        }
+
        default:
                break;
        }
@@ -1675,6 +1819,7 @@ void DrawingView::CheckObjectBounds(void)
                switch (obj->type)
                {
                case OTLine:
+               case OTDimension:
                {
                        Line * l = (Line *)obj;
 
@@ -1683,6 +1828,7 @@ void DrawingView::CheckObjectBounds(void)
 
                        break;
                }
+
                case OTCircle:
                {
                        Circle * c = (Circle *)obj;
@@ -1692,6 +1838,7 @@ void DrawingView::CheckObjectBounds(void)
 
                        break;
                }
+
                case OTArc:
                {
                        Arc * a = (Arc *)obj;
@@ -1757,6 +1904,18 @@ void DrawingView::CheckObjectBounds(void)
 
                        break;
                }
+
+               case OTText:
+               {
+                       Text * t = (Text *)obj;
+                       Rect r(obj->p[0], Point(t->p[0].x + t->extents.Width(), t->p[0].y - t->extents.Height()));
+
+                       if (Global::selection.contains(r.l, r.t) && Global::selection.contains(r.r, r.b))
+                               t->selected = true;
+
+                       break;
+               }
+
                default:
                        break;
                }
@@ -1841,6 +2000,7 @@ bool DrawingView::HitTest(Object * obj, Point point)
 
                break;
        }
+
        case OTCircle:
        {
                bool oldHP = obj->hitPoint[0], oldHO = obj->hitObject;
@@ -1848,7 +2008,11 @@ bool DrawingView::HitTest(Object * obj, Point point)
                double length = Vector::Magnitude(obj->p[0], point);
 
                if ((length * Global::zoom) < 8.0)
+               {
                        obj->hitPoint[0] = true;
+                       hoverPoint = obj->p[0];
+                       hoverPointValid = true;
+               }
                else if ((fabs(length - obj->radius[0]) * Global::zoom) < 2.0)
                        obj->hitObject = true;
 
@@ -1859,6 +2023,7 @@ bool DrawingView::HitTest(Object * obj, Point point)
 
                break;
        }
+
        case OTArc:
        {
                bool oldHP0 = obj->hitPoint[0], oldHP1 = obj->hitPoint[1], oldHP2 = obj->hitPoint[2], oldHO = obj->hitObject;
@@ -1881,7 +2046,11 @@ bool DrawingView::HitTest(Object * obj, Point point)
                double length3 = Vector::Magnitude(point, handle2);
 
                if ((length * Global::zoom) < 8.0)
+               {
                        obj->hitPoint[0] = true;
+                       hoverPoint = obj->p[0];
+                       hoverPointValid = true;
+               }
                else if ((length2 * Global::zoom) < 8.0)
                {
                        obj->hitPoint[1] = true;
@@ -1904,6 +2073,7 @@ bool DrawingView::HitTest(Object * obj, Point point)
 
                break;
        }
+
        case OTDimension:
        {
                bool oldHP0 = obj->hitPoint[0], oldHP1 = obj->hitPoint[1], oldHP2 = obj->hitPoint[2], oldHP3 = obj->hitPoint[3], oldHP4 = obj->hitPoint[4], oldHO = obj->hitObject;
@@ -1957,9 +2127,29 @@ bool DrawingView::HitTest(Object * obj, Point point)
                if ((oldHP0 != obj->hitPoint[0]) || (oldHP1 != obj->hitPoint[1]) || (oldHP2 != obj->hitPoint[2]) || (oldHP3 != obj->hitPoint[3]) || (oldHP4 != obj->hitPoint[4]) || (oldHO != obj->hitObject))
                        needUpdate = true;
 
+               break;
+       }
+
+       case OTText:
+       {
+               Text * t = (Text *)obj;
+               bool oldHO = obj->hitObject;
+               obj->hitObject = false;
+
+               Rect r(obj->p[0], Point(obj->p[0].x + t->extents.Width(), obj->p[0].y - t->extents.Height()));
+//printf("Text: p=<%lf, %lf>, w/h=%lf, %lf [lrtb=%lf, %lf, %lf, %lf]\n", obj->p[0].x, obj->p[0].y, t->extents.Width(), t->extents.Height(), t->extents.l, t->extents.r, t->extents.t, t->extents.b);
+
+               if (r.Contains(point))
+                       obj->hitObject = true;
+
+               obj->hovered = (obj->hitObject ? true : false);
+
+               if (oldHO != obj->hitObject)
+                       needUpdate = true;
 
                break;
        }
+
        case OTContainer:
        {
                // Containers must be recursively tested...
@@ -1984,6 +2174,7 @@ bool DrawingView::HitTest(Object * obj, Point point)
 
                break;
        }
+
        default:
                break;
        }
@@ -2157,6 +2348,12 @@ void DrawingView::HandleObjectMovement(Point point)
 
                break;
 
+       case OTText:
+               if (obj->hitObject)
+                       obj->p[0] += delta;
+
+               break;
+
        case OTContainer:
                // This is shitty, but works for now until I can code up something
                // nicer :-)