X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Feditwindow.cpp;h=dac63c28c736d5d3b2cf8bb8d9e8f151684bccec;hb=refs%2Fheads%2Fmaster;hp=89a4ef85d056a1e5912fde8b68623346c8378e35;hpb=3e731f52cfd35364e9516d09d00b61dd6fdc1919;p=ttedit diff --git a/src/editwindow.cpp b/src/editwindow.cpp old mode 100755 new mode 100644 index 89a4ef8..dac63c2 --- a/src/editwindow.cpp +++ b/src/editwindow.cpp @@ -6,7 +6,7 @@ // JLH = James L. Hammons // // 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,16 +36,17 @@ #include "editwindow.h" #include "charwindow.h" #include "debug.h" -#include "graphicprimitives.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) + 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); @@ -54,6 +55,7 @@ EditWindow::EditWindow(QWidget * parent/*= NULL*/): QWidget(parent), CreateCursors(); setCursor(cur[TOOLSelect]); setMouseTracking(true); + ClearSelection(); } @@ -71,40 +73,20 @@ QSize EditWindow::sizeHint() const void EditWindow::CreateCursors(void) { - int hotx[10] = { 1, 1, 11, 15, 1, 1, 1, 1, 1, 1 }; - int hoty[10] = { 1, 1, 11, 13, 1, 1, 1, 1, 1, 1 }; - char cursorName[10][48] = { "select", "select-poly", "scroll", "zoom", "add-point", - "add-poly", "del-point", "del-poly", "rotate", "rotate" }; + 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<10; i++) + 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) -{ - 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())); -} - - -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); -} - - /* TODO: o Different colors for polys on selected points @@ -114,274 +96,267 @@ TODO: */ void EditWindow::paintEvent(QPaintEvent * /*event*/) { - QPainter p(this); -//hm, causes lockup (or does it???) - p.setRenderHint(QPainter::Antialiasing); -//Doesn't do crap! -//dc.SetBackground(*wxWHITE_BRUSH); - -// Due to the screwiness of wxWidgets coord system, the origin is ALWAYS -// the upper left corner--regardless of axis orientation, etc... -// int width, height; -// dc.GetSize(&width, &height); - QSize winSize = size(); - -// dc.SetDeviceOrigin(-offsetX, height - (-offsetY)); -// dc.SetAxisOrientation(true, true); - p.translate(QPoint(-offsetX, winSize.height() - (-offsetY))); - p.scale(1.0, -1.0); - -// 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... - -// dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0x00, 0x00, 0xFF), 1, wxDOT))); -//// dc.DrawLine(0, 0, 10, 10); - p.setPen(QPen(Qt::blue, 1.0, Qt::DotLine)); + QPainter qtp(this); + Painter painter(&qtp); + painter.SetRenderHint(QPainter::Antialiasing); + + Global::viewportHeight = size().height(); + Global::screenSize = Vector(size().width(), size().height()); // Draw coordinate axes -// dc.CrossHair(0, 0); - p.drawLine(0, -16384, 0, 16384); - p.drawLine(-16384, 0, 16384, 0); + painter.SetPen(QPen(Qt::blue, 1.0, Qt::DotLine)); + 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; iFindOrCreatePen(wxColour(0xFF, 0x00, 0x00), 1, wxSOLID))); -//// SelectObject(hdc, hRedPen1); - p.setPen(QPen(Qt::red, 1.0, Qt::SolidLine)); + 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) { -// dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0x00, 0xAF, 0x00), 1, wxSOLID))); -//// SelectObject(hdc, hGreenPen1); - 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 { -// dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0x00, 0x00, 0x00), 1, wxSOLID))); -//// SelectObject(hdc, hBlackPen1); - 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) { -#if 0 - dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0xFF, 0x00, 0x00), 1, wxSOLID))); -// SelectObject(hdc, hRedPen1); -// MoveToEx(hdc, pts.GetX(i) - 5, pts.GetY(i) - 5, NULL); -// LineTo(hdc, pts.GetX(i) + 5, pts.GetY(i) + 5); -// LineTo(hdc, pts.GetX(i) - 5, pts.GetY(i) - 5);//Lameness! -// MoveToEx(hdc, pts.GetX(i) - 5, pts.GetY(i) + 5, NULL); -// LineTo(hdc, pts.GetX(i) + 5, pts.GetY(i) - 5); -// LineTo(hdc, pts.GetX(i) - 5, pts.GetY(i) + 5);//More lameness!! -#endif - 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); } } -//// SelectObject(hdc, hBlackPen1); -// dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0x00, 0x00, 0x00), 1, wxSOLID))); - p.setPen(QPen(Qt::black, 1.0, Qt::SolidLine)); - - // Draw curve formed by points - - for(int poly=0; poly 2) - { - // Initial move... - // If it's not on curve, then move to it, otherwise move to last point... + painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine)); - int x, y; + if (addPointOnCurve) + { + painter.DrawSquareDotN(addPoint, 7); + painter.DrawSquareDotN(addPoint, 9); + } + else + { + painter.DrawRoundDotN(addPoint, 7); + painter.DrawRoundDotN(addPoint, 9); + } + } - if (pts.GetOnCurve(poly, pts.GetNumPoints(poly) - 1)) - x = (int)pts.GetX(poly, pts.GetNumPoints(poly) - 1), y = (int)pts.GetY(poly, pts.GetNumPoints(poly) - 1); - else - x = (int)pts.GetX(poly, 0), y = (int)pts.GetY(poly, 0); + // Draw curve formed by points - for(int i=0; i 2) + // If this point and then next are both on curve, we have a line... + if (glyph.GetOnCurve(poly, i) && glyph.GetNextOnCurve(poly, i)) { - // Initial move... - // If it's not on curve, then move to it, otherwise move to last point... - - int x, y; + IPoint pt2 = glyph.GetNextPoint(poly, i); + p.drawLine(pt.x, pt.y, pt2.x, pt2.y); + pt = pt2; + } + else + { + // 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; - if (rotated.GetOnCurve(poly, rotated.GetNumPoints(poly) - 1)) - x = (int)rotated.GetX(poly, rotated.GetNumPoints(poly) - 1), y = (int)rotated.GetY(poly, rotated.GetNumPoints(poly) - 1); - else - x = (int)rotated.GetX(poly, 0), y = (int)rotated.GetY(poly, 0); + // 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)); - for(int i=0; i 2) - { - // Initial move... - // If it's not on curve, then move to it, otherwise move to last point... + // Sanity check + if (glyph.GetNumPoints(poly) < 3) + return; - int x, y; + IPoint p1 = glyph.GetPrevPoint(poly, 0); + IPoint p2 = glyph.GetPoint(poly, 0); - if (glyph.GetOnCurve(poly, glyph.GetNumPoints(poly) - 1)) - x = (int)glyph.GetX(poly, glyph.GetNumPoints(poly) - 1), y = (int)glyph.GetY(poly, glyph.GetNumPoints(poly) - 1); - else - x = (int)glyph.GetX(poly, 0), y = (int)glyph.GetY(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; ibutton() == 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 { - if (pts.GetNumPoints() > 0) +// 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) + { +// pts += IPoint(pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true)); + pts += pointToAdd; + ptHighlight = pts.GetNumPoints() - 1; + } + else { - QPoint pt = GetAdjustedMousePosition(event); - pts.InsertPoint(pts.GetNext(ptHighlight), pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true)); +// QPoint pt = GetAdjustedMousePosition(event); +// pts.InsertPoint(pts.GetNext(ptHighlight), pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true)); + pts.InsertPoint(pts.GetNext(ptHighlight), pointToAdd); ptHighlight = ptNextHighlight; - update(); +// update(); } + + update(); } +// Moved to mouse up routine, so we can slide the point around +#if 0 else if (tool == TOOLAddPoly) // "Add Poly" tool { #ifdef DEBUGFOO @@ -423,24 +424,27 @@ 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 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)); -//printf("GetAdjustedClientPosition = %i, %i\n", pt.x(), pt.y()); -// WarpPointer(pt.x, pt.y); - QCursor::setPos(mapToGlobal(pt)); +// pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight)); + 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)); if (event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) { @@ -464,15 +468,37 @@ 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. - rotationCenter = GetAdjustedMousePosition(event); + // 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; haveZeroPoint = false; rotationAngle = 0; update(); } + else if (tool == TOOLRotatePoly) + { + IPoint centroid = pts.GetPolyCentroid(pts.GetPolyForPointNumber(ptHighlight)); + rotationCenter = Vector(centroid.x, centroid.y); + showRotationCenter = true; +// pt = GetAdjustedClientPosition(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; + rotationAngle = 0; + update(); + } + else if (tool == TOOLFlipWinding) + { + pts.InvertPolyDrawSequence(pts.GetPolyForPointNumber(ptHighlight)); +// pt = GetAdjustedClientPosition(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(); + } } event->accept(); @@ -494,84 +520,119 @@ 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(); - 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) { - if (tool != TOOLAddPt || pts.GetNumPoints() > 0)//yecch. + // Bail out if we have the select tool and no points yet... + if ((tool == TOOLSelect) && (pts.GetNumPoints() == 0)) + return; + +// QPoint pt2 = GetAdjustedMousePosition(event); + Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y())); + + if (tool != TOOLSelect) { -//temporary, for testing. BTW, Select drag bug is here...! -#if 1 - QPoint pt2 = GetAdjustedMousePosition(event); - pts.SetXY(ptHighlight, pt2.x(), pt2.y()); - update(); -#endif + 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) { 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? - pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x() - pts.GetX(ptHighlight), pt2.y() - pts.GetY(ptHighlight)); +//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)); update(); } } - else if (tool == TOOLRotate) + else if (tool == TOOLRotate || tool == TOOLRotatePoly) { if (pts.GetNumPoints() > 0) { 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); + // 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, + 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); 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(); } } + 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; ibuttons() == Qt::NoButton) { // Moving, not dragging... if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt - || tool == TOOLPolySelect)// || tool == TOOLAddPoly) + || 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 1 && tool == TOOLAddPt) { @@ -599,16 +662,18 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event) for(int i=0; i 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(); @@ -619,12 +684,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 @@ -632,8 +699,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 @@ -653,7 +721,13 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event) } } - ptPrevious = event->pos(); + 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(); @@ -694,18 +768,103 @@ void EditWindow::mouseReleaseEvent(QMouseEvent * event) { showRotationCenter = false; haveZeroPoint = false; - pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x(), rotationCenter.y())); + + if (tool == TOOLRotate) + pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y)); + else + { + uint16_t poly = pts.GetPolyForPointNumber(ptHighlight); + pts.RotatePolyAroundCentroid(poly, rotationAngle); + } + 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(); } + + +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; + + if (event->key() == Qt::Key_Up) + { + pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) + 1); + } + else if (event->key() == Qt::Key_Down) + pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) - 1); + else if (event->key() == Qt::Key_Right) + pts.SetXY(ptHighlight, pts.GetX(ptHighlight) + 1, pts.GetY(ptHighlight)); + else if (event->key() == Qt::Key_Left) + pts.SetXY(ptHighlight, pts.GetX(ptHighlight) - 1, pts.GetY(ptHighlight)); + else + return; + +//Not need but you need to call the base class for some reason?? +// event->accept(); + update(); + Global::charWnd->MakePathFromPoints(&pts); + Global::charWnd->update(); +} + + +void EditWindow::keyReleaseEvent(QKeyEvent * event) +{ + if ((event->key() == Qt::Key_Shift) || (event->key() == Qt::Key_Control)) + { + addPointOnCurve = true; + } + else + return; + + update(); +} +