-void wxIndividualLayoutConstraint::Set(wxRelationship rel, wxWindow *otherW, wxEdge otherE, int val, int marg)
-{
- relationship = rel; otherWin = otherW; otherEdge = otherE; value = val; margin = marg;
-}
-
-void wxIndividualLayoutConstraint::LeftOf(wxWindow *sibling, int marg)
-{ Set(wxLeftOf, sibling, wxLeft, 0, marg); }
-
-void wxIndividualLayoutConstraint::RightOf(wxWindow *sibling, int marg)
-{ Set(wxRightOf, sibling, wxRight, 0, marg); }
-
-void wxIndividualLayoutConstraint::Above(wxWindow *sibling, int marg)
-{ Set(wxAbove, sibling, wxTop, 0, marg); }
-
-void wxIndividualLayoutConstraint::Below(wxWindow *sibling, int marg)
-{ Set(wxBelow, sibling, wxBottom, 0, marg); }
-
-//
-// 'Same edge' alignment
-//
-void wxIndividualLayoutConstraint::SameAs(wxWindow *otherW, wxEdge edge, int marg)
-{ Set(wxPercentOf, otherW, edge, 0, marg); percent = 100; }
-
-// The edge is a percentage of the other window's edge
-void wxIndividualLayoutConstraint::PercentOf(wxWindow *otherW, wxEdge wh, int per)
-{ otherWin = otherW; relationship = wxPercentOf; percent = per;
- otherEdge = wh;
-}
-
-//
-// Edge has absolute value
-//
-void wxIndividualLayoutConstraint::Absolute(int val)
-{ value = val; relationship = wxAbsolute; }
-
-// Reset constraint if it mentions otherWin
-bool wxIndividualLayoutConstraint::ResetIfWin(wxWindow *otherW)
-{
- if (otherW == otherWin)
- {
- myEdge = wxTop; relationship = wxAsIs; margin = 0; value = 0; percent = 0; otherEdge = wxTop;
- otherWin = (wxWindow *) NULL;
- return TRUE;
- }
- else
- return FALSE;
-}
-
-// Try to satisfy constraint
-bool wxIndividualLayoutConstraint::SatisfyConstraint(wxLayoutConstraints *constraints, wxWindow *win)
-{
- if (relationship == wxAbsolute)
- {
- done = TRUE;
- return TRUE;
- }
-
- switch (myEdge)
- {
- case wxLeft:
- {
- switch (relationship)
- {
- case wxLeftOf:
- {
- // We can know this edge if: otherWin is win's parent,
- // or otherWin has a satisfied constraint, or
- // otherWin has no constraint.
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos - margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxRightOf:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos + margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxPercentOf:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = (int)(edgePos*(((float)percent)*0.01) + margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxUnconstrained:
- {
- // We know the left-hand edge position if we know
- // the right-hand edge and we know the width; OR if we know the centre and the width.
- if (constraints->right.GetDone() && constraints->width.GetDone())
- {
- value = (constraints->right.GetValue() - constraints->width.GetValue() + margin);
- done = TRUE;
- return TRUE;
- }
- else if (constraints->centreX.GetDone() && constraints->width.GetDone())
- {
- value = (int)(constraints->centreX.GetValue() - (constraints->width.GetValue()/2) + margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxAsIs:
- {
- int y;
- win->GetPosition(&value, &y);
- done = TRUE;
- return TRUE;
- }
- default:
- break;
- }
- break;
- }
- case wxRight:
- {
- switch (relationship)
- {
- case wxLeftOf:
- {
- // We can know this edge if: otherWin is win's parent,
- // or otherWin has a satisfied constraint, or
- // otherWin has no constraint.
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos - margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxRightOf:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos + margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxPercentOf:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = (int)(edgePos*(((float)percent)*0.01) - margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxUnconstrained:
- {
- // We know the right-hand edge position if we know
- // the left-hand edge and we know the width, OR if we know the
- // centre edge and the width.
- if (constraints->left.GetDone() && constraints->width.GetDone())
- {
- value = (constraints->left.GetValue() + constraints->width.GetValue() - margin);
- done = TRUE;
- return TRUE;
- }
- else if (constraints->centreX.GetDone() && constraints->width.GetDone())
- {
- value = (int)(constraints->centreX.GetValue() + (constraints->width.GetValue()/2) - margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxAsIs:
- {
- int x, y;
- int w, h;
- win->GetSize(&w, &h);
- win->GetPosition(&x, &y);
- value = x + w;
- done = TRUE;
- return TRUE;
- }
- default:
- break;
- }
- break;
- }
- case wxTop:
- {
- switch (relationship)
- {
- case wxAbove:
- {
- // We can know this edge if: otherWin is win's parent,
- // or otherWin has a satisfied constraint, or
- // otherWin has no constraint.
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos - margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxBelow:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos + margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxPercentOf:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = (int)(edgePos*(((float)percent)*0.01) + margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxUnconstrained:
- {
- // We know the top edge position if we know
- // the bottom edge and we know the height; OR if we know the centre
- // edge and the height.
- if (constraints->bottom.GetDone() && constraints->height.GetDone())
- {
- value = (constraints->bottom.GetValue() - constraints->height.GetValue() + margin);
- done = TRUE;
- return TRUE;
- }
- else if (constraints->centreY.GetDone() && constraints->height.GetDone())
- {
- value = (constraints->centreY.GetValue() - (constraints->height.GetValue()/2) + margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxAsIs:
- {
- int x;
- win->GetPosition(&x, &value);
- done = TRUE;
- return TRUE;
- }
- default:
- break;
- }
- break;
- }
- case wxBottom:
- {
- switch (relationship)
- {
- case wxAbove:
- {
- // We can know this edge if: otherWin is win's parent,
- // or otherWin has a satisfied constraint, or
- // otherWin has no constraint.
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos + margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxBelow:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos - margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxPercentOf:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = (int)(edgePos*(((float)percent)*0.01) - margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxUnconstrained:
- {
- // We know the bottom edge position if we know
- // the top edge and we know the height; OR if we know the
- // centre edge and the height.
- if (constraints->top.GetDone() && constraints->height.GetDone())
- {
- value = (constraints->top.GetValue() + constraints->height.GetValue() - margin);
- done = TRUE;
- return TRUE;
- }
- else if (constraints->centreY.GetDone() && constraints->height.GetDone())
- {
- value = (constraints->centreY.GetValue() + (constraints->height.GetValue()/2) - margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxAsIs:
- {
- int x, y;
- int w, h;
- win->GetSize(&w, &h);
- win->GetPosition(&x, &y);
- value = h + y;
- done = TRUE;
- return TRUE;
- }
- default:
- break;
- }
- break;
- }
- case wxCentreX:
- {
- switch (relationship)
- {
- case wxLeftOf:
- {
- // We can know this edge if: otherWin is win's parent,
- // or otherWin has a satisfied constraint, or
- // otherWin has no constraint.
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos - margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxRightOf:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos + margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxPercentOf:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = (int)(edgePos*(((float)percent)*0.01) + margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxUnconstrained:
- {
- // We know the centre position if we know
- // the left-hand edge and we know the width, OR
- // the right-hand edge and the width
- if (constraints->left.GetDone() && constraints->width.GetDone())
- {
- value = (int)(constraints->left.GetValue() + (constraints->width.GetValue()/2) + margin);
- done = TRUE;
- return TRUE;
- }
- else if (constraints->right.GetDone() && constraints->width.GetDone())
- {
- value = (int)(constraints->left.GetValue() - (constraints->width.GetValue()/2) + margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- default:
- break;
- }
- break;
- }
- case wxCentreY:
- {
- switch (relationship)
- {
- case wxAbove:
- {
- // We can know this edge if: otherWin is win's parent,
- // or otherWin has a satisfied constraint, or
- // otherWin has no constraint.
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos - margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxBelow:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = edgePos + margin;
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxPercentOf:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = (int)(edgePos*(((float)percent)*0.01) + margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxUnconstrained:
- {
- // We know the centre position if we know
- // the top edge and we know the height, OR
- // the bottom edge and the height.
- if (constraints->bottom.GetDone() && constraints->height.GetDone())
- {
- value = (int)(constraints->bottom.GetValue() - (constraints->height.GetValue()/2) + margin);
- done = TRUE;
- return TRUE;
- }
- else if (constraints->top.GetDone() && constraints->height.GetDone())
- {
- value = (int)(constraints->top.GetValue() + (constraints->height.GetValue()/2) + margin);
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- default:
- break;
- }
- break;
- }
- case wxWidth:
- {
- switch (relationship)
- {
- case wxPercentOf:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = (int)(edgePos*(((float)percent)*0.01));
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxAsIs:
- {
- if (win)
- {
- int h;
- win->GetSize(&value, &h);
- done = TRUE;
- return TRUE;
- }
- else return FALSE;
- }
- case wxUnconstrained:
- {
- // We know the width if we know the left edge and the right edge, OR
- // if we know the left edge and the centre, OR
- // if we know the right edge and the centre
- if (constraints->left.GetDone() && constraints->right.GetDone())
- {
- value = constraints->right.GetValue() - constraints->left.GetValue();
- done = TRUE;
- return TRUE;
- }
- else if (constraints->centreX.GetDone() && constraints->left.GetDone())
- {
- value = (int)(2*(constraints->centreX.GetValue() - constraints->left.GetValue()));
- done = TRUE;
- return TRUE;
- }
- else if (constraints->centreX.GetDone() && constraints->right.GetDone())
- {
- value = (int)(2*(constraints->right.GetValue() - constraints->centreX.GetValue()));
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- default:
- break;
- }
- break;
- }
- case wxHeight:
- {
- switch (relationship)
- {
- case wxPercentOf:
- {
- int edgePos = GetEdge(otherEdge, win, otherWin);
- if (edgePos != -1)
- {
- value = (int)(edgePos*(((float)percent)*0.01));
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- case wxAsIs:
- {
- if (win)
- {
- int w;
- win->GetSize(&w, &value);
- done = TRUE;
- return TRUE;
- }
- else return FALSE;
- }
- case wxUnconstrained:
- {
- // We know the height if we know the top edge and the bottom edge, OR
- // if we know the top edge and the centre, OR
- // if we know the bottom edge and the centre
- if (constraints->top.GetDone() && constraints->bottom.GetDone())
- {
- value = constraints->bottom.GetValue() - constraints->top.GetValue();
- done = TRUE;
- return TRUE;
- }
- else if (constraints->top.GetDone() && constraints->centreY.GetDone())
- {
- value = (int)(2*(constraints->centreY.GetValue() - constraints->top.GetValue()));
- done = TRUE;
- return TRUE;
- }
- else if (constraints->bottom.GetDone() && constraints->centreY.GetDone())
- {
- value = (int)(2*(constraints->bottom.GetValue() - constraints->centreY.GetValue()));
- done = TRUE;
- return TRUE;
- }
- else
- return FALSE;
- }
- default:
- break;
- }
- break;
- }
- default:
- break;
- }
- return FALSE;
-}
-
-// Get the value of this edge or dimension, or if this
-// is not determinable, -1.
-int wxIndividualLayoutConstraint::GetEdge(wxEdge which,
- wxWindow *thisWin,
- wxWindow *other) const
-{
- // If the edge or dimension belongs to the parent, then we
- // know the dimension is obtainable immediately.
- // E.g. a wxExpandSizer may contain a button (but the button's
- // true parent is a panel, not the sizer)
- if (other->GetChildren()->Member(thisWin))
- {
- switch (which)
- {
- case wxLeft:
- {
- return wxSizerMarginX(other);
- }
- case wxTop:
- {
- return wxSizerMarginY(other);
- }
- case wxRight:
- {
- int w, h;
- other->GetClientSizeConstraint(&w, &h);
- return w - wxSizerMarginX(other);
- }
- case wxBottom:
- {
- int w, h;
- other->GetClientSizeConstraint(&w, &h);
- return h - wxSizerMarginY(other);
- }
- case wxWidth:
- {
- int w, h;
- other->GetClientSizeConstraint(&w, &h);
- return w - 2*wxSizerMarginX(other);
- }
- case wxHeight:
- {
- int w, h;
- other->GetClientSizeConstraint(&w, &h);
- return h - 2*wxSizerMarginY(other);
- }
- case wxCentreX:
- case wxCentreY:
- {
- int w, h;
- other->GetClientSizeConstraint(&w, &h);
- if (which == wxCentreX)
- return (int)(w/2);
- else
- return (int)(h/2);
- }
- default:
- return -1;
- }
- }
- switch (which)
- {
- case wxLeft:
- {
- wxLayoutConstraints *constr = other->GetConstraints();
- // If no constraints, it means the window is not dependent
- // on anything, and therefore we know its value immediately
- if (constr)
- {
- if (constr->left.GetDone())
- return constr->left.GetValue();
- else
- return -1;
- }
- else
- {
- int x, y;
- other->GetPosition(&x, &y);
- return x;
- }
- }
- case wxTop:
- {
- wxLayoutConstraints *constr = other->GetConstraints();
- // If no constraints, it means the window is not dependent
- // on anything, and therefore we know its value immediately
- if (constr)
- {
- if (constr->top.GetDone())
- return constr->top.GetValue();
- else
- return -1;
- }
- else
- {
- int x, y;
- other->GetPosition(&x, &y);
- return y;
- }
- }
- case wxRight:
- {
- wxLayoutConstraints *constr = other->GetConstraints();
- // If no constraints, it means the window is not dependent
- // on anything, and therefore we know its value immediately
- if (constr)
- {
- if (constr->right.GetDone())
- return constr->right.GetValue();
- else
- return -1;
- }
- else
- {
- int x, y, w, h;
- other->GetPosition(&x, &y);
- other->GetSize(&w, &h);
- return (int)(x + w);
- }
- }
- case wxBottom:
- {
- wxLayoutConstraints *constr = other->GetConstraints();
- // If no constraints, it means the window is not dependent
- // on anything, and therefore we know its value immediately
- if (constr)
- {
- if (constr->bottom.GetDone())
- return constr->bottom.GetValue();
- else
- return -1;
- }
- else
- {
- int x, y, w, h;
- other->GetPosition(&x, &y);
- other->GetSize(&w, &h);
- return (int)(y + h);
- }
- }
- case wxWidth:
- {
- wxLayoutConstraints *constr = other->GetConstraints();
- // If no constraints, it means the window is not dependent
- // on anything, and therefore we know its value immediately
- if (constr)
- {
- if (constr->width.GetDone())
- return constr->width.GetValue();
- else
- return -1;
- }
- else
- {
- int w, h;
- other->GetSize(&w, &h);
- return w;
- }
- }
- case wxHeight:
- {
- wxLayoutConstraints *constr = other->GetConstraints();
- // If no constraints, it means the window is not dependent
- // on anything, and therefore we know its value immediately
- if (constr)
- {
- if (constr->height.GetDone())
- return constr->height.GetValue();
- else
- return -1;
- }
- else
- {
- int w, h;
- other->GetSize(&w, &h);
- return h;
- }
- }
- case wxCentreX:
- {
- wxLayoutConstraints *constr = other->GetConstraints();
- // If no constraints, it means the window is not dependent
- // on anything, and therefore we know its value immediately
- if (constr)
- {
- if (constr->centreX.GetDone())
- return constr->centreX.GetValue();
- else
- return -1;
- }
- else
- {
- int x, y, w, h;
- other->GetPosition(&x, &y);
- other->GetSize(&w, &h);
- return (int)(x + (w/2));
- }
- }
- case wxCentreY:
- {
- wxLayoutConstraints *constr = other->GetConstraints();
- // If no constraints, it means the window is not dependent
- // on anything, and therefore we know its value immediately
- if (constr)
- {
- if (constr->centreY.GetDone())
- return constr->centreY.GetValue();
- else
- return -1;
- }
- else
- {
- int x, y, w, h;
- other->GetPosition(&x, &y);
- other->GetSize(&w, &h);
- return (int)(y + (h/2));
- }
- }
- default:
- break;
- }
- return -1;
-}
-
-wxLayoutConstraints::wxLayoutConstraints()
-{
- left.SetEdge(wxLeft);
- top.SetEdge(wxTop);
- right.SetEdge(wxRight);
- bottom.SetEdge(wxBottom);
- centreX.SetEdge(wxCentreX);
- centreY.SetEdge(wxCentreY);
- width.SetEdge(wxWidth);
- height.SetEdge(wxHeight);
-}
-
-wxLayoutConstraints::~wxLayoutConstraints()
-{
-}
-
-bool wxLayoutConstraints::SatisfyConstraints(wxWindow *win, int *nChanges)
-{
- int noChanges = 0;
-
- bool done = width.GetDone();
- bool newDone = (done ? TRUE : width.SatisfyConstraint(this, win));
- if (newDone != done)
- noChanges ++;
-
- done = height.GetDone();
- newDone = (done ? TRUE : height.SatisfyConstraint(this, win));
- if (newDone != done)
- noChanges ++;
-
- done = left.GetDone();
- newDone = (done ? TRUE : left.SatisfyConstraint(this, win));
- if (newDone != done)
- noChanges ++;
-
- done = top.GetDone();
- newDone = (done ? TRUE : top.SatisfyConstraint(this, win));
- if (newDone != done)
- noChanges ++;
-
- done = right.GetDone();
- newDone = (done ? TRUE : right.SatisfyConstraint(this, win));
- if (newDone != done)
- noChanges ++;
-
- done = bottom.GetDone();
- newDone = (done ? TRUE : bottom.SatisfyConstraint(this, win));
- if (newDone != done)
- noChanges ++;
-
- done = centreX.GetDone();
- newDone = (done ? TRUE : centreX.SatisfyConstraint(this, win));
- if (newDone != done)
- noChanges ++;
-
- done = centreY.GetDone();
- newDone = (done ? TRUE : centreY.SatisfyConstraint(this, win));
- if (newDone != done)
- noChanges ++;
-
- *nChanges = noChanges;
-
- return AreSatisfied();
-}
-
-/*
- * Main constrained layout algorithm. Look at all the child
- * windows, and their constraints (if any).
- * The idea is to keep iterating through the constraints
- * until all left, right, bottom and top edges, and widths and heights,
- * are known (or no change occurs and we've failed to resolve all
- * constraints).
- *
- * If the user has not specified a dimension or edge, it will be
- * be calculated from the other known values. E.g. If we know
- * the right hand edge and the left hand edge, we now know the width.
- * The snag here is that this means we must specify absolute dimensions
- * twice (in constructor and in constraint), if we wish to use the
- * constraint notation to just set the position, for example.
- * Otherwise, if we only set ONE edge and no dimension, it would never
- * find the other edge.
- *
- * Algorithm:
-
- Mark all constraints as not done.
-
- iterations = 0;
- until no change or iterations >= max iterations
- For each child:
- {
- Calculate all constraints
- }
- iterations ++;
-
- For each child
- Set each calculated position and size
-
- */
-
-bool wxOldDoLayout(wxWindow *win)