// utils.cpp: Stuff that's useful to have kicking around, in one spot
//
// Part of the Architektonas Project
-// (C) 2015 Underground Software
+// (C) 2020 Underground Software
// See the README and GPLv3 files for licensing and warranty information
//
// JLH = James Hammons <jlhamm@acm.org>
#include "utils.h"
#include <string.h> // For memcpy()
+#include "geometry.h"
//
//
void CopyObjects(std::vector<void *> & from, std::vector<void *> & to)
{
- std::vector<void *>::iterator i;
-
- for(i=from.begin(); i!=from.end(); i++)
+ for(std::vector<void *>::iterator i=from.begin(); i!=from.end(); i++)
{
Object * obj = (Object *)(*i);
Object * newObject = CopyObject(obj);
//
Object * CopyObject(Object * obj)
{
- Object * newObject = NULL;
+ void * newObject = NULL;
switch (obj->type)
{
case OTLine:
- newObject = (Object *)new Line();
+ newObject = new Line();
memcpy(newObject, obj, sizeof(Line));
break;
case OTCircle:
- newObject = (Object *)new Circle();
+ newObject = new Circle();
memcpy(newObject, obj, sizeof(Circle));
break;
case OTEllipse:
- newObject = (Object *)new Ellipse();
+ newObject = new Ellipse();
memcpy(newObject, obj, sizeof(Ellipse));
break;
case OTArc:
- newObject = (Object *)new Arc();
+ newObject = new Arc();
memcpy(newObject, obj, sizeof(Arc));
break;
case OTDimension:
- newObject = (Object *)new Dimension();
+ newObject = new Dimension();
memcpy(newObject, obj, sizeof(Dimension));
break;
#if 0
case OTSpline:
- newObject = (Object *)new Spline();
+ newObject = new Spline();
memcpy(newObject, obj, sizeof(Spline));
break;
#endif
case OTText:
- newObject = (Object *)new Text();
+ newObject = new Text();
memcpy(newObject, obj, sizeof(Text));
((Text *)newObject)->s = ((Text *)obj)->s;
break;
case OTContainer:
- newObject = (Object *)new Container();
+ newObject = new Container();
//this won't work...
// memcpy(newObject, obj, sizeof(Line));
+ ((Container *)newObject)->p[0] = obj->p[0];
+ ((Container *)newObject)->p[1] = obj->p[1];
CopyObjects(((Container *)obj)->objects, ((Container *)newObject)->objects);
break;
default:
}
// Fix objectID
- if (newObject && (newObject->type != OTContainer))
- newObject->id = Global::objectID;
+ if (newObject && (((Object *)newObject)->type != OTContainer))
+ ((Object *)newObject)->id = Global::objectID++;
- return newObject;
+ return (Object *)newObject;
}
}
+//hmm, this won't work, as these are just pointers...
+//[should work now]
+void CopySelectedObjectsTo(std::vector<void *> & dest, std::vector<void *> & from)
+{
+ for(std::vector<void *>::iterator i=from.begin(); i!=from.end(); i++)
+ {
+ Object * obj = (Object *)(*i);
+
+ if (obj->selected)
+// {
+// Object * newObject = CopyObject(obj);
+ dest.push_back(CopyObject(obj));
+// }
+ }
+}
+
+
void AddObjectsTo(std::vector<void *> & dest, std::vector<void *> & from)
{
for(std::vector<void *>::iterator i=from.begin(); i!=from.end(); i++)
//
// Recursively go down thru the Container's vectors, deleting all the objects
-// contained therein. Once that is done, the main Container can be deleted. We
-// don't have to worry about the underlying std::vectors, as they have their
+// contained therein. Once that is done, the main Container can be deleted.
+// We don't have to worry about the underlying std::vectors, as they have their
// own destructors--plus they don't take ownership of objects, which is why we
-// have to keep track of that stuff ourselves. :-P Believe it or not, this is a
-// Good Thing(TM). ;-)
+// have to keep track of that stuff ourselves. :-P Believe it or not, this is
+// a Good Thing(TM). ;-)
//
void DeleteContents(std::vector<void *> & v)
{
delete obj;
}
+
+ v.clear();
}
+
void DeleteSelectedObjects(std::vector<void *> & v)
{
std::vector<void *>::iterator i = v.begin();
for(std::vector<void *>::iterator i=v.begin(); i!=v.end(); i++)
{
- memcpy(&o, (*i), sizeof(Object));
+ memcpy(&o, (Object *)(*i), sizeof(Object));
save.push_back(o);
}
}
}
+void RestorePointsTo(std::vector<void *> & v, std::vector<void *> & s)
+{
+ std::vector<void *>::iterator i = s.begin();
+ std::vector<void *>::iterator j = v.begin();
+
+ for(; 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));
+ }
+}
+
+
void TranslateObject(Object * obj, Point delta)
{
if (obj->type == OTContainer)
for(i=c->objects.begin(); i!=c->objects.end(); i++)
TranslateObject((Object *)*i, delta);
}
- else
- {
+// else
+// {
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++);
+ Point clickedPoint;
+
+ 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)
+ 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;
+
+ break;
+
+ case OTArc:
+ break;
+
+ case OTDimension:
+ break;
+
+ case OTText:
+ break;
+ }
+
+ Point clickedDelta = point - clickedPoint;
+ TranslateObject((Object *)c, clickedDelta);
}
}
+std::vector<void *> Flatten(Container * src)
+{
+ std::vector<void *> flat;
+ std::vector<void *>::iterator i;
+
+ for(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)
+ {
+ std::vector<void *> sub = Flatten((Container *)obj);
+ flat.insert(flat.end(), sub.begin(), sub.end());
+ }
+ }
+
+ return flat;
+}
+