X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Futils.cpp;h=cd05ba735e95f30ac96aacf56f205e6548840a79;hb=10cf4c797bed05831e976068b7504908279dc997;hp=98902d7a80a439de0b39a6a0613e963dde30d1aa;hpb=790c1a6d97f73f7457c7fad7e82fa29e5b6accd5;p=architektonas diff --git a/src/utils.cpp b/src/utils.cpp index 98902d7..cd05ba7 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -1,3 +1,4 @@ +// // utils.cpp: Stuff that's useful to have kicking around, in one spot // // Part of the Architektonas Project @@ -12,17 +13,17 @@ // #include "utils.h" +#include #include // For memcpy() #include "geometry.h" - // // Copy objects in one vector to another, creating copies and placing them in // the other vector. Clearing & etc. of vectors is responsibility of the caller! // -void CopyObjects(std::vector & from, std::vector & to) +void CopyObjects(VPVector & from, VPVector & to) { - for(std::vector::iterator i=from.begin(); i!=from.end(); i++) + for(VPVectorIter i=from.begin(); i!=from.end(); i++) { Object * obj = (Object *)(*i); Object * newObject = CopyObject(obj); @@ -30,6 +31,18 @@ void CopyObjects(std::vector & from, std::vector & to) } } +VPVector CopyObjects(VPVector & src) +{ + VPVector copy; + + for(VPVectorIter i=src.begin(); i!=src.end(); i++) + { + Object * newObject = CopyObject2((Object *)(*i)); + copy.push_back(newObject); + } + + return copy; +} // // Create a copy of the passed in object. @@ -60,12 +73,15 @@ Object * CopyObject(Object * obj) newObject = new Dimension(); memcpy(newObject, obj, sizeof(Dimension)); break; -#if 0 + case OTPolyline: + newObject = new Polyline(); + memcpy(newObject, obj, sizeof(Polyline)); + ((Polyline *)newObject)->points = ((Polyline *)obj)->points; + break; case OTSpline: newObject = new Spline(); memcpy(newObject, obj, sizeof(Spline)); break; -#endif case OTText: newObject = new Text(); memcpy(newObject, obj, sizeof(Text)); @@ -77,6 +93,7 @@ Object * CopyObject(Object * obj) // memcpy(newObject, obj, sizeof(Line)); ((Container *)newObject)->p[0] = obj->p[0]; ((Container *)newObject)->p[1] = obj->p[1]; + ((Container *)newObject)->layer = obj->layer; CopyObjects(((Container *)obj)->objects, ((Container *)newObject)->objects); break; default: @@ -90,10 +107,77 @@ Object * CopyObject(Object * obj) return (Object *)newObject; } +// +// Create a copy of the passed in object. This version calls the second +// version of CopyObjects() (with one parameter and a vector return value). +// +Object * CopyObject2(Object * obj) +{ + void * newObject = NULL; + + switch (obj->type) + { + case OTLine: + newObject = new Line(); + memcpy(newObject, obj, sizeof(Line)); + break; + + case OTCircle: + newObject = new Circle(); + memcpy(newObject, obj, sizeof(Circle)); + break; + + case OTEllipse: + newObject = new Ellipse(); + memcpy(newObject, obj, sizeof(Ellipse)); + break; + + case OTArc: + newObject = new Arc(); + memcpy(newObject, obj, sizeof(Arc)); + break; + + case OTDimension: + newObject = new Dimension(); + memcpy(newObject, obj, sizeof(Dimension)); + break; + + case OTPolyline: + newObject = new Polyline(); + memcpy(newObject, obj, sizeof(Polyline)); + ((Polyline *)newObject)->points = ((Polyline *)obj)->points; + break; -void MoveSelectedObjectsTo(std::vector & dest, std::vector & from) + case OTSpline: + newObject = new Spline(); + memcpy(newObject, obj, sizeof(Spline)); + break; + + case OTText: + newObject = new Text(); + memcpy(newObject, obj, sizeof(Text)); + ((Text *)newObject)->s = ((Text *)obj)->s; + break; + + case OTContainer: + newObject = new Container(); + ((Container *)newObject)->p[0] = obj->p[0]; + ((Container *)newObject)->p[1] = obj->p[1]; + ((Container *)newObject)->layer = obj->layer; + ((Container *)newObject)->objects = CopyObjects(((Container *)obj)->objects); + break; + } + + // Fix objectID + if (newObject && (((Object *)newObject)->type != OTContainer)) + ((Object *)newObject)->id = Global::objectID++; + + return (Object *)newObject; +} + +void MoveSelectedObjectsTo(VPVector & dest, VPVector & from) { - std::vector::iterator i = from.begin(); + VPVectorIter i = from.begin(); while (i != from.end()) { @@ -109,49 +193,80 @@ void MoveSelectedObjectsTo(std::vector & dest, std::vector & fro } } +VPVector MoveSelectedObjectsFrom(VPVector & from) +{ + VPVector objects; + VPVectorIter i = from.begin(); + + while (i != from.end()) + { + Object * obj = (Object *)(*i); + + if (obj->selected) + { + objects.push_back(*i); + from.erase(i); + } + else + i++; + } + + return objects; +} //hmm, this won't work, as these are just pointers... //[should work now] -void CopySelectedObjectsTo(std::vector & dest, std::vector & from) +void CopySelectedObjectsTo(VPVector & dest, VPVector & from) { - for(std::vector::iterator i=from.begin(); i!=from.end(); i++) + for(VPVectorIter i=from.begin(); i!=from.end(); i++) { Object * obj = (Object *)(*i); if (obj->selected) -// { -// Object * newObject = CopyObject(obj); - dest.push_back(CopyObject(obj)); -// } + dest.push_back(CopyObject2(obj)); } } +VPVector CopySelectedObjects(VPVector & src) +{ + VPVector copy; + + for(VPVectorIter i=src.begin(); i!=src.end(); i++) + { + Object * obj = (Object *)(*i); + + if (obj->selected) + copy.push_back(CopyObject2(obj)); + } + + return copy; +} -void AddObjectsTo(std::vector & dest, std::vector & from) +void AddObjectsTo(VPVector & dest, VPVector & from) { - for(std::vector::iterator i=from.begin(); i!=from.end(); i++) + for(VPVectorIter i=from.begin(); i!=from.end(); i++) dest.push_back(*i); } - -void ClearSelected(std::vector & v) +void ClearSelected(VPVector & v) { - std::vector::iterator i; - - for(i=v.begin(); i!=v.end(); i++) + for(VPVectorIter i=v.begin(); i!=v.end(); i++) ((Object *)(*i))->selected = false; } - -void SelectAll(std::vector & v) +// +// Select all *visible* objects. If an object's layer is invisible, skip it. +// +void SelectAll(VPVector & v) { - std::vector::iterator i; - - for(i=v.begin(); i!=v.end(); i++) - ((Object *)(*i))->selected = true; + for(VPVectorIter i=v.begin(); i!=v.end(); i++) + { + Object * obj = (Object *)(*i); + bool visible = !Global::layerHidden[obj->layer]; + obj->selected = visible; + } } - // // Recursively go down thru the Container's vectors, deleting all the objects // contained therein. Once that is done, the main Container can be deleted. @@ -160,11 +275,9 @@ void SelectAll(std::vector & v) // have to keep track of that stuff ourselves. :-P Believe it or not, this is // a Good Thing(TM). ;-) // -void DeleteContents(std::vector & v) +void DeleteContents(VPVector & v) { - std::vector::iterator i; - - for(i=v.begin(); i!=v.end(); i++) + for(VPVectorIter i=v.begin(); i!=v.end(); i++) { Object * obj = (Object *)(*i); @@ -177,10 +290,9 @@ void DeleteContents(std::vector & v) v.clear(); } - -void DeleteSelectedObjects(std::vector & v) +void DeleteSelectedObjects(VPVector & v) { - std::vector::iterator i = v.begin(); + VPVectorIter i = v.begin(); while (i != v.end()) { @@ -196,14 +308,13 @@ void DeleteSelectedObjects(std::vector & v) } } - // // This is used to remove selected objects from one container in order to move // them to a different container. // -void RemoveSelectedObjects(std::vector & v) +void RemoveSelectedObjects(VPVector & v) { - std::vector::iterator i = v.begin(); + VPVectorIter i = v.begin(); while (i != v.end()) { @@ -216,26 +327,43 @@ void RemoveSelectedObjects(std::vector & v) } } +// +// This is used to remove hovered objects from one container in order to delete +// them from the same container. +// +void RemoveHoveredObjects(VPVector & v) +{ + VPVectorIter i = v.begin(); + + while (i != v.end()) + { + Object * obj = (Object *)(*i); + + if (obj->hovered) + v.erase(i); + else + i++; + } +} -void SavePointsFrom(std::vector & v, std::vector & save) +void SavePointsFrom(VPVector & v, std::vector & save) { save.clear(); Object o; - for(std::vector::iterator i=v.begin(); i!=v.end(); i++) + for(VPVectorIter i=v.begin(); i!=v.end(); i++) { memcpy(&o, (Object *)(*i), sizeof(Object)); save.push_back(o); } } - -void RestorePointsTo(std::vector & v, std::vector & s) +void RestorePointsTo(VPVector & v, std::vector & s) { - std::vector::iterator i = s.begin(); - std::vector::iterator j = v.begin(); + std::vector::iterator i; + VPVectorIter j; - for(; i!=s.end(); i++, j++) + for(i=s.begin(), j=v.begin(); i!=s.end(); i++, j++) { Object * obj2 = (Object *)(*j); obj2->p[0] = (*i).p[0]; @@ -247,13 +375,9 @@ void RestorePointsTo(std::vector & v, std::vector & s) } } - -void RestorePointsTo(std::vector & v, std::vector & s) +void RestorePointsTo(VPVector & v, VPVector & s) { - std::vector::iterator i = s.begin(); - std::vector::iterator j = v.begin(); - - for(; i!=s.end(); i++, j++) + for(VPVectorIter i=s.begin(), j=v.begin(); i!=s.end(); i++, j++) { Object * objS = (Object *)(*i); Object * objV = (Object *)(*j); @@ -273,24 +397,25 @@ void RestorePointsTo(std::vector & v, std::vector & s) } } - +// +// 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; - std::vector::iterator i; - for(i=c->objects.begin(); i!=c->objects.end(); i++) + for(VPVectorIter i=c->objects.begin(); i!=c->objects.end(); i++) TranslateObject((Object *)*i, delta); } -// else -// { - obj->p[0] += delta; - obj->p[1] += 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. @@ -298,14 +423,16 @@ So we need to make it so that we pick the container's point clicked on, and tran 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; +//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) { @@ -315,6 +442,7 @@ printf("TranslateContainer: boop (%i)\n", i++); 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; @@ -322,12 +450,21 @@ printf("TranslateContainer: boop (%i)\n", i++); case OTCircle: if (c->clicked->hitPoint[0]) clickedPoint = c->clicked->p[0]; - else if (c->clicked->hitObject) - clickedPoint = point; +// 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: @@ -341,42 +478,63 @@ printf("TranslateContainer: boop (%i)\n", i++); TranslateObject((Object *)c, clickedDelta); } - -void TranslateObjects(std::vector & v, Point delta) +// +// Translate all objects in the passed in vector, including Containers and all +// the objects they contain. +// +void TranslateObjects(VPVector & v, Point delta) { -#if 0 - if (obj->type == OTContainer) - { - Container * c = (Container *)obj; - std::vector::iterator i; - - for(i=c->objects.begin(); i!=c->objects.end(); i++) - TranslateObject((Object *)*i, delta); - } - else + 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); + } } -#endif - // Handle containters too??? - std::vector::iterator i; +} + +// +// 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(i=v.begin(); i!=v.end(); i++) + for(VPVectorIter i=src->objects.begin(); i!=src->objects.end(); i++) { + flat.push_back(*i); Object * obj = (Object *)(*i); - obj->p[0] += delta; - obj->p[1] += delta; + + // 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; +} -std::vector Flatten(Container * src) +// +// 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) { - std::vector flat; - std::vector::iterator i; + VPVector flat; - for(i=src->objects.begin(); i!=src->objects.end(); i++) + for(VPVectorIter i=src.begin(); i!=src.end(); i++) { flat.push_back(*i); Object * obj = (Object *)(*i); @@ -384,11 +542,10 @@ std::vector Flatten(Container * src) // Recursively add objects to the flat vector, if necessary if (obj->type == OTContainer) { - std::vector sub = Flatten((Container *)obj); + VPVector sub = Flatten(((Container *)obj)->objects); flat.insert(flat.end(), sub.begin(), sub.end()); } } return flat; } -