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