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);
272 void EditWindow::DrawGlyphPoly(Painter & p, GlyphPoints & glyph, uint16_t poly)
275 if (glyph.GetNumPoints(poly) < 3)
278 // Initial move: If our start point is on curve, then go to it. Otherwise,
279 // check previous point. If it's on curve, go to it otherwise go the
280 // midpoint between start point and previous (since it's between two curve
282 IPoint pt = (glyph.GetOnCurve(poly, 0)
283 ? glyph.GetPoint(poly, 0) : (glyph.GetPrevOnCurve(poly, 0)
284 ? glyph.GetPrevPoint(poly, 0) : glyph.GetMidpointToPrev(poly, 0)));
286 for(int i=0; i<glyph.GetNumPoints(poly); i++)
288 // If this point and then next are both on curve, we have a line...
289 if (glyph.GetOnCurve(poly, i) && glyph.GetNextOnCurve(poly, i))
291 IPoint pt2 = glyph.GetNextPoint(poly, i);
292 p.DrawLine(pt.x, pt.y, pt2.x, pt2.y);
297 // Skip point if it's on curve (start of curve--it's already
298 // been plotted so we don't need to handle it...)
299 if (glyph.GetOnCurve(poly, i))
302 // We are now guaranteed that we are sitting on a curve control
303 // point (off curve). Figure the extent of the curve: If the
304 // following is a curve control point, then use the midpoint to it
305 // otherwise go to the next point since it's on curve.
306 IPoint pt2 = (glyph.GetNextOnCurve(poly, i)
307 ? glyph.GetNextPoint(poly, i) : glyph.GetMidpointToNext(poly, i));
309 p.DrawBezier(pt, glyph.GetPoint(poly, i), pt2);
316 void EditWindow::ClearSelection(void)
318 for(int i=0; i<65536; i++)
319 selectedPoints[i] = false;
323 void EditWindow::mousePressEvent(QMouseEvent * event)
325 if (event->button() == Qt::RightButton)
327 toolPalette->move(event->globalPos());
328 toolPalette->setVisible(true);
329 setCursor(cur[TOOLSelect]);
330 toolPalette->prevTool = TOOLSelect;
332 else if (event->button() == Qt::MidButton)
336 ptPrevious = Vector(event->x(), event->y());
337 ptPrevious /= Global::zoom;
339 else if (event->button() == Qt::LeftButton)
341 if (tool == TOOLScroll || tool == TOOLZoom)
342 ;//meh CaptureMouse(); // Make sure we capture the mouse when in scroll/zoom mode
343 else if (tool == TOOLMultiSelect)
345 // QPoint pt = GetAdjustedMousePosition(event);
346 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
347 selectionInProgress = true;
348 selection.setTopLeft(QPoint(pt.x, pt.y));
349 selection.setBottomRight(QPoint(pt.x, pt.y));
351 else if (tool == TOOLAddPt) // "Add Point" tool
353 // QPoint pt = GetAdjustedMousePosition(event);
354 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
355 IPoint pointToAdd(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
357 if (pts.GetNumPoints() < 2)
359 // pts += IPoint(pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
361 ptHighlight = pts.GetNumPoints() - 1;
365 // QPoint pt = GetAdjustedMousePosition(event);
366 // pts.InsertPoint(pts.GetNext(ptHighlight), pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
367 pts.InsertPoint(pts.GetNext(ptHighlight), pointToAdd);
368 ptHighlight = ptNextHighlight;
374 else if (tool == TOOLAddPoly) // "Add Poly" tool
377 WriteLogMsg("Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.GetNumPoints());
381 polyFirstPoint = false;
382 pts.AddNewPolyAtEnd();
385 // QPoint pt = GetAdjustedMousePosition(event);
386 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
387 //printf("GetAdjustedMousePosition = %i, %i\n", pt.x(), pt.y());
388 // Append a point to the end of the structure
389 pts += IPoint(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
390 ptHighlight = pts.GetNumPoints() - 1;
393 WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumPoints());
396 else if (tool == TOOLSelect || tool == TOOLPolySelect)
398 if (pts.GetNumPoints() > 0)
400 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
401 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
402 //printf("GetAdjustedClientPosition = %lf, %lf\n", pt.x, pt.y);
403 QPoint warp(pt.x, pt.y);
404 QCursor::setPos(mapToGlobal(warp));
406 if (event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier)
408 pts.SetOnCurve(ptHighlight, !pts.GetOnCurve(ptHighlight));
413 else if (tool == TOOLDelPt)
415 if (pts.GetNumPoints() > 0)
417 // if (ptHighlight != -1)
419 //This assumes that WM_MOUSEMOVE happens before this!
420 //The above commented out line should take care of this contingency... !!! FIX !!!
421 pts.DeletePoint(ptHighlight);
425 else if (tool == TOOLRotate)
427 // I think what's needed here is to keep the initial mouse click,
428 // paint the rotation center, then use the 1st mouse move event to
429 // establish the rotation "zero line", which becomes the line of
430 // reference to all subsequent mouse moves.
431 // rotationCenter = GetAdjustedMousePosition(event);
432 rotationCenter = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
433 showRotationCenter = true;
434 haveZeroPoint = false;
438 else if (tool == TOOLRotatePoly)
440 IPoint centroid = pts.GetPolyCentroid(pts.GetPolyForPointNumber(ptHighlight));
441 rotationCenter = Vector(centroid.x, centroid.y);
442 showRotationCenter = true;
443 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
444 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
445 QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
446 rotationZeroPoint = Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
447 haveZeroPoint = true;
451 else if (tool == TOOLFlipWinding)
453 pts.InvertPolyDrawSequence(pts.GetPolyForPointNumber(ptHighlight));
454 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
455 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
456 QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
465 void EditWindow::mouseMoveEvent(QMouseEvent * event)
467 if (event->buttons() == Qt::RightButton)
469 ToolType newTool = toolPalette->FindSelectedTool();
471 if (newTool != toolPalette->prevTool)
473 toolPalette->prevTool = newTool;
474 toolPalette->repaint();
477 else if (event->buttons() == Qt::MidButton)
479 // Calc offset from previous point
480 Vector pt(event->x(), event->y());
482 ptOffset = Vector(pt.x - ptPrevious.x, -(pt.y - ptPrevious.y));
484 // Then multiply it by the scaling factor. Whee!
485 // This looks wacky because we're using screen coords for the offset...
486 // Otherwise, we would subtract both offsets!
487 // offsetX -= ptOffset.x, offsetY += ptOffset.y;
488 Global::origin -= ptOffset;
492 else if (event->buttons() == Qt::LeftButton)
494 if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect)
496 // Bail out if we have the select tool and no points yet...
497 if (tool == TOOLSelect && pts.GetNumPoints() == 0)
500 // QPoint pt2 = GetAdjustedMousePosition(event);
501 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
502 pts.SetXY(ptHighlight, pt2.x, pt2.y);
505 else if (tool == TOOLPolySelect)
507 if (pts.GetNumPoints() > 0)
509 // QPoint pt2 = GetAdjustedMousePosition(event);
510 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
511 // Should also set onCurve here as well, depending on keystate
513 //Would be nice, but we'd need to trap the keyPressEvent() as well, otherwise pressing/releasing
514 //the hotkey would show no change until the user moved their mouse.
515 pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x - pts.GetX(ptHighlight), pt2.y - pts.GetY(ptHighlight));
519 else if (tool == TOOLRotate || tool == TOOLRotatePoly)
521 if (pts.GetNumPoints() > 0)
525 // rotationZeroPoint = GetAdjustedMousePosition(event);
526 rotationZeroPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
527 haveZeroPoint = true;
531 // Figure out the angle between the "zero" vector and the current one,
532 // then rotate all points relative to the "zero" vector (done by paint())
533 // QPoint currentPoint = GetAdjustedMousePosition(event);
534 Vector currentPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
535 Vector v1(rotationZeroPoint.x, rotationZeroPoint.y, 0,
536 rotationCenter.x, rotationCenter.y, 0);
537 Vector v2(currentPoint.x, currentPoint.y, 0,
538 rotationCenter.x, rotationCenter.y, 0);
539 // rotationAngle = v1.Angle(v2);
540 rotationAngle = v2.Angle(v1);
543 s.sprintf("%.3f degrees", rotationAngle * 180.0 / 3.14159265358979323);
544 ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage(s);
550 else if (tool == TOOLMultiSelect)
552 // QPoint pt = GetAdjustedMousePosition(event);
553 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
554 selection.setBottomRight(QPoint(pt.x, pt.y));
556 for(int i=0; i<pts.GetNumPoints(); i++)
558 if (selection.contains(QPoint(pts.GetX(i), pts.GetY(i))))
559 selectedPoints[i] = true;
561 selectedPoints[i] = false;
567 else if (event->buttons() == Qt::NoButton)
569 // Moving, not dragging...
570 if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt
571 || tool == TOOLPolySelect || tool == TOOLRotatePoly || tool == TOOLFlipWinding)
573 // QPoint pt2 = GetAdjustedMousePosition(event);
574 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
575 double closest = 1.0e+99;
577 for(int i=0; i<pts.GetNumPoints(); i++)
579 double dist = ((pt2.x - pts.GetX(i)) * (pt2.x - pts.GetX(i)))
580 + ((pt2.y - pts.GetY(i)) * (pt2.y - pts.GetY(i)));
583 closest = dist, ptHighlight = i;
586 if (ptHighlight != oldPtHighlight)
588 oldPtHighlight = ptHighlight;
592 // What follows here looks like voodoo, but is really simple. What
593 // we do is check to see if the mouse point has a perpendicular
594 // intersection with any of the line segments. If it does,
595 // calculate the length of the perpendicular and choose the
596 // smallest length. If there is no perpendicular, then choose the
597 // length of line connecting the closer of either the first
598 // endpoint or the second and choose the smallest of those.
600 // There is one bit of math that looks like voodoo to me ATM--will
601 // explain once I understand it better (the calculation of the
602 // length of the perpendicular).
604 if (pts.GetNumPoints() > 1 && tool == TOOLAddPt)
606 double smallest = 1.0e+99;
608 for(int i=0; i<pts.GetNumPoints(); i++)
610 int32_t p1x = pts.GetX(i), p1y = pts.GetY(i),
611 p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
613 Vector ls(p2x, p2y, 0, p1x, p1y, 0),
614 v1(pt2.x, pt2.y, 0, p1x, p1y, 0),
615 v2(pt2.x, pt2.y, 0, p2x, p2y, 0);
616 double pp = ls.Dot(v1) / ls.Magnitude(), dist;
617 // Geometric interpretation:
618 // pp is the paremeterized point on the vector ls where the perpendicular
619 // intersects ls. If pp < 0, then the perpendicular lies beyond the 1st
620 // endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd
624 dist = v1.Magnitude();
625 else if (pp > ls.Magnitude())
626 dist = v2.Magnitude();
627 else // distance = ?Det?(ls, v1) / |ls|
628 dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.Magnitude());
630 //The answer to the above looks like it might be found here:
632 //If the segment endpoints are s and e, and the point is p, then the test for
633 //the perpendicular intercepting the segment is equivalent to insisting that
634 //the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
635 //Perpendicular distance from the point to the segment is computed by first
636 //computing the area of the triangle the three points form, then dividing by
637 //the length of the segment. Distances are done just by the Pythagorean
638 //theorem. Twice the area of the triangle formed by three points is the
639 //determinant of the following matrix:
645 //By translating the start point to the origin, this can be rewritten as:
646 //By subtracting row 1 from all rows, you get the following:
647 //[because sx = sy = 0. you could leave out the -sx/y terms below. because we
648 //subtracted row 1 from all rows (including row 1) row 1 turns out to be zero.
652 //(ex - sx) (ey - sy) 0
653 //(px - sx) (py - sy) 0
655 //which greatly simplifies the calculation of the determinant.
658 smallest = dist, ptNextHighlight = pts.GetNext(i), ptHighlight = i;
661 if (ptNextHighlight != oldPtNextHighlight)
663 oldPtNextHighlight = ptNextHighlight;
669 ptPrevious = Vector(event->x(), event->y());
676 void EditWindow::mouseReleaseEvent(QMouseEvent * event)
678 if (event->button() == Qt::RightButton)
680 ToolType newTool = toolPalette->FindSelectedTool();
682 // We only change the tool if a new one was actually selected. Otherwise, we do nothing.
683 if (newTool != TOOLNone)
687 if (tool == TOOLScroll || tool == TOOLZoom || tool == TOOLAddPoly
688 || tool == TOOLDelPoly)
691 if (tool == TOOLAddPoly)
692 polyFirstPoint = true;
695 toolPalette->setVisible(false);
696 setCursor(cur[tool]);
697 // Just in case we changed highlighting style with the new tool...
700 else if (event->button() == Qt::MidButton)
702 setCursor(cur[tool]); // Restore previous cursor
704 else if (event->button() == Qt::LeftButton)
706 if (showRotationCenter)
708 showRotationCenter = false;
709 haveZeroPoint = false;
711 if (tool == TOOLRotate)
712 pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
715 uint16_t poly = pts.GetPolyForPointNumber(ptHighlight);
716 pts.RotatePolyAroundCentroid(poly, rotationAngle);
720 ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage("");
723 // if (tool == TOOLScroll || tool == TOOLZoom)
725 //this is prolly too much
726 ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
727 ((TTEdit *)qApp)->charWnd->update();
729 if (tool == TOOLMultiSelect)
731 selectionInProgress = false;
740 void EditWindow::keyPressEvent(QKeyEvent * event)
742 // Sanity checking...
743 if (ptHighlight == -1)
746 if (event->key() == Qt::Key_Up)
748 pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) + 1);
750 else if (event->key() == Qt::Key_Down)
751 pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) - 1);
752 else if (event->key() == Qt::Key_Right)
753 pts.SetXY(ptHighlight, pts.GetX(ptHighlight) + 1, pts.GetY(ptHighlight));
754 else if (event->key() == Qt::Key_Left)
755 pts.SetXY(ptHighlight, pts.GetX(ptHighlight) - 1, pts.GetY(ptHighlight));
761 ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
762 ((TTEdit *)qApp)->charWnd->update();
766 void EditWindow::keyReleaseEvent(QKeyEvent * /*event*/)