+ for(VPVectorIter i=v.begin(); i!=v.end(); i++)
+ {
+ memcpy(&o, (Object *)(*i), sizeof(Object));
+ save.push_back(o);
+ }
+}
+
+void RestorePointsTo(VPVector & v, std::vector<Object> & s)
+{
+ std::vector<Object>::iterator i;
+ VPVectorIter j;
+
+ for(i=s.begin(), j=v.begin(); i!=s.end(); i++, j++)
+ {
+ Object * obj2 = (Object *)(*j);
+ obj2->p[0] = (*i).p[0];
+ obj2->p[1] = (*i).p[1];
+ obj2->angle[0] = (*i).angle[0];
+ obj2->angle[1] = (*i).angle[1];
+//we don't do this because we want to keep selected & friends from changing
+// memcpy(obj2, *j, sizeof(Object));
+ }
+}
+
+void RestorePointsTo(VPVector & v, VPVector & s)
+{
+ for(VPVectorIter i=s.begin(), j=v.begin(); i!=s.end(); i++, j++)
+ {
+ Object * objS = (Object *)(*i);
+ Object * objV = (Object *)(*j);
+
+ if (objV->type == OTContainer)
+ {
+ RestorePointsTo(((Container *)objV)->objects, ((Container *)objS)->objects);
+ return;
+ }
+
+ objV->p[0] = objS->p[0];
+ objV->p[1] = objS->p[1];
+ objV->angle[0] = objS->angle[0];
+ objV->angle[1] = objS->angle[1];
+//we don't do this because we want to keep selected & friends from changing
+// memcpy(obj2, *j, sizeof(Object));
+ }
+}
+
+//
+// Translate a single object; it it's a Container, translate all its contents,
+// including subcontainers.
+//
+void TranslateObject(Object * obj, Point delta)
+{
+ if (obj->type == OTContainer)
+ {
+ Container * c = (Container *)obj;
+
+ for(VPVectorIter i=c->objects.begin(); i!=c->objects.end(); i++)
+ TranslateObject((Object *)*i, delta);
+ }
+ else if (obj->type == OTPolyline)
+ ((Polyline *)obj)->Translate(delta);
+
+ obj->p[0] += delta;
+ obj->p[1] += delta;
+}
+
+/*
+So we need to make it so that we pick the container's point clicked on, and translate all the other parts *not* clicked on.
+*/
+void TranslateContainer(Container * c, Point point, Point delta)
+{
+ if (c->clicked == NULL)
+// {
+// TranslateObject((Object *)c, delta);
+ return;
+// }
+
+//static int i=0;
+//printf("TranslateContainer: boop (%i)\n", i++);
+//we can set this to "point" and it won't move...
+//do it *this* way, and non-enumerated clicks will do the right thing
+ Point clickedPoint = point - delta;
+
+ switch (c->clicked->type)
+ {
+ case OTLine:
+ if (c->clicked->hitPoint[0])
+ clickedPoint = c->clicked->p[0];
+ else if (c->clicked->hitPoint[1])
+ clickedPoint = c->clicked->p[1];
+ else if (c->clicked->hitObject)
+//Weirdness: some lines get a midpoint, some don't...
+ clickedPoint = Geometry::Midpoint((Line *)(c->clicked));
+
+ break;
+
+ case OTCircle:
+ if (c->clicked->hitPoint[0])
+ clickedPoint = c->clicked->p[0];
+// else if (c->clicked->hitObject)
+// clickedPoint = point - delta;
+
+ break;
+
+ case OTArc:
+ if (c->clicked->hitPoint[0])
+ clickedPoint = c->clicked->p[0];
+ else if (c->clicked->hitPoint[1])
+ clickedPoint = c->clicked->p[0] + (Vector(cos(c->clicked->angle[0]), sin(c->clicked->angle[0])) * c->clicked->radius[0]);
+ else if (c->clicked->hitPoint[2])
+ clickedPoint = c->clicked->p[0] + (Vector(cos(c->clicked->angle[0] + c->clicked->angle[1]), sin(c->clicked->angle[0] + c->clicked->angle[1])) * c->clicked->radius[0]);
+// else if (c->clicked->hitObject)
+// clickedPoint = point - delta;
+
+ break;
+
+ case OTDimension:
+ break;
+
+ case OTText:
+ break;
+ }
+
+ Point clickedDelta = point - clickedPoint;
+ TranslateObject((Object *)c, clickedDelta);
+}
+
+//
+// Translate all objects in the passed in vector, including Containers and all
+// the objects they contain.
+//
+void TranslateObjects(VPVector & v, Point delta)
+{
+ for(VPVectorIter i=v.begin(); i!=v.end(); i++)
+ {
+ Object * obj = (Object *)(*i);
+ obj->p[0] += delta;
+ obj->p[1] += delta;
+
+ if (obj->type == OTContainer)
+ {
+ Container * c = (Container *)obj;
+ TranslateObjects(c->objects, delta);
+ }
+ else if (obj->type == OTPolyline)
+ {
+ ((Polyline *)obj)->Translate(delta);
+ }
+ }
+}
+
+//
+// This does not *copy* the objects, it simply flattens out the pointers in the
+// Container and all sub-Containers.
+//
+VPVector Flatten(Container * src)
+{
+ VPVector flat;
+
+ for(VPVectorIter i=src->objects.begin(); i!=src->objects.end(); i++)
+ {
+ flat.push_back(*i);
+ Object * obj = (Object *)(*i);
+
+ // Recursively add objects to the flat vector, if necessary
+ if (obj->type == OTContainer)
+ {
+ VPVector sub = Flatten((Container *)obj);
+ flat.insert(flat.end(), sub.begin(), sub.end());
+ }
+ }
+
+ return flat;
+}
+
+//
+// This does not *copy* the objects, it simply flattens out the pointers in the
+// vector and all sub-Containers in the vector.
+//
+VPVector Flatten(VPVector src)
+{
+ VPVector flat;
+
+ for(VPVectorIter i=src.begin(); i!=src.end(); i++)
+ {
+ flat.push_back(*i);
+ Object * obj = (Object *)(*i);
+
+ // Recursively add objects to the flat vector, if necessary
+ if (obj->type == OTContainer)
+ {
+ VPVector sub = Flatten(((Container *)obj)->objects);
+ flat.insert(flat.end(), sub.begin(), sub.end());
+ }
+ }
+
+ return flat;
+}