]> Shamusworld >> Repos - architektonas/blobdiff - src/container.cpp
Initial stab at text object. Nonfunctional ATM.
[architektonas] / src / container.cpp
index 727c14360450cc498cf809b119bb08f3967021fb..a8cf0ad87ec45015ee5f0f73729ed7412b33a680 100644 (file)
@@ -4,16 +4,19 @@
 // (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),
@@ -21,16 +24,55 @@ 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()
 {
+       Clear();
+}
+
+
+// Assignment operator
+Container & Container::operator=(const Container & from)
+{
+       // Take care of self-assignment
+       if (this == &from)
+               return *this;
+
+       Clear();
+
+       // Small problem with this approach: if the copied object goes out of scope,
+       // all of the objects we copied in here will be deleted. D'oh!
+       for(uint i=0; i<from.objects.size(); i++)
+       {
+               Object * object = from.objects[i];
+
+               // Need to copy the object here...
+
+               objects.push_back(object);
+       }
+
+       return *this;
 }
 
-/*virtual*/ void Container::Draw(QPainter * painter)
+
+/*virtual*/ void Container::Draw(Painter * painter)
 {
        for(int i=0; i<(int)objects.size(); i++)
+       {
+//printf("Container: About to draw (object = $%X)\n", objects[i]);
                objects[i]->Draw(painter);
+       }
 }
 
+
 /*virtual*/ Vector Container::Center(void)
 {
        return position;
@@ -49,6 +91,7 @@ I click here and drag there?"
 Also: should put the snap logic into the Object base class (as a static method)...
 */
 
+
 /*virtual*/ bool Container::Collided(Vector point)
 {
        objectWasDragged = false;
@@ -101,64 +144,89 @@ Like so:
 #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;
-       }
+               for(int i=0; i<(int)objects.size(); i++)
+               {
+                       if (objects[i]->Collided(point))
+                       {
+#if 0
+Dimension * dimension = objects[i]->GetAttachedDimension();
 #endif
+                               Object * objectToDelete = objects[i];
+                               objects.erase(objects.begin() + i);     // Calls the destructor, (deletes the object, I presume... O_o) [NOPE! SURE DOESN'T!]
+                               delete objectToDelete;
 
-       // Do we decouple the state of the generic container from the objects inside???
-       state = OSInactive;
-//     return false;
-       return collision;
-}
-
-/*virtual*/ void Container::PointerMoved(Vector point)
-{
-       objectWasDragged = true;
+// 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 0
-       if (dragging)
+if (dimension)
+{
+       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;
+}
+#endif
+                               // 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
+
+       // Do we decouple the state of the generic container from the objects inside??? Mebbe.
+       state = OSInactive;
+//     return false;
+       return collision;
+}
 
-               endpoint += delta;
 
-               oldPoint = point;
-               needUpdate = true;
-       }*/
-       else
-               needUpdate = false;
-#else
+// 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");
+
        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;
@@ -179,11 +247,12 @@ about keeping track of old states...
                objects[i]->PointerReleased();
 }
 
+
 /*virtual*/ bool Container::NeedsUpdate(void)
 {
        needUpdate = false;
 
-       for(int i=0; i<(int)objects.size(); i++)
+       for(uint i=0; i<objects.size(); i++)
        {
                if (objects[i]->NeedsUpdate())
                        needUpdate = true;
@@ -192,7 +261,36 @@ about keeping track of old states...
        return needUpdate;
 }
 
-void Container::Add(Object * object)
+
+/*virtual*/ void Container::Add(Object * object)
 {
        objects.push_back(object);
+printf("Container: Added object (=$%X). size = %li\n", object, objects.size());
+}
+
+
+void Container::Clear(void)
+{
+       // No memory leaks!
+       while (objects.size() > 0)
+       {
+printf("Container: Deleting object ($%X)...\n", objects[0]);
+               delete objects[0];
+               objects.erase(objects.begin());
+       }
 }
+
+
+/*virtual*/ void Container::Enumerate(FILE * file)
+{
+       // Only put "CONTAINER" markers if *not* the top level container
+       if (parent != NULL)
+               fprintf(file, "CONTAINER\n");
+
+       for(uint i=0; i<objects.size(); i++)
+               objects[i]->Enumerate(file);
+
+       if (parent != NULL)
+               fprintf(file, "ENDCONTAINER\n");
+}
+