// (C) 2011 Underground Software
// See the README and GPLv3 files for licensing and warranty information
//
-// JLH = James L. Hammons <jlhamm@acm.org>
+// JLH = James Hammons <jlhamm@acm.org>
//
// WHO WHEN WHAT
// --- ---------- ------------------------------------------------------------
// JLH 03/30/2011 Created this file
+// JLH 06/02/2011 Added code to delete objects in this container when they go
+// out of scope
//
#include "container.h"
#include <QtGui>
+#include "dimension.h"
Container::Container(Vector p1, Object * p/*= NULL*/): Object(p1, p),
{
}
+
+// Copy constructor
+Container::Container(const Container & copy): Object(copy.position, copy.parent)
+{
+ // Use overloaded assignment operator
+ *this = copy;
+}
+
+
Container::~Container()
{
+#if 0
+ // No memory leaks!
+ while (objects.size() > 0)
+ {
+ delete objects[0];
+ objects.erase(objects.begin());
+ }
+#else
+ Clear();
+#endif
}
-/*virtual*/ void Container::Draw(QPainter * painter)
+
+// Assignment operator
+Container & Container::operator=(const Container & copy)
+{
+ // Take care of self-assignment
+ if (this == ©)
+ return *this;
+
+ Clear();
+
+ for(int i=0; i<(int)copy.objects.size(); i++)
+ objects.push_back(copy.objects[i]);
+
+ return *this;
+}
+
+
+/*virtual*/ void Container::Draw(Painter * painter)
{
for(int i=0; i<(int)objects.size(); i++)
objects[i]->Draw(painter);
}
+
/*virtual*/ Vector Container::Center(void)
{
return position;
Also: should put the snap logic into the Object base class (as a static method)...
*/
+
/*virtual*/ bool Container::Collided(Vector point)
{
objectWasDragged = false;
#else
bool collision = false;
- for(int i=0; i<(int)objects.size(); i++)
+ // NOTE that this deletes the object on mouse down instead of mouse up. Have to
+ // check to see how it feels to do it that way...
+ if (deleteActive)
{
- if (objects[i]->Collided(point))
- collision = true;
- }
-#endif
+ for(int i=0; i<(int)objects.size(); i++)
+ {
+ if (objects[i]->Collided(point))
+ {
+Dimension * dimension = objects[i]->GetAttachedDimension();
- // Do we decouple the state of the generic container from the objects inside???
- state = OSInactive;
-// return false;
- return collision;
-}
+ objects.erase(objects.begin() + i); // Calls the destructor, (deletes the object, I presume... O_o)
-/*virtual*/ void Container::PointerMoved(Vector point)
+// If this object had an attached dimension, reattach it to another object, if any...
+// The only problem with that approach is if the object it gets attached to is deleted,
+// it will call the dimension to use a NULL pointer and BLAMMO
+if (dimension)
{
- objectWasDragged = true;
-#if 0
- if (dragging)
+ Vector p1 = dimension->GetPoint1();
+ Vector p2 = dimension->GetPoint2();
+ for(int j=0; j<(int)objects.size(); j++)
{
- // Here we need to check whether or not we're dragging a handle or the object itself...
-// Vector delta = point - oldPoint;
+ Vector * objectP1 = objects[i]->GetPointAt(p1);
+ Vector * objectP2 = objects[i]->GetPointAt(p2);
-// position += delta;
-// endpoint += delta;
- radius = Vector(point - position).Magnitude();
+ if (objectP1)
+ dimension->SetPoint1(objectP1);
- oldPoint = point;
- needUpdate = true;
+ if (objectP2)
+ dimension->SetPoint2(objectP2);
}
- else if (draggingHandle1)
- {
- Vector delta = point - oldPoint;
- position += delta;
- oldPoint = point;
- needUpdate = true;
+}
+
+ // This only allows deleting objects one at a time...
+ break;
+ // however, this way of doing things could be problematic if we don't
+ // delete one at a time... Need to come up with a better approach.
+ }
+ }
}
-/* else if (draggingHandle2)
+ else
{
- Vector delta = point - oldPoint;
+ for(int i=0; i<(int)objects.size(); i++)
+ {
+ if (objects[i]->Collided(point))
+ collision = true;
+ }
+ }
+#endif
- endpoint += delta;
+ // Do we decouple the state of the generic container from the objects inside??? Mebbe.
+ state = OSInactive;
+// return false;
+ return collision;
+}
+
+
+// The TLC is passing all mouse movement here, so we're doing the same here.
+// Need to adjust all other objects to handle things correctly.
+
+// One optimization that will need to be done eventually is to subdivide the screen
+// into parts and keep subdividing until an acceptable number of objects lie within
+// the slice. This way, the GUI will still be responsive and *not* have to test
+// every object for collision.
+/*virtual*/ void Container::PointerMoved(Vector point)
+{
+// objectWasDragged = true;
+//printf("CONTAINER: PointerMoved()\n");
- oldPoint = point;
- needUpdate = true;
- }*/
- else
- needUpdate = false;
-#else
for(int i=0; i<(int)objects.size(); i++)
{
- if (objects[i]->GetState() == OSSelected)
+// if (objects[i]->GetState() == OSSelected)
objects[i]->PointerMoved(point);
}
-#endif
+
// Generic container doesn't need this???
// needUpdate = false;
}
+
/*virtual*/ void Container::PointerReleased(void)
{
dragging = false;
objects[i]->PointerReleased();
}
+
/*virtual*/ bool Container::NeedsUpdate(void)
{
needUpdate = false;
return needUpdate;
}
-void Container::Add(Object * object)
+
+/*virtual*/ void Container::Add(Object * object)
{
objects.push_back(object);
}
+
+
+void Container::Clear(void)
+{
+ // No memory leaks!
+ while (objects.size() > 0)
+ {
+ delete objects[0];
+ objects.erase(objects.begin());
+ }
+}