+ Vector v(toolObj[0]->p[0], toolObj[0]->p[1]);
+
+ // Check to see which case we have.
+ if ((toolParam[0] == 0) && (toolParam[1] == 1.0))
+ {
+ // There was no intersection, so delete the object
+ toolObj[0]->selected = true;
+ DeleteSelectedObjects(document.objects);
+ }
+ else if (toolParam[0] == 0)
+ {
+ // We delete the end near point #1
+ toolObj[0]->p[0] = toolObj[0]->p[0] + (v * toolParam[1]);
+ }
+ else if (toolParam[1] == 1.0)
+ {
+ // We delete the end near point #2
+ toolObj[0]->p[1] = toolObj[0]->p[0] + (v * toolParam[0]);
+ }
+ else
+ {
+ // We delete the segment in between, and create a new line in the process
+ Point p1 = toolObj[0]->p[0] + (v * toolParam[0]);
+ Point p2 = toolObj[0]->p[0] + (v * toolParam[1]);
+ Point p3 = toolObj[0]->p[1];
+ toolObj[0]->p[1] = p1;
+ Line * l = new Line(p2, p3, toolObj[0]->thickness, toolObj[0]->color, toolObj[0]->style);
+ document.objects.push_back(l);
+// Global::toolState = TSNone;
+ }
+
+ toolObj[0]->hitObject = toolObj[0]->hitPoint[0] = toolObj[0]->hitPoint[1] = false;
+ toolObj[0] = NULL;
+ }
+ break;
+
+ case ToolKeyDown:
+ break;
+
+ case ToolKeyUp:
+ break;
+
+ case ToolCleanup:
+ break;
+ }
+}
+
+void DrawingView::ParallelHandler(int mode, Point /*p*/)
+{
+ switch (mode)
+ {
+ case ToolMouseDown:
+ break;
+
+ case ToolMouseMove:
+ break;
+
+ case ToolMouseUp:
+ break;
+
+ case ToolKeyDown:
+ break;
+
+ case ToolKeyUp:
+ break;
+
+ case ToolCleanup:
+ break;
+ }
+}
+
+void DrawingView::mousePressEvent(QMouseEvent * event)
+{
+ if (event->button() == Qt::LeftButton)
+ {
+ Vector point = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+
+ // Handle tool processing, if any
+ if (Global::tool)
+ {
+ if (hoveringIntersection)
+ point = intersectionPoint;
+ else if (hoverPointValid)
+ point = hoverPoint;
+ else if (Global::snapToGrid)
+ point = SnapPointToGrid(point);
+
+ ToolHandler(ToolMouseDown, point);
+ return;
+ }
+
+ // Clear the selection only if CTRL isn't being held on click
+ if (!ctrlDown)
+ ClearSelected(document.objects);
+
+ // If any objects are being hovered on click, deal with 'em
+ if (numHovered > 0)
+ {
+ VPVector hover2 = GetHovered();
+ dragged = (Object *)hover2[0];
+
+ // Alert the pen widget
+ if (Global::penDropper)
+ {
+ Global::penColor = dragged->color;
+ Global::penWidth = dragged->thickness;
+ Global::penStyle = dragged->style;
+ emit ObjectSelected(dragged);
+ return;
+ }
+ else if (Global::penStamp)
+ {
+ dragged->color = Global::penColor;
+ dragged->thickness = Global::penWidth;
+ dragged->style = Global::penStyle;
+ return;
+ }
+ // See if anything is using just a straight click on a custom
+ // object handle (like Dimension objects)
+ else if (HandleObjectClicked())
+ {
+ update();
+ return;
+ }
+
+ draggingObject = true;
+ HandleSelectionClick(hover2);
+ update(); // needed??
+
+ // Needed for grab & moving objects
+ // We do it *after*... why? (doesn't seem to confer any advantage...)
+ if (hoveringIntersection)
+ oldPoint = intersectionPoint;
+ else if (hoverPointValid)
+ oldPoint = hoverPoint;
+ else if (Global::snapToGrid)
+ oldPoint = SnapPointToGrid(point);
+
+ // Needed for fixed length handling
+ if (Global::fixedLength)
+ {
+ if (dragged->type == OTLine)
+ {
+ dragged->length = Vector::Magnitude(dragged->p[0], dragged->p[1]);
+ }
+ }
+
+ if (dragged->type == OTCircle)
+ {
+ // Save for informative text, uh, er, informing
+ dragged->length = dragged->radius[0];
+ }
+
+ return;
+ }
+
+ // Didn't hit any object and not using a tool, so do a selection
+ // rectangle
+ Global::selectionInProgress = true;
+ Global::selection.setTopLeft(QPointF(point.x, point.y));
+ Global::selection.setBottomRight(QPointF(point.x, point.y));
+ select = GetSelection();
+ }
+ else if (event->button() == Qt::MiddleButton)
+ {
+ scrollDrag = true;
+ oldPoint = Vector(event->x(), event->y());
+ // Should also change the mouse pointer as well...
+ setCursor(Qt::SizeAllCursor);
+ }
+}
+
+void DrawingView::mouseMoveEvent(QMouseEvent * event)
+{
+ // It seems that wheelEvent() triggers this for some reason...
+ if (scrollWheelSeen)
+ {
+ scrollWheelSeen = false;
+ return;
+ }
+
+ Vector point = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+ Global::selection.setBottomRight(QPointF(point.x, point.y));
+ // Only needs to be done here, as mouse down is always preceded by movement
+ Global::snapPointIsValid = false;
+ hoveringIntersection = false;
+ oldScrollPoint = Vector(event->x(), event->y());
+
+ // Scrolling...
+ if ((event->buttons() & Qt::MiddleButton) || scrollDrag)
+ {
+ point = Vector(event->x(), event->y());
+ // Since we're using Qt coords for scrolling, we have to adjust them
+ // here to conform to Cartesian coords, since the origin is using
+ // Cartesian. :-)
+ Vector delta(oldPoint, point);
+ delta /= Global::zoom;
+ delta.y = -delta.y;
+ Global::origin -= delta;
+
+// UpdateGridBackground();
+ update();
+ oldPoint = point;
+ return;
+ }
+
+ // If we're doing a selection rect, see if any objects are engulfed by it
+ // (implies left mouse button held down)
+ if (Global::selectionInProgress)
+ {
+ CheckObjectBounds();
+
+ // Make sure previously selected objects stay selected (CTRL held)
+ for(VPVectorIter i=select.begin(); i!=select.end(); i++)
+ {
+ // Make sure *not* to select items on hidden layers
+ if (Global::layerHidden[((Object *)(*i))->layer] == false)
+ ((Object *)(*i))->selected = true;
+ }
+
+ update();
+ return;
+ }
+
+ // Do object hit testing...
+ bool needUpdate = HitTestObjects(point);
+ VPVector hover2 = GetHovered(true); // Exclude dimension objects and circle centers (probably need to add arc centers too) from hover (also dragged objects...)
+#if 0
+{
+if (needUpdate)
+{
+ printf("mouseMoveEvent:: numHovered=%li, hover2.size()=%li\n", numHovered, hover2.size());
+
+ if (hover2.size() > 0)
+ printf(" (hover2[0]=$%llX, type=%s)\n", hover2[0], objName[((Object *)hover2[0])->type]);
+}
+}
+#endif
+
+ // Check for multi-hover...
+ if (hover2.size() > 1)
+ {
+//need to check for case where hover is over 2 circles and a 3rd's center (no longer a problem, I think)...
+ Object * obj1 = (Object *)hover2[0], * obj2 = (Object *)hover2[1];
+
+ Geometry::Intersects(obj1, obj2);
+ int numIntersecting = Global::numIntersectParams;
+ double t = Global::intersectParam[0];
+ double u = Global::intersectParam[1];
+
+ if (numIntersecting > 0)
+ {
+ Vector v1 = Geometry::GetPointForParameter(obj1, t);
+ Vector v2 = Geometry::GetPointForParameter(obj2, u);
+ QString text = tr("Intersection t=%1 (%3, %4), u=%2 (%5, %6)");
+ informativeText = text.arg(t).arg(u).arg(v1.x).arg(v1.y).arg(v2.x).arg(v2.y);
+
+ hoveringIntersection = true;
+ intersectionPoint = v1;
+ }
+
+ numIntersecting = Global::numIntersectPoints;
+
+ if (numIntersecting > 0)
+ {
+ Vector v1 = Global::intersectPoint[0];
+
+ if (numIntersecting == 2)
+ {
+ Vector v2 = Global::intersectPoint[1];
+
+ if (Vector::Magnitude(v2, point) < Vector::Magnitude(v1, point))
+ v1 = v2;
+ }
+
+ QString text = tr("Intersection <%1, %2>");
+ informativeText = text.arg(v1.x).arg(v1.y);
+ hoveringIntersection = true;
+ intersectionPoint = v1;
+ }
+ }
+ else if (hover2.size() == 1)
+ {
+ Object * obj = (Object *)hover2[0];
+
+ if (obj->type == OTLine)
+ {
+/*
+Not sure that this is the best way to handle this, but it works(TM)...
+*/
+ Point midpoint = Geometry::Midpoint((Line *)obj);
+ Vector v1 = Vector::Magnitude(midpoint, point);
+
+ if ((v1.Magnitude() * Global::zoom) < 8.0)
+ {
+ QString text = tr("Midpoint <%1, %2>");
+ informativeText = text.arg(midpoint.x).arg(midpoint.y);
+ hoverPointValid = true;
+ hoverPoint = midpoint;
+ needUpdate = true;
+ }
+ }
+ else if (obj->type == OTCircle)
+ {
+ if ((draggingObject && (dragged->type == OTLine)) && (dragged->hitPoint[0] || dragged->hitPoint[1]))
+ {
+ Point p = (dragged->hitPoint[0] ? dragged->p[1] : dragged->p[0]);
+ Geometry::FindTangents(obj, p);
+
+ if (Global::numIntersectPoints > 0)
+ {
+ hoveringIntersection = true;
+ intersectionPoint = Geometry::NearestTo(point, Global::intersectPoint[0], Global::intersectPoint[1]);
+ }
+ }
+ else if ((Global::tool == TTLine) && (Global::toolState == TSPoint2))
+ {
+ Geometry::FindTangents(obj, toolPoint[0]);
+
+ if (Global::numIntersectPoints > 0)
+ {
+ hoveringIntersection = true;
+ intersectionPoint = Geometry::NearestTo(point, Global::intersectPoint[0], Global::intersectPoint[1]);
+ }
+ }
+ }
+ }
+
+ // Handle object movement (left button down & over an object)
+ if ((event->buttons() & Qt::LeftButton) && draggingObject && !Global::tool)
+ {
+ if (hoveringIntersection)
+ point = intersectionPoint;
+ else if (hoverPointValid)
+ point = hoverPoint;
+ else if (Global::snapToGrid)
+ point = SnapPointToGrid(point);
+
+ HandleObjectMovement(point);
+ update();
+ oldPoint = point;
+ return;
+ }
+
+ // Do tool handling, if any are active...
+ if (Global::tool)
+ {
+ if (hoveringIntersection)
+ point = intersectionPoint;
+ else if (hoverPointValid)
+ point = hoverPoint;
+ else if (Global::snapToGrid)
+ {
+ if (angleSnap)
+ point = SnapPointToAngle(point);
+ else
+ point = SnapPointToGrid(point);
+ }
+
+ ToolHandler(ToolMouseMove, point);
+ }
+
+ // This is used to draw the tool crosshair...
+ oldPoint = point;
+
+ if (needUpdate || Global::tool)
+ update();