2 // TTEDIT.CPP - The TrueType Editor
4 // (C) 2004 Underground Software
6 // JLH = James L. Hammons <jlhamm@acm.org>
9 // --- ---------- -----------------------------------------------------------
10 // JLH 08/28/2008 Created this file
11 // JLH 09/02/2008 Separated scrolling from dedicated tool to MMB drag
12 // JLH 03/13/2009 Converted from wxWidgets to Qt
21 // - Fix bug in Glyphpoints when dragging on an empty canvas or loading a font
22 // - Fix zooming, settings (ini)
23 // - Fix point adding bug 1: should be able to add points to empty canvas
24 // - Fix point adding bug 2: should be able to add point successfully to single
26 // - Add poly multi-select
27 // - Add point multi-select
31 // Uncomment this for debugging...
33 #define DEBUGFOO // Various tool debugging...
34 #define DEBUGTP // Toolpalette debugging...
36 #include "editwindow.h"
37 #include "charwindow.h"
40 #include "mainwindow.h"
45 EditWindow::EditWindow(QWidget * parent/*= NULL*/): QWidget(parent),
46 tool(TOOLSelect), ptHighlight(-1), oldPtHighlight(-1), ptNextHighlight(-1),
47 oldPtNextHighlight(-1), polyFirstPoint(true), showRotationCenter(false),
48 haveZeroPoint(false), selectionInProgress(false)
50 setBackgroundRole(QPalette::Base);
51 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
53 toolPalette = new ToolWindow();
55 setCursor(cur[TOOLSelect]);
56 setMouseTracking(true);
61 QSize EditWindow::minimumSizeHint() const
67 QSize EditWindow::sizeHint() const
69 return QSize(400, 400);
73 void EditWindow::CreateCursors(void)
75 int hotx[12] = { 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 1, 11 };
76 int hoty[12] = { 1, 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 11 };
77 char cursorName[12][48] = { "select", "select-poly", "select-multi", "zoom",
78 "add-point", "add-poly", "del-point", "del-poly", "rotate", "rotate",
81 for(int i=0; i<12; i++)
83 QPixmap pmTmp(QString(":/res/cursor-%1.png").arg(cursorName[i]));
84 cur[i] = QCursor(pmTmp, hotx[i], hoty[i]);
91 o Different colors for polys on selected points
92 o Different colors for handles on non-selected polys
93 o Line of sight (dashed, dotted) for off-curve points
94 o Repaints for press/release of CTRL/SHIFT during point creation
96 void EditWindow::paintEvent(QPaintEvent * /*event*/)
99 Painter painter(&qtp);
100 painter.SetRenderHint(QPainter::Antialiasing);
102 Global::viewportHeight = size().height();
103 Global::screenSize = Vector(size().width(), size().height());
105 // Draw coordinate axes
107 painter.SetPen(QPen(Qt::blue, 1.0, Qt::DotLine));
108 painter.DrawLine(0, -16384, 0, 16384);
109 painter.DrawLine(-16384, 0, 16384, 0);
111 // Draw rotation center (if active)
113 if (showRotationCenter)
115 painter.SetPen(QPen(Qt::red, 2.0, Qt::SolidLine));
116 painter.DrawLine(rotationCenter.x + 7, rotationCenter.y, rotationCenter.x - 7, rotationCenter.y);
117 painter.DrawLine(rotationCenter.x, rotationCenter.y + 7, rotationCenter.x, rotationCenter.y - 7);
122 for(int i=0; i<pts.GetNumPoints(); i++)
124 /*if (tool == TOOLMultiSelect)
126 if (selectedPoints[i])
128 qtp.setPen(QPen(Qt::red, 1.0, Qt::SolidLine));
132 qtp.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
136 if (((i == ptHighlight) && (tool != TOOLMultiSelect)) || ((tool == TOOLMultiSelect) && selectedPoints[i]))
138 painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
140 if (pts.GetOnCurve(i))
142 painter.DrawSquareDotN(pts.GetXY(i), 7);
143 painter.DrawSquareDotN(pts.GetXY(i), 9);
147 painter.DrawRoundDotN(pts.GetXY(i), 7);
148 painter.DrawRoundDotN(pts.GetXY(i), 9);
151 else if ((i == ptHighlight || i == ptNextHighlight) && tool == TOOLAddPt)
153 painter.SetPen(QPen(Qt::green, 1.0, Qt::SolidLine));
155 if (pts.GetOnCurve(i))
157 painter.DrawSquareDotN(pts.GetXY(i), 7);
158 painter.DrawSquareDotN(pts.GetXY(i), 9);
162 painter.DrawRoundDotN(pts.GetXY(i), 7);
163 painter.DrawRoundDotN(pts.GetXY(i), 9);
168 painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
171 if (pts.GetOnCurve(i))
172 painter.DrawSquareDot(pts.GetXY(i));
174 painter.DrawRoundDot(pts.GetXY(i));
176 (pts.GetOnCurve(i) ? DrawSquareDot(p, pts.GetX(i), pts.GetY(i))
177 : DrawRoundDot(p, pts.GetX(i), pts.GetY(i)));
181 if (tool == TOOLDelPt && i == ptHighlight)
183 painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
184 painter.DrawLine(pts.GetX(i) - 5, pts.GetY(i) - 5, pts.GetX(i) + 5, pts.GetY(i) + 5);
185 painter.DrawLine(pts.GetX(i) + 5, pts.GetY(i) - 5, pts.GetX(i) - 5, pts.GetY(i) + 5);
189 // Draw highlighted point on poly add tool
190 if (tool == TOOLAddPoly)
192 painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
196 painter.DrawSquareDotN(addPoint, 7);
197 painter.DrawSquareDotN(addPoint, 9);
201 painter.DrawRoundDotN(addPoint, 7);
202 painter.DrawRoundDotN(addPoint, 9);
206 // Draw curve formed by points
208 painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
209 DrawGlyph(painter, pts);
214 GlyphPoints rotated = pts;
216 if (tool == TOOLRotate)
217 rotated.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
218 else if (tool == TOOLRotatePoly)
220 uint16_t poly = rotated.GetPolyForPointNumber(ptHighlight);
221 rotated.RotatePolyAroundCentroid(poly, rotationAngle);
224 painter.SetPen(QPen(QColor(255, 0, 255), 1.0, Qt::SolidLine));
225 DrawGlyph(painter, rotated);
228 if (selectionInProgress)
230 painter.SetPen(QPen(QColor(255, 127, 0, 255)));
231 painter.SetBrush(QBrush(QColor(255, 127, 0, 100)));
232 painter.DrawRect(selection);
237 void EditWindow::DrawGlyph(Painter & p, GlyphPoints & glyph)
239 for(int poly=0; poly<glyph.GetNumPolys(); poly++)
242 if (glyph.GetNumPoints(poly) < 3)
245 // Initial move: If our start point is on curve, then go to it. Otherwise,
246 // check previous point. If it's on curve, go to it otherwise go the
247 // midpoint between start point and previous (since it's between two curve
249 IPoint pt = (glyph.GetOnCurve(poly, 0)
250 ? glyph.GetPoint(poly, 0) : (glyph.GetPrevOnCurve(poly, 0)
251 ? glyph.GetPrevPoint(poly, 0) : glyph.GetMidpointToPrev(poly, 0)));
253 // Need to add separate color handling here for polys that are being manipulated...
255 for(int i=0; i<glyph.GetNumPoints(poly); i++)
257 // If this point and then next are both on curve, we have a line...
258 if (glyph.GetOnCurve(poly, i) && glyph.GetNextOnCurve(poly, i))
260 IPoint pt2 = glyph.GetNextPoint(poly, i);
261 p.drawLine(pt.x, pt.y, pt2.x, pt2.y);
266 // Skip point if it's on curve (start of curve--it's already
267 // been plotted so we don't need to handle it...)
268 if (glyph.GetOnCurve(poly, i))
271 // We are now guaranteed that we are sitting on a curve control point
272 // (off curve). Figure the extent of the curve: If the following is a
273 // curve control point, then use the midpoint to it otherwise go to
274 // the next point since it's on curve.
275 IPoint pt2 = (glyph.GetNextOnCurve(poly, i)
276 ? glyph.GetNextPoint(poly, i) : glyph.GetMidpointToNext(poly, i));
278 Bezier(p, pt, glyph.GetPoint(poly, i), pt2);
283 DrawGlyphPoly(p, glyph, poly);
290 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
291 to change the color of the line(s) drawn to the point to signal to the user
292 that it isn't finalized until they click the button.
294 void EditWindow::DrawGlyphPoly(Painter & p, GlyphPoints & glyph, uint16_t poly)
297 if (glyph.GetNumPoints(poly) < 3)
300 IPoint p1 = glyph.GetPrevPoint(poly, 0);
301 IPoint p2 = glyph.GetPoint(poly, 0);
303 // Inject the new poly point into the current polygon
304 if ((tool == TOOLAddPoly) && (poly == (glyph.GetNumPolys() - 1)))
306 p1 = IPoint(addPoint.x, addPoint.y, addPointOnCurve);
309 for(int i=0; i<glyph.GetNumPoints(poly); i++)
311 IPoint p3 = glyph.GetNextPoint(poly, i);
313 if ((tool == TOOLAddPoly) && (poly == (glyph.GetNumPolys() - 1))
314 && (i == (glyph.GetNumPoints(poly) - 1)))
316 p3 = IPoint(addPoint.x, addPoint.y, addPointOnCurve);
317 p.SetPen(QPen(Qt::green, 1.0, Qt::SolidLine));
318 DrawGlyphSegment(p, p1, p2, p3);
321 p3 = glyph.GetNextPoint(poly, i);
324 DrawGlyphSegment(p, p1, p2, p3);
333 // Draw a glyph segment given 3 points
335 void EditWindow::DrawGlyphSegment(Painter & p, IPoint p1, IPoint p2, IPoint p3)
339 // Skip drawing if the middle point is on curve and the last is off
345 // The middle point is off curve, and so we need to draw a Bezier curve.
346 // Also, depending on whether or not the previous or follow points are
347 // off curve, we need to draw to the midpoints if so.
348 IPoint mid12 = IPoint((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
349 IPoint mid23 = IPoint((p2.x + p3.x) / 2, (p2.y + p3.y) / 2);
350 p.DrawBezier((p1.onCurve ? p1 : mid12), p2, (p3.onCurve ? p3 : mid23));
355 void EditWindow::ClearSelection(void)
357 for(int i=0; i<65536; i++)
358 selectedPoints[i] = false;
362 void EditWindow::mousePressEvent(QMouseEvent * event)
364 if (event->button() == Qt::RightButton)
366 toolPalette->move(event->globalPos());
367 toolPalette->setVisible(true);
368 setCursor(cur[TOOLSelect]);
369 toolPalette->prevTool = TOOLSelect;
371 else if (event->button() == Qt::MidButton)
375 ptPrevious = Vector(event->x(), event->y());
376 ptPrevious /= Global::zoom;
378 else if (event->button() == Qt::LeftButton)
380 if (tool == TOOLScroll || tool == TOOLZoom)
381 ;//meh CaptureMouse(); // Make sure we capture the mouse when in scroll/zoom mode
382 else if (tool == TOOLMultiSelect)
384 // QPoint pt = GetAdjustedMousePosition(event);
385 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
386 selectionInProgress = true;
387 selection.setTopLeft(QPoint(pt.x, pt.y));
388 selection.setBottomRight(QPoint(pt.x, pt.y));
390 else if (tool == TOOLAddPt) // "Add Point" tool
392 // QPoint pt = GetAdjustedMousePosition(event);
393 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
394 IPoint pointToAdd(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
396 if (pts.GetNumPoints() < 2)
398 // pts += IPoint(pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
400 ptHighlight = pts.GetNumPoints() - 1;
404 // QPoint pt = GetAdjustedMousePosition(event);
405 // pts.InsertPoint(pts.GetNext(ptHighlight), pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
406 pts.InsertPoint(pts.GetNext(ptHighlight), pointToAdd);
407 ptHighlight = ptNextHighlight;
413 // Moved to mouse up routine, so we can slide the point around
415 else if (tool == TOOLAddPoly) // "Add Poly" tool
418 WriteLogMsg("Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.GetNumPoints());
422 polyFirstPoint = false;
423 pts.AddNewPolyAtEnd();
426 // QPoint pt = GetAdjustedMousePosition(event);
427 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
428 //printf("GetAdjustedMousePosition = %i, %i\n", pt.x(), pt.y());
429 // Append a point to the end of the structure
430 pts += IPoint(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
431 ptHighlight = pts.GetNumPoints() - 1;
434 WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumPoints());
438 else if (tool == TOOLSelect || tool == TOOLPolySelect)
440 if (pts.GetNumPoints() > 0)
442 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
443 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
444 //printf("GetAdjustedClientPosition = %lf, %lf\n", pt.x, pt.y);
445 QPoint warp(pt.x, pt.y);
446 QCursor::setPos(mapToGlobal(warp));
448 if (event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier)
450 pts.SetOnCurve(ptHighlight, !pts.GetOnCurve(ptHighlight));
455 else if (tool == TOOLDelPt)
457 if (pts.GetNumPoints() > 0)
459 // if (ptHighlight != -1)
461 //This assumes that WM_MOUSEMOVE happens before this!
462 //The above commented out line should take care of this contingency... !!! FIX !!!
463 pts.DeletePoint(ptHighlight);
467 else if (tool == TOOLRotate)
469 // I think what's needed here is to keep the initial mouse click,
470 // paint the rotation center, then use the 1st mouse move event to
471 // establish the rotation "zero line", which becomes the line of
472 // reference to all subsequent mouse moves.
473 // rotationCenter = GetAdjustedMousePosition(event);
474 rotationCenter = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
475 showRotationCenter = true;
476 haveZeroPoint = false;
480 else if (tool == TOOLRotatePoly)
482 IPoint centroid = pts.GetPolyCentroid(pts.GetPolyForPointNumber(ptHighlight));
483 rotationCenter = Vector(centroid.x, centroid.y);
484 showRotationCenter = true;
485 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
486 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
487 QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
488 rotationZeroPoint = Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
489 haveZeroPoint = true;
493 else if (tool == TOOLFlipWinding)
495 pts.InvertPolyDrawSequence(pts.GetPolyForPointNumber(ptHighlight));
496 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
497 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
498 QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
507 void EditWindow::mouseMoveEvent(QMouseEvent * event)
509 if (event->buttons() == Qt::RightButton)
511 ToolType newTool = toolPalette->FindSelectedTool();
513 if (newTool != toolPalette->prevTool)
515 toolPalette->prevTool = newTool;
516 toolPalette->repaint();
519 else if (event->buttons() == Qt::MidButton)
521 // Calc offset from previous point
522 Vector pt(event->x(), event->y());
524 ptOffset = Vector(pt.x - ptPrevious.x, -(pt.y - ptPrevious.y));
526 // Then multiply it by the scaling factor. Whee!
527 // This looks wacky because we're using screen coords for the offset...
528 // Otherwise, we would subtract both offsets!
529 // offsetX -= ptOffset.x, offsetY += ptOffset.y;
530 Global::origin -= ptOffset;
534 else if (event->buttons() == Qt::LeftButton)
536 if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect)
538 // Bail out if we have the select tool and no points yet...
539 if ((tool == TOOLSelect) && (pts.GetNumPoints() == 0))
542 // QPoint pt2 = GetAdjustedMousePosition(event);
543 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
545 if (tool != TOOLSelect)
549 // Prolly should move this to the key handlers below...
551 // addPointOnCurve = ((event->modifiers() == Qt::ShiftModifier) || (event->modifiers() == Qt::ControlModifier) ? false : true);
554 pts.SetXY(ptHighlight, pt2.x, pt2.y);
558 else if (tool == TOOLPolySelect)
560 if (pts.GetNumPoints() > 0)
562 // QPoint pt2 = GetAdjustedMousePosition(event);
563 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
564 // Should also set onCurve here as well, depending on keystate
566 //Would be nice, but we'd need to trap the keyPressEvent() as well, otherwise pressing/releasing
567 //the hotkey would show no change until the user moved their mouse.
568 pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x - pts.GetX(ptHighlight), pt2.y - pts.GetY(ptHighlight));
572 else if (tool == TOOLRotate || tool == TOOLRotatePoly)
574 if (pts.GetNumPoints() > 0)
578 // rotationZeroPoint = GetAdjustedMousePosition(event);
579 rotationZeroPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
580 haveZeroPoint = true;
584 // Figure out the angle between the "zero" vector and the current one,
585 // then rotate all points relative to the "zero" vector (done by paint())
586 // QPoint currentPoint = GetAdjustedMousePosition(event);
587 Vector currentPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
588 Vector v1(rotationZeroPoint.x, rotationZeroPoint.y, 0,
589 rotationCenter.x, rotationCenter.y, 0);
590 Vector v2(currentPoint.x, currentPoint.y, 0,
591 rotationCenter.x, rotationCenter.y, 0);
592 // rotationAngle = v1.Angle(v2);
593 rotationAngle = v2.Angle(v1);
596 s.sprintf("%.3f degrees", rotationAngle * 180.0 / 3.14159265358979323);
597 ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage(s);
603 else if (tool == TOOLMultiSelect)
605 // QPoint pt = GetAdjustedMousePosition(event);
606 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
607 selection.setBottomRight(QPoint(pt.x, pt.y));
609 for(int i=0; i<pts.GetNumPoints(); i++)
611 if (selection.contains(QPoint(pts.GetX(i), pts.GetY(i))))
612 selectedPoints[i] = true;
614 selectedPoints[i] = false;
620 else if (event->buttons() == Qt::NoButton)
622 // Moving, not dragging...
623 if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt
624 || tool == TOOLPolySelect || tool == TOOLRotatePoly || tool == TOOLFlipWinding)
626 // QPoint pt2 = GetAdjustedMousePosition(event);
627 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
628 double closest = 1.0e+99;
630 for(int i=0; i<pts.GetNumPoints(); i++)
632 double dist = ((pt2.x - pts.GetX(i)) * (pt2.x - pts.GetX(i)))
633 + ((pt2.y - pts.GetY(i)) * (pt2.y - pts.GetY(i)));
636 closest = dist, ptHighlight = i;
639 if (ptHighlight != oldPtHighlight)
641 oldPtHighlight = ptHighlight;
645 // What follows here looks like voodoo, but is really simple. What
646 // we do is check to see if the mouse point has a perpendicular
647 // intersection with any of the line segments. If it does,
648 // calculate the length of the perpendicular and choose the
649 // smallest length. If there is no perpendicular, then choose the
650 // length of line connecting the closer of either the first
651 // endpoint or the second and choose the smallest of those.
653 // There is one bit of math that looks like voodoo to me ATM--will
654 // explain once I understand it better (the calculation of the
655 // length of the perpendicular).
657 if (pts.GetNumPoints() > 1 && tool == TOOLAddPt)
659 double smallest = 1.0e+99;
661 for(int i=0; i<pts.GetNumPoints(); i++)
663 int32_t p1x = pts.GetX(i), p1y = pts.GetY(i),
664 p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
666 Vector ls(p2x, p2y, 0, p1x, p1y, 0),
667 v1(pt2.x, pt2.y, 0, p1x, p1y, 0),
668 v2(pt2.x, pt2.y, 0, p2x, p2y, 0);
669 double pp = ls.Dot(v1) / ls.Magnitude(), dist;
670 // Geometric interpretation:
671 // pp is the paremeterized point on the vector ls where the perpendicular
672 // intersects ls. If pp < 0, then the perpendicular lies beyond the 1st
673 // endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd
677 dist = v1.Magnitude();
678 else if (pp > ls.Magnitude())
679 dist = v2.Magnitude();
680 else // distance = ?Det?(ls, v1) / |ls|
681 dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.Magnitude());
683 //The answer to the above looks like it might be found here:
685 //If the segment endpoints are s and e, and the point is p, then the test for
686 //the perpendicular intercepting the segment is equivalent to insisting that
687 //the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
688 //Perpendicular distance from the point to the segment is computed by first
689 //computing the area of the triangle the three points form, then dividing by
690 //the length of the segment. Distances are done just by the Pythagorean
691 //theorem. Twice the area of the triangle formed by three points is the
692 //determinant of the following matrix:
698 //By translating the start point to the origin, this can be rewritten as:
699 //By subtracting row 1 from all rows, you get the following:
700 //[because sx = sy = 0. you could leave out the -sx/y terms below. because we
701 //subtracted row 1 from all rows (including row 1) row 1 turns out to be zero.
705 //(ex - sx) (ey - sy) 0
706 //(px - sx) (py - sy) 0
708 //which greatly simplifies the calculation of the determinant.
711 smallest = dist, ptNextHighlight = pts.GetNext(i), ptHighlight = i;
714 if (ptNextHighlight != oldPtNextHighlight)
716 oldPtNextHighlight = ptNextHighlight;
722 ptPrevious = Vector(event->x(), event->y());
723 addPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
724 //handled by real key handlers now...
725 // addPointOnCurve = ((event->modifiers() == Qt::ShiftModifier) || (event->modifiers() == Qt::ControlModifier) ? false : true);
727 if (tool == TOOLAddPoly)
735 void EditWindow::mouseReleaseEvent(QMouseEvent * event)
737 if (event->button() == Qt::RightButton)
739 ToolType newTool = toolPalette->FindSelectedTool();
741 // We only change the tool if a new one was actually selected. Otherwise, we do nothing.
742 if (newTool != TOOLNone)
746 if (tool == TOOLScroll || tool == TOOLZoom || tool == TOOLAddPoly
747 || tool == TOOLDelPoly)
750 if (tool == TOOLAddPoly)
751 polyFirstPoint = true;
754 toolPalette->setVisible(false);
755 setCursor(cur[tool]);
756 // Just in case we changed highlighting style with the new tool...
759 else if (event->button() == Qt::MidButton)
761 setCursor(cur[tool]); // Restore previous cursor
763 else if (event->button() == Qt::LeftButton)
765 if (showRotationCenter)
767 showRotationCenter = false;
768 haveZeroPoint = false;
770 if (tool == TOOLRotate)
771 pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
774 uint16_t poly = pts.GetPolyForPointNumber(ptHighlight);
775 pts.RotatePolyAroundCentroid(poly, rotationAngle);
779 ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage("");
782 // if (tool == TOOLScroll || tool == TOOLZoom)
784 //this is prolly too much
785 ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
786 ((TTEdit *)qApp)->charWnd->update();
788 if (tool == TOOLMultiSelect)
790 selectionInProgress = false;
793 else if (tool == TOOLAddPoly) // "Add Poly" tool
796 WriteLogMsg("Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.GetNumPoints());
800 polyFirstPoint = false;
801 pts.AddNewPolyAtEnd();
804 // QPoint pt = GetAdjustedMousePosition(event);
805 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
806 //printf("GetAdjustedMousePosition = %i, %i\n", pt.x(), pt.y());
807 // Append a point to the end of the structure
808 pts += IPoint(pt.x, pt.y, addPointOnCurve);
809 // ptHighlight = pts.GetNumPoints() - 1;
812 WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumPoints());
821 void EditWindow::keyPressEvent(QKeyEvent * event)
823 // We do this here because of the ptHighlight nonsense. If we're in
824 // the add poly tool, we'll never see this if it's under the 'sanity'
825 // check (which is needed for the arrow key shite, but still...)
826 if ((event->key() == Qt::Key_Shift) || (event->key() == Qt::Key_Control))
828 addPointOnCurve = false;
832 // Sanity checking...
833 if (ptHighlight == -1)
836 if (event->key() == Qt::Key_Up)
838 pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) + 1);
840 else if (event->key() == Qt::Key_Down)
841 pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) - 1);
842 else if (event->key() == Qt::Key_Right)
843 pts.SetXY(ptHighlight, pts.GetX(ptHighlight) + 1, pts.GetY(ptHighlight));
844 else if (event->key() == Qt::Key_Left)
845 pts.SetXY(ptHighlight, pts.GetX(ptHighlight) - 1, pts.GetY(ptHighlight));
849 //Not need but you need to call the base class for some reason??
852 ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
853 ((TTEdit *)qApp)->charWnd->update();
857 void EditWindow::keyReleaseEvent(QKeyEvent * event)
859 if ((event->key() == Qt::Key_Shift) || (event->key() == Qt::Key_Control))
861 addPointOnCurve = true;