]> Shamusworld >> Repos - architektonas/blob - src/object.cpp
2e85bf2d3e57c0b9666099dfb81a5a796d2692ac
[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*/ bool Object::PointerMoved(Vector)
79 {
80         return false;
81 }
82
83
84 /*virtual*/ void Object::PointerReleased(void)
85 {
86 }
87
88
89 /*virtual*/ bool Object::NeedsUpdate(void)
90 {
91         return needUpdate;
92 }
93
94
95 /*virtual*/ bool Object::HitTest(Point)
96 {
97         return false;
98 }
99
100
101 // This is intended to be overridden by the Container class, for object morphing
102 /*virtual*/ void Object::Transmute(Object *, Object *)
103 {
104 }
105
106
107 /*virtual*/ Object * Object::GetParent(void)
108 {
109         return parent;
110 }
111
112
113 /*virtual*/ void Object::Add(Object *)
114 {
115 }
116
117
118 // This returns a pointer to the point passed in, if it coincides. Otherwise returns NULL.
119 /*virtual*/ Vector * Object::GetPointAt(Vector)
120 {
121         return 0;
122 }
123
124
125 // This is meant for writing object data to a file.
126 /*virtual*/ void Object::Enumerate(FILE *)
127 {
128 }
129
130
131 /*virtual*/ Object * Object::Copy(void)
132 {
133         return new Object(position, parent);
134 }
135
136
137 // This returns a point on the object at 'parameter', which is between 0 and 1.
138 // Default is to return the object's position.
139 /*virtual*/ Vector Object::GetPointAtParameter(double)
140 {
141         return position;
142 }
143
144
145 // Since these functions are pretty much non-object specific, we can implement
146 // them here. :-)
147 /*virtual*/ void Object::Connect(Object * obj, double parameter)
148 {
149         // Check to see if this connection is already in our list...
150         Connection c(obj, parameter);
151         std::vector<Connection>::iterator i;
152
153         for(i=connected.begin(); i!=connected.end(); i++)
154         {
155                 // Bail out if this connection is already present...
156                 if (*i == c)
157                         return;
158         }
159
160         // Connection is a new one, add it in...
161         connected.push_back(c);
162 }
163
164
165 /*virtual*/ void Object::Disconnect(Object * obj, double parameter)
166 {
167         std::vector<Connection>::iterator i;
168
169         for(i=connected.begin(); i!=connected.end(); i++)
170         {
171                 if (((*i).object == obj) && ((*i).t == parameter))
172                 {
173                         connected.erase(i);
174                         return;
175                 }
176         }
177 }
178
179
180 /*virtual*/ void Object::DisconnectAll(Object * obj)
181 {
182         std::vector<Connection>::iterator i;
183
184         for(i=connected.begin(); i!=connected.end(); )
185         {
186                 if ((*i).object == obj)
187                         connected.erase(i);
188                 else
189                         i++;
190         }
191 }
192
193
194 /*virtual*/ QRectF Object::Extents(void)
195 {
196         // Generic object returns an empty rect...
197         return QRectF();
198 }
199
200
201 #if 0
202 /*virtual*/ ObjectType Object::Type(void)
203 {
204         return OTObject;
205 }
206 #endif
207
208
209 /*virtual*/ void Object::Translate(Vector amount)
210 {
211         position += amount;
212 }
213
214
215 /*virtual*/ void Object::Rotate(Point, double)
216 {
217 }
218
219
220 /*virtual*/ void Object::Scale(Point, double)
221 {
222 }
223
224
225 /*virtual*/ void Object::Mirror(Point, Point)
226 {
227 }
228
229
230 /*virtual*/ void Object::Save(void)
231 {
232         oldPosition = position;
233 }
234
235
236 /*virtual*/ void Object::Restore(void)
237 {
238         position = oldPosition;
239 }
240
241
242 ObjectState Object::GetState(void)
243 {
244         return state;
245 }
246
247
248 void Object::Reparent(Object * newParent)
249 {
250         parent = newParent;
251 }
252
253
254 /*Dimension * Object::GetAttachedDimension(void)
255 {
256         return attachedDimension;
257 }*/
258
259
260 // Class methods...
261
262 void Object::SetFixedAngle(bool state/*= true*/)
263 {
264         fixedAngle = state;
265 }
266
267
268 void Object::SetFixedLength(bool state/*= true*/)
269 {
270         fixedLength = state;
271 }
272
273
274 void Object::SetFont(QFont * f)
275 {
276         font = f;
277 }
278
279
280 void Object::SetViewportHeight(int height)
281 {
282         viewportHeight = height;
283 }
284
285
286 void Object::SetDeleteActive(bool state/*= true*/)
287 {
288         deleteActive = state;
289 }
290
291
292 void Object::SetDimensionActive(bool state/*= true*/)
293 {
294         dimensionActive = state;
295 }
296
297
298 void Object::SetSnapMode(bool state/*= true*/)
299 {
300         snapToGrid = state;
301 }
302
303
304 //
305 // This looks strange, but it's really quite simple: We want a point that's
306 // more than half-way to the next grid point to snap there while conversely we
307 // want a point that's less than half-way to to the next grid point then snap
308 // to the one before it. So we add half of the grid spacing to the point, then
309 // divide by it so that we can remove the fractional part, then multiply it
310 // back to get back to the correct answer.
311 //
312 Vector Object::SnapPointToGrid(Vector point)
313 {
314         point += gridSpacing / 2.0;             // *This* adds to Z!!!
315         point /= gridSpacing;
316         point.x = floor(point.x);//need to fix this for negative numbers...
317         point.y = floor(point.y);
318         point.z = 0;                                    // Make *sure* Z doesn't go anywhere!!!
319         point *= gridSpacing;
320         return point;
321 }
322
323