]> Shamusworld >> Repos - ttedit/blobdiff - src/editwindow.cpp
Added rectangle point selection, canvas zooming.
[ttedit] / src / editwindow.cpp
index 9d0f5d8d803b725ca27ab5a2f051e3f39bf3ea4a..85b4d9c716360349edefda5b7128dcfe14d06fbe 100755 (executable)
@@ -6,7 +6,7 @@
 // JLH = James L. Hammons <jlhamm@acm.org>
 //
 // Who  When        What
-// ---  ----------  -------------------------------------------------------------
+// ---  ----------  -----------------------------------------------------------
 // JLH  08/28/2008  Created this file
 // JLH  09/02/2008  Separated scrolling from dedicated tool to MMB drag
 // JLH  03/13/2009  Converted from wxWidgets to Qt
@@ -36,7 +36,7 @@
 #include "editwindow.h"
 #include "charwindow.h"
 #include "debug.h"
-#include "graphicprimitives.h"
+#include "global.h"
 #include "mainwindow.h"
 #include "ttedit.h"
 #include "vector.h"
@@ -45,7 +45,8 @@
 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)
+       polyFirstPoint(true), showRotationCenter(false), haveZeroPoint(false),
+       selectionInProgress(false)
 {
        setBackgroundRole(QPalette::Base);
        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
@@ -54,6 +55,7 @@ EditWindow::EditWindow(QWidget * parent/*= NULL*/): QWidget(parent),
        CreateCursors();
        setCursor(cur[TOOLSelect]);
        setMouseTracking(true);
+       ClearSelection();
 }
 
 
