]> git.saurik.com Git - wxWidgets.git/blame - utils/ogl/src/constrnt.cpp
spurious error messages from wxRegKey::HasValue() suppressed
[wxWidgets.git] / utils / ogl / src / constrnt.cpp
CommitLineData
0fc1a713
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: constrnt.cpp
3// Purpose: OGL Constraint classes
4// Author: Julian Smart
5// Modified by:
6// Created: 12/07/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "constrnt.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include <wx/wxprec.h>
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include <wx/wx.h>
25#endif
26
27#ifdef PROLOGIO
28#include <wx/wxexpr.h>
29#endif
30
31#include "basic.h"
32#include "constrnt.h"
33#include "canvas.h"
34
5de76427 35wxList *OGLConstraintTypes = NULL;
0fc1a713
JS
36
37/*
38 * Constraint type
39 *
40 */
41
42IMPLEMENT_DYNAMIC_CLASS(OGLConstraintType, wxObject)
43
44OGLConstraintType::OGLConstraintType(int theType, const wxString& theName, const wxString& thePhrase)
45{
46 m_type = theType;
47 m_name = theName;
48 m_phrase = thePhrase;
49}
50
51OGLConstraintType::~OGLConstraintType()
52{
53}
54
55void OGLInitializeConstraintTypes()
56{
5de76427
JS
57 if (!OGLConstraintTypes)
58 return;
0fc1a713 59
5de76427 60 OGLConstraintTypes = new wxList(wxKEY_INTEGER);
0fc1a713 61
5de76427
JS
62 OGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_VERTICALLY,
63 new OGLConstraintType(gyCONSTRAINT_CENTRED_VERTICALLY, "Centre vertically", "centred vertically w.r.t."));
0fc1a713 64
5de76427
JS
65 OGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_HORIZONTALLY,
66 new OGLConstraintType(gyCONSTRAINT_CENTRED_HORIZONTALLY, "Centre horizontally", "centred horizontally w.r.t."));
0fc1a713 67
5de76427
JS
68 OGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_BOTH,
69 new OGLConstraintType(gyCONSTRAINT_CENTRED_BOTH, "Centre", "centred w.r.t."));
0fc1a713 70
5de76427
JS
71 OGLConstraintTypes->Append(gyCONSTRAINT_LEFT_OF,
72 new OGLConstraintType(gyCONSTRAINT_LEFT_OF, "Left of", "left of"));
0fc1a713 73
5de76427
JS
74 OGLConstraintTypes->Append(gyCONSTRAINT_RIGHT_OF,
75 new OGLConstraintType(gyCONSTRAINT_RIGHT_OF, "Right of", "right of"));
0fc1a713 76
5de76427
JS
77 OGLConstraintTypes->Append(gyCONSTRAINT_ABOVE,
78 new OGLConstraintType(gyCONSTRAINT_ABOVE, "Above", "above"));
0fc1a713 79
5de76427
JS
80 OGLConstraintTypes->Append(gyCONSTRAINT_BELOW,
81 new OGLConstraintType(gyCONSTRAINT_BELOW, "Below", "below"));
0fc1a713 82
5de76427
JS
83 // Alignment
84 OGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_TOP,
85 new OGLConstraintType(gyCONSTRAINT_ALIGNED_TOP, "Top-aligned", "aligned to the top of"));
0fc1a713 86
5de76427
JS
87 OGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_BOTTOM,
88 new OGLConstraintType(gyCONSTRAINT_ALIGNED_BOTTOM, "Bottom-aligned", "aligned to the bottom of"));
0fc1a713 89
5de76427
JS
90 OGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_LEFT,
91 new OGLConstraintType(gyCONSTRAINT_ALIGNED_LEFT, "Left-aligned", "aligned to the left of"));
0fc1a713 92
5de76427
JS
93 OGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_RIGHT,
94 new OGLConstraintType(gyCONSTRAINT_ALIGNED_RIGHT, "Right-aligned", "aligned to the right of"));
0fc1a713 95
5de76427
JS
96 // Mid-alignment
97 OGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_TOP,
98 new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_TOP, "Top-midaligned", "centred on the top of"));
0fc1a713 99
5de76427
JS
100 OGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_BOTTOM,
101 new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_BOTTOM, "Bottom-midaligned", "centred on the bottom of"));
102
103 OGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_LEFT,
104 new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_LEFT, "Left-midaligned", "centred on the left of"));
105
106 OGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_RIGHT,
107 new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_RIGHT, "Right-midaligned", "centred on the right of"));
108}
109
110void OGLCleanUpConstraintTypes()
111{
112 if (!OGLConstraintTypes)
113 return;
114
115 wxNode* node = OGLConstraintTypes->First();
116 while (node)
117 {
118 OGLConstraintType* ct = (OGLConstraintType*) node->Data();
119 delete ct;
120 node = node->Next();
121 }
122 delete OGLConstraintTypes;
123 OGLConstraintTypes = NULL;
0fc1a713
JS
124}
125
126/*
127 * Constraint Stuff
128 *
129 */
130
131IMPLEMENT_DYNAMIC_CLASS(OGLConstraint, wxObject)
132
133OGLConstraint::OGLConstraint(int type, wxShape *constraining, wxList& constrained)
134{
135 m_xSpacing = 0.0;
136 m_ySpacing = 0.0;
137
138 m_constraintType = type;
139 m_constrainingObject = constraining;
140
141 m_constraintId = 0;
142 m_constraintName = "noname";
143
144 wxNode *node = constrained.First();
145 while (node)
146 {
147 m_constrainedObjects.Append(node->Data());
148 node = node->Next();
149 }
150}
151
152OGLConstraint::~OGLConstraint()
153{
154}
155
156bool OGLConstraint::Equals(float a, float b)
157{
158 float marg = 0.5;
159
160 bool eq = ((b <= a + marg) && (b >= a - marg));
161 return eq;
162}
163
164// Return TRUE if anything changed
165bool OGLConstraint::Evaluate()
166{
167 float maxWidth, maxHeight, minWidth, minHeight, x, y;
168 m_constrainingObject->GetBoundingBoxMax(&maxWidth, &maxHeight);
169 m_constrainingObject->GetBoundingBoxMin(&minWidth, &minHeight);
170 x = m_constrainingObject->GetX();
171 y = m_constrainingObject->GetY();
172
173 wxClientDC dc(m_constrainingObject->GetCanvas());
174 m_constrainingObject->GetCanvas()->PrepareDC(dc);
175
176 switch (m_constraintType)
177 {
178 case gyCONSTRAINT_CENTRED_VERTICALLY:
179 {
180 int n = m_constrainedObjects.Number();
181 float totalObjectHeight = 0.0;
182 wxNode *node = m_constrainedObjects.First();
183 while (node)
184 {
185 wxShape *constrainedObject = (wxShape *)node->Data();
186
187 float width2, height2;
188 constrainedObject->GetBoundingBoxMax(&width2, &height2);
189 totalObjectHeight += height2;
190 node = node->Next();
191 }
192 float startY;
193 float spacingY;
194 // Check if within the constraining object...
195 if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight)
196 {
197 spacingY = (float)((minHeight - totalObjectHeight)/(n + 1));
198 startY = (float)(y - (minHeight/2.0));
199 }
200 // Otherwise, use default spacing
201 else
202 {
203 spacingY = m_ySpacing;
204 startY = (float)(y - ((totalObjectHeight + (n+1)*spacingY)/2.0));
205 }
206
207 // Now position the objects
208 bool changed = FALSE;
209 node = m_constrainedObjects.First();
210 while (node)
211 {
212 wxShape *constrainedObject = (wxShape *)node->Data();
213 float width2, height2;
214 constrainedObject->GetBoundingBoxMax(&width2, &height2);
215 startY += (float)(spacingY + (height2/2.0));
216 if (!Equals(startY, constrainedObject->GetY()))
217 {
218 constrainedObject->Move(dc, constrainedObject->GetX(), startY, FALSE);
219 changed = TRUE;
220 }
221 startY += (float)(height2/2.0);
222 node = node->Next();
223 }
224 return changed;
225 }
226 case gyCONSTRAINT_CENTRED_HORIZONTALLY:
227 {
228 int n = m_constrainedObjects.Number();
229 float totalObjectWidth = 0.0;
230 wxNode *node = m_constrainedObjects.First();
231 while (node)
232 {
233 wxShape *constrainedObject = (wxShape *)node->Data();
234
235 float width2, height2;
236 constrainedObject->GetBoundingBoxMax(&width2, &height2);
237 totalObjectWidth += width2;
238 node = node->Next();
239 }
240 float startX;
241 float spacingX;
242 // Check if within the constraining object...
243 if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth)
244 {
245 spacingX = (float)((minWidth - totalObjectWidth)/(n + 1));
246 startX = (float)(x - (minWidth/2.0));
247 }
248 // Otherwise, use default spacing
249 else
250 {
251 spacingX = m_xSpacing;
252 startX = (float)(x - ((totalObjectWidth + (n+1)*spacingX)/2.0));
253 }
254
255 // Now position the objects
256 bool changed = FALSE;
257 node = m_constrainedObjects.First();
258 while (node)
259 {
260 wxShape *constrainedObject = (wxShape *)node->Data();
261 float width2, height2;
262 constrainedObject->GetBoundingBoxMax(&width2, &height2);
263 startX += (float)(spacingX + (width2/2.0));
264 if (!Equals(startX, constrainedObject->GetX()))
265 {
266 constrainedObject->Move(dc, startX, constrainedObject->GetY(), FALSE);
267 changed = TRUE;
268 }
269 startX += (float)(width2/2.0);
270 node = node->Next();
271 }
272 return changed;
273 }
274 case gyCONSTRAINT_CENTRED_BOTH:
275 {
276 int n = m_constrainedObjects.Number();
277 float totalObjectWidth = 0.0;
278 float totalObjectHeight = 0.0;
279 wxNode *node = m_constrainedObjects.First();
280 while (node)
281 {
282 wxShape *constrainedObject = (wxShape *)node->Data();
283
284 float width2, height2;
285 constrainedObject->GetBoundingBoxMax(&width2, &height2);
286 totalObjectWidth += width2;
287 totalObjectHeight += height2;
288 node = node->Next();
289 }
290 float startX;
291 float spacingX;
292 float startY;
293 float spacingY;
294
295 // Check if within the constraining object...
296 if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth)
297 {
298 spacingX = (float)((minWidth - totalObjectWidth)/(n + 1));
299 startX = (float)(x - (minWidth/2.0));
300 }
301 // Otherwise, use default spacing
302 else
303 {
304 spacingX = m_xSpacing;
305 startX = (float)(x - ((totalObjectWidth + (n+1)*spacingX)/2.0));
306 }
307
308 // Check if within the constraining object...
309 if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight)
310 {
311 spacingY = (float)((minHeight - totalObjectHeight)/(n + 1));
312 startY = (float)(y - (minHeight/2.0));
313 }
314 // Otherwise, use default spacing
315 else
316 {
317 spacingY = m_ySpacing;
318 startY = (float)(y - ((totalObjectHeight + (n+1)*spacingY)/2.0));
319 }
320
321 // Now position the objects
322 bool changed = FALSE;
323 node = m_constrainedObjects.First();
324 while (node)
325 {
326 wxShape *constrainedObject = (wxShape *)node->Data();
327 float width2, height2;
328 constrainedObject->GetBoundingBoxMax(&width2, &height2);
329 startX += (float)(spacingX + (width2/2.0));
330 startY += (float)(spacingY + (height2/2.0));
331
332 if ((!Equals(startX, constrainedObject->GetX())) || (!Equals(startY, constrainedObject->GetY())))
333 {
334 constrainedObject->Move(dc, startX, startY, FALSE);
335 changed = TRUE;
336 }
337
338 startX += (float)(width2/2.0);
339 startY += (float)(height2/2.0);
340
341 node = node->Next();
342 }
343 return changed;
344 }
345 case gyCONSTRAINT_LEFT_OF:
346 {
347 bool changed = FALSE;
348
349 wxNode *node = m_constrainedObjects.First();
350 while (node)
351 {
352 wxShape *constrainedObject = (wxShape *)node->Data();
353
354 float width2, height2;
355 constrainedObject->GetBoundingBoxMax(&width2, &height2);
356
357 float x3 = (float)(x - (minWidth/2.0) - (width2/2.0) - m_xSpacing);
358 if (!Equals(x3, constrainedObject->GetX()))
359 {
360 changed = TRUE;
361 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
362 }
363
364 node = node->Next();
365 }
366 return changed;
367 }
368 case gyCONSTRAINT_RIGHT_OF:
369 {
370 bool changed = FALSE;
371
372 wxNode *node = m_constrainedObjects.First();
373 while (node)
374 {
375 wxShape *constrainedObject = (wxShape *)node->Data();
376
377 float width2, height2;
378 constrainedObject->GetBoundingBoxMax(&width2, &height2);
379
380 float x3 = (float)(x + (minWidth/2.0) + (width2/2.0) + m_xSpacing);
381 if (!Equals(x3, constrainedObject->GetX()))
382 {
383 changed = TRUE;
384 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
385 }
386
387 node = node->Next();
388 }
389 return changed;
390
391 return FALSE;
392 }
393 case gyCONSTRAINT_ABOVE:
394 {
395 bool changed = FALSE;
396
397 wxNode *node = m_constrainedObjects.First();
398 while (node)
399 {
400 wxShape *constrainedObject = (wxShape *)node->Data();
401
402 float width2, height2;
403 constrainedObject->GetBoundingBoxMax(&width2, &height2);
404
405 float y3 = (float)(y - (minHeight/2.0) - (height2/2.0) - m_ySpacing);
406 if (!Equals(y3, constrainedObject->GetY()))
407 {
408 changed = TRUE;
409 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
410 }
411
412 node = node->Next();
413 }
414 return changed;
415 }
416 case gyCONSTRAINT_BELOW:
417 {
418 bool changed = FALSE;
419
420 wxNode *node = m_constrainedObjects.First();
421 while (node)
422 {
423 wxShape *constrainedObject = (wxShape *)node->Data();
424
425 float width2, height2;
426 constrainedObject->GetBoundingBoxMax(&width2, &height2);
427
428 float y3 = (float)(y + (minHeight/2.0) + (height2/2.0) + m_ySpacing);
429 if (!Equals(y3, constrainedObject->GetY()))
430 {
431 changed = TRUE;
432 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
433 }
434
435 node = node->Next();
436 }
437 return changed;
438 }
439 case gyCONSTRAINT_ALIGNED_LEFT:
440 {
441 bool changed = FALSE;
442
443 wxNode *node = m_constrainedObjects.First();
444 while (node)
445 {
446 wxShape *constrainedObject = (wxShape *)node->Data();
447
448 float width2, height2;
449 constrainedObject->GetBoundingBoxMax(&width2, &height2);
450
451 float x3 = (float)(x - (minWidth/2.0) + (width2/2.0) + m_xSpacing);
452 if (!Equals(x3, constrainedObject->GetX()))
453 {
454 changed = TRUE;
455 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
456 }
457
458 node = node->Next();
459 }
460 return changed;
461 }
462 case gyCONSTRAINT_ALIGNED_RIGHT:
463 {
464 bool changed = FALSE;
465
466 wxNode *node = m_constrainedObjects.First();
467 while (node)
468 {
469 wxShape *constrainedObject = (wxShape *)node->Data();
470
471 float width2, height2;
472 constrainedObject->GetBoundingBoxMax(&width2, &height2);
473
474 float x3 = (float)(x + (minWidth/2.0) - (width2/2.0) - m_xSpacing);
475 if (!Equals(x3, constrainedObject->GetX()))
476 {
477 changed = TRUE;
478 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
479 }
480
481 node = node->Next();
482 }
483 return changed;
484
485 return FALSE;
486 }
487 case gyCONSTRAINT_ALIGNED_TOP:
488 {
489 bool changed = FALSE;
490
491 wxNode *node = m_constrainedObjects.First();
492 while (node)
493 {
494 wxShape *constrainedObject = (wxShape *)node->Data();
495
496 float width2, height2;
497 constrainedObject->GetBoundingBoxMax(&width2, &height2);
498
499 float y3 = (float)(y - (minHeight/2.0) + (height2/2.0) + m_ySpacing);
500 if (!Equals(y3, constrainedObject->GetY()))
501 {
502 changed = TRUE;
503 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
504 }
505
506 node = node->Next();
507 }
508 return changed;
509 }
510 case gyCONSTRAINT_ALIGNED_BOTTOM:
511 {
512 bool changed = FALSE;
513
514 wxNode *node = m_constrainedObjects.First();
515 while (node)
516 {
517 wxShape *constrainedObject = (wxShape *)node->Data();
518
519 float width2, height2;
520 constrainedObject->GetBoundingBoxMax(&width2, &height2);
521
522 float y3 = (float)(y + (minHeight/2.0) - (height2/2.0) - m_ySpacing);
523 if (!Equals(y3, constrainedObject->GetY()))
524 {
525 changed = TRUE;
526 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
527 }
528
529 node = node->Next();
530 }
531 return changed;
532 }
533 case gyCONSTRAINT_MIDALIGNED_LEFT:
534 {
535 bool changed = FALSE;
536
537 wxNode *node = m_constrainedObjects.First();
538 while (node)
539 {
540 wxShape *constrainedObject = (wxShape *)node->Data();
541
542 float x3 = (float)(x - (minWidth/2.0));
543 if (!Equals(x3, constrainedObject->GetX()))
544 {
545 changed = TRUE;
546 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
547 }
548
549 node = node->Next();
550 }
551 return changed;
552 }
553 case gyCONSTRAINT_MIDALIGNED_RIGHT:
554 {
555 bool changed = FALSE;
556
557 wxNode *node = m_constrainedObjects.First();
558 while (node)
559 {
560 wxShape *constrainedObject = (wxShape *)node->Data();
561
562 float x3 = (float)(x + (minWidth/2.0));
563 if (!Equals(x3, constrainedObject->GetX()))
564 {
565 changed = TRUE;
566 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
567 }
568
569 node = node->Next();
570 }
571 return changed;
572
573 return FALSE;
574 }
575 case gyCONSTRAINT_MIDALIGNED_TOP:
576 {
577 bool changed = FALSE;
578
579 wxNode *node = m_constrainedObjects.First();
580 while (node)
581 {
582 wxShape *constrainedObject = (wxShape *)node->Data();
583
584 float y3 = (float)(y - (minHeight/2.0));
585 if (!Equals(y3, constrainedObject->GetY()))
586 {
587 changed = TRUE;
588 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
589 }
590
591 node = node->Next();
592 }
593 return changed;
594 }
595 case gyCONSTRAINT_MIDALIGNED_BOTTOM:
596 {
597 bool changed = FALSE;
598
599 wxNode *node = m_constrainedObjects.First();
600 while (node)
601 {
602 wxShape *constrainedObject = (wxShape *)node->Data();
603
604 float y3 = (float)(y + (minHeight/2.0));
605 if (!Equals(y3, constrainedObject->GetY()))
606 {
607 changed = TRUE;
608 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
609 }
610
611 node = node->Next();
612 }
613 return changed;
614 }
615
616 default:
617 return FALSE;
618 }
619 return FALSE;
620}
621