X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Feditwindow.cpp;h=429943d2a7c707cfbcdc08cff1f0e894ce1319f9;hb=3ef71393f70213eb53db552605ae3c93f1303ee9;hp=f3cc70fdebc03d551e9186fc9efa898b92217202;hpb=0cdf0ebfb4b788156b8eb2c2acadd5f95fe5be26;p=ttedit diff --git a/src/editwindow.cpp b/src/editwindow.cpp index f3cc70f..429943d 100755 --- a/src/editwindow.cpp +++ b/src/editwindow.cpp @@ -34,17 +34,18 @@ #define DEBUGTP // Toolpalette debugging... #include "editwindow.h" -//#include -#include "graphicprimitives.h" -#include "debug.h" -#include "vector.h" #include "charwindow.h" +#include "debug.h" +#include "graphicprimitives.h" +#include "mainwindow.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) + polyFirstPoint(true), showRotationCenter(false), haveZeroPoint(false) { setBackgroundRole(QPalette::Base); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -55,30 +56,36 @@ EditWindow::EditWindow(QWidget * parent/*= NULL*/): QWidget(parent), setMouseTracking(true); } + QSize EditWindow::minimumSizeHint() const { return QSize(50, 50); } + QSize EditWindow::sizeHint() const { return QSize(400, 400); } + void EditWindow::CreateCursors(void) { - int hotx[8] = { 1, 1, 11, 15, 1, 1, 1, 1 }; - int hoty[8] = { 1, 1, 11, 13, 1, 1, 1, 1 }; + 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" }; - for(int i=0; i<8; i++) + for(int i=0; i<11; i++) { QString s; - s.sprintf(":/res/cursor%u.png", i+1); + s.sprintf(":/res/cursor-%s.png", cursorName[i]); QPixmap pmTmp(s); cur[i] = QCursor(pmTmp, hotx[i], hoty[i]); } } + QPoint EditWindow::GetAdjustedMousePosition(QMouseEvent * event) { QSize winSize = size(); @@ -88,6 +95,7 @@ QPoint EditWindow::GetAdjustedMousePosition(QMouseEvent * event) return QPoint(offsetX + event->x(), offsetY + (winSize.height() - event->y())); } + QPoint EditWindow::GetAdjustedClientPosition(int x, int y) { QSize winSize = size(); @@ -96,6 +104,7 @@ QPoint EditWindow::GetAdjustedClientPosition(int x, int y) return QPoint(-offsetX + x, (winSize.height() - (-offsetY + y)) * +1.0); } + /* TODO: o Different colors for polys on selected points @@ -108,17 +117,9 @@ 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); @@ -129,24 +130,28 @@ void EditWindow::paintEvent(QPaintEvent * /*event*/) // 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)); - // Draw coordinate axes + // Draw coordinate axes -// dc.CrossHair(0, 0); p.drawLine(0, -16384, 0, 16384); p.drawLine(-16384, 0, 16384, 0); - // Draw points + // 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); + } + + // 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)); if (pts.GetOnCurve(i)) @@ -162,8 +167,6 @@ void EditWindow::paintEvent(QPaintEvent * /*event*/) } 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)); if (pts.GetOnCurve(i)) @@ -179,8 +182,6 @@ void EditWindow::paintEvent(QPaintEvent * /*event*/) } else { -// dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0x00, 0x00, 0x00), 1, wxSOLID))); -//// SelectObject(hdc, hBlackPen1); p.setPen(QPen(Qt::black, 1.0, Qt::SolidLine)); if (pts.GetOnCurve(i)) @@ -191,75 +192,128 @@ void EditWindow::paintEvent(QPaintEvent * /*event*/) 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); } } -//// 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) + // Rotation code + GlyphPoints rotated = pts; + + if (tool == TOOLRotate) + rotated.RotatePoints(rotationAngle, IPoint(rotationCenter.x(), rotationCenter.y())); + else if (tool == TOOLRotatePoly) { - // Initial move... - // If it's not on curve, then move to it, otherwise move to last point... + uint16 poly = rotated.GetPolyForPointNumber(ptHighlight); + rotated.RotatePolyAroundCentroid(poly, rotationAngle); + } - int x, y; + p.setPen(QPen(QColor(255, 0, 255), 1.0, Qt::SolidLine)); + DrawGlyph(p, rotated); + } +} - 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); - for(int i=0; ibutton() == Qt::RightButton) @@ -279,13 +333,25 @@ void EditWindow::mousePressEvent(QMouseEvent * event) ;//meh CaptureMouse(); // Make sure we capture the mouse when in scroll/zoom mode else if (tool == TOOLAddPt) // "Add Point" tool { - if (pts.GetNumPoints() > 0) + QPoint pt = GetAdjustedMousePosition(event); + IPoint pointToAdd(pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true)); + + if (pts.GetNumPoints() < 2) { - QPoint pt = GetAdjustedMousePosition(event); - pts.InsertPoint(pts.GetNext(ptHighlight), 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)); + 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)); + pts.InsertPoint(pts.GetNext(ptHighlight), pointToAdd); ptHighlight = ptNextHighlight; - update(); +// update(); } + + update(); } else if (tool == TOOLAddPoly) // "Add Poly" tool { @@ -336,11 +402,43 @@ WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumP update(); } } + 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); + showRotationCenter = true; + haveZeroPoint = false; + rotationAngle = 0; + update(); + } + else if (tool == TOOLRotatePoly) + { + IPoint centroid = pts.GetPolyCentroid(pts.GetPolyForPointNumber(ptHighlight)); + rotationCenter = QPoint(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)); + haveZeroPoint = true; + rotationAngle = 0; + update(); + } + else if (tool == TOOLFlipWinding) + { + pts.InvertPolyDrawSequence(pts.GetPolyForPointNumber(ptHighlight)); + pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight)); + QCursor::setPos(mapToGlobal(pt)); + update(); + } } event->accept(); } + void EditWindow::mouseMoveEvent(QMouseEvent * event) { if (event->buttons() == Qt::RightButton) @@ -368,63 +466,64 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event) } else if (event->buttons() == Qt::LeftButton) { -#if 0 - if (tool == TOOLScroll) - { - // Extract current point from lParam/calc offset from previous point - - pt = e.GetPosition(); - ptOffset.x = pt.x - ptPrevious.x, - ptOffset.y = pt.y - ptPrevious.y; - - // NOTE: OffsetViewportOrg operates in DEVICE UNITS... - -//Seems there's no equivalent for this in wxWidgets...! -//!!! FIX !!! -// hdc = GetDC(hWnd); -// OffsetViewportOrgEx(hdc, ptOffset.x, ptOffset.y, NULL); -// ReleaseDC(hWnd, hdc); + 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) + return; -// this shows that it works, so the logic above must be faulty... -// And it is. It should convert the coords first, then do the subtraction to figure the offset... -// Above: DONE -// 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; - Refresh(); + QPoint pt2 = GetAdjustedMousePosition(event); + pts.SetXY(ptHighlight, pt2.x(), pt2.y()); + update(); + } + else if (tool == TOOLPolySelect) + { + if (pts.GetNumPoints() > 0) + { + QPoint pt2 = GetAdjustedMousePosition(event); + // 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)); + update(); } - else -#endif - if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect) + } + else if (tool == TOOLRotate || tool == TOOLRotatePoly) + { + if (pts.GetNumPoints() > 0) { - if (tool != TOOLAddPt || pts.GetNumPoints() > 0)//yecch. + if (!haveZeroPoint) { -//temporary, for testing. BTW, Select drag bug is here...! -#if 1 - QPoint pt2 = GetAdjustedMousePosition(event); - pts.SetXY(ptHighlight, pt2.x(), pt2.y()); - update(); -#endif + rotationZeroPoint = GetAdjustedMousePosition(event); + haveZeroPoint = true; } - } - else if (tool == TOOLPolySelect) - { - if (pts.GetNumPoints() > 0) + else { - QPoint pt2 = GetAdjustedMousePosition(event); - // 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)); - update(); + // 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); +// 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); } + + update(); } + } } else if (event->buttons() == 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); double closest = 1.0e+99; @@ -463,20 +562,20 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event) int32 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), + 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.length(), dist; + 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. if (pp < 0.0) - dist = v1.length(); - else if (pp > ls.length()) - dist = v2.length(); + dist = v1.Magnitude(); + else if (pp > ls.Magnitude()) + dist = v2.Magnitude(); else // distance = ?Det?(ls, v1) / |ls| - dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.length()); + dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.Magnitude()); //The answer to the above looks like it might be found here: // @@ -520,6 +619,7 @@ void EditWindow::mouseMoveEvent(QMouseEvent * event) event->accept(); } + void EditWindow::mouseReleaseEvent(QMouseEvent * event) { if (event->button() == Qt::RightButton) @@ -550,12 +650,41 @@ void EditWindow::mouseReleaseEvent(QMouseEvent * event) } else if (event->button() == Qt::LeftButton) { + if (showRotationCenter) + { + showRotationCenter = false; + haveZeroPoint = false; + + if (tool == TOOLRotate) + pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x(), rotationCenter.y())); + else + { + uint16 poly = pts.GetPolyForPointNumber(ptHighlight); + pts.RotatePolyAroundCentroid(poly, rotationAngle); + } + + update(); + ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage(""); + } + // if (tool == TOOLScroll || tool == TOOLZoom) // ReleaseMouse(); //this is prolly too much ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts); ((TTEdit *)qApp)->charWnd->update(); + } event->accept(); } + + +void EditWindow::keyPressEvent(QKeyEvent * event) +{ +} + + +void EditWindow::keyReleaseEvent(QKeyEvent * event) +{ +} +