- if (newTool != toolPalette->prevTool)
- {
- toolPalette->prevTool = newTool;
- toolPalette->repaint();
- }
- }
- else if (event->buttons() == Qt::MidButton)
- {
- // Calc offset from previous point
- pt = event->pos();
- ptOffset = QPoint(pt.x() - ptPrevious.x(), pt.y() - ptPrevious.y());
-
-// Then multiply it by the scaling factor. Whee!
- // This looks wacky because we're using screen coords for the offset...
- // Otherwise, we would subtract both offsets!
- offsetX -= ptOffset.x(), offsetY += ptOffset.y();
- update();
- ptPrevious = pt;
- }
- else if (event->buttons() == Qt::LeftButton)
- {
-#if 0
- if (tool == TOOLScroll)
- {
- // Extract current point from lParam/calc offset from previous point
-
- pt = e.GetPosition();
- ptOffset.x = pt.x - ptPrevious.x,
- ptOffset.y = pt.y - ptPrevious.y;
-
- // NOTE: OffsetViewportOrg operates in DEVICE UNITS...
-
-//Seems there's no equivalent for this in wxWidgets...!
-//!!! FIX !!!
-// hdc = GetDC(hWnd);
-// OffsetViewportOrgEx(hdc, ptOffset.x, ptOffset.y, NULL);
-// ReleaseDC(hWnd, hdc);
-
-// this shows that it works, so the logic above must be faulty...
-// And it is. It should convert the coords first, then do the subtraction to figure the offset...
-// Above: DONE
-// Then multiply it by the scaling factor. Whee!
- // This looks wacky because we're using screen coords for the offset...
- // Otherwise, we would subtract both offsets!
- offsetX -= ptOffset.x, offsetY += ptOffset.y;
- Refresh();
- }
- else
-#endif
- if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect)
- {
- if (tool != TOOLAddPt || pts.GetNumPoints() > 0)//yecch.
- {
-//temporary, for testing. BTW, Select drag bug is here...!
-#if 1
- QPoint pt2 = GetAdjustedMousePosition(event);
- pts.SetXY(ptHighlight, pt2.x(), pt2.y());
- update();
-#endif
- }
- }
- else if (tool == TOOLPolySelect)
- {
- if (pts.GetNumPoints() > 0)
- {
- QPoint pt2 = GetAdjustedMousePosition(event);
- // Should also set onCurve here as well, depending on keystate
-//Or should we?
- pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x() - pts.GetX(ptHighlight), pt2.y() - pts.GetY(ptHighlight));
- update();
- }
- }
- }
- else if (event->buttons() == Qt::NoButton)
- {
- // Moving, not dragging...
- if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt
- || tool == TOOLPolySelect)// || tool == TOOLAddPoly)
- {
- QPoint pt2 = GetAdjustedMousePosition(event);
- double closest = 1.0e+99;
-
- for(int i=0; i<pts.GetNumPoints(); i++)
- {
- double dist = ((pt2.x() - pts.GetX(i)) * (pt2.x() - pts.GetX(i)))
- + ((pt2.y() - pts.GetY(i)) * (pt2.y() - pts.GetY(i)));
-
- if (dist < closest)
- closest = dist, ptHighlight = i;
- }
-
- if (ptHighlight != oldPtHighlight)
- {
- oldPtHighlight = ptHighlight;
- update();
- }
-
- // What follows here looks like voodoo, but is really simple. What we do is
- // check to see if the mouse point has a perpendicular intersection with any of
- // the line segments. If it does, calculate the length of the perpendicular
- // and choose the smallest length. If there is no perpendicular, then choose the
- // length of line connecting the closer of either the first endpoint or the
- // second and choose the smallest of those.
-
- // There is one bit of math that looks like voodoo to me ATM--will explain once
- // I understand it better (the calculation of the length of the perpendicular).
-
- if (pts.GetNumPoints() > 1 && tool == TOOLAddPt)
- {
- double smallest = 1.0e+99;
-
- for(int i=0; i<pts.GetNumPoints(); i++)
- {
- int32 p1x = pts.GetX(i), p1y = pts.GetY(i),
- p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
-
- vector ls(p2x, p2y, 0, p1x, p1y, 0), v1(pt2.x(), pt2.y(), 0, p1x, p1y, 0),
- v2(pt2.x(), pt2.y(), 0, p2x, p2y, 0);
- double pp = ls.dot(v1) / ls.length(), dist;
-// Geometric interpretation:
-// pp is the paremeterized point on the vector ls where the perpendicular intersects ls.
-// If pp < 0, then the perpendicular lies beyond the 1st endpoint. If pp > length of ls,
-// then the perpendicular lies beyond the 2nd endpoint.
-
- if (pp < 0.0)
- dist = v1.length();
- else if (pp > ls.length())
- dist = v2.length();
- else // distance = ?Det?(ls, v1) / |ls|
- dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.length());
-
-//The answer to the above looks like it might be found here:
-//
-//If the segment endpoints are s and e, and the point is p, then the test for the perpendicular
-//intercepting the segment is equivalent to insisting that the two dot products {s-e}.{s-p} and
-//{e-s}.{e-p} are both non-negative. Perpendicular distance from the point to the segment is
-//computed by first computing the area of the triangle the three points form, then dividing by the
-//length of the segment. Distances are done just by the Pythagorean theorem. Twice the area of the
-//triangle formed by three points is the determinant of the following matrix:
-//
-//sx sy 1
-//ex ey 1
-//px py 1
-//
-//By translating the start point to the origin, this can be rewritten as:
-//By subtracting row 1 from all rows, you get the following:
-//[because sx = sy = 0. you could leave out the -sx/y terms below. because we subtracted
-// row 1 from all rows (including row 1) row 1 turns out to be zero. duh!]
-//
-//0 0 0
-//(ex - sx) (ey - sy) 0
-//(px - sx) (py - sy) 0
-//
-//which greatly simplifies the calculation of the determinant.
-
- if (dist < smallest)
- smallest = dist, ptNextHighlight = pts.GetNext(i), ptHighlight = i;
- }
-
- if (ptNextHighlight != oldPtNextHighlight)
- {
- oldPtNextHighlight = ptNextHighlight;
- update();
- }
- }
- }
-
- ptPrevious = event->pos();