]> Shamusworld >> Repos - ttedit/blobdiff - src/editwindow.cpp
Added preview window to file loading dialog. :-)
[ttedit] / src / editwindow.cpp
old mode 100755 (executable)
new mode 100644 (file)
index 85b4d9c..dac63c2
 #include "debug.h"
 #include "global.h"
 #include "mainwindow.h"
+#include "mathconstants.h"
 #include "ttedit.h"
 #include "vector.h"
 
 
 EditWindow::EditWindow(QWidget * parent/*= NULL*/): QWidget(parent),
-       scale(1.0), offsetX(-10), offsetY(-10), tool(TOOLSelect),
-       ptHighlight(-1), oldPtHighlight(-1), ptNextHighlight(-1), oldPtNextHighlight(-1),
-       polyFirstPoint(true), showRotationCenter(false), haveZeroPoint(false),
-       selectionInProgress(false)
+       tool(TOOLSelect), ptHighlight(-1), oldPtHighlight(-1), ptNextHighlight(-1),
+       oldPtNextHighlight(-1), polyFirstPoint(true), showRotationCenter(false),
+       haveZeroPoint(false), selectionInProgress(false)
 {
        setBackgroundRole(QPalette::Base);
        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
@@ -81,30 +81,12 @@ void EditWindow::CreateCursors(void)
 
        for(int i=0; i<12; i++)
        {
-               QString s;
-               s.sprintf(":/res/cursor-%s.png", cursorName[i]);
-               QPixmap pmTmp(s);
+               QPixmap pmTmp(QString(":/res/cursor-%1.png").arg(cursorName[i]));
                cur[i] = QCursor(pmTmp, hotx[i], hoty[i]);
        }
 }
 
 
-QPoint EditWindow::GetAdjustedMousePosition(QMouseEvent * event)
-{
-       // This is undoing the transform, e.g. going from client coords to local
-       // coords. In essence, the height - y is height + (y * -1), the (y * -1)
-       // term doing the conversion of the y-axis from increasing bottom to top.
-       return QPoint(offsetX + event->x(), offsetY + (size().height() - event->y()));
-}
-
-
-QPoint EditWindow::GetAdjustedClientPosition(int x, int y)
-{
-       // VOODOO ALERT (ON Y COMPONENT!!!!)
-       return QPoint(-offsetX + x, (size().height() - (-offsetY + y)) * +1.0);
-}
-
-
 /*
 TODO:
  o  Different colors for polys on selected points
@@ -116,31 +98,14 @@ void EditWindow::paintEvent(QPaintEvent * /*event*/)
 {
        QPainter qtp(this);
        Painter painter(&qtp);
-//hm, causes lockup (or does it???)
-//& it doesn't help with our Bezier rendering code :-P
        painter.SetRenderHint(QPainter::Antialiasing);
 
-       Global::zoom = scale;
-       Global::origin = Vector(offsetX, offsetY);
        Global::viewportHeight = size().height();
        Global::screenSize = Vector(size().width(), size().height());
-//     p.translate(QPoint(-offsetX, size().height() - (-offsetY)));
-//     p.scale(1.0, -1.0);
-//Nope, a big load of shit. So we'll have to bite the bullet and do it the
-//hard way™.
-//     p.scale(scale, -scale);
-
-// Scrolling can be done by using OffsetViewportOrgEx
-// Scaling can be done by adjusting SetWindowExtEx (it's denominator of txform)
-// you'd use: % = ViewportExt / WindowExt
-// But it makes the window look like crap: fuggetuboutit.
-// Instead, we have to scale EVERYTHING by hand. Crap!
-// It's not *that* bad, but not as convenient either...
-
-       painter.SetPen(QPen(Qt::blue, 1.0, Qt::DotLine));
 
        // Draw coordinate axes
 
+       painter.SetPen(QPen(Qt::blue, 1.0, Qt::DotLine));
        painter.DrawLine(0, -16384, 0, 16384);
        painter.DrawLine(-16384, 0, 16384, 0);
 
@@ -222,6 +187,23 @@ void EditWindow::paintEvent(QPaintEvent * /*event*/)
                }
        }
 
