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 curve formed by points
191 painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
192 DrawGlyph(painter, pts);
197 GlyphPoints rotated = pts;
199 if (tool == TOOLRotate)
200 rotated.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
201 else if (tool == TOOLRotatePoly)
203 uint16_t poly = rotated.GetPolyForPointNumber(ptHighlight);
204 rotated.RotatePolyAroundCentroid(poly, rotationAngle);
207 painter.SetPen(QPen(QColor(255, 0, 255), 1.0, Qt::SolidLine));
208 DrawGlyph(painter, rotated);
211 if (selectionInProgress)
213 painter.SetPen(QPen(QColor(255, 127, 0, 255)));
214 painter.SetBrush(QBrush(QColor(255, 127, 0, 100)));
215 painter.DrawRect(selection);
220 void EditWindow::DrawGlyph(Painter & p, GlyphPoints & glyph)
222 for(int poly=0; poly<glyph.GetNumPolys(); poly++)
225 if (glyph.GetNumPoints(poly) < 3)
228 // Initial move: If our start point is on curve, then go to it. Otherwise,
229 // check previous point. If it's on curve, go to it otherwise go the
230 // midpoint between start point and previous (since it's between two curve
232 IPoint pt = (glyph.GetOnCurve(poly, 0)
233 ? glyph.GetPoint(poly, 0) : (glyph.GetPrevOnCurve(poly, 0)
234 ? glyph.GetPrevPoint(poly, 0) : glyph.GetMidpointToPrev(poly, 0)));
236 // Need to add separate color handling here for polys that are being manipulated...
238 for(int i=0; i<glyph.GetNumPoints(poly); i++)
240 // If this point and then next are both on curve, we have a line...
241 if (glyph.GetOnCurve(poly, i) && glyph.GetNextOnCurve(poly, i))
243 IPoint pt2 = glyph.GetNextPoint(poly, i);
244 p.drawLine(pt.x, pt.y, pt2.x, pt2.y);
249 // Skip point if it's on curve (start of curve--it's already
250 // been plotted so we don't need to handle it...)
251 if (glyph.GetOnCurve(poly, i))
254 // We are now guaranteed that we are sitting on a curve control point
255 // (off curve). Figure the extent of the curve: If the following is a
256 // curve control point, then use the midpoint to it otherwise go to
257 // the next point since it's on curve.
258 IPoint pt2 = (glyph.GetNextOnCurve(poly, i)
259 ? glyph.GetNextPoint(poly, i) : glyph.GetMidpointToNext(poly, i));
261 Bezier(p, pt, glyph.GetPoint(poly, i), pt2);
266 DrawGlyphPoly(p, glyph, poly);
273 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
274 to change the color of the line(s) drawn to the point to signal to the user
275 that it isn't finalized until they click the button.
277 void EditWindow::DrawGlyphPoly(Painter & p, GlyphPoints & glyph, uint16_t poly)
280 if (glyph.GetNumPoints(poly) < 3)
283 IPoint p1 = glyph.GetPrevPoint(poly, 0);
284 IPoint p2 = glyph.GetPoint(poly, 0);
286 // Inject the new poly point into the current polygon
287 if ((tool == TOOLAddPoly) && (poly == (glyph.GetNumPolys() - 1)))
289 p1 = IPoint(addPoint.x, addPoint.y, addPointOnCurve);
292 for(int i=0; i<glyph.GetNumPoints(poly); i++)
294 IPoint p3 = glyph.GetNextPoint(poly, i);
296 if ((tool == TOOLAddPoly) && (poly == (glyph.GetNumPolys() - 1))
297 && (i == (glyph.GetNumPoints(poly) - 1)))
299 p3 = IPoint(addPoint.x, addPoint.y, addPointOnCurve);
300 p.SetPen(QPen(Qt::green, 1.0, Qt::SolidLine));
301 DrawGlyphSegment(p, p1, p2, p3);
304 p3 = glyph.GetNextPoint(poly, i);
307 DrawGlyphSegment(p, p1, p2, p3);
316 // Draw a glyph segment given 3 points
318 void EditWindow::DrawGlyphSegment(Painter & p, IPoint p1, IPoint p2, IPoint p3)
322 // Skip drawing if the middle point is on curve and the last is off
328 // The middle point is off curve, and so we need to draw a Bezier curve.
329 // Also, depending on whether or not the previous or follow points are
330 // off curve, we need to draw to the midpoints if so.
331 IPoint mid12 = IPoint((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
332 IPoint mid23 = IPoint((p2.x + p3.x) / 2, (p2.y + p3.y) / 2);
333 p.DrawBezier((p1.onCurve ? p1 : mid12), p2, (p3.onCurve ? p3 : mid23));
338 void EditWindow::ClearSelection(void)
340 for(int i=0; i<65536; i++)
341 selectedPoints[i] = false;
345 void EditWindow::mousePressEvent(QMouseEvent * event)
347 if (event->button() == Qt::RightButton)
349 toolPalette->move(event->globalPos());
350 toolPalette->setVisible(true);
351 setCursor(cur[TOOLSelect]);
352 toolPalette->prevTool = TOOLSelect;
354 else if (event->button() == Qt::MidButton)
358 ptPrevious = Vector(event->x(), event->y());
359 ptPrevious /= Global::zoom;
361 else if (event->button() == Qt::LeftButton)
363 if (tool == TOOLScroll || tool == TOOLZoom)
364 ;//meh CaptureMouse(); // Make sure we capture the mouse when in scroll/zoom mode
365 else if (tool == TOOLMultiSelect)
367 // QPoint pt = GetAdjustedMousePosition(event);
368 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
369 selectionInProgress = true;
370 selection.setTopLeft(QPoint(pt.x, pt.y));
371 selection.setBottomRight(QPoint(pt.x, pt.y));
373 else if (tool == TOOLAddPt) // "Add Point" tool
375 // QPoint pt = GetAdjustedMousePosition(event);
376 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
377 IPoint pointToAdd(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
379 if (pts.GetNumPoints() < 2)
381 // pts += IPoint(pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
383 ptHighlight = pts.GetNumPoints() - 1;
387 // QPoint pt = GetAdjustedMousePosition(event);
388 // pts.InsertPoint(pts.GetNext(ptHighlight), pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
389 pts.InsertPoint(pts.GetNext(ptHighlight), pointToAdd);
390 ptHighlight = ptNextHighlight;
396 else if (tool == TOOLAddPoly) // "Add Poly" tool
399 WriteLogMsg("Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.GetNumPoints());
403 polyFirstPoint = false;
404 pts.AddNewPolyAtEnd();
407 // QPoint pt = GetAdjustedMousePosition(event);
408 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
409 //printf("GetAdjustedMousePosition = %i, %i\n", pt.x(), pt.y());
410 // Append a point to the end of the structure
411 pts += IPoint(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
412 ptHighlight = pts.GetNumPoints() - 1;
415 WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumPoints());
418 else if (tool == TOOLSelect || tool == TOOLPolySelect)
420 if (pts.GetNumPoints() > 0)
422 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
423 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
424 //printf("GetAdjustedClientPosition = %lf, %lf\n", pt.x, pt.y);
425 QPoint warp(pt.x, pt.y);
426 QCursor::setPos(mapToGlobal(warp));
428 if (event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier)
430 pts.SetOnCurve(ptHighlight, !pts.GetOnCurve(ptHighlight));
435 else if (tool == TOOLDelPt)
437 if (pts.GetNumPoints() > 0)
439 // if (ptHighlight != -1)
441 //This assumes that WM_MOUSEMOVE happens before this!
442 //The above commented out line should take care of this contingency... !!! FIX !!!
443 pts.DeletePoint(ptHighlight);
447 else if (tool == TOOLRotate)
449 // I think what's needed here is to keep the initial mouse click,
450 // paint the rotation center, then use the 1st mouse move event to
451 // establish the rotation "zero line", which becomes the line of
452 // reference to all subsequent mouse moves.
453 // rotationCenter = GetAdjustedMousePosition(event);
454 rotationCenter = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
455 showRotationCenter = true;
456 haveZeroPoint = false;
460 else if (tool == TOOLRotatePoly)
462 IPoint centroid = pts.GetPolyCentroid(pts.GetPolyForPointNumber(ptHighlight));
463 rotationCenter = Vector(centroid.x, centroid.y);
464 showRotationCenter = true;
465 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
466 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
467 QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
468 rotationZeroPoint = Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
469 haveZeroPoint = true;
473 else if (tool == TOOLFlipWinding)
475 pts.InvertPolyDrawSequence(pts.GetPolyForPointNumber(ptHighlight));
476 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
477 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
478 QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
487 void EditWindow::mouseMoveEvent(QMouseEvent * event)
489 if (event->buttons() == Qt::RightButton)
491 ToolType newTool = toolPalette->FindSelectedTool();
493 if (newTool != toolPalette->prevTool)
495 toolPalette->prevTool = newTool;
496 toolPalette->repaint();
499 else if (event->buttons() == Qt::MidButton)
501 // Calc offset from previous point
502 Vector pt(event->x(), event->y());
504 ptOffset = Vector(pt.x - ptPrevious.x, -(pt.y - ptPrevious.y));
506 // Then multiply it by the scaling factor. Whee!
507 // This looks wacky because we're using screen coords for the offset...
508 // Otherwise, we would subtract both offsets!
509 // offsetX -= ptOffset.x, offsetY += ptOffset.y;
510 Global::origin -= ptOffset;
514 else if (event->buttons() == Qt::LeftButton)
516 if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect)
518 // Bail out if we have the select tool and no points yet...
519 if (tool == TOOLSelect && pts.GetNumPoints() == 0)
522 // QPoint pt2 = GetAdjustedMousePosition(event);
523 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
525 if (tool != TOOLSelect)
528 // Prolly should move this to the key handlers below...
529 addPointOnCurve = ((event->modifiers() == Qt::ShiftModifier) || (event->modifiers() == Qt::ControlModifier) ? false : true);
532 pts.SetXY(ptHighlight, pt2.x, pt2.y);
536 else if (tool == TOOLPolySelect)
538 if (pts.GetNumPoints() > 0)
540 // QPoint pt2 = GetAdjustedMousePosition(event);
541 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
542 // Should also set onCurve here as well, depending on keystate
544 //Would be nice, but we'd need to trap the keyPressEvent() as well, otherwise pressing/releasing
545 //the hotkey would show no change until the user moved their mouse.
546 pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x - pts.GetX(ptHighlight), pt2.y - pts.GetY(ptHighlight));
550 else if (tool == TOOLRotate || tool == TOOLRotatePoly)
552 if (pts.GetNumPoints() > 0)
556 // rotationZeroPoint = GetAdjustedMousePosition(event);
557 rotationZeroPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
558 haveZeroPoint = true;
562 // Figure out the angle between the "zero" vector and the current one,
563 // then rotate all points relative to the "zero" vector (done by paint())
564 // QPoint currentPoint = GetAdjustedMousePosition(event);
565 Vector currentPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
566 Vector v1(rotationZeroPoint.x, rotationZeroPoint.y, 0,
567 rotationCenter.x, rotationCenter.y, 0);
568 Vector v2(currentPoint.x, currentPoint.y, 0,
569 rotationCenter.x, rotationCenter.y, 0);
570 // rotationAngle = v1.Angle(v2);
571 rotationAngle = v2.Angle(v1);
574 s.sprintf("%.3f degrees", rotationAngle * 180.0 / 3.14159265358979323);
575 ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage(s);
581 else if (tool == TOOLMultiSelect)
583 // QPoint pt = GetAdjustedMousePosition(event);
584 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
585 selection.setBottomRight(QPoint(pt.x, pt.y));
587 for(int i=0; i<pts.GetNumPoints(); i++)
589 if (selection.contains(QPoint(pts.GetX(i), pts.GetY(i))))
590 selectedPoints[i] = true;
592 selectedPoints[i] = false;
598 else if (event->buttons() == Qt::NoButton)
600 // Moving, not dragging...
601 if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt
602 || tool == TOOLPolySelect || tool == TOOLRotatePoly || tool == TOOLFlipWinding)
604 // QPoint pt2 = GetAdjustedMousePosition(event);
605 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
606 double closest = 1.0e+99;
608 for(int i=0; i<pts.GetNumPoints(); i++)
610 double dist = ((pt2.x - pts.GetX(i)) * (pt2.x - pts.GetX(i)))
611 + ((pt2.y - pts.GetY(i)) * (pt2.y - pts.GetY(i)));
614 closest = dist, ptHighlight = i;
617 if (ptHighlight != oldPtHighlight)
619 oldPtHighlight = ptHighlight;
623 // What follows here looks like voodoo, but is really simple. What
624 // we do is check to see if the mouse point has a perpendicular
625 // intersection with any of the line segments. If it does,
626 // calculate the length of the perpendicular and choose the
627 // smallest length. If there is no perpendicular, then choose the
628 // length of line connecting the closer of either the first
629 // endpoint or the second and choose the smallest of those.
631 // There is one bit of math that looks like voodoo to me ATM--will
632 // explain once I understand it better (the calculation of the
633 // length of the perpendicular).
635 if (pts.GetNumPoints() > 1 && tool == TOOLAddPt)
637 double smallest = 1.0e+99;
639 for(int i=0; i<pts.GetNumPoints(); i++)
641 int32_t p1x = pts.GetX(i), p1y = pts.GetY(i),
642 p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
644 Vector ls(p2x, p2y, 0, p1x, p1y, 0),
645 v1(pt2.x, pt2.y, 0, p1x, p1y, 0),
646 v2(pt2.x, pt2.y, 0, p2x, p2y, 0);
647 double pp = ls.Dot(v1) / ls.Magnitude(), dist;
648 // Geometric interpretation:
649 // pp is the paremeterized point on the vector ls where the perpendicular
650 // intersects ls. If pp < 0, then the perpendicular lies beyond the 1st
651 // endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd
655 dist = v1.Magnitude();
656 else if (pp > ls.Magnitude())
657 dist = v2.Magnitude();
658 else // distance = ?Det?(ls, v1) / |ls|
659 dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.Magnitude());
661 //The answer to the above looks like it might be found here:
663 //If the segment endpoints are s and e, and the point is p, then the test for
664 //the perpendicular intercepting the segment is equivalent to insisting that
665 //the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
666 //Perpendicular distance from the point to the segment is computed by first
667 //computing the area of the triangle the three points form, then dividing by
668 //the length of the segment. Distances are done just by the Pythagorean
669 //theorem. Twice the area of the triangle formed by three points is the
670 //determinant of the following matrix:
676 //By translating the start point to the origin, this can be rewritten as:
677 //By subtracting row 1 from all rows, you get the following:
678 //[because sx = sy = 0. you could leave out the -sx/y terms below. because we
679 //subtracted row 1 from all rows (including row 1) row 1 turns out to be zero.
683 //(ex - sx) (ey - sy) 0
684 //(px - sx) (py - sy) 0
686 //which greatly simplifies the calculation of the determinant.
689 smallest = dist, ptNextHighlight = pts.GetNext(i), ptHighlight = i;
692 if (ptNextHighlight != oldPtNextHighlight)
694 oldPtNextHighlight = ptNextHighlight;
700 ptPrevious = Vector(event->x(), event->y());
701 addPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
702 // addPointOnCurve = ((event->modifiers() == Qt::ShiftModifier) || (event->modifiers() == Qt::ControlModifier) ? false : true);
704 if (tool == TOOLAddPoly)
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));
792 else if ((event->key() == Qt::Key_Shift) || (event->key() == Qt::Key_Control))
794 addPointOnCurve = false;
801 ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
802 ((TTEdit *)qApp)->charWnd->update();
806 void EditWindow::keyReleaseEvent(QKeyEvent * event)
808 if ((event->key() == Qt::Key_Shift) || (event->key() == Qt::Key_Control))
810 addPointOnCurve = true;