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 painter.SetRenderHint(QPainter::Antialiasing);
121 Global::zoom = scale;
122 Global::origin = Vector(offsetX, offsetY);
123 Global::viewportHeight = size().height();
124 Global::screenSize = Vector(size().width(), size().height());
125 // p.translate(QPoint(-offsetX, size().height() - (-offsetY)));
126 // p.scale(1.0, -1.0);
127 //Nope, a big load of shit. So we'll have to bite the bullet and do it the
129 // p.scale(scale, -scale);
131 // Scrolling can be done by using OffsetViewportOrgEx
132 // Scaling can be done by adjusting SetWindowExtEx (it's denominator of txform)
133 // you'd use: % = ViewportExt / WindowExt
134 // But it makes the window look like crap: fuggetuboutit.
135 // Instead, we have to scale EVERYTHING by hand. Crap!
136 // It's not *that* bad, but not as convenient either...
138 painter.SetPen(QPen(Qt::blue, 1.0, Qt::DotLine));
140 // Draw coordinate axes
142 painter.DrawLine(0, -16384, 0, 16384);
143 painter.DrawLine(-16384, 0, 16384, 0);
145 // Draw rotation center (if active)
147 if (showRotationCenter)
149 painter.SetPen(QPen(Qt::red, 2.0, Qt::SolidLine));
150 painter.DrawLine(rotationCenter.x + 7, rotationCenter.y, rotationCenter.x - 7, rotationCenter.y);
151 painter.DrawLine(rotationCenter.x, rotationCenter.y + 7, rotationCenter.x, rotationCenter.y - 7);
156 for(int i=0; i<pts.GetNumPoints(); i++)
158 /*if (tool == TOOLMultiSelect)
160 if (selectedPoints[i])
162 qtp.setPen(QPen(Qt::red, 1.0, Qt::SolidLine));
166 qtp.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
170 if (((i == ptHighlight) && (tool != TOOLMultiSelect)) || ((tool == TOOLMultiSelect) && selectedPoints[i]))
172 painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
174 if (pts.GetOnCurve(i))
176 painter.DrawSquareDotN(pts.GetXY(i), 7);
177 painter.DrawSquareDotN(pts.GetXY(i), 9);
181 painter.DrawRoundDotN(pts.GetXY(i), 7);
182 painter.DrawRoundDotN(pts.GetXY(i), 9);
185 else if ((i == ptHighlight || i == ptNextHighlight) && tool == TOOLAddPt)
187 painter.SetPen(QPen(Qt::green, 1.0, Qt::SolidLine));
189 if (pts.GetOnCurve(i))
191 painter.DrawSquareDotN(pts.GetXY(i), 7);
192 painter.DrawSquareDotN(pts.GetXY(i), 9);
196 painter.DrawRoundDotN(pts.GetXY(i), 7);
197 painter.DrawRoundDotN(pts.GetXY(i), 9);
202 painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
205 if (pts.GetOnCurve(i))
206 painter.DrawSquareDot(pts.GetXY(i));
208 painter.DrawRoundDot(pts.GetXY(i));
210 (pts.GetOnCurve(i) ? DrawSquareDot(p, pts.GetX(i), pts.GetY(i))
211 : DrawRoundDot(p, pts.GetX(i), pts.GetY(i)));
215 if (tool == TOOLDelPt && i == ptHighlight)
217 painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
218 painter.DrawLine(pts.GetX(i) - 5, pts.GetY(i) - 5, pts.GetX(i) + 5, pts.GetY(i) + 5);
219 painter.DrawLine(pts.GetX(i) + 5, pts.GetY(i) - 5, pts.GetX(i) - 5, pts.GetY(i) + 5);
223 // Draw curve formed by points
225 painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
226 DrawGlyph(painter, pts);
231 GlyphPoints rotated = pts;
233 if (tool == TOOLRotate)
234 rotated.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
235 else if (tool == TOOLRotatePoly)
237 uint16_t poly = rotated.GetPolyForPointNumber(ptHighlight);
238 rotated.RotatePolyAroundCentroid(poly, rotationAngle);
241 painter.SetPen(QPen(QColor(255, 0, 255), 1.0, Qt::SolidLine));
242 DrawGlyph(painter, rotated);
245 if (selectionInProgress)
247 painter.SetPen(QPen(QColor(255, 127, 0, 255)));
248 painter.SetBrush(QBrush(QColor(255, 127, 0, 100)));
249 painter.DrawRect(selection);
254 void EditWindow::DrawGlyph(Painter & p, GlyphPoints & glyph)
256 for(int poly=0; poly<glyph.GetNumPolys(); poly++)
259 if (glyph.GetNumPoints(poly) < 3)
262 // Initial move: If our start point is on curve, then go to it. Otherwise,
263 // check previous point. If it's on curve, go to it otherwise go the
264 // midpoint between start point and previous (since it's between two curve
266 IPoint pt = (glyph.GetOnCurve(poly, 0)
267 ? glyph.GetPoint(poly, 0) : (glyph.GetPrevOnCurve(poly, 0)
268 ? glyph.GetPrevPoint(poly, 0) : glyph.GetMidpointToPrev(poly, 0)));
270 // Need to add separate color handling here for polys that are being manipulated...
272 for(int i=0; i<glyph.GetNumPoints(poly); i++)
274 // If this point and then next are both on curve, we have a line...
275 if (glyph.GetOnCurve(poly, i) && glyph.GetNextOnCurve(poly, i))
277 IPoint pt2 = glyph.GetNextPoint(poly, i);
278 p.drawLine(pt.x, pt.y, pt2.x, pt2.y);
283 // Skip point if it's on curve (start of curve--it's already
284 // been plotted so we don't need to handle it...)
285 if (glyph.GetOnCurve(poly, i))
288 // We are now guaranteed that we are sitting on a curve control point
289 // (off curve). Figure the extent of the curve: If the following is a
290 // curve control point, then use the midpoint to it otherwise go to
291 // the next point since it's on curve.
292 IPoint pt2 = (glyph.GetNextOnCurve(poly, i)
293 ? glyph.GetNextPoint(poly, i) : glyph.GetMidpointToNext(poly, i));
295 Bezier(p, pt, glyph.GetPoint(poly, i), pt2);
300 DrawGlyphPoly(p, glyph, poly);
306 void EditWindow::DrawGlyphPoly(Painter & p, GlyphPoints & glyph, uint16_t poly)
309 if (glyph.GetNumPoints(poly) < 3)
312 // Initial move: If our start point is on curve, then go to it. Otherwise,
313 // check previous point. If it's on curve, go to it otherwise go the
314 // midpoint between start point and previous (since it's between two curve
316 IPoint pt = (glyph.GetOnCurve(poly, 0)
317 ? glyph.GetPoint(poly, 0) : (glyph.GetPrevOnCurve(poly, 0)
318 ? glyph.GetPrevPoint(poly, 0) : glyph.GetMidpointToPrev(poly, 0)));
320 for(int i=0; i<glyph.GetNumPoints(poly); i++)
322 // If this point and then next are both on curve, we have a line...
323 if (glyph.GetOnCurve(poly, i) && glyph.GetNextOnCurve(poly, i))
325 IPoint pt2 = glyph.GetNextPoint(poly, i);
326 p.DrawLine(pt.x, pt.y, pt2.x, pt2.y);
331 // Skip point if it's on curve (start of curve--it's already
332 // been plotted so we don't need to handle it...)
333 if (glyph.GetOnCurve(poly, i))
336 // We are now guaranteed that we are sitting on a curve control
337 // point (off curve). Figure the extent of the curve: If the
338 // following is a curve control point, then use the midpoint to it
339 // otherwise go to the next point since it's on curve.
340 IPoint pt2 = (glyph.GetNextOnCurve(poly, i)
341 ? glyph.GetNextPoint(poly, i) : glyph.GetMidpointToNext(poly, i));
343 p.DrawBezier(pt, glyph.GetPoint(poly, i), pt2);
350 void EditWindow::ClearSelection(void)
352 for(int i=0; i<65536; i++)
353 selectedPoints[i] = false;
357 void EditWindow::mousePressEvent(QMouseEvent * event)
359 if (event->button() == Qt::RightButton)
361 toolPalette->move(event->globalPos());
362 toolPalette->setVisible(true);
363 setCursor(cur[TOOLSelect]);
364 toolPalette->prevTool = TOOLSelect;
366 else if (event->button() == Qt::MidButton)
370 ptPrevious = Vector(event->x(), event->y());
371 ptPrevious /= Global::zoom;
373 else if (event->button() == Qt::LeftButton)
375 if (tool == TOOLScroll || tool == TOOLZoom)
376 ;//meh CaptureMouse(); // Make sure we capture the mouse when in scroll/zoom mode
377 else if (tool == TOOLMultiSelect)
379 // QPoint pt = GetAdjustedMousePosition(event);
380 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
381 selectionInProgress = true;
382 selection.setTopLeft(QPoint(pt.x, pt.y));
383 selection.setBottomRight(QPoint(pt.x, pt.y));
385 else if (tool == TOOLAddPt) // "Add Point" tool
387 // QPoint pt = GetAdjustedMousePosition(event);
388 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
389 IPoint pointToAdd(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
391 if (pts.GetNumPoints() < 2)
393 // pts += IPoint(pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
395 ptHighlight = pts.GetNumPoints() - 1;
399 // QPoint pt = GetAdjustedMousePosition(event);
400 // pts.InsertPoint(pts.GetNext(ptHighlight), pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
401 pts.InsertPoint(pts.GetNext(ptHighlight), pointToAdd);
402 ptHighlight = ptNextHighlight;
408 else if (tool == TOOLAddPoly) // "Add Poly" tool
411 WriteLogMsg("Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.GetNumPoints());
415 polyFirstPoint = false;
416 pts.AddNewPolyAtEnd();
419 // QPoint pt = GetAdjustedMousePosition(event);
420 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
421 //printf("GetAdjustedMousePosition = %i, %i\n", pt.x(), pt.y());
422 // Append a point to the end of the structure
423 pts += IPoint(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
424 ptHighlight = pts.GetNumPoints() - 1;
427 WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumPoints());
430 else if (tool == TOOLSelect || tool == TOOLPolySelect)
432 if (pts.GetNumPoints() > 0)
434 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
435 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
436 //printf("GetAdjustedClientPosition = %i, %i\n", pt.x(), pt.y());
437 QPoint warp(pt.x, pt.y);
438 QCursor::setPos(mapToGlobal(warp));
440 if (event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier)
442 pts.SetOnCurve(ptHighlight, !pts.GetOnCurve(ptHighlight));
447 else if (tool == TOOLDelPt)
449 if (pts.GetNumPoints() > 0)
451 // if (ptHighlight != -1)
453 //This assumes that WM_MOUSEMOVE happens before this!
454 //The above commented out line should take care of this contingency... !!! FIX !!!
455 pts.DeletePoint(ptHighlight);
459 else if (tool == TOOLRotate)
461 // I think what's needed here is to keep the initial mouse click,
462 // paint the rotation center, then use the 1st mouse move event to establish
463 // the rotation "zero line", which becomes the line of reference to all
464 // subsequent mouse moves.
465 // rotationCenter = GetAdjustedMousePosition(event);
466 rotationCenter = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
467 showRotationCenter = true;
468 haveZeroPoint = false;
472 else if (tool == TOOLRotatePoly)
474 IPoint centroid = pts.GetPolyCentroid(pts.GetPolyForPointNumber(ptHighlight));
475 rotationCenter = Vector(centroid.x, centroid.y);
476 showRotationCenter = true;
477 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
478 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
479 QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
480 rotationZeroPoint = Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
481 haveZeroPoint = true;
485 else if (tool == TOOLFlipWinding)
487 pts.InvertPolyDrawSequence(pts.GetPolyForPointNumber(ptHighlight));
488 // pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
489 Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
490 QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
499 void EditWindow::mouseMoveEvent(QMouseEvent * event)
501 if (event->buttons() == Qt::RightButton)
503 ToolType newTool = toolPalette->FindSelectedTool();
505 if (newTool != toolPalette->prevTool)
507 toolPalette->prevTool = newTool;
508 toolPalette->repaint();
511 else if (event->buttons() == Qt::MidButton)
513 // Calc offset from previous point
514 Vector pt(event->x(), event->y());
516 ptOffset = Vector(pt.x - ptPrevious.x, pt.y - ptPrevious.y);
518 // Then multiply it by the scaling factor. Whee!
519 // This looks wacky because we're using screen coords for the offset...
520 // Otherwise, we would subtract both offsets!
521 offsetX -= ptOffset.x, offsetY += ptOffset.y;
525 else if (event->buttons() == Qt::LeftButton)
527 if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect)
529 // Bail out if we have the select tool and no points yet...
530 if (tool == TOOLSelect && pts.GetNumPoints() == 0)
533 // QPoint pt2 = GetAdjustedMousePosition(event);
534 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
535 pts.SetXY(ptHighlight, pt2.x, pt2.y);
538 else if (tool == TOOLPolySelect)
540 if (pts.GetNumPoints() > 0)
542 // QPoint pt2 = GetAdjustedMousePosition(event);
543 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
544 // Should also set onCurve here as well, depending on keystate
546 //Would be nice, but we'd need to trap the keyPressEvent() as well, otherwise pressing/releasing
547 //the hotkey would show no change until the user moved their mouse.
548 pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x - pts.GetX(ptHighlight), pt2.y - pts.GetY(ptHighlight));
552 else if (tool == TOOLRotate || tool == TOOLRotatePoly)
554 if (pts.GetNumPoints() > 0)
558 // rotationZeroPoint = GetAdjustedMousePosition(event);
559 rotationZeroPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
560 haveZeroPoint = true;
564 // Figure out the angle between the "zero" vector and the current one,
565 // then rotate all points relative to the "zero" vector (done by paint())
566 // QPoint currentPoint = GetAdjustedMousePosition(event);
567 Vector currentPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
568 Vector v1(rotationZeroPoint.x, rotationZeroPoint.y, 0,
569 rotationCenter.x, rotationCenter.y, 0);
570 Vector v2(currentPoint.x, currentPoint.y, 0,
571 rotationCenter.x, rotationCenter.y, 0);
572 // rotationAngle = v1.Angle(v2);
573 rotationAngle = v2.Angle(v1);
576 s.sprintf("%.3f degrees", rotationAngle * 180.0 / 3.14159265358979323);
577 ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage(s);
583 else if (tool == TOOLMultiSelect)
585 // QPoint pt = GetAdjustedMousePosition(event);
586 Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
587 selection.setBottomRight(QPoint(pt.x, pt.y));
589 for(int i=0; i<pts.GetNumPoints(); i++)
591 if (selection.contains(QPoint(pts.GetX(i), pts.GetY(i))))
592 selectedPoints[i] = true;
594 selectedPoints[i] = false;
600 else if (event->buttons() == Qt::NoButton)
602 // Moving, not dragging...
603 if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt
604 || tool == TOOLPolySelect || tool == TOOLRotatePoly || tool == TOOLFlipWinding)
606 // QPoint pt2 = GetAdjustedMousePosition(event);
607 Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
608 double closest = 1.0e+99;
610 for(int i=0; i<pts.GetNumPoints(); i++)
612 double dist = ((pt2.x - pts.GetX(i)) * (pt2.x - pts.GetX(i)))
613 + ((pt2.y - pts.GetY(i)) * (pt2.y - pts.GetY(i)));
616 closest = dist, ptHighlight = i;
619 if (ptHighlight != oldPtHighlight)
621 oldPtHighlight = ptHighlight;
625 // What follows here looks like voodoo, but is really simple. What
626 // we do is check to see if the mouse point has a perpendicular
627 // intersection with any of the line segments. If it does,
628 // calculate the length of the perpendicular and choose the
629 // smallest length. If there is no perpendicular, then choose the
630 // length of line connecting the closer of either the first
631 // endpoint or the second and choose the smallest of those.
633 // There is one bit of math that looks like voodoo to me ATM--will
634 // explain once I understand it better (the calculation of the
635 // length of the perpendicular).
637 if (pts.GetNumPoints() > 1 && tool == TOOLAddPt)
639 double smallest = 1.0e+99;
641 for(int i=0; i<pts.GetNumPoints(); i++)
643 int32_t p1x = pts.GetX(i), p1y = pts.GetY(i),
644 p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
646 Vector ls(p2x, p2y, 0, p1x, p1y, 0),
647 v1(pt2.x, pt2.y, 0, p1x, p1y, 0),
648 v2(pt2.x, pt2.y, 0, p2x, p2y, 0);
649 double pp = ls.Dot(v1) / ls.Magnitude(), dist;
650 // Geometric interpretation:
651 // pp is the paremeterized point on the vector ls where the perpendicular
652 // intersects ls. If pp < 0, then the perpendicular lies beyond the 1st
653 // endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd
657 dist = v1.Magnitude();
658 else if (pp > ls.Magnitude())
659 dist = v2.Magnitude();
660 else // distance = ?Det?(ls, v1) / |ls|
661 dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.Magnitude());
663 //The answer to the above looks like it might be found here:
665 //If the segment endpoints are s and e, and the point is p, then the test for
666 //the perpendicular intercepting the segment is equivalent to insisting that
667 //the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
668 //Perpendicular distance from the point to the segment is computed by first
669 //computing the area of the triangle the three points form, then dividing by
670 //the length of the segment. Distances are done just by the Pythagorean
671 //theorem. Twice the area of the triangle formed by three points is the
672 //determinant of the following matrix:
678 //By translating the start point to the origin, this can be rewritten as:
679 //By subtracting row 1 from all rows, you get the following:
680 //[because sx = sy = 0. you could leave out the -sx/y terms below. because we
681 //subtracted row 1 from all rows (including row 1) row 1 turns out to be zero.
685 //(ex - sx) (ey - sy) 0
686 //(px - sx) (py - sy) 0
688 //which greatly simplifies the calculation of the determinant.
691 smallest = dist, ptNextHighlight = pts.GetNext(i), ptHighlight = i;
694 if (ptNextHighlight != oldPtNextHighlight)
696 oldPtNextHighlight = ptNextHighlight;
702 ptPrevious = Vector(event->x(), event->y());
709 void EditWindow::mouseReleaseEvent(QMouseEvent * event)
711 if (event->button() == Qt::RightButton)
713 ToolType newTool = toolPalette->FindSelectedTool();
715 // We only change the tool if a new one was actually selected. Otherwise, we do nothing.
716 if (newTool != TOOLNone)
720 if (tool == TOOLScroll || tool == TOOLZoom || tool == TOOLAddPoly
721 || tool == TOOLDelPoly)
724 if (tool == TOOLAddPoly)
725 polyFirstPoint = true;
728 toolPalette->setVisible(false);
729 setCursor(cur[tool]);
730 // Just in case we changed highlighting style with the new tool...
733 else if (event->button() == Qt::MidButton)
735 setCursor(cur[tool]); // Restore previous cursor
737 else if (event->button() == Qt::LeftButton)
739 if (showRotationCenter)
741 showRotationCenter = false;
742 haveZeroPoint = false;
744 if (tool == TOOLRotate)
745 pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
748 uint16_t poly = pts.GetPolyForPointNumber(ptHighlight);
749 pts.RotatePolyAroundCentroid(poly, rotationAngle);
753 ((TTEdit *)qApp)->mainWindow->statusBar()->showMessage("");
756 // if (tool == TOOLScroll || tool == TOOLZoom)
758 //this is prolly too much
759 ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
760 ((TTEdit *)qApp)->charWnd->update();
762 if (tool == TOOLMultiSelect)
764 selectionInProgress = false;
773 void EditWindow::keyPressEvent(QKeyEvent * event)
775 // Sanity checking...
776 if (ptHighlight == -1)
779 if (event->key() == Qt::Key_Up)
781 pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) + 1);
783 else if (event->key() == Qt::Key_Down)
784 pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) - 1);
785 else if (event->key() == Qt::Key_Right)
786 pts.SetXY(ptHighlight, pts.GetX(ptHighlight) + 1, pts.GetY(ptHighlight));
787 else if (event->key() == Qt::Key_Left)
788 pts.SetXY(ptHighlight, pts.GetX(ptHighlight) - 1, pts.GetY(ptHighlight));
794 ((TTEdit *)qApp)->charWnd->MakePathFromPoints(&pts);
795 ((TTEdit *)qApp)->charWnd->update();
799 void EditWindow::keyReleaseEvent(QKeyEvent * /*event*/)