+       // Draw highlighted point on poly add tool
+       if (tool == TOOLAddPoly)
+       {
+               painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
+
+               if (addPointOnCurve)
+               {
+                       painter.DrawSquareDotN(addPoint, 7);
+                       painter.DrawSquareDotN(addPoint, 9);
+               }
+               else
+               {
+                       painter.DrawRoundDotN(addPoint, 7);
+                       painter.DrawRoundDotN(addPoint, 9);
+               }
+       }
+
        // Draw curve formed by points
 
        painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
@@ -305,46 +287,68 @@ void EditWindow::DrawGlyph(Painter & p, GlyphPoints & glyph)
 }
 
 
+/*
+So, to make it draw the point the pointer is pointing at, we need to do something. Either patch the GlyphPoints to handle it, or insert the point into the GlyphPoints and delete it if the user changes tools. Either way, need
+to change the color of the line(s) drawn to the point to signal to the user
+that it isn't finalized until they click the button.
+*/
 void EditWindow::DrawGlyphPoly(Painter & p, GlyphPoints & glyph, uint16_t poly)
 {
        // Sanity check
        if (glyph.GetNumPoints(poly) < 3)
                return;
 
-       // Initial move: If our start point is on curve, then go to it. Otherwise,
-       // check previous point. If it's on curve, go to it otherwise go the
-       // midpoint between start point and previous (since it's between two curve
-       // control points).
-       IPoint pt = (glyph.GetOnCurve(poly, 0)
-               ? glyph.GetPoint(poly, 0) : (glyph.GetPrevOnCurve(poly, 0)
-                       ? glyph.GetPrevPoint(poly, 0) : glyph.GetMidpointToPrev(poly, 0)));
+       IPoint p1 = glyph.GetPrevPoint(poly, 0);
+       IPoint p2 = glyph.GetPoint(poly, 0);
+
+       // Inject the new poly point into the current polygon
+       if ((tool == TOOLAddPoly) && (poly == (glyph.GetNumPolys() - 1)))
+       {
+               p1 = IPoint(addPoint.x, addPoint.y, addPointOnCurve);
+       }
 
        for(int i=0; i<glyph.GetNumPoints(poly); i++)
        {
-               // If this point and then next are both on curve, we have a line...
-               if (glyph.GetOnCurve(poly, i) && glyph.GetNextOnCurve(poly, i))
-               {
-                       IPoint pt2 = glyph.GetNextPoint(poly, i);
-                       p.DrawLine(pt.x, pt.y, pt2.x, pt2.y);
-                       pt = pt2;
-               }
-               else
+               IPoint p3 = glyph.GetNextPoint(poly, i);
+
+               if ((tool == TOOLAddPoly) && (poly == (glyph.GetNumPolys() - 1))
+                       && (i == (glyph.GetNumPoints(poly) - 1)))
                {
-                       // Skip point if it's on curve (start of curve--it's already
-                       // been plotted so we don't need to handle it...)
-                       if (glyph.GetOnCurve(poly, i))
-                               continue;
-
-                       // We are now guaranteed that we are sitting on a curve control
-                       // point (off curve). Figure the extent of the curve: If the
-                       // following is a curve control point, then use the midpoint to it
-                       // otherwise go to the next point since it's on curve.
-                       IPoint pt2 = (glyph.GetNextOnCurve(poly, i)
-                               ? glyph.GetNextPoint(poly, i) : glyph.GetMidpointToNext(poly, i));
-
-                       p.DrawBezier(pt, glyph.GetPoint(poly, i), pt2);
-                       pt = pt2;
+                       p3 = IPoint(addPoint.x, addPoint.y, addPointOnCurve);
+                       p.SetPen(QPen(Qt::green, 1.0, Qt::SolidLine));
+                       DrawGlyphSegment(p, p1, p2, p3);
+                       p1 = p2;
+                       p2 = p3;
+                       p3 = glyph.GetNextPoint(poly, i);
                }
+
+               DrawGlyphSegment(p, p1, p2, p3);
+
+               p1 = p2;
+               p2 = p3;
+       }
+}
+
+
+//
+// Draw a glyph segment given 3 points
+//
+void EditWindow::DrawGlyphSegment(Painter & p, IPoint p1, IPoint p2, IPoint p3)
+{
+       if (p2.onCurve)
+       {
+               // Skip drawing if the middle point is on curve and the last is off
+               if (p3.onCurve)
+                       p.DrawLine(p2, p3);
+       }
+       else
+       {
+               // The middle point is off curve, and so we need to draw a Bezier curve.
+               // Also, depending on whether or not the previous or follow points are
+               // off curve, we need to draw to the midpoints if so.
+               IPoint mid12 = IPoint((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
+               IPoint mid23 = IPoint((p2.x + p3.x) / 2, (p2.y + p3.y) / 2);
+               p.DrawBezier((p1.onCurve ? p1 : mid12), p2, (p3.onCurve ? p3 : mid23));
        }
 }
 
@@ -407,6 +411,8 @@ void EditWindow::mousePressEvent(QMouseEvent * event)
 
                        update();
                }
+// Moved to mouse up routine, so we can slide the point around
+#if 0
                else if (tool == TOOLAddPoly)   // "Add Poly" tool
                {
 #ifdef DEBUGFOO
@@ -429,14 +435,14 @@ WriteLogMsg("Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.
 WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumPoints());
 #endif
                }
+#endif
                else if (tool == TOOLSelect || tool == TOOLPolySelect)
                {
                        if (pts.GetNumPoints() > 0)
                        {
 //                             pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
-                               Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
-//printf("GetAdjustedClientPosition = %i, %i\n", pt.x(), pt.y());
-//                             WarpPointer(pt.x, pt.y);
+                               Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
+//printf("GetAdjustedClientPosition = %lf, %lf\n", pt.x, pt.y);
                                QPoint warp(pt.x, pt.y);
                                QCursor::setPos(mapToGlobal(warp));
 
@@ -462,9 +468,9 @@ WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumP
                else if (tool == TOOLRotate)
                {
                        // I think what's needed here is to keep the initial mouse click,
-                       // paint the rotation center, then use the 1st mouse move event to establish
-                       // the rotation "zero line", which becomes the line of reference to all
-                       // subsequent mouse moves.
+                       // paint the rotation center, then use the 1st mouse move event to
+                       // establish the rotation "zero line", which becomes the line of
+                       // reference to all subsequent mouse moves.
 //                     rotationCenter = GetAdjustedMousePosition(event);
                        rotationCenter = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
                        showRotationCenter = true;
@@ -478,7 +484,7 @@ WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumP
                        rotationCenter = Vector(centroid.x, centroid.y);
                        showRotationCenter = true;
 //                     pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
-                       Vector pt = Painter::QtToCartesianCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
+                       Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
                        QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
                        rotationZeroPoint = Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
                        haveZeroPoint = true;
@@ -489,7 +495,7 @@ WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumP
                {
                        pts.InvertPolyDrawSequence(pts.GetPolyForPointNumber(ptHighlight));
 //                     pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
-                       Vector pt = Painter::QtToCartesianCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
+                       Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
                        QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
                        update();
                }
@@ -516,26 +522,38 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                // Calc offset from previous point
                Vector pt(event->x(), event->y());
                pt /= Global::zoom;
-               ptOffset = Vector(pt.x - ptPrevious.x, pt.y - ptPrevious.y);
+               ptOffset = Vector(pt.x - ptPrevious.x, -(pt.y - ptPrevious.y));
 
 // Then multiply it by the scaling factor. Whee!
                // This looks wacky because we're using screen coords for the offset...
                // Otherwise, we would subtract both offsets!
-               offsetX -= ptOffset.x, offsetY += ptOffset.y;
-               update();
+//             offsetX -= ptOffset.x, offsetY += ptOffset.y;
+               Global::origin -= ptOffset;
                ptPrevious = pt;
+               update();
        }
        else if (event->buttons() == Qt::LeftButton)
        {
                if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect)
                {
                        // Bail out if we have the select tool and no points yet...
-                       if (tool == TOOLSelect && pts.GetNumPoints() == 0)
+                       if ((tool == TOOLSelect) && (pts.GetNumPoints() == 0))
                                return;
 
 //                     QPoint pt2 = GetAdjustedMousePosition(event);
                        Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
-                       pts.SetXY(ptHighlight, pt2.x, pt2.y);
+
+                       if (tool != TOOLSelect)
+                       {
+                               addPoint = pt2;
+                               ptHighlight = -1;
+                               // Prolly should move this to the key handlers below...
+//now we do! :-D
+//                             addPointOnCurve = ((event->modifiers() == Qt::ShiftModifier) || (event->modifiers() == Qt::ControlModifier) ? false : true);
+                       }
+                       else
+                               pts.SetXY(ptHighlight, pt2.x, pt2.y);
+
                        update();
                }
                else if (tool == TOOLPolySelect)
@@ -564,8 +582,9 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                                }
                                else
                                {
-                                       // Figure out the angle between the "zero" vector and the current one,
-                                       // then rotate all points relative to the "zero" vector (done by paint())
+                                       // Figure out the angle between the "zero" vector and the
+                                       // current one, then rotate all points relative to the
+                                       // "zero" vector (done by paint())
 //                                     QPoint currentPoint = GetAdjustedMousePosition(event);
                                        Vector currentPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
                                        Vector v1(rotationZeroPoint.x, rotationZeroPoint.y, 0,
@@ -576,8 +595,8 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                                        rotationAngle = v2.Angle(v1);
 
                                        QString s;
-                                       s.sprintf("%.3f degrees", rotationAngle * 180.0 / 3.14159265358979323);
-                                       ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage(s);
+                                       s.sprintf("%.3f degrees", rotationAngle * RADIANS_TO_DEGREES);
+                                       Global::mainWindow->statusBar()->showMessage(s);
                                }
 
                                update();
@@ -703,6 +722,12 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                }
 
                ptPrevious = Vector(event->x(), event->y());
+               addPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+//handled by real key handlers now...
+//             addPointOnCurve = ((event->modifiers() == Qt::ShiftModifier) || (event->modifiers() == Qt::ControlModifier) ? false : true);
+
+               if (tool == TOOLAddPoly)
+                       update();
        }
 
        event->accept();
@@ -753,20 +778,42 @@ void EditWindow::mouseReleaseEvent(QMouseEvent * event)
                        }
 
                        update();
