1 |
///////////////////////////////////////////////////////////////////////////// |
2 |
// Name: src/common/layout.cpp |
3 |
// Purpose: Constraint layout system classes |
4 |
// Author: Julian Smart |
5 |
// Modified by: |
6 |
// Created: 04/01/98 |
7 |
// RCS-ID: $Id: layout.cpp 39627 2006-06-08 06:57:39Z ABX $ |
8 |
// Copyright: (c) Julian Smart |
9 |
// Licence: wxWindows licence |
10 |
///////////////////////////////////////////////////////////////////////////// |
11 |
|
12 |
// ============================================================================= |
13 |
// declarations |
14 |
// ============================================================================= |
15 |
|
16 |
// ---------------------------------------------------------------------------- |
17 |
// headers |
18 |
// ---------------------------------------------------------------------------- |
19 |
|
20 |
// For compilers that support precompilation, includes "wx.h". |
21 |
#include "wx/wxprec.h" |
22 |
|
23 |
#ifdef __BORLANDC__ |
24 |
#pragma hdrstop |
25 |
#endif |
26 |
|
27 |
#if wxUSE_CONSTRAINTS |
28 |
|
29 |
#include "wx/layout.h" |
30 |
|
31 |
#ifndef WX_PRECOMP |
32 |
#include "wx/window.h" |
33 |
#include "wx/utils.h" |
34 |
#include "wx/dialog.h" |
35 |
#include "wx/msgdlg.h" |
36 |
#include "wx/intl.h" |
37 |
#endif |
38 |
|
39 |
|
40 |
IMPLEMENT_DYNAMIC_CLASS(wxIndividualLayoutConstraint, wxObject) |
41 |
IMPLEMENT_DYNAMIC_CLASS(wxLayoutConstraints, wxObject) |
42 |
|
43 |
|
44 |
inline void wxGetAsIs(wxWindowBase* win, int* w, int* h) |
45 |
{ |
46 |
#if 1 |
47 |
// The old way. Works for me. |
48 |
win->GetSize(w, h); |
49 |
#endif |
50 |
|
51 |
#if 0 |
52 |
// Vadim's change. Breaks wxPython's LayoutAnchors |
53 |
win->GetBestSize(w, h); |
54 |
#endif |
55 |
|
56 |
#if 0 |
57 |
// Proposed compromise. Doesn't work. |
58 |
int sw, sh, bw, bh; |
59 |
win->GetSize(&sw, &sh); |
60 |
win->GetBestSize(&bw, &bh); |
61 |
if (w) |
62 |
*w = wxMax(sw, bw); |
63 |
if (h) |
64 |
*h = wxMax(sh, bh); |
65 |
#endif |
66 |
} |
67 |
|
68 |
|
69 |
wxIndividualLayoutConstraint::wxIndividualLayoutConstraint() |
70 |
{ |
71 |
myEdge = wxTop; |
72 |
relationship = wxUnconstrained; |
73 |
margin = 0; |
74 |
value = 0; |
75 |
percent = 0; |
76 |
otherEdge = wxTop; |
77 |
done = false; |
78 |
otherWin = (wxWindowBase *) NULL; |
79 |
} |
80 |
|
81 |
void wxIndividualLayoutConstraint::Set(wxRelationship rel, wxWindowBase *otherW, wxEdge otherE, int val, int marg) |
82 |
{ |
83 |
if (rel == wxSameAs) |
84 |
{ |
85 |
// If Set is called by the user with wxSameAs then call SameAs to do |
86 |
// it since it will actually use wxPercent instead. |
87 |
SameAs(otherW, otherE, marg); |
88 |
return; |
89 |
} |
90 |
|
91 |
relationship = rel; |
92 |
otherWin = otherW; |
93 |
otherEdge = otherE; |
94 |
|
95 |
if ( rel == wxPercentOf ) |
96 |
{ |
97 |
percent = val; |
98 |
} |
99 |
else |
100 |
{ |
101 |
value = val; |
102 |
} |
103 |
|
104 |
margin = marg; |
105 |
} |
106 |
|
107 |
void wxIndividualLayoutConstraint::LeftOf(wxWindowBase *sibling, int marg) |
108 |
{ |
109 |
Set(wxLeftOf, sibling, wxLeft, 0, marg); |
110 |
} |
111 |
|
112 |
void wxIndividualLayoutConstraint::RightOf(wxWindowBase *sibling, int marg) |
113 |
{ |
114 |
Set(wxRightOf, sibling, wxRight, 0, marg); |
115 |
} |
116 |
|
117 |
void wxIndividualLayoutConstraint::Above(wxWindowBase *sibling, int marg) |
118 |
{ |
119 |
Set(wxAbove, sibling, wxTop, 0, marg); |
120 |
} |
121 |
|
122 |
void wxIndividualLayoutConstraint::Below(wxWindowBase *sibling, int marg) |
123 |
{ |
124 |
Set(wxBelow, sibling, wxBottom, 0, marg); |
125 |
} |
126 |
|
127 |
// |
128 |
// 'Same edge' alignment |
129 |
// |
130 |
void wxIndividualLayoutConstraint::SameAs(wxWindowBase *otherW, wxEdge edge, int marg) |
131 |
{ |
132 |
Set(wxPercentOf, otherW, edge, 100, marg); |
133 |
} |
134 |
|
135 |
// The edge is a percentage of the other window's edge |
136 |
void wxIndividualLayoutConstraint::PercentOf(wxWindowBase *otherW, wxEdge wh, int per) |
137 |
{ |
138 |
Set(wxPercentOf, otherW, wh, per); |
139 |
} |
140 |
|
141 |
// |
142 |
// Edge has absolute value |
143 |
// |
144 |
void wxIndividualLayoutConstraint::Absolute(int val) |
145 |
{ |
146 |
value = val; |
147 |
relationship = wxAbsolute; |
148 |
} |
149 |
|
150 |
// Reset constraint if it mentions otherWin |
151 |
bool wxIndividualLayoutConstraint::ResetIfWin(wxWindowBase *otherW) |
152 |
{ |
153 |
if (otherW == otherWin) |
154 |
{ |
155 |
myEdge = wxTop; |
156 |
relationship = wxAsIs; |
157 |
margin = 0; |
158 |
value = 0; |
159 |
percent = 0; |
160 |
otherEdge = wxTop; |
161 |
otherWin = (wxWindowBase *) NULL; |
162 |
return true; |
163 |
} |
164 |
|
165 |
return false; |
166 |
} |
167 |
|
168 |
// Try to satisfy constraint |
169 |
bool wxIndividualLayoutConstraint::SatisfyConstraint(wxLayoutConstraints *constraints, wxWindowBase *win) |
170 |
{ |
171 |
if (relationship == wxAbsolute) |
172 |
{ |
173 |
done = true; |
174 |
return true; |
175 |
} |
176 |
|
177 |
switch (myEdge) |
178 |
{ |
179 |
case wxLeft: |
180 |
{ |
181 |
switch (relationship) |
182 |
{ |
183 |
case wxLeftOf: |
184 |
{ |
185 |
// We can know this edge if: otherWin is win's |
186 |
// parent, or otherWin has a satisfied constraint, |
187 |
// or otherWin has no constraint. |
188 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
189 |
if (edgePos != -1) |
190 |
{ |
191 |
value = edgePos - margin; |
192 |
done = true; |
193 |
return true; |
194 |
} |
195 |
else |
196 |
return false; |
197 |
} |
198 |
case wxRightOf: |
199 |
{ |
200 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
201 |
if (edgePos != -1) |
202 |
{ |
203 |
value = edgePos + margin; |
204 |
done = true; |
205 |
return true; |
206 |
} |
207 |
else |
208 |
return false; |
209 |
} |
210 |
case wxPercentOf: |
211 |
{ |
212 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
213 |
if (edgePos != -1) |
214 |
{ |
215 |
value = (int)(edgePos*(((float)percent)*0.01) + margin); |
216 |
done = true; |
217 |
return true; |
218 |
} |
219 |
else |
220 |
return false; |
221 |
} |
222 |
case wxUnconstrained: |
223 |
{ |
224 |
// We know the left-hand edge position if we know |
225 |
// the right-hand edge and we know the width; OR if |
226 |
// we know the centre and the width. |
227 |
if (constraints->right.GetDone() && constraints->width.GetDone()) |
228 |
{ |
229 |
value = (constraints->right.GetValue() - constraints->width.GetValue() + margin); |
230 |
done = true; |
231 |
return true; |
232 |
} |
233 |
else if (constraints->centreX.GetDone() && constraints->width.GetDone()) |
234 |
{ |
235 |
value = (int)(constraints->centreX.GetValue() - (constraints->width.GetValue()/2) + margin); |
236 |
done = true; |
237 |
return true; |
238 |
} |
239 |
else |
240 |
return false; |
241 |
} |
242 |
case wxAsIs: |
243 |
{ |
244 |
int y; |
245 |
win->GetPosition(&value, &y); |
246 |
done = true; |
247 |
return true; |
248 |
} |
249 |
default: |
250 |
break; |
251 |
} |
252 |
break; |
253 |
} |
254 |
case wxRight: |
255 |
{ |
256 |
switch (relationship) |
257 |
{ |
258 |
case wxLeftOf: |
259 |
{ |
260 |
// We can know this edge if: otherWin is win's |
261 |
// parent, or otherWin has a satisfied constraint, |
262 |
// or otherWin has no constraint. |
263 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
264 |
if (edgePos != -1) |
265 |
{ |
266 |
value = edgePos - margin; |
267 |
done = true; |
268 |
return true; |
269 |
} |
270 |
else |
271 |
return false; |
272 |
} |
273 |
case wxRightOf: |
274 |
{ |
275 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
276 |
if (edgePos != -1) |
277 |
{ |
278 |
value = edgePos + margin; |
279 |
done = true; |
280 |
return true; |
281 |
} |
282 |
else |
283 |
return false; |
284 |
} |
285 |
case wxPercentOf: |
286 |
{ |
287 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
288 |
if (edgePos != -1) |
289 |
{ |
290 |
value = (int)(edgePos*(((float)percent)*0.01) - margin); |
291 |
done = true; |
292 |
return true; |
293 |
} |
294 |
else |
295 |
return false; |
296 |
} |
297 |
case wxUnconstrained: |
298 |
{ |
299 |
// We know the right-hand edge position if we know the |
300 |
// left-hand edge and we know the width, OR if we know the |
301 |
// centre edge and the width. |
302 |
if (constraints->left.GetDone() && constraints->width.GetDone()) |
303 |
{ |
304 |
value = (constraints->left.GetValue() + constraints->width.GetValue() - margin); |
305 |
done = true; |
306 |
return true; |
307 |
} |
308 |
else if (constraints->centreX.GetDone() && constraints->width.GetDone()) |
309 |
{ |
310 |
value = (int)(constraints->centreX.GetValue() + (constraints->width.GetValue()/2) - margin); |
311 |
done = true; |
312 |
return true; |
313 |
} |
314 |
else |
315 |
return false; |
316 |
} |
317 |
case wxAsIs: |
318 |
{ |
319 |
int x, y; |
320 |
int w, h; |
321 |
wxGetAsIs(win, &w, &h); |
322 |
win->GetPosition(&x, &y); |
323 |
value = x + w; |
324 |
done = true; |
325 |
return true; |
326 |
} |
327 |
default: |
328 |
break; |
329 |
} |
330 |
break; |
331 |
} |
332 |
case wxTop: |
333 |
{ |
334 |
switch (relationship) |
335 |
{ |
336 |
case wxAbove: |
337 |
{ |
338 |
// We can know this edge if: otherWin is win's |
339 |
// parent, or otherWin has a satisfied constraint, |
340 |
// or otherWin has no constraint. |
341 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
342 |
if (edgePos != -1) |
343 |
{ |
344 |
value = edgePos - margin; |
345 |
done = true; |
346 |
return true; |
347 |
} |
348 |
else |
349 |
return false; |
350 |
} |
351 |
case wxBelow: |
352 |
{ |
353 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
354 |
if (edgePos != -1) |
355 |
{ |
356 |
value = edgePos + margin; |
357 |
done = true; |
358 |
return true; |
359 |
} |
360 |
else |
361 |
return false; |
362 |
} |
363 |
case wxPercentOf: |
364 |
{ |
365 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
366 |
if (edgePos != -1) |
367 |
{ |
368 |
value = (int)(edgePos*(((float)percent)*0.01) + margin); |
369 |
done = true; |
370 |
return true; |
371 |
} |
372 |
else |
373 |
return false; |
374 |
} |
375 |
case wxUnconstrained: |
376 |
{ |
377 |
// We know the top edge position if we know the bottom edge |
378 |
// and we know the height; OR if we know the centre edge and |
379 |
// the height. |
380 |
if (constraints->bottom.GetDone() && constraints->height.GetDone()) |
381 |
{ |
382 |
value = (constraints->bottom.GetValue() - constraints->height.GetValue() + margin); |
383 |
done = true; |
384 |
return true; |
385 |
} |
386 |
else if (constraints->centreY.GetDone() && constraints->height.GetDone()) |
387 |
{ |
388 |
value = (constraints->centreY.GetValue() - (constraints->height.GetValue()/2) + margin); |
389 |
done = true; |
390 |
return true; |
391 |
} |
392 |
else |
393 |
return false; |
394 |
} |
395 |
case wxAsIs: |
396 |
{ |
397 |
int x; |
398 |
win->GetPosition(&x, &value); |
399 |
done = true; |
400 |
return true; |
401 |
} |
402 |
default: |
403 |
break; |
404 |
} |
405 |
break; |
406 |
} |
407 |
case wxBottom: |
408 |
{ |
409 |
switch (relationship) |
410 |
{ |
411 |
case wxAbove: |
412 |
{ |
413 |
// We can know this edge if: otherWin is win's parent, |
414 |
// or otherWin has a satisfied constraint, or |
415 |
// otherWin has no constraint. |
416 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
417 |
if (edgePos != -1) |
418 |
{ |
419 |
value = edgePos + margin; |
420 |
done = true; |
421 |
return true; |
422 |
} |
423 |
else |
424 |
return false; |
425 |
} |
426 |
case wxBelow: |
427 |
{ |
428 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
429 |
if (edgePos != -1) |
430 |
{ |
431 |
value = edgePos - margin; |
432 |
done = true; |
433 |
return true; |
434 |
} |
435 |
else |
436 |
return false; |
437 |
} |
438 |
case wxPercentOf: |
439 |
{ |
440 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
441 |
if (edgePos != -1) |
442 |
{ |
443 |
value = (int)(edgePos*(((float)percent)*0.01) - margin); |
444 |
done = true; |
445 |
return true; |
446 |
} |
447 |
else |
448 |
return false; |
449 |
} |
450 |
case wxUnconstrained: |
451 |
{ |
452 |
// We know the bottom edge position if we know the top edge |
453 |
// and we know the height; OR if we know the centre edge and |
454 |
// the height. |
455 |
if (constraints->top.GetDone() && constraints->height.GetDone()) |
456 |
{ |
457 |
value = (constraints->top.GetValue() + constraints->height.GetValue() - margin); |
458 |
done = true; |
459 |
return true; |
460 |
} |
461 |
else if (constraints->centreY.GetDone() && constraints->height.GetDone()) |
462 |
{ |
463 |
value = (constraints->centreY.GetValue() + (constraints->height.GetValue()/2) - margin); |
464 |
done = true; |
465 |
return true; |
466 |
} |
467 |
else |
468 |
return false; |
469 |
} |
470 |
case wxAsIs: |
471 |
{ |
472 |
int x, y; |
473 |
int w, h; |
474 |
wxGetAsIs(win, &w, &h); |
475 |
win->GetPosition(&x, &y); |
476 |
value = h + y; |
477 |
done = true; |
478 |
return true; |
479 |
} |
480 |
default: |
481 |
break; |
482 |
} |
483 |
break; |
484 |
} |
485 |
case wxCentreX: |
486 |
{ |
487 |
switch (relationship) |
488 |
{ |
489 |
case wxLeftOf: |
490 |
{ |
491 |
// We can know this edge if: otherWin is win's parent, or |
492 |
// otherWin has a satisfied constraint, or otherWin has no |
493 |
// constraint. |
494 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
495 |
if (edgePos != -1) |
496 |
{ |
497 |
value = edgePos - margin; |
498 |
done = true; |
499 |
return true; |
500 |
} |
501 |
else |
502 |
return false; |
503 |
} |
504 |
case wxRightOf: |
505 |
{ |
506 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
507 |
if (edgePos != -1) |
508 |
{ |
509 |
value = edgePos + margin; |
510 |
done = true; |
511 |
return true; |
512 |
} |
513 |
else |
514 |
return false; |
515 |
} |
516 |
case wxPercentOf: |
517 |
{ |
518 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
519 |
if (edgePos != -1) |
520 |
{ |
521 |
value = (int)(edgePos*(((float)percent)*0.01) + margin); |
522 |
done = true; |
523 |
return true; |
524 |
} |
525 |
else |
526 |
return false; |
527 |
} |
528 |
case wxUnconstrained: |
529 |
{ |
530 |
// We know the centre position if we know |
531 |
// the left-hand edge and we know the width, OR |
532 |
// the right-hand edge and the width |
533 |
if (constraints->left.GetDone() && constraints->width.GetDone()) |
534 |
{ |
535 |
value = (int)(constraints->left.GetValue() + (constraints->width.GetValue()/2) + margin); |
536 |
done = true; |
537 |
return true; |
538 |
} |
539 |
else if (constraints->right.GetDone() && constraints->width.GetDone()) |
540 |
{ |
541 |
value = (int)(constraints->left.GetValue() - (constraints->width.GetValue()/2) + margin); |
542 |
done = true; |
543 |
return true; |
544 |
} |
545 |
else |
546 |
return false; |
547 |
} |
548 |
default: |
549 |
break; |
550 |
} |
551 |
break; |
552 |
} |
553 |
case wxCentreY: |
554 |
{ |
555 |
switch (relationship) |
556 |
{ |
557 |
case wxAbove: |
558 |
{ |
559 |
// We can know this edge if: otherWin is win's parent, |
560 |
// or otherWin has a satisfied constraint, or otherWin |
561 |
// has no constraint. |
562 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
563 |
if (edgePos != -1) |
564 |
{ |
565 |
value = edgePos - margin; |
566 |
done = true; |
567 |
return true; |
568 |
} |
569 |
else |
570 |
return false; |
571 |
} |
572 |
case wxBelow: |
573 |
{ |
574 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
575 |
if (edgePos != -1) |
576 |
{ |
577 |
value = edgePos + margin; |
578 |
done = true; |
579 |
return true; |
580 |
} |
581 |
else |
582 |
return false; |
583 |
} |
584 |
case wxPercentOf: |
585 |
{ |
586 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
587 |
if (edgePos != -1) |
588 |
{ |
589 |
value = (int)(edgePos*(((float)percent)*0.01) + margin); |
590 |
done = true; |
591 |
return true; |
592 |
} |
593 |
else |
594 |
return false; |
595 |
} |
596 |
case wxUnconstrained: |
597 |
{ |
598 |
// We know the centre position if we know |
599 |
// the top edge and we know the height, OR |
600 |
// the bottom edge and the height. |
601 |
if (constraints->bottom.GetDone() && constraints->height.GetDone()) |
602 |
{ |
603 |
value = (int)(constraints->bottom.GetValue() - (constraints->height.GetValue()/2) + margin); |
604 |
done = true; |
605 |
return true; |
606 |
} |
607 |
else if (constraints->top.GetDone() && constraints->height.GetDone()) |
608 |
{ |
609 |
value = (int)(constraints->top.GetValue() + (constraints->height.GetValue()/2) + margin); |
610 |
done = true; |
611 |
return true; |
612 |
} |
613 |
else |
614 |
return false; |
615 |
} |
616 |
default: |
617 |
break; |
618 |
} |
619 |
break; |
620 |
} |
621 |
case wxWidth: |
622 |
{ |
623 |
switch (relationship) |
624 |
{ |
625 |
case wxPercentOf: |
626 |
{ |
627 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
628 |
if (edgePos != -1) |
629 |
{ |
630 |
value = (int)(edgePos*(((float)percent)*0.01)); |
631 |
done = true; |
632 |
return true; |
633 |
} |
634 |
else |
635 |
return false; |
636 |
} |
637 |
case wxAsIs: |
638 |
{ |
639 |
if (win) |
640 |
{ |
641 |
int h; |
642 |
wxGetAsIs(win, &value, &h); |
643 |
done = true; |
644 |
return true; |
645 |
} |
646 |
else return false; |
647 |
} |
648 |
case wxUnconstrained: |
649 |
{ |
650 |
// We know the width if we know the left edge and the right edge, OR |
651 |
// if we know the left edge and the centre, OR |
652 |
// if we know the right edge and the centre |
653 |
if (constraints->left.GetDone() && constraints->right.GetDone()) |
654 |
{ |
655 |
value = constraints->right.GetValue() - constraints->left.GetValue(); |
656 |
done = true; |
657 |
return true; |
658 |
} |
659 |
else if (constraints->centreX.GetDone() && constraints->left.GetDone()) |
660 |
{ |
661 |
value = (int)(2*(constraints->centreX.GetValue() - constraints->left.GetValue())); |
662 |
done = true; |
663 |
return true; |
664 |
} |
665 |
else if (constraints->centreX.GetDone() && constraints->right.GetDone()) |
666 |
{ |
667 |
value = (int)(2*(constraints->right.GetValue() - constraints->centreX.GetValue())); |
668 |
done = true; |
669 |
return true; |
670 |
} |
671 |
else |
672 |
return false; |
673 |
} |
674 |
default: |
675 |
break; |
676 |
} |
677 |
break; |
678 |
} |
679 |
case wxHeight: |
680 |
{ |
681 |
switch (relationship) |
682 |
{ |
683 |
case wxPercentOf: |
684 |
{ |
685 |
int edgePos = GetEdge(otherEdge, win, otherWin); |
686 |
if (edgePos != -1) |
687 |
{ |
688 |
value = (int)(edgePos*(((float)percent)*0.01)); |
689 |
done = true; |
690 |
return true; |
691 |
} |
692 |
else |
693 |
return false; |
694 |
} |
695 |
case wxAsIs: |
696 |
{ |
697 |
if (win) |
698 |
{ |
699 |
int w; |
700 |
wxGetAsIs(win, &w, &value); |
701 |
done = true; |
702 |
return true; |
703 |
} |
704 |
else return false; |
705 |
} |
706 |
case wxUnconstrained: |
707 |
{ |
708 |
// We know the height if we know the top edge and the bottom edge, OR |
709 |
// if we know the top edge and the centre, OR |
710 |
// if we know the bottom edge and the centre |
711 |
if (constraints->top.GetDone() && constraints->bottom.GetDone()) |
712 |
{ |
713 |
value = constraints->bottom.GetValue() - constraints->top.GetValue(); |
714 |
done = true; |
715 |
return true; |
716 |
} |
717 |
else if (constraints->top.GetDone() && constraints->centreY.GetDone()) |
718 |
{ |
719 |
value = (int)(2*(constraints->centreY.GetValue() - constraints->top.GetValue())); |
720 |
done = true; |
721 |
return true; |
722 |
} |
723 |
else if (constraints->bottom.GetDone() && constraints->centreY.GetDone()) |
724 |
{ |
725 |
value = (int)(2*(constraints->bottom.GetValue() - constraints->centreY.GetValue())); |
726 |
done = true; |
727 |
return true; |
728 |
} |
729 |
else |
730 |
return false; |
731 |
} |
732 |
default: |
733 |
break; |
734 |
} |
735 |
break; |
736 |
} |
737 |
default: |
738 |
break; |
739 |
} |
740 |
return false; |
741 |
} |
742 |
|
743 |
// Get the value of this edge or dimension, or if this is not determinable, -1. |
744 |
int wxIndividualLayoutConstraint::GetEdge(wxEdge which, |
745 |
wxWindowBase *thisWin, |
746 |
wxWindowBase *other) const |
747 |
{ |
748 |
// If the edge or dimension belongs to the parent, then we know the |
749 |
// dimension is obtainable immediately. E.g. a wxExpandSizer may contain a |
750 |
// button (but the button's true parent is a panel, not the sizer) |
751 |
if (other->GetChildren().Find((wxWindow*)thisWin)) |
752 |
{ |
753 |
switch (which) |
754 |
{ |
755 |
case wxLeft: |
756 |
{ |
757 |
return 0; |
758 |
} |
759 |
case wxTop: |
760 |
{ |
761 |
return 0; |
762 |
} |
763 |
case wxRight: |
764 |
{ |
765 |
int w, h; |
766 |
other->GetClientSizeConstraint(&w, &h); |
767 |
return w; |
768 |
} |
769 |
case wxBottom: |
770 |
{ |
771 |
int w, h; |
772 |
other->GetClientSizeConstraint(&w, &h); |
773 |
return h; |
774 |
} |
775 |
case wxWidth: |
776 |
{ |
777 |
int w, h; |
778 |
other->GetClientSizeConstraint(&w, &h); |
779 |
return w; |
780 |
} |
781 |
case wxHeight: |
782 |
{ |
783 |
int w, h; |
784 |
other->GetClientSizeConstraint(&w, &h); |
785 |
return h; |
786 |
} |
787 |
case wxCentreX: |
788 |
case wxCentreY: |
789 |
{ |
790 |
int w, h; |
791 |
other->GetClientSizeConstraint(&w, &h); |
792 |
if (which == wxCentreX) |
793 |
return (int)(w/2); |
794 |
else |
795 |
return (int)(h/2); |
796 |
} |
797 |
default: |
798 |
return -1; |
799 |
} |
800 |
} |
801 |
switch (which) |
802 |
{ |
803 |
case wxLeft: |
804 |
{ |
805 |
wxLayoutConstraints *constr = other->GetConstraints(); |
806 |
// If no constraints, it means the window is not dependent |
807 |
// on anything, and therefore we know its value immediately |
808 |
if (constr) |
809 |
{ |
810 |
if (constr->left.GetDone()) |
811 |
return constr->left.GetValue(); |
812 |
else |
813 |
return -1; |
814 |
} |
815 |
else |
816 |
{ |
817 |
int x, y; |
818 |
other->GetPosition(&x, &y); |
819 |
return x; |
820 |
} |
821 |
} |
822 |
case wxTop: |
823 |
{ |
824 |
wxLayoutConstraints *constr = other->GetConstraints(); |
825 |
// If no constraints, it means the window is not dependent |
826 |
// on anything, and therefore we know its value immediately |
827 |
if (constr) |
828 |
{ |
829 |
if (constr->top.GetDone()) |
830 |
return constr->top.GetValue(); |
831 |
else |
832 |
return -1; |
833 |
} |
834 |
else |
835 |
{ |
836 |
int x, y; |
837 |
other->GetPosition(&x, &y); |
838 |
return y; |
839 |
} |
840 |
} |
841 |
case wxRight: |
842 |
{ |
843 |
wxLayoutConstraints *constr = other->GetConstraints(); |
844 |
// If no constraints, it means the window is not dependent |
845 |
// on anything, and therefore we know its value immediately |
846 |
if (constr) |
847 |
{ |
848 |
if (constr->right.GetDone()) |
849 |
return constr->right.GetValue(); |
850 |
else |
851 |
return -1; |
852 |
} |
853 |
else |
854 |
{ |
855 |
int x, y, w, h; |
856 |
other->GetPosition(&x, &y); |
857 |
other->GetSize(&w, &h); |
858 |
return (int)(x + w); |
859 |
} |
860 |
} |
861 |
case wxBottom: |
862 |
{ |
863 |
wxLayoutConstraints *constr = other->GetConstraints(); |
864 |
// If no constraints, it means the window is not dependent |
865 |
// on anything, and therefore we know its value immediately |
866 |
if (constr) |
867 |
{ |
868 |
if (constr->bottom.GetDone()) |
869 |
return constr->bottom.GetValue(); |
870 |
else |
871 |
return -1; |
872 |
} |
873 |
else |
874 |
{ |
875 |
int x, y, w, h; |
876 |
other->GetPosition(&x, &y); |
877 |
other->GetSize(&w, &h); |
878 |
return (int)(y + h); |
879 |
} |
880 |
} |
881 |
case wxWidth: |
882 |
{ |
883 |
wxLayoutConstraints *constr = other->GetConstraints(); |
884 |
// If no constraints, it means the window is not dependent |
885 |
// on anything, and therefore we know its value immediately |
886 |
if (constr) |
887 |
{ |
888 |
if (constr->width.GetDone()) |
889 |
return constr->width.GetValue(); |
890 |
else |
891 |
return -1; |
892 |
} |
893 |
else |
894 |
{ |
895 |
int w, h; |
896 |
other->GetSize(&w, &h); |
897 |
return w; |
898 |
} |
899 |
} |
900 |
case wxHeight: |
901 |
{ |
902 |
wxLayoutConstraints *constr = other->GetConstraints(); |
903 |
// If no constraints, it means the window is not dependent |
904 |
// on anything, and therefore we know its value immediately |
905 |
if (constr) |
906 |
{ |
907 |
if (constr->height.GetDone()) |
908 |
return constr->height.GetValue(); |
909 |
else |
910 |
return -1; |
911 |
} |
912 |
else |
913 |
{ |
914 |
int w, h; |
915 |
other->GetSize(&w, &h); |
916 |
return h; |
917 |
} |
918 |
} |
919 |
case wxCentreX: |
920 |
{ |
921 |
wxLayoutConstraints *constr = other->GetConstraints(); |
922 |
// If no constraints, it means the window is not dependent |
923 |
// on anything, and therefore we know its value immediately |
924 |
if (constr) |
925 |
{ |
926 |
if (constr->centreX.GetDone()) |
927 |
return constr->centreX.GetValue(); |
928 |
else |
929 |
return -1; |
930 |
} |
931 |
else |
932 |
{ |
933 |
int x, y, w, h; |
934 |
other->GetPosition(&x, &y); |
935 |
other->GetSize(&w, &h); |
936 |
return (int)(x + (w/2)); |
937 |
} |
938 |
} |
939 |
case wxCentreY: |
940 |
{ |
941 |
wxLayoutConstraints *constr = other->GetConstraints(); |
942 |
// If no constraints, it means the window is not dependent |
943 |
// on anything, and therefore we know its value immediately |
944 |
if (constr) |
945 |
{ |
946 |
if (constr->centreY.GetDone()) |
947 |
return constr->centreY.GetValue(); |
948 |
else |
949 |
return -1; |
950 |
} |
951 |
else |
952 |
{ |
953 |
int x, y, w, h; |
954 |
other->GetPosition(&x, &y); |
955 |
other->GetSize(&w, &h); |
956 |
return (int)(y + (h/2)); |
957 |
} |
958 |
} |
959 |
default: |
960 |
break; |
961 |
} |
962 |
return -1; |
963 |
} |
964 |
|
965 |
wxLayoutConstraints::wxLayoutConstraints() |
966 |
{ |
967 |
left.SetEdge(wxLeft); |
968 |
top.SetEdge(wxTop); |
969 |
right.SetEdge(wxRight); |
970 |
bottom.SetEdge(wxBottom); |
971 |
centreX.SetEdge(wxCentreX); |
972 |
centreY.SetEdge(wxCentreY); |
973 |
width.SetEdge(wxWidth); |
974 |
height.SetEdge(wxHeight); |
975 |
} |
976 |
|
977 |
bool wxLayoutConstraints::SatisfyConstraints(wxWindowBase *win, int *nChanges) |
978 |
{ |
979 |
int noChanges = 0; |
980 |
|
981 |
bool done = width.GetDone(); |
982 |
bool newDone = (done ? true : width.SatisfyConstraint(this, win)); |
983 |
if (newDone != done) |
984 |
noChanges ++; |
985 |
|
986 |
done = height.GetDone(); |
987 |
newDone = (done ? true : height.SatisfyConstraint(this, win)); |
988 |
if (newDone != done) |
989 |
noChanges ++; |
990 |
|
991 |
done = left.GetDone(); |
992 |
newDone = (done ? true : left.SatisfyConstraint(this, win)); |
993 |
if (newDone != done) |
994 |
noChanges ++; |
995 |
|
996 |
done = top.GetDone(); |
997 |
newDone = (done ? true : top.SatisfyConstraint(this, win)); |
998 |
if (newDone != done) |
999 |
noChanges ++; |
1000 |
|
1001 |
done = right.GetDone(); |
1002 |
newDone = (done ? true : right.SatisfyConstraint(this, win)); |
1003 |
if (newDone != done) |
1004 |
noChanges ++; |
1005 |
|
1006 |
done = bottom.GetDone(); |
1007 |
newDone = (done ? true : bottom.SatisfyConstraint(this, win)); |
1008 |
if (newDone != done) |
1009 |
noChanges ++; |
1010 |
|
1011 |
done = centreX.GetDone(); |
1012 |
newDone = (done ? true : centreX.SatisfyConstraint(this, win)); |
1013 |
if (newDone != done) |
1014 |
noChanges ++; |
1015 |
|
1016 |
done = centreY.GetDone(); |
1017 |
newDone = (done ? true : centreY.SatisfyConstraint(this, win)); |
1018 |
if (newDone != done) |
1019 |
noChanges ++; |
1020 |
|
1021 |
*nChanges = noChanges; |
1022 |
|
1023 |
return AreSatisfied(); |
1024 |
} |
1025 |
|
1026 |
#endif // wxUSE_CONSTRAINTS |