+void DrawingView::CircleHandler(int mode, Point p)
+{
+ switch (mode)
+ {
+ case ToolMouseDown:
+ if (Global::toolState == TSNone)
+ toolPoint[0] = p;
+ else
+ toolPoint[1] = p;
+
+ break;
+ case ToolMouseMove:
+ if (Global::toolState == TSNone)
+ toolPoint[0] = p;
+ else
+ toolPoint[1] = p;
+
+ break;
+ case ToolMouseUp:
+ if (Global::toolState == TSNone)
+ {
+ Global::toolState = TSPoint2;
+ // Prevent spurious line from drawing...
+ toolPoint[1] = toolPoint[0];
+ }
+ else if ((Global::toolState == TSPoint2) && shiftDown)
+ {
+ // Key override is telling us to make a new line, not continue the
+ // previous one.
+ toolPoint[0] = toolPoint[1];
+ }
+ else
+ {
+ double length = Vector::Magnitude(toolPoint[0], toolPoint[1]);
+ Circle * c = new Circle(toolPoint[0], length);
+ document.objects.push_back(c);
+ toolPoint[0] = toolPoint[1];
+ Global::toolState = TSNone;
+ }
+ }
+}
+
+
+void DrawingView::ArcHandler(int mode, Point p)
+{
+ switch (mode)
+ {
+ case ToolMouseDown:
+ if (Global::toolState == TSNone)
+ toolPoint[0] = p;
+ else if (Global::toolState == TSPoint2)
+ toolPoint[1] = p;
+ else if (Global::toolState == TSPoint3)
+ toolPoint[2] = p;
+ else
+ toolPoint[3] = p;
+
+ break;
+ case ToolMouseMove:
+ if (Global::toolState == TSNone)
+ toolPoint[0] = p;
+ else if (Global::toolState == TSPoint2)
+ toolPoint[1] = p;
+ else if (Global::toolState == TSPoint3)
+ toolPoint[2] = p;
+ else
+ toolPoint[3] = p;
+
+ break;
+ case ToolMouseUp:
+ if (Global::toolState == TSNone)
+ {
+ // Prevent spurious line from drawing...
+ toolPoint[1] = toolPoint[0];
+ Global::toolState = TSPoint2;
+ }
+ else if (Global::toolState == TSPoint2)
+ {
+ if (shiftDown)
+ {
+ // Key override is telling us to start circle at new center, not
+ // continue the current one.
+ toolPoint[0] = toolPoint[1];
+ return;
+ }
+
+ // Set the radius in toolPoint[1].x
+ toolPoint[1].x = Vector::Magnitude(toolPoint[0], toolPoint[1]);
+ Global::toolState = TSPoint3;
+ }
+ else if (Global::toolState == TSPoint3)
+ {
+ // Set the angle in toolPoint[2].x
+ toolPoint[2].x = Vector::Angle(toolPoint[0], toolPoint[2]);
+ Global::toolState = TSPoint4;
+ }
+ else
+ {
+ double endAngle = Vector::Angle(toolPoint[0], toolPoint[3]);
+ double span = endAngle - toolPoint[2].x;
+
+ if (span < 0)
+ span += PI_TIMES_2;
+
+ Arc * arc = new Arc(toolPoint[0], toolPoint[1].x, toolPoint[2].x, span);
+ document.objects.push_back(arc);
+ Global::toolState = TSNone;
+ }
+ }
+}
+
+
+void DrawingView::RotateHandler(int mode, Point p)
+{
+ switch (mode)
+ {
+ case ToolMouseDown:
+ if (Global::toolState == TSNone)
+ {
+ toolPoint[0] = p;
+ SavePointsFrom(select, toolScratch);
+ Global::toolState = TSPoint1;
+ }
+ else if (Global::toolState == TSPoint1)
+ toolPoint[0] = p;
+ else
+ toolPoint[1] = p;
+
+ break;
+ case ToolMouseMove:
+ if ((Global::toolState == TSPoint1) || (Global::toolState == TSNone))
+ toolPoint[0] = p;
+ else if (Global::toolState == TSPoint2)
+ {
+ toolPoint[1] = p;
+
+ if (shiftDown)
+ return;
+
+ double angle = Vector(toolPoint[0], toolPoint[1]).Angle();
+ std::vector<void *>::iterator j = select.begin();
+ std::vector<Object>::iterator i = toolScratch.begin();
+
+ for(; i!=toolScratch.end(); i++, j++)
+ {
+ Object obj = *i;
+ Point p1 = Geometry::RotatePointAroundPoint(obj.p[0], toolPoint[0], angle);
+ Point p2 = Geometry::RotatePointAroundPoint(obj.p[1], toolPoint[0], angle);
+ Object * obj2 = (Object *)(*j);
+ obj2->p[0] = p1;
+ obj2->p[1] = p2;
+
+ if (obj.type == OTArc)
+ {
+ obj2->angle[0] = obj.angle[0] + angle;
+
+ if (obj2->angle[0] > PI_TIMES_2)
+ obj2->angle[0] -= PI_TIMES_2;
+ }
+ }
+ }
+
+ break;
+ case ToolMouseUp:
+ if (Global::toolState == TSPoint1)
+ {
+ Global::toolState = TSPoint2;
+ // Prevent spurious line from drawing...
+ toolPoint[1] = toolPoint[0];
+ }
+ else if ((Global::toolState == TSPoint2) && shiftDown)
+ {
+ // Key override is telling us to make a new line, not continue the
+ // previous one.
+ toolPoint[0] = toolPoint[1];
+ }
+ else
+ {
+ // Either we're finished with our rotate, or we're stamping a copy.
+ if (ctrlDown)
+ {
+ // Stamp a copy of the selection at the current rotation & bail
+ std::vector<void *> temp;
+ CopyObjects(select, temp);
+ ClearSelected(temp);
+ AddObjectsTo(document.objects, temp);
+ RestorePointsTo(select, toolScratch);
+ return;
+ }
+
+ toolPoint[0] = p;
+ Global::toolState = TSPoint1;
+ SavePointsFrom(select, toolScratch);
+ }
+
+ break;
+ case ToolKeyDown:
+ // Reset the selection if shift held down...
+ if (shiftDown)
+ RestorePointsTo(select, toolScratch);
+
+ break;
+ case ToolKeyUp:
+ // Reset selection when key is let up
+ if (!shiftDown)
+ RotateHandler(ToolMouseMove, toolPoint[1]);
+
+ break;
+ case ToolCleanup:
+ RestorePointsTo(select, toolScratch);
+ }
+}
+
+
+void DrawingView::MirrorHandler(int mode, Point p)
+{
+ switch (mode)
+ {
+ case ToolMouseDown:
+ if (Global::toolState == TSNone)
+ {
+ toolPoint[0] = p;
+ SavePointsFrom(select, toolScratch);
+ Global::toolState = TSPoint1;
+ }
+ else if (Global::toolState == TSPoint1)
+ toolPoint[0] = p;
+ else
+ toolPoint[1] = p;
+
+ break;
+ case ToolMouseMove:
+ if ((Global::toolState == TSPoint1) || (Global::toolState == TSNone))
+ toolPoint[0] = p;
+ else if (Global::toolState == TSPoint2)
+ {
+ toolPoint[1] = p;
+
+ if (shiftDown)
+ return;
+
+ double angle = Vector(toolPoint[0], toolPoint[1]).Angle();
+ std::vector<void *>::iterator j = select.begin();
+ std::vector<Object>::iterator i = toolScratch.begin();
+
+ for(; i!=toolScratch.end(); i++, j++)
+ {
+ Object obj = *i;
+ Point p1 = Geometry::MirrorPointAroundLine(obj.p[0], toolPoint[0], toolPoint[1]);
+ Point p2 = Geometry::MirrorPointAroundLine(obj.p[1], toolPoint[0], toolPoint[1]);
+ Object * obj2 = (Object *)(*j);
+ obj2->p[0] = p1;
+ obj2->p[1] = p2;
+
+ if (obj.type == OTArc)
+ {
+ // This is 2*mirror angle - obj angle - obj span
+ obj2->angle[0] = (2.0 * angle) - obj.angle[0] - obj.angle[1];
+
+ if (obj2->angle[0] > PI_TIMES_2)
+ obj2->angle[0] -= PI_TIMES_2;
+ }
+ }
+ }
+
+ break;
+ case ToolMouseUp:
+ if (Global::toolState == TSPoint1)
+ {
+ Global::toolState = TSPoint2;
+ // Prevent spurious line from drawing...
+ toolPoint[1] = toolPoint[0];
+ }
+ else if ((Global::toolState == TSPoint2) && shiftDown)
+ {
+ // Key override is telling us to make a new line, not continue the
+ // previous one.
+ toolPoint[0] = toolPoint[1];
+ }
+ else
+ {
+ // Either we're finished with our rotate, or we're stamping a copy.
+ if (ctrlDown)
+ {
+ // Stamp a copy of the selection at the current rotation & bail
+ std::vector<void *> temp;
+ CopyObjects(select, temp);
+ ClearSelected(temp);
+ AddObjectsTo(document.objects, temp);
+ RestorePointsTo(select, toolScratch);
+ return;
+ }
+
+ toolPoint[0] = p;
+ Global::toolState = TSPoint1;
+ SavePointsFrom(select, toolScratch);
+ }
+
+ break;
+ case ToolKeyDown:
+ // Reset the selection if shift held down...
+ if (shiftDown)
+ RestorePointsTo(select, toolScratch);
+
+ break;
+ case ToolKeyUp:
+ // Reset selection when key is let up
+ if (!shiftDown)
+ MirrorHandler(ToolMouseMove, toolPoint[1]);
+
+ break;
+ case ToolCleanup:
+ RestorePointsTo(select, toolScratch);
+ }
+}
+
+