]> Shamusworld >> Repos - architektonas/commitdiff
Added ability to manipulate Text objects.
authorShamus Hammons <jlhamm@acm.org>
Sat, 11 Feb 2017 14:33:30 +0000 (08:33 -0600)
committerShamus Hammons <jlhamm@acm.org>
Sat, 11 Feb 2017 14:33:30 +0000 (08:33 -0600)
It's not possible yet to edit their content or change their angle, but
that's coming. :-)

src/drawingview.cpp
src/objectwidget.cpp
src/painter.cpp
src/painter.h
src/rect.cpp
src/rect.h
src/structs.h

index ca063c51d548070b1a000158d15b0d53e9fdcf7e..0ef95dd7edece441097e24590038ed8fe4d550ab 100644 (file)
@@ -607,7 +607,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:
@@ -1601,12 +1608,14 @@ Rect DrawingView::GetObjectExtents(Object * obj)
                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;
@@ -1643,9 +1652,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;
@@ -1656,6 +1672,7 @@ Rect DrawingView::GetObjectExtents(Object * obj)
                for(; i!=c->objects.end(); i++)
                        rect |= GetObjectExtents((Object *)*i);
        }
+
        default:
                break;
        }
@@ -1685,6 +1702,7 @@ void DrawingView::CheckObjectBounds(void)
 
                        break;
                }
+
                case OTCircle:
                {
                        Circle * c = (Circle *)obj;
@@ -1694,6 +1712,7 @@ void DrawingView::CheckObjectBounds(void)
 
                        break;
                }
+
                case OTArc:
                {
                        Arc * a = (Arc *)obj;
@@ -1759,6 +1778,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;
                }
@@ -1843,6 +1874,7 @@ bool DrawingView::HitTest(Object * obj, Point point)
 
                break;
        }
+
        case OTCircle:
        {
                bool oldHP = obj->hitPoint[0], oldHO = obj->hitObject;
@@ -1850,7 +1882,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;
 
@@ -1861,6 +1897,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;
@@ -1883,7 +1920,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;
@@ -1906,6 +1947,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;
@@ -1959,9 +2001,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...
@@ -1986,6 +2048,7 @@ bool DrawingView::HitTest(Object * obj, Point point)
 
                break;
        }
+
        default:
                break;
        }
@@ -2159,6 +2222,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 :-)
index c7e0cf69e61178816bb4bda616399acec017102b..554ce34bcf291f8b45d423fb303374f3cd27f309 100644 (file)
@@ -74,6 +74,10 @@ void ObjectWidget::ShowInfo(Object * obj)
        const char objName[OTCount][16] = {
                "None", "Line", "Circle", "Ellipse", "Arc", "Polygon", "Dimension", "Spline", "Text", "Container"
        };
+       const char dimName[DTCount][32] = {
+               "Linear", "Vertical", "Horizontal", "Radial", "Diametric",
+               "Circumferential", "Angular", "Leader"
+       };
 
        // Sanity check
        if (obj == NULL)
@@ -89,25 +93,38 @@ void ObjectWidget::ShowInfo(Object * obj)
                s += QString("&lt;%1, %2&gt; to &lt;%3, %4&gt;<br>Length: %5<br>Angle: %6&#x00B0;<br>").arg(obj->p[0].x).arg(obj->p[0].y).arg(obj->p[1].x).arg(obj->p[1].y).arg(line.Magnitude()).arg(line.Angle() * RADIANS_TO_DEGREES);
                break;
        }
+
        case OTCircle:
                s += QString("Center: &lt;%1, %2&gt;<br>Radius: %3<br>").arg(obj->p[0].x).arg(obj->p[0].y).arg(obj->radius[0]);
                break;
+
        case OTEllipse:
                break;
+
        case OTArc:
                s += QString("Center: &lt;%1, %2&gt;<br>Radius: %3<br>Start: %4&#x00B0;<br>End: %5&#x00B0;<br>").arg(obj->p[0].x).arg(obj->p[0].y).arg(obj->radius[0]).arg(obj->angle[0] * RADIANS_TO_DEGREES).arg(obj->angle[1] * RADIANS_TO_DEGREES);
                break;
                break;
+
        case OTPolygon:
                break;
+
        case OTDimension:
                break;
+
        case OTSpline:
                break;
+
        case OTText:
+       {
+               Text * t = (Text *)obj;
+               s += QString("&lt;%1, %2&gt;<br>Width/Height: %3/%4<br>Angle: %5&#x00B0;<br>").arg(t->p[0].x).arg(t->p[0].y).arg(t->extents.Width()).arg(t->extents.Height()).arg(obj->angle[0] * RADIANS_TO_DEGREES);
                break;
+       }
+
        case OTContainer:
                break;
+
        default:
                break;
        }
