]> Shamusworld >> Repos - architektonas/blobdiff - src/utils.cpp
GUI functionality fixes.
[architektonas] / src / utils.cpp
index 98902d7a80a439de0b39a6a0613e963dde30d1aa..b9ca463bbc948bda5ba79bcfeaa220af0588d0c3 100644 (file)
@@ -12,6 +12,7 @@
 //
 
 #include "utils.h"
+#include <math.h>
 #include <string.h>            // For memcpy()
 #include "geometry.h"
 
@@ -20,9 +21,9 @@
 // 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<void *> & from, std::vector<void *> & to)
+void CopyObjects(VPVector & from, VPVector & to)
 {
-       for(std::vector<void *>::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);
@@ -31,6 +32,20 @@ void CopyObjects(std::vector<void *> & from, std::vector<void *> & 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 +75,10 @@ Object * CopyObject(Object * obj)
                newObject = new Dimension();
                memcpy(newObject, obj, sizeof(Dimension));
                break;
-#if 0
        case OTSpline:
                newObject = new Spline();
                memcpy(newObject, obj, sizeof(Spline));
                break;
-#endif
        case OTText:
                newObject = new Text();
                memcpy(newObject, obj, sizeof(Text));
@@ -77,6 +90,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:
@@ -91,9 +105,72 @@ Object * CopyObject(Object * obj)
 }
 
 
-void MoveSelectedObjectsTo(std::vector<void *> & dest, std::vector<void *> & from)
+//
+// 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 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<void *>::iterator i = from.begin();
+       VPVectorIter i = from.begin();
 
        while (i != from.end())
        {
@@ -110,45 +187,83 @@ void MoveSelectedObjectsTo(std::vector<void *> & dest, std::vector<void *> & 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<void *> & dest, std::vector<void *> & from)
+void CopySelectedObjectsTo(VPVector & dest, VPVector & from)
 {
-       for(std::vector<void *>::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));
        }
 }
 
 
-void AddObjectsTo(std::vector<void *> & dest, std::vector<void *> & from)
+VPVector CopySelectedObjects(VPVector & src)
 {
-       for(std::vector<void *>::iterator i=from.begin(); i!=from.end(); i++)
-               dest.push_back(*i);
+       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 ClearSelected(std::vector<void *> & v)
+void AddObjectsTo(VPVector & dest, VPVector & from)
 {
-       std::vector<void *>::iterator i;
+       for(VPVectorIter i=from.begin(); i!=from.end(); i++)
+               dest.push_back(*i);
+}
 
-       for(i=v.begin(); i!=v.end(); i++)
+
+void ClearSelected(VPVector & v)
+{
+       for(VPVectorIter i=v.begin(); i!=v.end(); i++)
                ((Object *)(*i))->selected = false;
 }
 
 
-void SelectAll(std::vector<void *> & v)
+//
+// Select all *visible* objects.  If an object's layer is invisible, skip it.
+//
+void SelectAll(VPVector & v)
 {
-       std::vector<void *>::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;
+       }
 }
 
 
@@ -160,11 +275,9 @@ void SelectAll(std::vector<void *> & v)
 // 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)
+void DeleteContents(VPVector & v)
 {
-       std::vector<void *>::iterator i;
-
-       for(i=v.begin(); i!=v.end(); i++)
+       for(VPVectorIter i=v.begin(); i!=v.end(); i++)
        {
                Object * obj = (Object *)(*i);
 
@@ -178,9 +291,9 @@ void DeleteContents(std::vector<void *> & v)
 }
 
 
-void DeleteSelectedObjects(std::vector<void *> & v)
+void DeleteSelectedObjects(VPVector & v)
 {
-       std::vector<void *>::iterator i = v.begin();
+       VPVectorIter i = v.begin();
 
        while (i != v.end())
        {
@@ -201,9 +314,9 @@ void DeleteSelectedObjects(std::vector<void *> & v)
 // This is used to remove selected objects from one container in order to move
 // them to a different container.
 //
-void RemoveSelectedObjects(std::vector<void *> & v)
+void RemoveSelectedObjects(VPVector & v)
 {
-       std::vector<void *>::iterator i = v.begin();
+       VPVectorIter i = v.begin();
 
        while (i != v.end())
        {
@@ -217,12 +330,12 @@ void RemoveSelectedObjects(std::vector<void *> & v)
 }
 
 
-void SavePointsFrom(std::vector<void *> & v, std::vector<Object> & save)
+void SavePointsFrom(VPVector & v, std::vector<Object> & save)
 {
        save.clear();
        Object o;
 
-       for(std::vector<void *>::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);
@@ -230,12 +343,12 @@ void SavePointsFrom(std::vector<void *> & v, std::vector<Object> & save)
 }
 
 
-void RestorePointsTo(std::vector<void *> & v, std::vector<Object> & s)
+void RestorePointsTo(VPVector & v, std::vector<Object> & s)
 {
-       std::vector<Object>::iterator i = s.begin();
-       std::vector<void *>::iterator j = v.begin();
+       std::vector<Object>::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];
@@ -248,12 +361,9 @@ void RestorePointsTo(std::vector<void *> & v, std::vector<Object> & s)
 }
 
 
-void RestorePointsTo(std::vector<void *> & v, std::vector<void *> & s)
+void RestorePointsTo(VPVector & v, VPVector & s)
 {
-       std::vector<void *>::iterator i = s.begin();
-       std::vector<void *>::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);
@@ -274,21 +384,22 @@ void RestorePointsTo(std::vector<void *> & v, std::vector<void *> & 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<void *>::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;
-//     }
+
+       obj->p[0] += delta;
+       obj->p[1] += delta;
 }
 
 
@@ -298,14 +409,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 +428,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 +436,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:
@@ -342,41 +465,61 @@ printf("TranslateContainer: boop (%i)\n", i++);
 }
 
 
-void TranslateObjects(std::vector<void *> & 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<void *>::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);
+               }
        }
-#endif
-       // Handle containters too???
-       std::vector<void *>::iterator i;
+}
 
-       for(i=v.begin(); i!=v.end(); 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(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<void *> 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<void *> flat;
-       std::vector<void *>::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,7 +527,7 @@ std::vector<void *> Flatten(Container * src)
                // Recursively add objects to the flat vector, if necessary
                if (obj->type == OTContainer)
                {
-                       std::vector<void *> sub = Flatten((Container *)obj);
+                       VPVector sub = Flatten(((Container *)obj)->objects);
                        flat.insert(flat.end(), sub.begin(), sub.end());
                }
        }