1 // utils.cpp: Stuff that's useful to have kicking around, in one spot
3 // Part of the Architektonas Project
4 // (C) 2020 Underground Software
5 // See the README and GPLv3 files for licensing and warranty information
7 // JLH = James Hammons <jlhamm@acm.org>
10 // --- ---------- ------------------------------------------------------------
11 // JLH 05/01/2015 Created this file
15 #include <string.h> // For memcpy()
20 // Copy objects in one vector to another, creating copies and placing them in
21 // the other vector. Clearing & etc. of vectors is responsibility of the caller!
23 void CopyObjects(std::vector<void *> & from, std::vector<void *> & to)
25 for(std::vector<void *>::iterator i=from.begin(); i!=from.end(); i++)
27 Object * obj = (Object *)(*i);
28 Object * newObject = CopyObject(obj);
29 to.push_back(newObject);
35 // Create a copy of the passed in object.
37 Object * CopyObject(Object * obj)
39 void * newObject = NULL;
44 newObject = new Line();
45 memcpy(newObject, obj, sizeof(Line));
48 newObject = new Circle();
49 memcpy(newObject, obj, sizeof(Circle));
52 newObject = new Ellipse();
53 memcpy(newObject, obj, sizeof(Ellipse));
56 newObject = new Arc();
57 memcpy(newObject, obj, sizeof(Arc));
60 newObject = new Dimension();
61 memcpy(newObject, obj, sizeof(Dimension));
65 newObject = new Spline();
66 memcpy(newObject, obj, sizeof(Spline));
70 newObject = new Text();
71 memcpy(newObject, obj, sizeof(Text));
72 ((Text *)newObject)->s = ((Text *)obj)->s;
75 newObject = new Container();
77 // memcpy(newObject, obj, sizeof(Line));
78 ((Container *)newObject)->p[0] = obj->p[0];
79 ((Container *)newObject)->p[1] = obj->p[1];
80 CopyObjects(((Container *)obj)->objects, ((Container *)newObject)->objects);
87 if (newObject && (((Object *)newObject)->type != OTContainer))
88 ((Object *)newObject)->id = Global::objectID++;
90 return (Object *)newObject;
94 void MoveSelectedObjectsTo(std::vector<void *> & dest, std::vector<void *> & from)
96 std::vector<void *>::iterator i = from.begin();
98 while (i != from.end())
100 Object * obj = (Object *)(*i);
113 //hmm, this won't work, as these are just pointers...
115 void CopySelectedObjectsTo(std::vector<void *> & dest, std::vector<void *> & from)
117 for(std::vector<void *>::iterator i=from.begin(); i!=from.end(); i++)
119 Object * obj = (Object *)(*i);
123 // Object * newObject = CopyObject(obj);
124 dest.push_back(CopyObject(obj));
130 void AddObjectsTo(std::vector<void *> & dest, std::vector<void *> & from)
132 for(std::vector<void *>::iterator i=from.begin(); i!=from.end(); i++)
137 void ClearSelected(std::vector<void *> & v)
139 std::vector<void *>::iterator i;
141 for(i=v.begin(); i!=v.end(); i++)
142 ((Object *)(*i))->selected = false;
146 void SelectAll(std::vector<void *> & v)
148 std::vector<void *>::iterator i;
150 for(i=v.begin(); i!=v.end(); i++)
151 ((Object *)(*i))->selected = true;
156 // Recursively go down thru the Container's vectors, deleting all the objects
157 // contained therein. Once that is done, the main Container can be deleted.
158 // We don't have to worry about the underlying std::vectors, as they have their
159 // own destructors--plus they don't take ownership of objects, which is why we
160 // have to keep track of that stuff ourselves. :-P Believe it or not, this is
161 // a Good Thing(TM). ;-)
163 void DeleteContents(std::vector<void *> & v)
165 std::vector<void *>::iterator i;
167 for(i=v.begin(); i!=v.end(); i++)
169 Object * obj = (Object *)(*i);
171 if (obj->type == OTContainer)
172 DeleteContents(((Container *)obj)->objects);
181 void DeleteSelectedObjects(std::vector<void *> & v)
183 std::vector<void *>::iterator i = v.begin();
187 Object * obj = (Object *)(*i);
201 // This is used to remove selected objects from one container in order to move
202 // them to a different container.
204 void RemoveSelectedObjects(std::vector<void *> & v)
206 std::vector<void *>::iterator i = v.begin();
210 Object * obj = (Object *)(*i);
220 void SavePointsFrom(std::vector<void *> & v, std::vector<Object> & save)
225 for(std::vector<void *>::iterator i=v.begin(); i!=v.end(); i++)
227 memcpy(&o, (Object *)(*i), sizeof(Object));
233 void RestorePointsTo(std::vector<void *> & v, std::vector<Object> & s)
235 std::vector<Object>::iterator i = s.begin();
236 std::vector<void *>::iterator j = v.begin();
238 for(; i!=s.end(); i++, j++)
240 Object * obj2 = (Object *)(*j);
241 obj2->p[0] = (*i).p[0];
242 obj2->p[1] = (*i).p[1];
243 obj2->angle[0] = (*i).angle[0];
244 obj2->angle[1] = (*i).angle[1];
245 //we don't do this because we want to keep selected & friends from changing
246 // memcpy(obj2, *j, sizeof(Object));
251 void RestorePointsTo(std::vector<void *> & v, std::vector<void *> & s)
253 std::vector<void *>::iterator i = s.begin();
254 std::vector<void *>::iterator j = v.begin();
256 for(; i!=s.end(); i++, j++)
258 Object * objS = (Object *)(*i);
259 Object * objV = (Object *)(*j);
261 if (objV->type == OTContainer)
263 RestorePointsTo(((Container *)objV)->objects, ((Container *)objS)->objects);
267 objV->p[0] = objS->p[0];
268 objV->p[1] = objS->p[1];
269 objV->angle[0] = objS->angle[0];
270 objV->angle[1] = objS->angle[1];
271 //we don't do this because we want to keep selected & friends from changing
272 // memcpy(obj2, *j, sizeof(Object));
277 void TranslateObject(Object * obj, Point delta)
279 if (obj->type == OTContainer)
281 Container * c = (Container *)obj;
282 std::vector<void *>::iterator i;
284 for(i=c->objects.begin(); i!=c->objects.end(); i++)
285 TranslateObject((Object *)*i, delta);
296 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 void TranslateContainer(Container * c, Point point, Point delta)
300 if (c->clicked == NULL)
302 // TranslateObject((Object *)c, delta);
307 printf("TranslateContainer: boop (%i)\n", i++);
310 switch (c->clicked->type)
313 if (c->clicked->hitPoint[0])
314 clickedPoint = c->clicked->p[0];
315 else if (c->clicked->hitPoint[1])
316 clickedPoint = c->clicked->p[1];
317 else if (c->clicked->hitObject)
318 clickedPoint = Geometry::Midpoint((Line *)(c->clicked));
323 if (c->clicked->hitPoint[0])
324 clickedPoint = c->clicked->p[0];
325 else if (c->clicked->hitObject)
326 clickedPoint = point;
340 Point clickedDelta = point - clickedPoint;
341 TranslateObject((Object *)c, clickedDelta);
345 void TranslateObjects(std::vector<void *> & v, Point delta)
348 if (obj->type == OTContainer)
350 Container * c = (Container *)obj;
351 std::vector<void *>::iterator i;
353 for(i=c->objects.begin(); i!=c->objects.end(); i++)
354 TranslateObject((Object *)*i, delta);
362 // Handle containters too???
363 std::vector<void *>::iterator i;
365 for(i=v.begin(); i!=v.end(); i++)
367 Object * obj = (Object *)(*i);
374 std::vector<void *> Flatten(Container * src)
376 std::vector<void *> flat;
377 std::vector<void *>::iterator i;
379 for(i=src->objects.begin(); i!=src->objects.end(); i++)
382 Object * obj = (Object *)(*i);
384 // Recursively add objects to the flat vector, if necessary
385 if (obj->type == OTContainer)
387 std::vector<void *> sub = Flatten((Container *)obj);
388 flat.insert(flat.end(), sub.begin(), sub.end());