+// ----------------------------------------------------------------------------
+// update region testing
+// ----------------------------------------------------------------------------
+
+bool wxWindowBase::IsExposed(int x, int y) const
+{
+ return m_updateRegion.Contains(x, y) != wxOutRegion;
+}
+
+bool wxWindowBase::IsExposed(int x, int y, int w, int h) const
+{
+ return m_updateRegion.Contains(x, y, w, h) != wxOutRegion;
+}
+
+// ----------------------------------------------------------------------------
+// find window by id or name
+// ----------------------------------------------------------------------------
+
+wxWindow *wxWindowBase::FindWindow( long id )
+{
+ if ( id == m_windowId )
+ return (wxWindow *)this;
+
+ wxWindowBase *res = (wxWindow *)NULL;
+ wxWindowList::Node *node;
+ for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
+ {
+ wxWindowBase *child = node->GetData();
+ res = child->FindWindow( id );
+ }
+
+ return (wxWindow *)res;
+}
+
+wxWindow *wxWindowBase::FindWindow( const wxString& name )
+{
+ if ( name == m_windowName )
+ return (wxWindow *)this;
+
+ wxWindowBase *res = (wxWindow *)NULL;
+ wxWindowList::Node *node;
+ for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
+ {
+ wxWindow *child = node->GetData();
+ res = child->FindWindow(name);
+ }
+
+ return (wxWindow *)res;
+}
+
+// ----------------------------------------------------------------------------
+// dialog oriented functions
+// ----------------------------------------------------------------------------
+
+void wxWindowBase::MakeModal(bool modal)
+{
+ // Disable all other windows
+ if ( IsTopLevel() )
+ {
+ wxWindowList::Node *node = wxTopLevelWindows.GetFirst();
+ while (node)
+ {
+ wxWindow *win = node->GetData();
+ if (win != this)
+ win->Enable(!modal);
+
+ node = node->GetNext();
+ }
+ }
+}
+
+bool wxWindowBase::Validate()
+{
+#if wxUSE_VALIDATORS
+ wxWindowList::Node *node;
+ for ( node = m_children.GetFirst(); node; node = node->GetNext() )
+ {
+ wxWindowBase *child = node->GetData();
+ wxValidator *validator = child->GetValidator();
+ if ( validator && !validator->Validate((wxWindow *)this) )
+ {
+ return FALSE;
+ }
+ }
+#endif // wxUSE_VALIDATORS
+
+ return TRUE;
+}
+
+bool wxWindowBase::TransferDataToWindow()
+{
+#if wxUSE_VALIDATORS
+ wxWindowList::Node *node;
+ for ( node = m_children.GetFirst(); node; node = node->GetNext() )
+ {
+ wxWindowBase *child = node->GetData();
+ wxValidator *validator = child->GetValidator();
+ if ( validator && !validator->TransferToWindow() )
+ {
+ wxLog *log = wxLog::GetActiveTarget();
+ if ( log )
+ {
+ wxLogWarning(_("Could not transfer data to window"));
+ log->Flush();
+ }
+
+ return FALSE;
+ }
+ }
+#endif // wxUSE_VALIDATORS
+
+ return TRUE;
+}
+
+bool wxWindowBase::TransferDataFromWindow()
+{
+#if wxUSE_VALIDATORS
+ wxWindowList::Node *node;
+ for ( node = m_children.GetFirst(); node; node = node->GetNext() )
+ {
+ wxWindow *child = node->GetData();
+ if ( child->GetValidator() &&
+ !child->GetValidator()->TransferFromWindow() )
+ {
+ return FALSE;
+ }
+ }
+#endif // wxUSE_VALIDATORS
+
+ return TRUE;
+}
+
+void wxWindowBase::InitDialog()
+{
+ wxInitDialogEvent event(GetId());
+ event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent(event);
+}
+
+// ----------------------------------------------------------------------------
+// tooltips
+// ----------------------------------------------------------------------------
+
+#if wxUSE_TOOLTIPS
+
+void wxWindowBase::SetToolTip( const wxString &tip )
+{
+ // don't create the new tooltip if we already have one
+ if ( m_tooltip )
+ {
+ m_tooltip->SetTip( tip );
+ }
+ else
+ {
+ SetToolTip( new wxToolTip( tip ) );
+ }
+
+ // setting empty tooltip text does not remove the tooltip any more - use
+ // SetToolTip((wxToolTip *)NULL) for this
+}
+
+void wxWindowBase::DoSetToolTip(wxToolTip *tooltip)
+{
+ if ( m_tooltip )
+ delete m_tooltip;
+
+ m_tooltip = tooltip;
+}
+
+#endif // wxUSE_TOOLTIPS
+
+// ----------------------------------------------------------------------------
+// constraints and sizers
+// ----------------------------------------------------------------------------
+
+#if wxUSE_CONSTRAINTS
+
+void wxWindowBase::SetConstraints( wxLayoutConstraints *constraints )
+{
+ if ( m_constraints )
+ {
+ UnsetConstraints(m_constraints);
+ delete m_constraints;
+ }
+ m_constraints = constraints;
+ if ( m_constraints )
+ {
+ // Make sure other windows know they're part of a 'meaningful relationship'
+ if ( m_constraints->left.GetOtherWindow() && (m_constraints->left.GetOtherWindow() != this) )
+ m_constraints->left.GetOtherWindow()->AddConstraintReference(this);
+ if ( m_constraints->top.GetOtherWindow() && (m_constraints->top.GetOtherWindow() != this) )
+ m_constraints->top.GetOtherWindow()->AddConstraintReference(this);
+ if ( m_constraints->right.GetOtherWindow() && (m_constraints->right.GetOtherWindow() != this) )
+ m_constraints->right.GetOtherWindow()->AddConstraintReference(this);
+ if ( m_constraints->bottom.GetOtherWindow() && (m_constraints->bottom.GetOtherWindow() != this) )
+ m_constraints->bottom.GetOtherWindow()->AddConstraintReference(this);
+ if ( m_constraints->width.GetOtherWindow() && (m_constraints->width.GetOtherWindow() != this) )
+ m_constraints->width.GetOtherWindow()->AddConstraintReference(this);
+ if ( m_constraints->height.GetOtherWindow() && (m_constraints->height.GetOtherWindow() != this) )
+ m_constraints->height.GetOtherWindow()->AddConstraintReference(this);
+ if ( m_constraints->centreX.GetOtherWindow() && (m_constraints->centreX.GetOtherWindow() != this) )
+ m_constraints->centreX.GetOtherWindow()->AddConstraintReference(this);
+ if ( m_constraints->centreY.GetOtherWindow() && (m_constraints->centreY.GetOtherWindow() != this) )
+ m_constraints->centreY.GetOtherWindow()->AddConstraintReference(this);
+ }
+}
+
+// This removes any dangling pointers to this window in other windows'
+// constraintsInvolvedIn lists.
+void wxWindowBase::UnsetConstraints(wxLayoutConstraints *c)
+{
+ if ( c )
+ {
+ if ( c->left.GetOtherWindow() && (c->top.GetOtherWindow() != this) )
+ c->left.GetOtherWindow()->RemoveConstraintReference(this);
+ if ( c->top.GetOtherWindow() && (c->top.GetOtherWindow() != this) )
+ c->top.GetOtherWindow()->RemoveConstraintReference(this);
+ if ( c->right.GetOtherWindow() && (c->right.GetOtherWindow() != this) )
+ c->right.GetOtherWindow()->RemoveConstraintReference(this);
+ if ( c->bottom.GetOtherWindow() && (c->bottom.GetOtherWindow() != this) )
+ c->bottom.GetOtherWindow()->RemoveConstraintReference(this);
+ if ( c->width.GetOtherWindow() && (c->width.GetOtherWindow() != this) )
+ c->width.GetOtherWindow()->RemoveConstraintReference(this);
+ if ( c->height.GetOtherWindow() && (c->height.GetOtherWindow() != this) )
+ c->height.GetOtherWindow()->RemoveConstraintReference(this);
+ if ( c->centreX.GetOtherWindow() && (c->centreX.GetOtherWindow() != this) )
+ c->centreX.GetOtherWindow()->RemoveConstraintReference(this);
+ if ( c->centreY.GetOtherWindow() && (c->centreY.GetOtherWindow() != this) )
+ c->centreY.GetOtherWindow()->RemoveConstraintReference(this);
+ }
+}
+
+// Back-pointer to other windows we're involved with, so if we delete this
+// window, we must delete any constraints we're involved with.
+void wxWindowBase::AddConstraintReference(wxWindowBase *otherWin)
+{
+ if ( !m_constraintsInvolvedIn )
+ m_constraintsInvolvedIn = new wxWindowList;
+ if ( !m_constraintsInvolvedIn->Find(otherWin) )
+ m_constraintsInvolvedIn->Append(otherWin);
+}
+
+// REMOVE back-pointer to other windows we're involved with.
+void wxWindowBase::RemoveConstraintReference(wxWindowBase *otherWin)
+{
+ if ( m_constraintsInvolvedIn )
+ m_constraintsInvolvedIn->DeleteObject(otherWin);
+}
+
+// Reset any constraints that mention this window
+void wxWindowBase::DeleteRelatedConstraints()
+{
+ if ( m_constraintsInvolvedIn )
+ {
+ wxWindowList::Node *node = m_constraintsInvolvedIn->GetFirst();
+ while (node)
+ {
+ wxWindow *win = node->GetData();
+ wxLayoutConstraints *constr = win->GetConstraints();
+
+ // Reset any constraints involving this window
+ if ( constr )
+ {
+ constr->left.ResetIfWin(this);
+ constr->top.ResetIfWin(this);
+ constr->right.ResetIfWin(this);
+ constr->bottom.ResetIfWin(this);
+ constr->width.ResetIfWin(this);
+ constr->height.ResetIfWin(this);
+ constr->centreX.ResetIfWin(this);
+ constr->centreY.ResetIfWin(this);
+ }
+
+ wxWindowList::Node *next = node->GetNext();
+ delete node;
+ node = next;
+ }
+
+ delete m_constraintsInvolvedIn;
+ m_constraintsInvolvedIn = (wxWindowList *) NULL;
+ }
+}
+
+void wxWindowBase::SetSizer(wxSizer *sizer)
+{
+ if (m_windowSizer) delete m_windowSizer;
+
+ m_windowSizer = sizer;
+}
+
+bool wxWindowBase::Layout()
+{
+ int w, h;
+ GetClientSize(&w, &h);
+
+ // If there is a sizer, use it instead of the constraints
+ if ( GetSizer() )
+ {
+ GetSizer()->SetDimension( 0, 0, w, h );
+ return TRUE;
+ }
+
+ if ( GetConstraints() )
+ {
+ GetConstraints()->width.SetValue(w);
+ GetConstraints()->height.SetValue(h);
+ }
+
+ // Evaluate child constraints
+ ResetConstraints(); // Mark all constraints as unevaluated
+ DoPhase(1); // Just one phase need if no sizers involved
+ DoPhase(2);
+ SetConstraintSizes(); // Recursively set the real window sizes
+
+ return TRUE;
+}
+
+
+// Do a phase of evaluating constraints: the default behaviour. wxSizers may
+// do a similar thing, but also impose their own 'constraints' and order the
+// evaluation differently.
+bool wxWindowBase::LayoutPhase1(int *noChanges)
+{
+ wxLayoutConstraints *constr = GetConstraints();
+ if ( constr )
+ {
+ return constr->SatisfyConstraints(this, noChanges);
+ }
+ else
+ return TRUE;
+}
+
+bool wxWindowBase::LayoutPhase2(int *noChanges)
+{
+ *noChanges = 0;
+
+ // Layout children
+ DoPhase(1);
+ DoPhase(2);
+ return TRUE;
+}
+
+// Do a phase of evaluating child constraints
+bool wxWindowBase::DoPhase(int phase)
+{
+ int noIterations = 0;
+ int maxIterations = 500;
+ int noChanges = 1;
+ int noFailures = 0;
+ wxWindowList succeeded;
+ while ((noChanges > 0) && (noIterations < maxIterations))
+ {
+ noChanges = 0;
+ noFailures = 0;
+ wxWindowList::Node *node = GetChildren().GetFirst();
+ while (node)
+ {
+ wxWindow *child = node->GetData();
+ if ( !child->IsTopLevel() )
+ {
+ wxLayoutConstraints *constr = child->GetConstraints();
+ if ( constr )
+ {
+ if ( !succeeded.Find(child) )
+ {
+ int tempNoChanges = 0;
+ bool success = ( (phase == 1) ? child->LayoutPhase1(&tempNoChanges) : child->LayoutPhase2(&tempNoChanges) ) ;
+ noChanges += tempNoChanges;
+ if ( success )
+ {
+ succeeded.Append(child);
+ }
+ }
+ }
+ }
+ node = node->GetNext();
+ }
+
+ noIterations++;
+ }
+
+ return TRUE;
+}
+
+void wxWindowBase::ResetConstraints()
+{
+ wxLayoutConstraints *constr = GetConstraints();
+ if ( constr )
+ {
+ constr->left.SetDone(FALSE);
+ constr->top.SetDone(FALSE);
+ constr->right.SetDone(FALSE);
+ constr->bottom.SetDone(FALSE);
+ constr->width.SetDone(FALSE);
+ constr->height.SetDone(FALSE);
+ constr->centreX.SetDone(FALSE);
+ constr->centreY.SetDone(FALSE);
+ }
+ wxWindowList::Node *node = GetChildren().GetFirst();
+ while (node)
+ {
+ wxWindow *win = node->GetData();
+ if ( !win->IsTopLevel() )
+ win->ResetConstraints();
+ node = node->GetNext();
+ }
+}
+
+// Need to distinguish between setting the 'fake' size for windows and sizers,
+// and setting the real values.
+void wxWindowBase::SetConstraintSizes(bool recurse)
+{
+ wxLayoutConstraints *constr = GetConstraints();
+ if ( constr && constr->left.GetDone() && constr->right.GetDone( ) &&
+ constr->width.GetDone() && constr->height.GetDone())
+ {
+ int x = constr->left.GetValue();
+ int y = constr->top.GetValue();
+ int w = constr->width.GetValue();
+ int h = constr->height.GetValue();
+
+ if ( (constr->width.GetRelationship() != wxAsIs ) ||
+ (constr->height.GetRelationship() != wxAsIs) )
+ {
+ SetSize(x, y, w, h);
+ }
+ else
+ {
+ // If we don't want to resize this window, just move it...
+ Move(x, y);
+ }
+ }
+ else if ( constr )
+ {
+ wxChar *windowClass = GetClassInfo()->GetClassName();
+
+ wxString winName;
+ if ( GetName() == wxT("") )
+ winName = wxT("unnamed");
+ else
+ winName = GetName();
+ wxLogDebug( wxT("Constraint(s) not satisfied for window of type %s, name %s:\n"),
+ (const wxChar *)windowClass,
+ (const wxChar *)winName);
+ if ( !constr->left.GetDone()) wxLogDebug( wxT(" unsatisfied 'left' constraint.\n") );
+ if ( !constr->right.GetDone()) wxLogDebug( wxT(" unsatisfied 'right' constraint.\n") );
+ if ( !constr->width.GetDone()) wxLogDebug( wxT(" unsatisfied 'width' constraint.\n") );
+ if ( !constr->height.GetDone()) wxLogDebug( wxT(" unsatisfied 'height' constraint.\n") );
+ wxLogDebug( wxT("Please check constraints: try adding AsIs() constraints.\n") );
+ }
+
+ if ( recurse )
+ {
+ wxWindowList::Node *node = GetChildren().GetFirst();
+ while (node)
+ {
+ wxWindow *win = node->GetData();
+ if ( !win->IsTopLevel() )
+ win->SetConstraintSizes();
+ node = node->GetNext();
+ }
+ }
+}
+
+// Only set the size/position of the constraint (if any)
+void wxWindowBase::SetSizeConstraint(int x, int y, int w, int h)
+{
+ wxLayoutConstraints *constr = GetConstraints();
+ if ( constr )
+ {
+ if ( x != -1 )
+ {
+ constr->left.SetValue(x);
+ constr->left.SetDone(TRUE);
+ }
+ if ( y != -1 )
+ {
+ constr->top.SetValue(y);
+ constr->top.SetDone(TRUE);
+ }
+ if ( w != -1 )
+ {
+ constr->width.SetValue(w);
+ constr->width.SetDone(TRUE);
+ }
+ if ( h != -1 )
+ {
+ constr->height.SetValue(h);
+ constr->height.SetDone(TRUE);
+ }
+ }
+}
+
+void wxWindowBase::MoveConstraint(int x, int y)
+{
+ wxLayoutConstraints *constr = GetConstraints();
+ if ( constr )
+ {
+ if ( x != -1 )
+ {
+ constr->left.SetValue(x);
+ constr->left.SetDone(TRUE);
+ }
+ if ( y != -1 )
+ {
+ constr->top.SetValue(y);
+ constr->top.SetDone(TRUE);
+ }
+ }
+}
+
+void wxWindowBase::GetSizeConstraint(int *w, int *h) const
+{
+ wxLayoutConstraints *constr = GetConstraints();
+ if ( constr )
+ {
+ *w = constr->width.GetValue();
+ *h = constr->height.GetValue();
+ }
+ else
+ GetSize(w, h);
+}
+
+void wxWindowBase::GetClientSizeConstraint(int *w, int *h) const
+{
+ wxLayoutConstraints *constr = GetConstraints();
+ if ( constr )
+ {
+ *w = constr->width.GetValue();
+ *h = constr->height.GetValue();
+ }
+ else
+ GetClientSize(w, h);
+}
+
+void wxWindowBase::GetPositionConstraint(int *x, int *y) const
+{
+ wxLayoutConstraints *constr = GetConstraints();
+ if ( constr )
+ {
+ *x = constr->left.GetValue();
+ *y = constr->top.GetValue();
+ }
+ else
+ GetPosition(x, y);
+}
+
+#endif // wxUSE_CONSTRAINTS
+
+// ----------------------------------------------------------------------------
+// do Update UI processing for child controls
+// ----------------------------------------------------------------------------