1 // container.cpp: Container object
3 // Part of the Architektonas Project
4 // (C) 2011 Underground Software
5 // See the README and GPLv3 files for licensing and warranty information
7 // JLH = James Hammons <jlhamm@acm.org>
10 // --- ---------- ------------------------------------------------------------
11 // JLH 03/30/2011 Created this file
12 // JLH 06/02/2011 Added code to delete objects in this container when they go
16 #include "container.h"
19 #include "dimension.h"
23 Container::Container(Vector p1, Object * p/*= NULL*/): Object(p1, p),
24 dragging(false), draggingHandle1(false), draggingHandle2(false)//, needUpdate(false)
31 Container::Container(const Container & copy): Object(copy.position, copy.parent)
33 // Use overloaded assignment operator
39 Container::~Container()
45 // Assignment operator
46 Container & Container::operator=(const Container & from)
48 // Take care of self-assignment
54 // Small problem with this approach: if the copied object goes out of scope,
55 // all of the objects we copied in here will be deleted. D'oh!
56 for(uint i=0; i<from.objects.size(); i++)
58 Object * object = from.objects[i];
60 // Need to copy the object here...
62 objects.push_back(object);
69 /*virtual*/ void Container::Draw(Painter * painter)
73 for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
74 // for(int i=0; i<(int)objects.size(); i++)
77 //printf("Container: About to draw (object = $%X)\n", objects[i]);
78 objects[i]->Draw(painter);
79 bounds = bounds.united(objects[i].RectangularExtents());
82 boundary = boundary.united((*i)->Extents());
86 if (state == OSSelected)
88 painter->SetPen(QPen(Qt::magenta, 2.0, Qt::DashLine));
89 painter->SetBrush(QBrush(Qt::NoBrush));
90 painter->DrawRect(boundary);
95 /*virtual*/ Vector Container::Center(void)
101 We need at least *three* handles for this object:
106 We need to think about the intuitive way (if there is any) to grab and
107 manipulate a complex object like this... Need to think, "What should happen when
108 I click here and drag there?"
110 Also: should put the snap logic into the Object base class (as a static method)...
114 /*virtual*/ bool Container::Collided(Vector point)
116 objectWasDragged = false;
117 // Vector v1 = position - point;
119 bool collision = false;
121 // NOTE that this deletes the object on mouse down instead of mouse up. Have to
122 // check to see how it feels to do it that way...
125 for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end();)
127 if ((*i)->Collided(point))
129 printf("Container::Collided: Deleting object ($%X)\n", *i);
130 Object * objectToDelete = *i;
132 delete objectToDelete;
140 for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
142 if ((*i)->Collided(point))
147 // Do we decouple the state of the generic container from the objects inside??? Mebbe.
153 // The TLC is passing all mouse movement here, so we're doing the same here.
154 // Need to adjust all other objects to handle things correctly.
156 // One optimization that will need to be done eventually is to subdivide the screen
157 // into parts and keep subdividing until an acceptable number of objects lie within
158 // the slice. This way, the GUI will still be responsive and *not* have to test
159 // every object for collision.
160 /*virtual*/ void Container::PointerMoved(Vector point)
162 // objectWasDragged = true;
163 //printf("CONTAINER: PointerMoved()\n");
165 for(int i=0; i<(int)objects.size(); i++)
167 // if (objects[i]->GetState() == OSSelected)
168 objects[i]->PointerMoved(point);
171 // Generic container doesn't need this???
172 // needUpdate = false;
176 /*virtual*/ void Container::PointerReleased(void)
179 draggingHandle1 = false;
180 draggingHandle2 = false;
182 // Here we check for just a click: If object was clicked and dragged, then
183 // revert to the old state (OSInactive). Otherwise, keep the new state that
185 /*Maybe it would be better to just check for "object was dragged" state and not have to worry
186 about keeping track of old states...
188 if (objectWasDragged)
190 //Note that the preceeding is unnecessary for a generic container!
192 for(int i=0; i<(int)objects.size(); i++)
193 objects[i]->PointerReleased();
197 /*virtual*/ bool Container::NeedsUpdate(void)
201 for(uint i=0; i<objects.size(); i++)
203 if (objects[i]->NeedsUpdate())
211 /*virtual*/ void Container::Add(Object * object)
213 objects.push_back(object);
214 printf("Container: Added object (=$%X). size = %li\n", object, objects.size());
219 /*virtual*/ ObjectType Container::Type(void)
226 void Container::Delete(Object * objectToDelete)
228 std::vector<Object *>::iterator i = objects.begin();
230 while (i != objects.end())
232 if (*i == objectToDelete)
235 delete objectToDelete;
244 void Container::DeleteSelectedItems(void)
246 std::vector<Object *>::iterator i = objects.begin();
248 while (i != objects.end())
250 if ((*i)->state == OSSelected)
261 void Container::Clear(void)
265 while (objects.size() > 0)
267 printf("Container: Deleting object ($%X)...\n", objects[0]);
269 objects.erase(objects.begin());
272 std::vector<Object *>::iterator i = objects.begin();
274 while (i != objects.end())
276 printf("Container: Deleting object ($%X)...\n", *i);
284 void Container::SelectAll(void)
286 for(unsigned int i=0; i<objects.size(); i++)
287 objects[i]->state = OSSelected;
291 void Container::DeselectAll(void)
293 for(unsigned int i=0; i<objects.size(); i++)
294 objects[i]->state = OSInactive;
298 int Container::ItemsSelected(void)
302 for(uint i=0; i<objects.size(); i++)
303 if (objects[i]->state == OSSelected)
310 Object * Container::SelectedItem(unsigned int index)
312 unsigned int selectedIndex = 0;
314 for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end(); i++)
316 if ((*i)->state == OSSelected)
318 if (selectedIndex == index)
329 void Container::MoveContentsTo(Container * newContainer)
332 if (newContainer == NULL)
335 // Shuffle the contents of this container to the new one
336 for(unsigned int i=0; i<objects.size(); i++)
337 newContainer->Add(objects[i]);
339 // & clear our vector
344 void Container::MoveSelectedContentsTo(Container * newContainer)
347 if (newContainer == NULL)
350 // Shuffle the contents of this container to the new one
351 for(std::vector<Object *>::iterator i=objects.begin(); i!=objects.end();)
353 if ((*i)->state != OSSelected)
359 newContainer->Add(*i);
365 /*virtual*/ void Container::Enumerate(FILE * file)
367 // Only put "CONTAINER" markers if *not* the top level container
369 fprintf(file, "CONTAINER\n");
371 for(uint i=0; i<objects.size(); i++)
372 objects[i]->Enumerate(file);
375 fprintf(file, "ENDCONTAINER\n");