-                       ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage("");
+                       Global::mainWindow->statusBar()->showMessage("");
                }
 
 //             if (tool == TOOLScroll || tool == TOOLZoom)
 //                     ReleaseMouse();
 //this is prolly too much
-               ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
-               ((TTEdit *)qApp)->charWnd->update();
+               Global::charWnd->MakePathFromPoints(&pts);
+               Global::charWnd->update();
 
                if (tool == TOOLMultiSelect)
                {
                        selectionInProgress = false;
                        update();
                }
+               else if (tool == TOOLAddPoly)   // "Add Poly" tool
+               {
+#ifdef DEBUGFOO
+WriteLogMsg("Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.GetNumPoints());
+#endif
+                       if (polyFirstPoint)
+                       {
+                               polyFirstPoint = false;
+                               pts.AddNewPolyAtEnd();
+                       }
+
+//                     QPoint pt = GetAdjustedMousePosition(event);
+                       Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+//printf("GetAdjustedMousePosition = %i, %i\n", pt.x(), pt.y());
+                       // Append a point to the end of the structure
+                       pts += IPoint(pt.x, pt.y, addPointOnCurve);
+//                     ptHighlight = pts.GetNumPoints() - 1;
+                       update();
+#ifdef DEBUGFOO
+WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumPoints());
+#endif
+               }
        }
 
        event->accept();