@@ -71,12 +73,13 @@ QSize EditWindow::sizeHint() const
 
 void EditWindow::CreateCursors(void)
 {
-       int hotx[11] = {  1,  1, 11, 15,  1,  1,  1,  1,  1,  1,  1 };
-       int hoty[11] = {  1,  1, 11, 13,  1,  1,  1,  1,  1,  1,  1 };
-       char cursorName[11][48] = { "select", "select-poly", "scroll", "zoom", "add-point",
-               "add-poly", "del-point", "del-poly", "rotate", "rotate", "select" };
+       int hotx[12] = {  1,  1, 1, 15,  1,  1,  1,  1,  1,  1,  1, 11 };
+       int hoty[12] = {  1,  1, 1, 13,  1,  1,  1,  1,  1,  1,  1, 11 };
+       char cursorName[12][48] = { "select", "select-poly", "select-multi", "zoom",
+               "add-point", "add-poly", "del-point", "del-poly", "rotate", "rotate",
+               "select", "scroll" };
 
-       for(int i=0; i<11; i++)
+       for(int i=0; i<12; i++)
        {
                QString s;
                s.sprintf(":/res/cursor-%s.png", cursorName[i]);
@@ -88,20 +91,17 @@ void EditWindow::CreateCursors(void)
 
 QPoint EditWindow::GetAdjustedMousePosition(QMouseEvent * event)
 {
-       QSize winSize = size();
-       // 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 + (winSize.height() - event->y()));
+       // 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)
 {
-       QSize winSize = size();
-
        // VOODOO ALERT (ON Y COMPONENT!!!!)
-       return QPoint(-offsetX + x, (winSize.height() - (-offsetY + y)) * +1.0);
+       return QPoint(-offsetX + x, (size().height() - (-offsetY + y)) * +1.0);
 }
 
 
@@ -114,14 +114,21 @@ TODO:
 */
 void EditWindow::paintEvent(QPaintEvent * /*event*/)
 {
-       QPainter p(this);
+       QPainter qtp(this);
+       Painter painter(&qtp);
 //hm, causes lockup (or does it???)
-       p.setRenderHint(QPainter::Antialiasing);
-
-       QSize winSize = size();
-
-       p.translate(QPoint(-offsetX, winSize.height() - (-offsetY)));
-       p.scale(1.0, -1.0);
+//& 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)
@@ -130,78 +137,95 @@ void EditWindow::paintEvent(QPaintEvent * /*event*/)
 // Instead, we have to scale EVERYTHING by hand. Crap!
 // It's not *that* bad, but not as convenient either...
 
-       p.setPen(QPen(Qt::blue, 1.0, Qt::DotLine));
+       painter.SetPen(QPen(Qt::blue, 1.0, Qt::DotLine));
 
        // Draw coordinate axes
 
-       p.drawLine(0, -16384, 0, 16384);
-       p.drawLine(-16384, 0, 16384, 0);
+       painter.DrawLine(0, -16384, 0, 16384);
+       painter.DrawLine(-16384, 0, 16384, 0);
 
        // Draw rotation center (if active)
 
        if (showRotationCenter)
        {
-               p.setPen(QPen(Qt::red, 2.0, Qt::SolidLine));
-               p.drawLine(rotationCenter.x() + 7, rotationCenter.y(), rotationCenter.x() - 7, rotationCenter.y());
-               p.drawLine(rotationCenter.x(), rotationCenter.y() + 7, rotationCenter.x(), rotationCenter.y() - 7);
+               painter.SetPen(QPen(Qt::red, 2.0, Qt::SolidLine));
+               painter.DrawLine(rotationCenter.x + 7, rotationCenter.y, rotationCenter.x - 7, rotationCenter.y);
+               painter.DrawLine(rotationCenter.x, rotationCenter.y + 7, rotationCenter.x, rotationCenter.y - 7);
        }
 
        // Draw points
 
        for(int i=0; i<pts.GetNumPoints(); i++)
        {
-               if (i == ptHighlight)
+               /*if (tool == TOOLMultiSelect)
                {
-                       p.setPen(QPen(Qt::red, 1.0, Qt::SolidLine));
+                       if (selectedPoints[i])
+                       {
+                               qtp.setPen(QPen(Qt::red, 1.0, Qt::SolidLine));
+                       }
+                       else
+                       {
+                               qtp.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
+                       }
+               }
+               else*/
+               if (((i == ptHighlight) && (tool != TOOLMultiSelect)) || ((tool == TOOLMultiSelect) && selectedPoints[i]))
+               {
+                       painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
 
                        if (pts.GetOnCurve(i))
                        {
-                               DrawSquareDotN(p, pts.GetX(i), pts.GetY(i), 7);
-                               DrawSquareDotN(p, pts.GetX(i), pts.GetY(i), 9);
+                               painter.DrawSquareDotN(pts.GetXY(i), 7);
+                               painter.DrawSquareDotN(pts.GetXY(i), 9);
                        }
                        else
                        {
-                               DrawRoundDotN(p, pts.GetX(i), pts.GetY(i), 7);
-                               DrawRoundDotN(p, pts.GetX(i), pts.GetY(i), 9);
+                               painter.DrawRoundDotN(pts.GetXY(i), 7);
+                               painter.DrawRoundDotN(pts.GetXY(i), 9);
                        }
                }
                else if ((i == ptHighlight || i == ptNextHighlight) && tool == TOOLAddPt)
                {
-                       p.setPen(QPen(Qt::green, 1.0, Qt::SolidLine));
+                       painter.SetPen(QPen(Qt::green, 1.0, Qt::SolidLine));
 
                        if (pts.GetOnCurve(i))
                        {
-                               DrawSquareDotN(p, pts.GetX(i), pts.GetY(i), 7);
-                               DrawSquareDotN(p, pts.GetX(i), pts.GetY(i), 9);
+                               painter.DrawSquareDotN(pts.GetXY(i), 7);
+                               painter.DrawSquareDotN(pts.GetXY(i), 9);
                        }
                        else
                        {
-                               DrawRoundDotN(p, pts.GetX(i), pts.GetY(i), 7);
-                               DrawRoundDotN(p, pts.GetX(i), pts.GetY(i), 9);
+                               painter.DrawRoundDotN(pts.GetXY(i), 7);
+                               painter.DrawRoundDotN(pts.GetXY(i), 9);
                        }
                }
                else
                {
-                       p.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
+                       painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
 
+#if 1
                        if (pts.GetOnCurve(i))
-                               DrawSquareDot(p, pts.GetX(i), pts.GetY(i));
+                               painter.DrawSquareDot(pts.GetXY(i));
                        else
-                               DrawRoundDot(p, pts.GetX(i), pts.GetY(i));
+                               painter.DrawRoundDot(pts.GetXY(i));
+#else
+                       (pts.GetOnCurve(i) ? DrawSquareDot(p, pts.GetX(i), pts.GetY(i))
+                               : DrawRoundDot(p, pts.GetX(i), pts.GetY(i)));
+#endif
                }
 
                if (tool == TOOLDelPt && i == ptHighlight)
                {
-                       p.setPen(QPen(Qt::red, 1.0, Qt::SolidLine));
-                       p.drawLine(pts.GetX(i) - 5, pts.GetY(i) - 5, pts.GetX(i) + 5, pts.GetY(i) + 5);
-                       p.drawLine(pts.GetX(i) + 5, pts.GetY(i) - 5, pts.GetX(i) - 5, pts.GetY(i) + 5);
+                       painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
+                       painter.DrawLine(pts.GetX(i) - 5, pts.GetY(i) - 5, pts.GetX(i) + 5, pts.GetY(i) + 5);
+                       painter.DrawLine(pts.GetX(i) + 5, pts.GetY(i) - 5, pts.GetX(i) - 5, pts.GetY(i) + 5);
                }
        }
 
        // Draw curve formed by points
 
-       p.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
-       DrawGlyph(p, pts);
+       painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
+       DrawGlyph(painter, pts);
 
        if (haveZeroPoint)
        {
@@ -209,20 +233,27 @@ void EditWindow::paintEvent(QPaintEvent * /*event*/)
                GlyphPoints rotated = pts;
 
                if (tool == TOOLRotate)
-                       rotated.RotatePoints(rotationAngle, IPoint(rotationCenter.x(), rotationCenter.y()));
+                       rotated.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
                else if (tool == TOOLRotatePoly)
                {
                        uint16_t poly = rotated.GetPolyForPointNumber(ptHighlight);
                        rotated.RotatePolyAroundCentroid(poly, rotationAngle);
                }
 
-               p.setPen(QPen(QColor(255, 0, 255), 1.0, Qt::SolidLine));
-               DrawGlyph(p, rotated);
+               painter.SetPen(QPen(QColor(255, 0, 255), 1.0, Qt::SolidLine));
+               DrawGlyph(painter, rotated);
+       }
+
+       if (selectionInProgress)
+       {
+               painter.SetPen(QPen(QColor(255, 127, 0, 255)));
+               painter.SetBrush(QBrush(QColor(255, 127, 0, 100)));
+               painter.DrawRect(selection);
        }
 }
 
 
-void EditWindow::DrawGlyph(QPainter & p, GlyphPoints & glyph)
+void EditWindow::DrawGlyph(Painter & p, GlyphPoints & glyph)
 {
        for(int poly=0; poly<glyph.GetNumPolys(); poly++)
        {
@@ -274,7 +305,7 @@ void EditWindow::DrawGlyph(QPainter & p, GlyphPoints & glyph)
 }
 
 
-void EditWindow::DrawGlyphPoly(QPainter & p, GlyphPoints & glyph, uint16_t poly)
+void EditWindow::DrawGlyphPoly(Painter & p, GlyphPoints & glyph, uint16_t poly)
 {
        // Sanity check
        if (glyph.GetNumPoints(poly) < 3)
@@ -294,7 +325,7 @@ void EditWindow::DrawGlyphPoly(QPainter & p, GlyphPoints & glyph, uint16_t poly)
                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);
+                       p.DrawLine(pt.x, pt.y, pt2.x, pt2.y);
                        pt = pt2;
                }
                else
@@ -304,20 +335,27 @@ void EditWindow::DrawGlyphPoly(QPainter & p, GlyphPoints & glyph, uint16_t poly)
                        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.
+                       // 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));
 
-                       Bezier(p, pt, glyph.GetPoint(poly, i), pt2);
+                       p.DrawBezier(pt, glyph.GetPoint(poly, i), pt2);
                        pt = pt2;
                }
        }
 }
 
 
