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 scale(1.0), offsetX(-10), offsetY(-10), tool(TOOLSelect),
47 ptHighlight(-1), oldPtHighlight(-1), ptNextHighlight(-1), oldPtNextHighlight(-1),
48 polyFirstPoint(true), showRotationCenter(false), haveZeroPoint(false),
49 selectionInProgress(false)
51 setBackgroundRole(QPalette::Base);
52 setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
54 toolPalette = new ToolWindow();
56 setCursor(cur[TOOLSelect]);
57 setMouseTracking(true);
62 QSize EditWindow::minimumSizeHint() const
68 QSize EditWindow::sizeHint() const
70 return QSize(400, 400);
74 void EditWindow::CreateCursors(void)
76 int hotx[12] = { 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 1, 11 };
77 int hoty[12] = { 1, 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 11 };
78 char cursorName[12][48] = { "select", "select-poly", "select-multi", "zoom",
79 "add-point", "add-poly", "del-point", "del-poly", "rotate", "rotate",
82 for(int i=0; i<12; i++)
85 s.sprintf(":/res/cursor-%s.png", cursorName[i]);
87 cur[i] = QCursor(pmTmp, hotx[i], hoty[i]);
92 QPoint EditWindow::GetAdjustedMousePosition(QMouseEvent * event)
94 // This is undoing the transform, e.g. going from client coords to local
95 // coords. In essence, the height - y is height + (y * -1), the (y * -1)
96 // term doing the conversion of the y-axis from increasing bottom to top.
97 return QPoint(offsetX + event->x(), offsetY + (size().height() - event->y()));
101 QPoint EditWindow::GetAdjustedClientPosition(int x, int y)
103 // VOODOO ALERT (ON Y COMPONENT!!!!)
104 return QPoint(-offsetX + x, (size().height() - (-offsetY + y)) * +1.0);
110 o Different colors for polys on selected points
111 o Different colors for handles on non-selected polys
112 o Line of sight (dashed, dotted) for off-curve points
113 o Repaints for press/release of CTRL/SHIFT during point creation
115 void EditWindow::paintEvent(QPaintEvent * /*event*/)
118 Painter painter(&qtp);
119 //hm, causes lockup (or does it???)
120 //& it doesn't help with our Bezier rendering code :-P
121 painter.SetRenderHint(QPainter::Antialiasing);
123 Global::zoom = scale;
124 Global::origin = Vector(offsetX, offsetY);
125 Global::viewportHeight = size().height();
126 Global::screenSize = Vector(size().width(), size().height());
127 // p.translate(QPoint(-offsetX, size().height() - (-offsetY)));
128 // p.scale(1.0, -1.0);
129 //Nope, a big load of shit. So we'll have to bite the bullet and do it the
131 // p.scale(scale, -scale);
133 // Scrolling can be done by using OffsetViewportOrgEx
134 // Scaling can be done by adjusting SetWindowExtEx (it's denominator of txform)
135 // you'd use: % = ViewportExt / WindowExt
136 // But it makes the window look like crap: fuggetuboutit.
137 // Instead, we have to scale EVERYTHING by hand. Crap!
138 // It's not *that* bad, but not as convenient either...
140 painter.SetPen(QPen(Qt::blue, 1.0, Qt::DotLine));
142 // Draw coordinate axes
144 painter.DrawLine(0, -16384, 0, 16384);
145 painter.DrawLine(-16384, 0, 16384, 0);
147 // Draw rotation center (if active)
149 if (showRotationCenter)
151 painter.SetPen(QPen(Qt::red, 2.0, Qt::SolidLine));
152 painter.DrawLine(rotationCenter.x + 7, rotationCenter.y, rotationCenter.x - 7, rotationCenter.y);
153 painter.DrawLine(rotationCenter.x, rotationCenter.y + 7, rotationCenter.x, rotationCenter.y - 7);
158 for(int i=0; i<pts.GetNumPoints(); i++)
160 /*if (tool == TOOLMultiSelect)
162 if (selectedPoints[i])
164 qtp.setPen(QPen(Qt::red, 1.0, Qt::SolidLine));
168 qtp.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
172 if (((i == ptHighlight) && (tool != TOOLMultiSelect)) || ((tool == TOOLMultiSelect) && selectedPoints[i]))
174 painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
176 if (pts.GetOnCurve(i))
178 painter.DrawSquareDotN(pts.GetXY(i), 7);
179 painter.DrawSquareDotN(pts.GetXY(i), 9);
183 painter.DrawRoundDotN(pts.GetXY(i), 7);
184 painter.DrawRoundDotN(pts.GetXY(i), 9);
187 else if ((i == ptHighlight || i == ptNextHighlight) && tool == TOOLAddPt)
189 painter.SetPen(QPen(Qt::green, 1.0, Qt::SolidLine));
191 if (pts.GetOnCurve(i))
193 painter.DrawSquareDotN(pts.GetXY(i), 7);
194 painter.DrawSquareDotN(pts.GetXY(i), 9);
198 painter.DrawRoundDotN(pts.GetXY(i), 7);
199 painter.DrawRoundDotN(pts.GetXY(i), 9);
204 painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
207 if (pts.GetOnCurve(i))
208 painter.DrawSquareDot(pts.GetXY(i));
210 painter.DrawRoundDot(pts.GetXY(i));
212 (pts.GetOnCurve(i) ? DrawSquareDot(p, pts.GetX(i), pts.GetY(i))
213 : DrawRoundDot(p, pts.GetX(i), pts.GetY(i)));
217 if (tool == TOOLDelPt && i == ptHighlight)
219 painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
220 painter.DrawLine(pts.GetX(i) - 5, pts.GetY(i) - 5, pts.GetX(i) + 5, pts.GetY(i) + 5);
221 painter.DrawLine(pts.GetX(i) + 5, pts.GetY(i) - 5, pts.GetX(i) - 5, pts.GetY(i) + 5);
225 // Draw curve formed by points
227 painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
228 DrawGlyph(painter, pts);
233 GlyphPoints rotated = pts;
235 if (tool == TOOLRotate)
236 rotated.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
237 else if (tool == TOOLRotatePoly)
239 uint16_t poly = rotated.GetPolyForPointNumber(ptHighlight);
240 rotated.RotatePolyAroundCentroid(poly, rotationAngle);
243 painter.SetPen(QPen(QColor(255, 0, 255), 1.0, Qt::SolidLine));
244 DrawGlyph(painter, rotated);
247 if (selectionInProgress)
249 painter.SetPen(QPen(QColor(255, 127, 0, 255)));
250 painter.SetBrush(QBrush(QColor(255, 127, 0, 100)));
251 painter.DrawRect(selection);
256 void EditWindow::DrawGlyph(Painter & p, GlyphPoints & glyph)
258 for(int poly=0; poly<glyph.GetNumPolys(); poly++)
261 if (glyph.GetNumPoints(poly) < 3)
264 // Initial move: If our start point is on curve, then go to it. Otherwise,
265 // check previous point. If it's on curve, go to it otherwise go the
266 // midpoint between start point and previous (since it's between two curve
268 IPoint pt = (glyph.GetOnCurve(poly, 0)
269 ? glyph.GetPoint(poly, 0) : (glyph.GetPrevOnCurve(poly, 0)
270 ? glyph.GetPrevPoint(poly, 0) : glyph.GetMidpointToPrev(poly, 0)));
272 // Need to add separate color handling here for polys that are being manipulated...
274 for(int i=0; i<glyph.GetNumPoints(poly); i++)
276 // If this point and then next are both on curve, we have a line...
277 if (glyph.GetOnCurve(poly, i) && glyph.GetNextOnCurve(poly, i))
279 IPoint pt2 = glyph.GetNextPoint(poly, i);
280 p.drawLine(pt.x, pt.y, pt2.x, pt2.y);
285 // Skip point if it's on curve (start of curve--it's already
286 // been plotted so we don't need to handle it...)
287 if (glyph.GetOnCurve(poly, i))
290 // We are now guaranteed that we are sitting on a curve control point
291 // (off curve). Figure the extent of the curve: If the following is a
292 // curve control point, then use the midpoint to it otherwise go to
293 // the next point since it's on curve.
294 IPoint pt2 = (glyph.GetNextOnCurve(poly, i)
295 ? glyph.GetNextPoint(poly, i) : glyph.GetMidpointToNext(poly, i));
297 Bezier(p, pt, glyph.GetPoint(poly, i), pt2);
302 DrawGlyphPoly(p, glyph, poly);
308 void EditWindow::DrawGlyphPoly(Painter & p, GlyphPoints & glyph, uint16_t poly)
311 if (glyph.GetNumPoints(poly) < 3)
314 // Initial move: If our start point is on curve, then go to it. Otherwise,
315 // check previous point. If it's on curve, go to it otherwise go the
316 // midpoint between start point and previous (since it's between two curve
318 IPoint pt = (glyph.GetOnCurve(poly, 0)
319 ? glyph.GetPoint(poly, 0) : (glyph.GetPrevOnCurve(poly, 0)
320 ? glyph.GetPrevPoint(poly, 0) : glyph.GetMidpointToPrev(poly, 0)));
322 for(int i=0; i<glyph.GetNumPoints(poly); i++)
324 // If this point and then next are both on curve, we have a line...
325 if (glyph.GetOnCurve(poly, i) && glyph.GetNextOnCurve(poly, i))
327 IPoint pt2 = glyph.GetNextPoint(poly, i);
328 p.DrawLine(pt.x, pt.y, pt2.x, pt2.y);
333 // Skip point if it's on curve (start of curve--it's already
334 // been plotted so we don't need to handle it...)
335 if (glyph.GetOnCurve(poly, i))
338 // We are now guaranteed that we are sitting on a curve control
339 // point (off curve). Figure the extent of the curve: If the
340 // following is a curve control point, then use the midpoint to it
341 // otherwise go to the next point since it's on curve.
342 IPoint pt2 = (glyph.GetNextOnCurve(poly, i)
343 ? glyph.GetNextPoint(poly, i) : glyph.GetMidpointToNext(poly, i));
345 p.DrawBezier(pt, glyph.GetPoint(poly, i), pt2);
352 void EditWindow::ClearSelection(void)
354 for(int i=0; i<65536; i++)
355 selectedPoints[i] = false;
359 void EditWindow::mousePressEvent(QMouseEvent * event)
361 if (event->button() == Qt::RightButton)
363 toolPalette->move(event->globalPos());
364 toolPalette->setVisible(true);
365 setCursor(cur[TOOLSelect]);
366 toolPalette->prevTool = TOOLSelect;
368 else if (event->button() == Qt::MidButton)
372 ptPrevious = Vector(event->x(), event->y());
373 ptPrevious /= Global::zoom;
375 else if (event->button() == Qt::LeftButton)
377 if (tool == TOOLScroll || tool == TOOLZoom)
378 ;//meh CaptureMouse(); // Make sure we capture the mouse when in scroll/zoom mode
379 else if (tool == TOOLMultiSelect)
381 // QPoint pt = GetAdjustedMousePosition(event);
382 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
383 selectionInProgress = true;
384 selection.setTopLeft(QPoint(pt.x, pt.y));
385 selection.setBottomRight(QPoint(pt.x, pt.y));
387 else if (tool == TOOLAddPt) // "Add Point" tool
389 // QPoint pt = GetAdjustedMousePosition(event);
390 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
391 IPoint pointToAdd(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
393 if (pts.GetNumPoints() < 2)
395 // pts += IPoint(pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
397 ptHighlight = pts.GetNumPoints() - 1;
401 // QPoint pt = GetAdjustedMousePosition(event);
402 // pts.InsertPoint(pts.GetNext(ptHighlight), pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
403 pts.InsertPoint(pts.GetNext(ptHighlight), pointToAdd);
404 ptHighlight = ptNextHighlight;
410 else if (tool == TOOLAddPoly) // "Add Poly" tool
413 WriteLogMsg("Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.GetNumPoints());
417 polyFirstPoint = false;
418 pts.AddNewPolyAtEnd();
421 // QPoint pt = GetAdjustedMousePosition(event);
422 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
423 //printf("GetAdjustedMousePosition = %i, %i\n", pt.x(), pt.y());
424 // Append a point to the end of the structure
425 pts += IPoint(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
426 ptHighlight = pts.GetNumPoints() - 1;
429 WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumPoints());
432 else if (tool == TOOLSelect || tool == TOOLPolySelect)
434 if (pts.GetNumPoints() > 0)
436 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
437 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
438 //printf("GetAdjustedClientPosition = %i, %i\n", pt.x(), pt.y());
439 // WarpPointer(pt.x, pt.y);
440 QPoint warp(pt.x, pt.y);
441 QCursor::setPos(mapToGlobal(warp));
443 if (event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier)
445 pts.SetOnCurve(ptHighlight, !pts.GetOnCurve(ptHighlight));
450 else if (tool == TOOLDelPt)
452 if (pts.GetNumPoints() > 0)
454 // if (ptHighlight != -1)
456 //This assumes that WM_MOUSEMOVE happens before this!
457 //The above commented out line should take care of this contingency... !!! FIX !!!
458 pts.DeletePoint(ptHighlight);
462 else if (tool == TOOLRotate)
464 // I think what's needed here is to keep the initial mouse click,
465 // paint the rotation center, then use the 1st mouse move event to establish
466 // the rotation "zero line", which becomes the line of reference to all
467 // subsequent mouse moves.
468 // rotationCenter = GetAdjustedMousePosition(event);
469 rotationCenter = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
470 showRotationCenter = true;
471 haveZeroPoint = false;
475 else if (tool == TOOLRotatePoly)
477 IPoint centroid = pts.GetPolyCentroid(pts.GetPolyForPointNumber(ptHighlight));
478 rotationCenter = Vector(centroid.x, centroid.y);
479 showRotationCenter = true;
480 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
481 Vector pt = Painter::QtToCartesianCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
482 QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
483 rotationZeroPoint = Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
484 haveZeroPoint = true;
488 else if (tool == TOOLFlipWinding)
490 pts.InvertPolyDrawSequence(pts.GetPolyForPointNumber(ptHighlight));
491 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
492 Vector pt = Painter::QtToCartesianCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
493 QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
502 void EditWindow::mouseMoveEvent(QMouseEvent * event)
504 if (event->buttons() == Qt::RightButton)
506 ToolType newTool = toolPalette->FindSelectedTool();
508 if (newTool != toolPalette->prevTool)
510 toolPalette->prevTool = newTool;
511 toolPalette->repaint();
514 else if (event->buttons() == Qt::MidButton)
516 // Calc offset from previous point
517 Vector pt(event->x(), event->y());
519 ptOffset = Vector(pt.x - ptPrevious.x, pt.y - ptPrevious.y);
521 // Then multiply it by the scaling factor. Whee!
522 // This looks wacky because we're using screen coords for the offset...
523 // Otherwise, we would subtract both offsets!
524 offsetX -= ptOffset.x, offsetY += ptOffset.y;
528 else if (event->buttons() == Qt::LeftButton)
530 if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect)
532 // Bail out if we have the select tool and no points yet...
533 if (tool == TOOLSelect && pts.GetNumPoints() == 0)
536 // QPoint pt2 = GetAdjustedMousePosition(event);
537 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
538 pts.SetXY(ptHighlight, pt2.x, pt2.y);
541 else if (tool == TOOLPolySelect)
543 if (pts.GetNumPoints() > 0)
545 // QPoint pt2 = GetAdjustedMousePosition(event);
546 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
547 // Should also set onCurve here as well, depending on keystate
549 //Would be nice, but we'd need to trap the keyPressEvent() as well, otherwise pressing/releasing
550 //the hotkey would show no change until the user moved their mouse.
551 pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x - pts.GetX(ptHighlight), pt2.y - pts.GetY(ptHighlight));
555 else if (tool == TOOLRotate || tool == TOOLRotatePoly)
557 if (pts.GetNumPoints() > 0)
561 // rotationZeroPoint = GetAdjustedMousePosition(event);
562 rotationZeroPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
563 haveZeroPoint = true;
567 // Figure out the angle between the "zero" vector and the current one,
568 // then rotate all points relative to the "zero" vector (done by paint())
569 // QPoint currentPoint = GetAdjustedMousePosition(event);
570 Vector currentPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
571 Vector v1(rotationZeroPoint.x, rotationZeroPoint.y, 0,
572 rotationCenter.x, rotationCenter.y, 0);
573 Vector v2(currentPoint.x, currentPoint.y, 0,
574 rotationCenter.x, rotationCenter.y, 0);
575 // rotationAngle = v1.Angle(v2);
576 rotationAngle = v2.Angle(v1);
579 s.sprintf("%.3f degrees", rotationAngle * 180.0 / 3.14159265358979323);
580 ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage(s);
586 else if (tool == TOOLMultiSelect)
588 // QPoint pt = GetAdjustedMousePosition(event);
589 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
590 selection.setBottomRight(QPoint(pt.x, pt.y));
592 for(int i=0; i<pts.GetNumPoints(); i++)
594 if (selection.contains(QPoint(pts.GetX(i), pts.GetY(i))))
595 selectedPoints[i] = true;
597 selectedPoints[i] = false;
603 else if (event->buttons() == Qt::NoButton)
605 // Moving, not dragging...
606 if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt
607 || tool == TOOLPolySelect || tool == TOOLRotatePoly || tool == TOOLFlipWinding)
609 // QPoint pt2 = GetAdjustedMousePosition(event);
610 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
611 double closest = 1.0e+99;
613 for(int i=0; i<pts.GetNumPoints(); i++)
615 double dist = ((pt2.x - pts.GetX(i)) * (pt2.x - pts.GetX(i)))
616 + ((pt2.y - pts.GetY(i)) * (pt2.y - pts.GetY(i)));
619 closest = dist, ptHighlight = i;
622 if (ptHighlight != oldPtHighlight)
624 oldPtHighlight = ptHighlight;
628 // What follows here looks like voodoo, but is really simple. What
629 // we do is check to see if the mouse point has a perpendicular
630 // intersection with any of the line segments. If it does,
631 // calculate the length of the perpendicular and choose the
632 // smallest length. If there is no perpendicular, then choose the
633 // length of line connecting the closer of either the first
634 // endpoint or the second and choose the smallest of those.
636 // There is one bit of math that looks like voodoo to me ATM--will
637 // explain once I understand it better (the calculation of the
638 // length of the perpendicular).
640 if (pts.GetNumPoints() > 1 && tool == TOOLAddPt)
642 double smallest = 1.0e+99;
644 for(int i=0; i<pts.GetNumPoints(); i++)
646 int32_t p1x = pts.GetX(i), p1y = pts.GetY(i),
647 p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
649 Vector ls(p2x, p2y, 0, p1x, p1y, 0),
650 v1(pt2.x, pt2.y, 0, p1x, p1y, 0),
651 v2(pt2.x, pt2.y, 0, p2x, p2y, 0);
652 double pp = ls.Dot(v1) / ls.Magnitude(), dist;
653 // Geometric interpretation:
654 // pp is the paremeterized point on the vector ls where the perpendicular
655 // intersects ls. If pp < 0, then the perpendicular lies beyond the 1st
656 // endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd
660 dist = v1.Magnitude();
661 else if (pp > ls.Magnitude())
662 dist = v2.Magnitude();
663 else // distance = ?Det?(ls, v1) / |ls|
664 dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.Magnitude());
666 //The answer to the above looks like it might be found here:
668 //If the segment endpoints are s and e, and the point is p, then the test for
669 //the perpendicular intercepting the segment is equivalent to insisting that
670 //the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
671 //Perpendicular distance from the point to the segment is computed by first
672 //computing the area of the triangle the three points form, then dividing by
673 //the length of the segment. Distances are done just by the Pythagorean
674 //theorem. Twice the area of the triangle formed by three points is the
675 //determinant of the following matrix:
681 //By translating the start point to the origin, this can be rewritten as:
682 //By subtracting row 1 from all rows, you get the following:
683 //[because sx = sy = 0. you could leave out the -sx/y terms below. because we
684 //subtracted row 1 from all rows (including row 1) row 1 turns out to be zero.
688 //(ex - sx) (ey - sy) 0
689 //(px - sx) (py - sy) 0
691 //which greatly simplifies the calculation of the determinant.
694 smallest = dist, ptNextHighlight = pts.GetNext(i), ptHighlight = i;
697 if (ptNextHighlight != oldPtNextHighlight)
699 oldPtNextHighlight = ptNextHighlight;
705 ptPrevious = Vector(event->x(), event->y());
712 void EditWindow::mouseReleaseEvent(QMouseEvent * event)
714 if (event->button() == Qt::RightButton)
716 ToolType newTool = toolPalette->FindSelectedTool();
718 // We only change the tool if a new one was actually selected. Otherwise, we do nothing.
719 if (newTool != TOOLNone)
723 if (tool == TOOLScroll || tool == TOOLZoom || tool == TOOLAddPoly
724 || tool == TOOLDelPoly)
727 if (tool == TOOLAddPoly)
728 polyFirstPoint = true;
731 toolPalette->setVisible(false);
732 setCursor(cur[tool]);
733 // Just in case we changed highlighting style with the new tool...
736 else if (event->button() == Qt::MidButton)
738 setCursor(cur[tool]); // Restore previous cursor
740 else if (event->button() == Qt::LeftButton)
742 if (showRotationCenter)
744 showRotationCenter = false;
745 haveZeroPoint = false;
747 if (tool == TOOLRotate)
748 pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
751 uint16_t poly = pts.GetPolyForPointNumber(ptHighlight);
752 pts.RotatePolyAroundCentroid(poly, rotationAngle);
756 ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage("");
759 // if (tool == TOOLScroll || tool == TOOLZoom)
761 //this is prolly too much
762 ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
763 ((TTEdit *)qApp)->charWnd->update();
765 if (tool == TOOLMultiSelect)
767 selectionInProgress = false;
776 void EditWindow::keyPressEvent(QKeyEvent * event)
778 // Sanity checking...
779 if (ptHighlight == -1)
782 if (event->key() == Qt::Key_Up)
784 pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) + 1);
786 else if (event->key() == Qt::Key_Down)
787 pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) - 1);
788 else if (event->key() == Qt::Key_Right)
789 pts.SetXY(ptHighlight, pts.GetX(ptHighlight) + 1, pts.GetY(ptHighlight));
790 else if (event->key() == Qt::Key_Left)
791 pts.SetXY(ptHighlight, pts.GetX(ptHighlight) - 1, pts.GetY(ptHighlight));
797 ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
798 ((TTEdit *)qApp)->charWnd->update();
802 void EditWindow::keyReleaseEvent(QKeyEvent * /*event*/)