@@ -775,6 +822,15 @@ void EditWindow::mouseReleaseEvent(QMouseEvent * event)
 
 void EditWindow::keyPressEvent(QKeyEvent * event)
 {
+       // We do this here because of the ptHighlight nonsense. If we're in
+       // the add poly tool, we'll never see this if it's under the 'sanity'
+       // check (which is needed for the arrow key shite, but still...)
+       if ((event->key() == Qt::Key_Shift) || (event->key() == Qt::Key_Control))
+       {
+               addPointOnCurve = false;
+               update();
+       }
+
        // Sanity checking...
        if (ptHighlight == -1)
                return;
@@ -792,14 +848,23 @@ void EditWindow::keyPressEvent(QKeyEvent * event)
        else
                return;
 
-       event->accept();
+//Not need but you need to call the base class for some reason??
+//     event->accept();
        update();
-       ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
-       ((TTEdit *)qApp)->charWnd->update();
+       Global::charWnd->MakePathFromPoints(&pts);
+       Global::charWnd->update();
 }
 
 
-void EditWindow::keyReleaseEvent(QKeyEvent * /*event*/)
+void EditWindow::keyReleaseEvent(QKeyEvent * event)
 {
+       if ((event->key() == Qt::Key_Shift) || (event->key() == Qt::Key_Control))
+       {
+               addPointOnCurve = true;
+       }
+       else
+               return;
+
+       update();
 }