+void EditWindow::ClearSelection(void)
+{
+       for(int i=0; i<65536; i++)
+               selectedPoints[i] = false;
+}
+
+
 void EditWindow::mousePressEvent(QMouseEvent * event)
 {
        if (event->button() == Qt::RightButton)
@@ -329,16 +367,28 @@ void EditWindow::mousePressEvent(QMouseEvent * event)
        }
        else if (event->button() == Qt::MidButton)
        {
-               setCursor(cur[2]);                                                      // Scrolling cursor
+               // Scrolling cursor
+               setCursor(cur[11]);
+               ptPrevious = Vector(event->x(), event->y());
+               ptPrevious /= Global::zoom;
        }
        else if (event->button() == Qt::LeftButton)
        {
                if (tool == TOOLScroll || tool == TOOLZoom)
 ;//meh                 CaptureMouse();                                         // Make sure we capture the mouse when in scroll/zoom mode
+               else if (tool == TOOLMultiSelect)
+               {
+//                     QPoint pt = GetAdjustedMousePosition(event);
+                       Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                       selectionInProgress = true;
+                       selection.setTopLeft(QPoint(pt.x, pt.y));
+                       selection.setBottomRight(QPoint(pt.x, pt.y));
+               }
                else if (tool == TOOLAddPt)             // "Add Point" tool
                {
-                       QPoint pt = GetAdjustedMousePosition(event);
-                       IPoint pointToAdd(pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
+//                     QPoint pt = GetAdjustedMousePosition(event);
+                       Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                       IPoint pointToAdd(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
 
                        if (pts.GetNumPoints() < 2)
                        {
@@ -368,10 +418,11 @@ WriteLogMsg("Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.
                                pts.AddNewPolyAtEnd();
                        }
 
-                       QPoint pt = GetAdjustedMousePosition(event);
+//                     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(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
+                       pts += IPoint(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
                        ptHighlight = pts.GetNumPoints() - 1;
                        update();
 #ifdef DEBUGFOO
@@ -382,10 +433,12 @@ WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumP
                {
                        if (pts.GetNumPoints() > 0)
                        {
-                               pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+//                             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);
-                               QCursor::setPos(mapToGlobal(pt));
+                               QPoint warp(pt.x, pt.y);
+                               QCursor::setPos(mapToGlobal(warp));
 
                                if (event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier)
                                {
@@ -412,7 +465,8 @@ WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumP
                        // 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 = GetAdjustedMousePosition(event);
+                       rotationCenter = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
                        showRotationCenter = true;
                        haveZeroPoint = false;
                        rotationAngle = 0;
@@ -421,11 +475,12 @@ WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumP
                else if (tool == TOOLRotatePoly)
                {
                        IPoint centroid = pts.GetPolyCentroid(pts.GetPolyForPointNumber(ptHighlight));
-                       rotationCenter = QPoint(centroid.x, centroid.y);
+                       rotationCenter = Vector(centroid.x, centroid.y);
                        showRotationCenter = true;
-                       pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
-                       QCursor::setPos(mapToGlobal(pt));
-                       rotationZeroPoint = QPoint(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+//                     pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+                       Vector pt = Painter::QtToCartesianCoords(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;
                        rotationAngle = 0;
                        update();
@@ -433,8 +488,9 @@ WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumP
                else if (tool == TOOLFlipWinding)
                {
                        pts.InvertPolyDrawSequence(pts.GetPolyForPointNumber(ptHighlight));
-                       pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
-                       QCursor::setPos(mapToGlobal(pt));
+//                     pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+                       Vector pt = Painter::QtToCartesianCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
+                       QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
                        update();
                }
        }
@@ -458,13 +514,14 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
        else if (event->buttons() == Qt::MidButton)
        {
                // Calc offset from previous point
-               pt = event->pos();
-               ptOffset = QPoint(pt.x() - ptPrevious.x(), pt.y() - ptPrevious.y());
+               Vector pt(event->x(), event->y());
+               pt /= Global::zoom;
+               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();
+               offsetX -= ptOffset.x, offsetY += ptOffset.y;
                update();
                ptPrevious = pt;
        }
@@ -476,20 +533,22 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                        if (tool == TOOLSelect && pts.GetNumPoints() == 0)
                                return;
 
-                       QPoint pt2 = GetAdjustedMousePosition(event);
-                       pts.SetXY(ptHighlight, pt2.x(), pt2.y());
+//                     QPoint pt2 = GetAdjustedMousePosition(event);
+                       Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                       pts.SetXY(ptHighlight, pt2.x, pt2.y);
                        update();
                }
                else if (tool == TOOLPolySelect)
                {
                        if (pts.GetNumPoints() > 0)
                        {
-                               QPoint pt2 = GetAdjustedMousePosition(event);
+//                             QPoint pt2 = GetAdjustedMousePosition(event);
+                               Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
                                // Should also set onCurve here as well, depending on keystate
 //Or should we?
 //Would be nice, but we'd need to trap the keyPressEvent() as well, otherwise pressing/releasing
 //the hotkey would show no change until the user moved their mouse.
-                               pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x() - pts.GetX(ptHighlight), pt2.y() - pts.GetY(ptHighlight));
+                               pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x - pts.GetX(ptHighlight), pt2.y - pts.GetY(ptHighlight));
                                update();
                        }
                }
@@ -499,18 +558,20 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                        {
                                if (!haveZeroPoint)
                                {
-                                       rotationZeroPoint = GetAdjustedMousePosition(event);
+//                                     rotationZeroPoint = GetAdjustedMousePosition(event);
+                                       rotationZeroPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
                                        haveZeroPoint = true;
                                }
                                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())
-                                       QPoint currentPoint = GetAdjustedMousePosition(event);
-                                       Vector v1(rotationZeroPoint.x(), rotationZeroPoint.y(), 0,
-                                               rotationCenter.x(), rotationCenter.y(), 0);
-                                       Vector v2(currentPoint.x(), currentPoint.y(), 0,
-                                               rotationCenter.x(), rotationCenter.y(), 0);
+//                                     QPoint currentPoint = GetAdjustedMousePosition(event);
+                                       Vector currentPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                                       Vector v1(rotationZeroPoint.x, rotationZeroPoint.y, 0,
+                                               rotationCenter.x, rotationCenter.y, 0);
+                                       Vector v2(currentPoint.x, currentPoint.y, 0,
+                                               rotationCenter.x, rotationCenter.y, 0);
 //                                     rotationAngle = v1.Angle(v2);
                                        rotationAngle = v2.Angle(v1);
 
@@ -522,6 +583,22 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                                update();
                        }
                }
+               else if (tool == TOOLMultiSelect)
+               {
+//                     QPoint pt = GetAdjustedMousePosition(event);
+                       Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                       selection.setBottomRight(QPoint(pt.x, pt.y));
+
+                       for(int i=0; i<pts.GetNumPoints(); i++)
+                       {
+                               if (selection.contains(QPoint(pts.GetX(i), pts.GetY(i))))
+                                       selectedPoints[i] = true;
+                               else
+                                       selectedPoints[i] = false;
+                       }
+
+                       update();
+               }
        }
        else if (event->buttons() == Qt::NoButton)
        {
@@ -529,13 +606,14 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt
                        || tool == TOOLPolySelect || tool == TOOLRotatePoly || tool == TOOLFlipWinding)
                {
-                       QPoint pt2 = GetAdjustedMousePosition(event);
+//                     QPoint pt2 = GetAdjustedMousePosition(event);
+                       Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
                        double closest = 1.0e+99;
 
                        for(int i=0; i<pts.GetNumPoints(); i++)
                        {
-                               double dist = ((pt2.x() - pts.GetX(i)) * (pt2.x() - pts.GetX(i)))
-                                       + ((pt2.y() - pts.GetY(i)) * (pt2.y() - pts.GetY(i)));
+                               double dist = ((pt2.x - pts.GetX(i)) * (pt2.x - pts.GetX(i)))
+                                       + ((pt2.y - pts.GetY(i)) * (pt2.y - pts.GetY(i)));
 
                                if (dist < closest)
                                        closest = dist, ptHighlight = i;
@@ -547,15 +625,17 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                                update();
                        }
 
-                       // What follows here looks like voodoo, but is really simple. What we do is
-                       // check to see if the mouse point has a perpendicular intersection with any of
-                       // the line segments. If it does, calculate the length of the perpendicular
-                       // and choose the smallest length. If there is no perpendicular, then choose the
-                       // length of line connecting the closer of either the first endpoint or the
-                       // second and choose the smallest of those.
+                       // What follows here looks like voodoo, but is really simple. What
+                       // we do is check to see if the mouse point has a perpendicular
+                       // intersection with any of the line segments. If it does,
+                       // calculate the length of the perpendicular and choose the
+                       // smallest length. If there is no perpendicular, then choose the
+                       // length of line connecting the closer of either the first
+                       // endpoint or the second and choose the smallest of those.
 
-                       // There is one bit of math that looks like voodoo to me ATM--will explain once
-                       // I understand it better (the calculation of the length of the perpendicular).
+                       // There is one bit of math that looks like voodoo to me ATM--will
+                       // explain once I understand it better (the calculation of the
+                       // length of the perpendicular).
 
                        if (pts.GetNumPoints() > 1 && tool == TOOLAddPt)
                        {
@@ -566,13 +646,15 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                                        int32_t p1x = pts.GetX(i), p1y = pts.GetY(i),
                                                p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
 
-                                       Vector ls(p2x, p2y, 0, p1x, p1y, 0), v1(pt2.x(), pt2.y(), 0, p1x, p1y, 0),
-                                               v2(pt2.x(), pt2.y(), 0, p2x, p2y, 0);
+                                       Vector ls(p2x, p2y, 0, p1x, p1y, 0),
+                                               v1(pt2.x, pt2.y, 0, p1x, p1y, 0),
+                                               v2(pt2.x, pt2.y, 0, p2x, p2y, 0);
                                        double pp = ls.Dot(v1) / ls.Magnitude(), dist;
 // Geometric interpretation:
-// pp is the paremeterized point on the vector ls where the perpendicular intersects ls.
-// If pp < 0, then the perpendicular lies beyond the 1st endpoint. If pp > length of ls,
-// then the perpendicular lies beyond the 2nd endpoint.
+// pp is the paremeterized point on the vector ls where the perpendicular
+// intersects ls. If pp < 0, then the perpendicular lies beyond the 1st
+// endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd
+// endpoint.
 
                                        if (pp < 0.0)
                                                dist = v1.Magnitude();
@@ -583,12 +665,14 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
 
 //The answer to the above looks like it might be found here:
 //
-//If the segment endpoints are s and e, and the point is p, then the test for the perpendicular
-//intercepting the segment is equivalent to insisting that the two dot products {s-e}.{s-p} and
-//{e-s}.{e-p} are both non-negative.  Perpendicular distance from the point to the segment is
-//computed by first computing the area of the triangle the three points form, then dividing by the
-//length of the segment.  Distances are done just by the Pythagorean theorem.  Twice the area of the
-//triangle formed by three points is the determinant of the following matrix:
+//If the segment endpoints are s and e, and the point is p, then the test for
+//the perpendicular intercepting the segment is equivalent to insisting that
+//the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
+//Perpendicular distance from the point to the segment is computed by first
+//computing the area of the triangle the three points form, then dividing by
+//the length of the segment.  Distances are done just by the Pythagorean
+//theorem. Twice the area of the triangle formed by three points is the
+//determinant of the following matrix:
 //
 //sx sy 1
 //ex ey 1
@@ -596,8 +680,9 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
 //
 //By translating the start point to the origin, this can be rewritten as:
 //By subtracting row 1 from all rows, you get the following:
-//[because sx = sy = 0. you could leave out the -sx/y terms below. because we subtracted
-// row 1 from all rows (including row 1) row 1 turns out to be zero. duh!]
+//[because sx = sy = 0. you could leave out the -sx/y terms below. because we
+//subtracted row 1 from all rows (including row 1) row 1 turns out to be zero.
+//duh!]
 //
 //0         0         0
 //(ex - sx) (ey - sy) 0
@@ -617,7 +702,7 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event)
                        }
                }
 
-               ptPrevious = event->pos();
+               ptPrevious = Vector(event->x(), event->y());
        }
 
        event->accept();
@@ -660,7 +745,7 @@ void EditWindow::mouseReleaseEvent(QMouseEvent * event)
                        haveZeroPoint = false;
 
                        if (tool == TOOLRotate)
-                               pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x(), rotationCenter.y()));
+                               pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
                        else
                        {
                                uint16_t poly = pts.GetPolyForPointNumber(ptHighlight);
@@ -677,6 +762,11 @@ void EditWindow::mouseReleaseEvent(QMouseEvent * event)
                ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
                ((TTEdit *)qApp)->charWnd->update();
 
+               if (tool == TOOLMultiSelect)
+               {
+                       selectionInProgress = false;
+                       update();
+               }
        }
 
        event->accept();