index 08068119afde63c7ccd3b5b0eb263b3ab774663a..df1d7d5d1c548a6cfe8014300485362d6f02bce8 100644 (file)
@@ -183,6 +183,25 @@ void Painter::DrawTextObject(Point p, QString text, double size, double angle/*=
 }
 
 
+//
+// Return the non-rotated rectangle containing the extents of the text in
+// Cartesian coordiates (starting from <0, 0>, the lower left hand side)
+//
+Rect Painter::MeasureTextObject(QString text, double size)
+{
+       if (!painter)
+               return Rect();
+
+       painter->setFont(QFont("Arial", Global::zoom * size));
+       int textWidth = QFontMetrics(painter->font()).width(text);
+       int textHeight = QFontMetrics(painter->font()).height();
+       Point measured((double)textWidth / Global::zoom, (double)textHeight / Global::zoom);// = QtToCartesianCoords(Point(textWidth, textHeight));
+//printf("QFontMetrics w/h=%i/%i, measured=%lf/%lf\n", textWidth, textHeight, measured.x, measured.y);
+
+       return Rect(Point(0, 0), measured);
+}
+
+
 void Painter::DrawArc(Vector center, double radius, double startAngle, double span)
 {
        if (!painter)
@@ -245,13 +264,8 @@ void Painter::DrawRectCorners(Rect rect)
        if (!painter)
                return;
 
-//     QRectF screenRect(QPointF(v1.x, v1.y), QPointF(v2.x, v2.y));
-       
        Vector v1 = CartesianToQtCoords(Vector(rect.l, rect.t));
        Vector v2 = CartesianToQtCoords(Vector(rect.r, rect.b));
-//     QRectF screenRect(QPointF(v1.x, v1.y), QPointF(v2.x, v2.y));
-//     screenRect.adjust(-8, 8, 8, -8);        // Left/top, right/bottom
-//     painter->drawRect(screenRect);
        v1 += Vector(-8.0, -8.0);
        v2 += Vector(+8.0, +8.0);
        painter->setPen(QPen(Qt::red, 2.0, Qt::DashLine));
index 4ff50b2298887145ee587bc29e11550a666ac529..5b11e25aadead93a1c418627fe3abbe50e02b332 100644 (file)
@@ -22,6 +22,7 @@ class Painter
                void SetFont(QFont);
                void DrawAngledText(Vector, double, QString, double);
                void DrawTextObject(Vector, QString, double, double angle = 0);
+               Rect MeasureTextObject(QString text, double size);
                void DrawArc(Vector, double, double, double);
                void DrawEllipse(Vector, double, double);
                void DrawHandle(Vector);
index 8207f234a3f397915c25344649462d02896971ac..8c9c74ed70c949ef22a49553afe150f9de021f77 100644 (file)
@@ -98,3 +98,33 @@ void Rect::Expand(double amt)
        b -= amt;
 }
 
+
+double Rect::Width(void)
+{
+       return r - l;
+}
+
+
+double Rect::Height(void)
+{
+       return t - b;
+}
+
+
+bool Rect::Contains(Point p)
+{
+       return ((p.x >= l) && (p.x <= r) && (p.y >= b) && (p.y <= t) ? true : false);
+}
+
+
+Point Rect::TopLeft(void)
+{
+       return Point(t, l);
+}
+
+
+Point Rect::BottomRight(void)
+{
+       return Point(b, r);
+}
+
index 0a8478a6b47cc461d80eb408777d3148018dc18c..2689bae3f5469e15bc73873c07b168bba623b919 100644 (file)
@@ -20,6 +20,11 @@ struct Rect
        void Normalize(void);
        void Translate(Point p);
        void Expand(double amt);
+       double Width(void);
+       double Height(void);
+       bool Contains(Point p);
+       Point TopLeft(void);
+       Point BottomRight(void);
 };
 
 #endif // __RECT_H__
index 7fe1f09e96eca0c5d018c315a15d5498c598c676..cdd11ecac46540b778ac61659d62a20c981d4aa9 100644 (file)
@@ -5,11 +5,12 @@
 #include <vector>
 #include <string>
 #include "global.h"
+#include "rect.h"
 #include "vector.h"
 
 enum ObjectType { OTNone = 0, OTLine, OTCircle, OTEllipse, OTArc, OTPolygon, OTDimension, OTSpline, OTText, OTContainer, OTCount };
 
-enum DimensionType { DTLinear, DTLinearVert, DTLinearHorz, DTRadial, DTDiametric, DTCircumferential, DTAngular, DTLeader };
+enum DimensionType { DTLinear = 0, DTLinearVert, DTLinearHorz, DTRadial, DTDiametric, DTCircumferential, DTAngular, DTLeader, DTCount };
 
 enum ToolType { TTNone, TTLine, TTCircle, TTEllipse, TTArc, TTDimension, TTText, TTPolygon, TTSpline, TTRotate, TTMirror, TTTrim, TTTriangulate, TTDelete };
 
@@ -30,6 +31,10 @@ enum ToolState { TSNone, TSPoint1, TSPoint2, TSPoint3, TSPoint4, TSDone };
        double angle[2];  \
        double radius[2];
 
+struct Object {
+       OBJECT_COMMON;
+};
+
 struct Line {
        OBJECT_COMMON;
 
@@ -85,12 +90,15 @@ struct Dimension {
 
 struct Text {
        OBJECT_COMMON;
+       Rect extents;
+       bool measured;
        std::string s;
 
        Text(): type(OTText), id(Global::objectID++) {}
        Text(Vector pt1, char * str, float th = 10.0, uint32_t c = 0):
                type(OTText), id(Global::objectID++), layer(0), color(c), thickness(th),
-               style(LSSolid), selected(false), hovered(false), hitObject(false), s(str) { p[0] = pt1; }
+               style(LSSolid), selected(false), hovered(false), hitObject(false),
+               measured(false), s(str) { p[0] = pt1; angle[0] = 0; }
 };
 
 struct Polygon {
@@ -129,9 +137,5 @@ struct Container {
        }*/
 };
 
-struct Object {
-       OBJECT_COMMON;
-};
-
 #endif // __STRUCTS_H__