]> Shamusworld >> Repos - architektonas/blob - src/container.cpp
4fceefdac106829e6d0a939f5e89fc27b66f437e
[architektonas] / src / container.cpp
1 // container.cpp: Container object
2 //
3 // Part of the Architektonas Project
4 // (C) 2011 Underground Software
5 // See the README and GPLv3 files for licensing and warranty information
6 //
7 // JLH = James L. Hammons <jlhamm@acm.org>
8 //
9 // WHO  WHEN        WHAT
10 // ---  ----------  ------------------------------------------------------------
11 // JLH  03/30/2011  Created this file
12 //
13
14 #include "container.h"
15
16 #include <QtGui>
17
18
19 Container::Container(Vector p1, Object * p/*= NULL*/): Object(p1, p),
20         dragging(false), draggingHandle1(false), draggingHandle2(false)//, needUpdate(false)
21 {
22 }
23
24 Container::~Container()
25 {
26 }
27
28 /*virtual*/ void Container::Draw(QPainter * painter)
29 {
30         for(int i=0; i<(int)objects.size(); i++)
31                 objects[i]->Draw(painter);
32 }
33
34 /*virtual*/ Vector Container::Center(void)
35 {
36         return position;
37 }
38
39 /*
40  We need at least *three* handles for this object:
41  - one for moving
42  - one for resizing
43  - one for rotation
44
45 We need to think about the intuitive way (if there is any) to grab and
46 manipulate a complex object like this... Need to think, "What should happen when
47 I click here and drag there?"
48
49 Also: should put the snap logic into the Object base class (as a static method)...
50 */
51
52 /*virtual*/ bool Container::Collided(Vector point)
53 {
54         objectWasDragged = false;
55         Vector v1 = position - point;
56
57 #if 0
58         if (state == OSInactive)
59         {
60 //printf("Circle: pp = %lf, length = %lf, distance = %lf\n", parameterizedPoint, lineSegment.Magnitude(), distance);
61 //printf("      v1.Magnitude = %lf, v2.Magnitude = %lf\n", v1.Magnitude(), v2.Magnitude());
62 //printf("      point = %lf,%lf,%lf; p1 = %lf,%lf,%lf; p2 = %lf,%lf,%lf\n", point.x, point.y, point.z, position.x, position.y, position.z, endpoint.x, endpoint.y, endpoint.z);
63 //printf("      \n", );
64 //How to translate this into pixels from Document space???
65 //Maybe we need to pass a scaling factor in here from the caller? That would make sense, as
66 //the caller knows about the zoom factor and all that good kinda crap
67                 if (v1.Magnitude() < 10.0)
68                 {
69                         oldState = state;
70                         state = OSSelected;
71                         oldPoint = position; //maybe "position"?
72                         draggingHandle1 = true;
73                         return true;
74                 }
75                 else if ((v1.Magnitude() < radius + 2.0) && (v1.Magnitude() > radius - 2.0))
76                 {
77                         oldState = state;
78                         state = OSSelected;
79                         oldPoint = point;
80                         dragging = true;
81                         return true;
82                 }
83         }
84         else if (state == OSSelected)
85         {
86                 // Here we test for collision with handles as well! (SOON!)
87 /*
88 Like so:
89                 if (v1.Magnitude() < 2.0) // Handle #1
90                 else if (v2.Magnitude() < 2.0) // Handle #2
91 */
92                 if ((v1.Magnitude() < radius + 2.0) && (v1.Magnitude() > radius - 2.0))
93                 {
94                         oldState = state;
95 //                      state = OSInactive;
96                         oldPoint = point;
97                         dragging = true;
98                         return true;
99                 }
100         }
101 #else
102         bool collision = false;
103
104         // NOTE that this deletes the object on mouse down instead of mouse up. Have to
105         // check to see how it feels to do it that way...
106         if (deleteActive)
107         {
108                 for(int i=0; i<(int)objects.size(); i++)
109                 {
110                         if (objects[i]->Collided(point))
111                         {
112                                 objects.erase(objects.begin() + i);     // Calls the destructor, (deletes the object, I presume... O_o)
113                                 break;
114                         }
115                 }
116         }
117         else
118         {
119                 for(int i=0; i<(int)objects.size(); i++)
120                 {
121                         if (objects[i]->Collided(point))
122                                 collision = true;
123                 }
124         }
125 #endif
126
127         // Do we decouple the state of the generic container from the objects inside??? Mebbe.
128         state = OSInactive;
129 //      return false;
130         return collision;
131 }
132
133 /*virtual*/ void Container::PointerMoved(Vector point)
134 {
135         objectWasDragged = true;
136 #if 0
137         if (dragging)
138         {
139                 // Here we need to check whether or not we're dragging a handle or the object itself...
140 //              Vector delta = point - oldPoint;
141
142 //              position += delta;
143 //              endpoint += delta;
144                 radius = Vector(point - position).Magnitude();
145
146                 oldPoint = point;
147                 needUpdate = true;
148         }
149         else if (draggingHandle1)
150         {
151                 Vector delta = point - oldPoint;
152                 position += delta;
153                 oldPoint = point;
154                 needUpdate = true;
155         }
156 /*      else if (draggingHandle2)
157         {
158                 Vector delta = point - oldPoint;
159
160                 endpoint += delta;
161
162                 oldPoint = point;
163                 needUpdate = true;
164         }*/
165         else
166                 needUpdate = false;
167 #else
168         for(int i=0; i<(int)objects.size(); i++)
169         {
170                 if (objects[i]->GetState() == OSSelected)
171                         objects[i]->PointerMoved(point);
172         }
173 #endif
174         // Generic container doesn't need this???
175 //      needUpdate = false;
176 }
177
178 /*virtual*/ void Container::PointerReleased(void)
179 {
180         dragging = false;
181         draggingHandle1 = false;
182         draggingHandle2 = false;
183
184         // Here we check for just a click: If object was clicked and dragged, then
185         // revert to the old state (OSInactive). Otherwise, keep the new state that
186         // we set.
187 /*Maybe it would be better to just check for "object was dragged" state and not have to worry
188 about keeping track of old states...
189 */
190         if (objectWasDragged)
191                 state = oldState;
192 //Note that the preceeding is unnecessary for a generic container!
193
194         for(int i=0; i<(int)objects.size(); i++)
195                 objects[i]->PointerReleased();
196 }
197
198 /*virtual*/ bool Container::NeedsUpdate(void)
199 {
200         needUpdate = false;
201
202         for(int i=0; i<(int)objects.size(); i++)
203         {
204                 if (objects[i]->NeedsUpdate())
205                         needUpdate = true;
206         }
207
208         return needUpdate;
209 }
210
211 void Container::Add(Object * object)
212 {
213         objects.push_back(object);
214 }