]> Shamusworld >> Repos - architektonas/blob - src/object.cpp
09d52bf3357b02165410e82e4200877421eddb7e
[architektonas] / src / object.cpp
1 //
2 // object.cpp: Base class for all CAD objects
3 //
4 // Part of the Architektonas Project
5 // (C) 2011 Underground Software
6 // See the README and GPLv3 files for licensing and warranty information
7 //
8 // JLH = James Hammons <jlhamm@acm.org>
9 //
10 // WHO  WHEN        WHAT
11 // ---  ----------  ------------------------------------------------------------
12 // JLH  03/22/2011  Created this file
13 // JLH  04/01/2011  Added constructor to allow derived objects to have empty
14 //                  constructor bodies, added state querying
15 // JLH  04/02/2001  Added static methods for global states (fixed angle, etc)
16 //
17
18 #include "object.h"
19 #include <stdlib.h>
20 #include <math.h>
21
22 // Initialize static variables
23 bool Object::fixedAngle = false;
24 bool Object::fixedLength = false;
25 QFont * Object::font = 0;
26 int Object::viewportHeight = 0;
27 bool Object::deleteActive = false;
28 bool Object::dimensionActive = false;
29 bool Object::snapToGrid = true;
30 //snapToPoints all well here?
31 bool Object::ignoreClicks = false;
32 bool Object::dontMove = false;
33 bool Object::selectionInProgress = false;
34 QRectF Object::selection;
35 double Object::gridSpacing;
36 int Object::currentLayer = 0;
37
38
39 Object::Object(): position(Vector(0, 0)), parent(0), type(OTObject),
40         state(OSInactive), layer(0), oldState(OSInactive), needUpdate(false)
41         //, attachedDimension(0)
42 {
43 }
44
45
46 Object::Object(Vector v,  Object * passedInParent/*= 0*/): position(v),
47         parent(passedInParent), state(OSInactive), layer(0), oldState(OSInactive),
48         needUpdate(false)//, attachedDimension(0)
49 {
50 }
51
52
53 Object::~Object()
54 {
55 printf("Object: Destroyed!\n");
56         for(uint i=0; i<connected.size(); i++)
57                 connected[i].object->DisconnectAll(this);
58 }
59
60
61 /*virtual*/ void Object::Draw(Painter *)
62 {
63 }
64
65
66 /*virtual*/ Vector Object::Center(void)
67 {
68         return Vector();
69 }
70
71
72 /*virtual*/ bool Object::Collided(Vector)
73 {
74         return false;
75 }
76
77
78 /*virtual*/ void Object::PointerMoved(Vector)
79 {
80 }
81
82
83 /*virtual*/ void Object::PointerReleased(void)
84 {
85 }
86
87
88 /*virtual*/ bool Object::NeedsUpdate(void)
89 {
90         return needUpdate;
91 }
92
93
94 /*virtual*/ bool Object::HitTest(Point)
95 {
96         return false;
97 }
98
99
100 // This is intended to be overridden by the Container class, for object morphing
101 /*virtual*/ void Object::Transmute(Object *, Object *)
102 {
103 }
104
105
106 /*virtual*/ Object * Object::GetParent(void)
107 {
108         return parent;
109 }
110
111
112 /*virtual*/ void Object::Add(Object *)
113 {
114 }
115
116
117 // This returns a pointer to the point passed in, if it coincides. Otherwise returns NULL.
118 /*virtual*/ Vector * Object::GetPointAt(Vector)
119 {
120         return 0;
121 }
122
123
124 // This is meant for writing object data to a file.
125 /*virtual*/ void Object::Enumerate(FILE *)
126 {
127 }
128
129
130 /*virtual*/ Object * Object::Copy(void)
131 {
132         return new Object(position, parent);
133 }
134
135
136 // This returns a point on the object at 'parameter', which is between 0 and 1.
137 // Default is to return the object's position.
138 /*virtual*/ Vector Object::GetPointAtParameter(double)
139 {
140         return position;
141 }
142
143
144 // Since these functions are pretty much non-object specific, we can implement
145 // them here. :-)
146 /*virtual*/ void Object::Connect(Object * obj, double parameter)
147 {
148         // Check to see if this connection is already in our list...
149         Connection c(obj, parameter);
150         std::vector<Connection>::iterator i;
151
152         for(i=connected.begin(); i!=connected.end(); i++)
153         {
154                 // Bail out if this connection is already present...
155                 if (*i == c)
156                         return;
157         }
158
159         // Connection is a new one, add it in...
160         connected.push_back(c);
161 }
162
163
164 /*virtual*/ void Object::Disconnect(Object * obj, double parameter)
165 {
166         std::vector<Connection>::iterator i;
167
168         for(i=connected.begin(); i!=connected.end(); i++)
169         {
170                 if (((*i).object == obj) && ((*i).t == parameter))
171                 {
172                         connected.erase(i);
173                         return;
174                 }
175         }
176 }
177
178
179 /*virtual*/ void Object::DisconnectAll(Object * obj)
180 {
181         std::vector<Connection>::iterator i;
182
183         for(i=connected.begin(); i!=connected.end(); )
184         {
185                 if ((*i).object == obj)
186                         connected.erase(i);
187                 else
188                         i++;
189         }
190 }
191
192
193 /*virtual*/ QRectF Object::Extents(void)
194 {
195         // Generic object returns an empty rect...
196         return QRectF();
197 }
198
199
200 #if 0
201 /*virtual*/ ObjectType Object::Type(void)
202 {
203         return OTObject;
204 }
205 #endif
206
207
208 /*virtual*/ void Object::Translate(Vector amount)
209 {
210         position += amount;
211 }
212
213
214 /*virtual*/ void Object::Rotate(Point, double)
215 {
216 }
217
218
219 /*virtual*/ void Object::Scale(Point, double)
220 {
221 }
222
223
224 /*virtual*/ void Object::Mirror(Point, Point)
225 {
226 }
227
228
229 /*virtual*/ void Object::Save(void)
230 {
231         oldPosition = position;
232 }
233
234
235 /*virtual*/ void Object::Restore(void)
236 {
237         position = oldPosition;
238 }
239
240
241 ObjectState Object::GetState(void)
242 {
243         return state;
244 }
245
246
247 void Object::Reparent(Object * newParent)
248 {
249         parent = newParent;
250 }
251
252
253 /*Dimension * Object::GetAttachedDimension(void)
254 {
255         return attachedDimension;
256 }*/
257
258
259 // Class methods...
260
261 void Object::SetFixedAngle(bool state/*= true*/)
262 {
263         fixedAngle = state;
264 }
265
266
267 void Object::SetFixedLength(bool state/*= true*/)
268 {
269         fixedLength = state;
270 }
271
272
273 void Object::SetFont(QFont * f)
274 {
275         font = f;
276 }
277
278
279 void Object::SetViewportHeight(int height)
280 {
281         viewportHeight = height;
282 }
283
284
285 void Object::SetDeleteActive(bool state/*= true*/)
286 {
287         deleteActive = state;
288 }
289
290
291 void Object::SetDimensionActive(bool state/*= true*/)
292 {
293         dimensionActive = state;
294 }
295
296
297 void Object::SetSnapMode(bool state/*= true*/)
298 {
299         snapToGrid = state;
300 }
301
302
303 //
304 // This looks strange, but it's really quite simple: We want a point that's
305 // more than half-way to the next grid point to snap there while conversely we
306 // want a point that's less than half-way to to the next grid point then snap
307 // to the one before it. So we add half of the grid spacing to the point, then
308 // divide by it so that we can remove the fractional part, then multiply it
309 // back to get back to the correct answer.
310 //
311 Vector Object::SnapPointToGrid(Vector point)
312 {
313         point += gridSpacing / 2.0;             // *This* adds to Z!!!
314         point /= gridSpacing;
315         point.x = floor(point.x);//need to fix this for negative numbers...
316         point.y = floor(point.y);
317         point.z = 0;                                    // Make *sure* Z doesn't go anywhere!!!
318         point *= gridSpacing;
319         return point;
320 }
321
322