]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
wxWindow::Fit() infinite loop bug fixed
[wxWidgets.git] / src / common / wincmn.cpp
index 153a0408afaeed3b02aab2982ae1e799cf05f6a5..87709ad66a4b3dcc167a3a3f55fcca2783800481 100644 (file)
     #include "wx/tooltip.h"
 #endif // wxUSE_TOOLTIPS
 
+#if wxUSE_CARET
+    #include "wx/caret.h"
+#endif // wxUSE_CARET
+
 // ----------------------------------------------------------------------------
 // static data
 // ----------------------------------------------------------------------------
 
-int wxWindowBase::ms_lastControlId = -2;
+int wxWindowBase::ms_lastControlId = -200;
 
 IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler)
 
@@ -103,8 +107,10 @@ void wxWindowBase::InitBase()
     // the default event handler is just this window
     m_eventHandler = this;
 
+#if wxUSE_VALIDATORS
     // no validator
     m_windowValidator = (wxValidator *) NULL;
+#endif // wxUSE_VALIDATORS
 
     // use the system default colours
     wxSystemSettings settings;
@@ -136,6 +142,10 @@ void wxWindowBase::InitBase()
 #if wxUSE_TOOLTIPS
     m_tooltip = (wxToolTip *)NULL;
 #endif // wxUSE_TOOLTIPS
+
+#if wxUSE_CARET
+    m_caret = (wxCaret *)NULL;
+#endif // wxUSE_CARET
 }
 
 // common part of window creation process
@@ -178,11 +188,18 @@ wxWindowBase::~wxWindowBase()
     // Just in case we've loaded a top-level window via LoadNativeDialog but
     // we weren't a dialog class
     wxTopLevelWindows.DeleteObject(this);
-    
-    wxASSERT_MSG( GetChildren().GetCount() == 0, "children not destroyed" );
 
+    wxASSERT_MSG( GetChildren().GetCount() == 0, _T("children not destroyed") );
+
+#if wxUSE_CARET
+    if ( m_caret )
+        delete m_caret;
+#endif // wxUSE_CARET
+
+#if wxUSE_VALIDATORS
     if ( m_windowValidator )
         delete m_windowValidator;
+#endif // wxUSE_VALIDATORS
 
     if ( m_clientObject )
         delete m_clientObject;
@@ -244,15 +261,21 @@ bool wxWindowBase::Close(bool force)
 bool wxWindowBase::DestroyChildren()
 {
     wxWindowList::Node *node;
-    while ( (node = GetChildren().GetFirst()) )
+    for ( ;; )
     {
+        // we iterate until the list becomes empty
+        node = GetChildren().GetFirst();
+        if ( !node )
+            break;
+
         wxWindow *child = node->GetData();
-       
-       wxASSERT_MSG( child, "m_children contains empty nodes" );
-       
+
+        wxASSERT_MSG( child, _T("children list contains empty nodes") );
+
         delete child;
-       
-        wxASSERT_MSG( !GetChildren().Find(child), "child didn't remove itself using RemoveChild()" );
+
+        wxASSERT_MSG( !GetChildren().Find(child),
+                      _T("child didn't remove itself using RemoveChild()") );
     }
 
     return TRUE;
@@ -293,16 +316,52 @@ void wxWindowBase::Centre(int direction)
     Move(new_x, new_y);
 }
 
+// Center TopLevel windows over thier parent instead of the whole screen
+void wxWindowBase::CentreOnParent(int direction)
+{
+    wxPoint     ppos;
+    wxSize      psze;
+    wxSize      wsze;
+    wxWindow*   parent = GetParent();
+    int         x, y;
+
+    if (!parent || !IsTopLevel()) {
+        Centre(direction);
+        return;
+    }
+
+    psze = parent->GetSize();
+    ppos = parent->ClientToScreen(wxPoint(0,0));
+    wsze = GetSize();
+
+    x = y = -1;
+
+    if (direction == wxBOTH || direction == wxHORIZONTAL)
+        x = ppos.x + (psze.x  - wsze.x)/2;
+    if (direction == wxBOTH || direction == wxVERTICAL)
+        y = ppos.y + (psze.y - wsze.y)/2;
+
+    Move(x, y);
+}
+
 // fits the window around the children
 void wxWindowBase::Fit()
 {
     int maxX = 0,
         maxY = 0;
 
-    wxWindowList::Node *node = GetChildren().GetFirst();
-    while ( node )
+    for ( wxWindowList::Node *node = GetChildren().GetFirst();
+          node;
+          node = node->GetNext() )
     {
         wxWindow *win = node->GetData();
+        if ( win->IsTopLevel() )
+        {
+            // dialogs and frames lie in different top level windows - don't
+            // deal with them here
+            continue;
+        }
+
         int wx, wy, ww, wh;
         win->GetPosition(&wx, &wy);
         win->GetSize(&ww, &wh);
@@ -310,8 +369,6 @@ void wxWindowBase::Fit()
             maxX = wx + ww;
         if ( wy + wh > maxY )
             maxY = wy + wh;
-
-        node = node->GetNext();
     }
 
     // leave a margin
@@ -361,6 +418,14 @@ bool wxWindowBase::Enable(bool enable)
         return FALSE;
     }
 }
+// ----------------------------------------------------------------------------
+// RTTI
+// ----------------------------------------------------------------------------
+
+bool wxWindowBase::IsTopLevel() const
+{
+    return wxDynamicCast(this, wxFrame) || wxDynamicCast(this, wxDialog);
+}
 
 // ----------------------------------------------------------------------------
 // reparenting the window
@@ -498,6 +563,25 @@ bool wxWindowBase::SetFont(const wxFont& font)
     return TRUE;
 }
 
+#if wxUSE_CARET
+void wxWindowBase::SetCaret(wxCaret *caret)
+{
+    if ( m_caret )
+    {
+        delete m_caret;
+    }
+
+    m_caret = caret;
+
+    if ( m_caret )
+    {
+        wxASSERT_MSG( m_caret->GetWindow() == this,
+                      _T("caret should be created associated to this window") );
+    }
+}
+#endif // wxUSE_CARET
+
+#if wxUSE_VALIDATORS
 // ----------------------------------------------------------------------------
 // validators
 // ----------------------------------------------------------------------------
@@ -512,6 +596,7 @@ void wxWindowBase::SetValidator(const wxValidator& validator)
     if ( m_windowValidator )
         m_windowValidator->SetWindow(this) ;
 }
+#endif // wxUSE_VALIDATORS
 
 // ----------------------------------------------------------------------------
 // update region testing
@@ -567,29 +652,44 @@ wxWindow *wxWindowBase::FindWindow( const wxString& name )
 // dialog oriented functions
 // ----------------------------------------------------------------------------
 
-void wxWindowBase::MakeModal(bool WXUNUSED(modal))
+void wxWindowBase::MakeModal(bool modal)
 {
-    wxFAIL_MSG("TODO");
+    // 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(this) )
+        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() )
     {
@@ -607,12 +707,14 @@ bool wxWindowBase::TransferDataToWindow()
             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() )
     {
@@ -623,6 +725,7 @@ bool wxWindowBase::TransferDataFromWindow()
             return FALSE;
         }
     }
+#endif // wxUSE_VALIDATORS
 
     return TRUE;
 }
@@ -857,7 +960,7 @@ bool wxWindowBase::DoPhase(int phase)
         while (node)
         {
             wxWindow *child = node->GetData();
-            if ( !child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)) )
+            if ( !child->IsTopLevel() )
             {
                 wxLayoutConstraints *constr = child->GetConstraints();
                 if ( constr )
@@ -901,7 +1004,7 @@ void wxWindowBase::ResetConstraints()
     while (node)
     {
         wxWindow *win = node->GetData();
-        if ( !win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)) )
+        if ( !win->IsTopLevel() )
             win->ResetConstraints();
         node = node->GetNext();
     }
@@ -958,7 +1061,7 @@ void wxWindowBase::SetConstraintSizes(bool recurse)
         while (node)
         {
             wxWindow *win = node->GetData();
-            if ( !win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)) )
+            if ( !win->IsTopLevel() )
                 win->SetConstraintSizes();
             node = node->GetNext();
         }
@@ -969,8 +1072,7 @@ void wxWindowBase::SetConstraintSizes(bool recurse)
 // this window.
 void wxWindowBase::TransformSizerToActual(int *x, int *y) const
 {
-    if ( !m_sizerParent || m_sizerParent->IsKindOf(CLASSINFO(wxDialog) ) ||
-            m_sizerParent->IsKindOf(CLASSINFO(wxFrame)) )
+    if ( !m_sizerParent || m_sizerParent->IsTopLevel() )
         return;
 
     int xp, yp;
@@ -1102,22 +1204,30 @@ void wxWindowBase::UpdateWindowUI()
             if ( event.GetSetEnabled() )
                 Enable(event.GetEnabled());
 
-            if ( event.GetSetText() && IsKindOf(CLASSINFO(wxControl)) )
-                ((wxControl*)this)->SetLabel(event.GetText());
+            if ( event.GetSetText() )
+            {
+                wxControl *control = wxDynamicCast(this, wxControl);
+                if ( control )
+                    control->SetLabel(event.GetText());
+            }
 
-            if ( IsKindOf(CLASSINFO(wxCheckBox)) )
+#if wxUSE_CHECKBOX
+            wxCheckBox *checkbox = wxDynamicCast(this, wxCheckBox);
+            if ( checkbox )
             {
                 if ( event.GetSetChecked() )
-                    ((wxCheckBox *)this)->SetValue(event.GetChecked());
+                    checkbox->SetValue(event.GetChecked());
             }
-            // TODO No radio buttons in wxGTK yet
-#ifndef __WXGTK__
-            else if ( IsKindOf(CLASSINFO(wxRadioButton)) )
+#endif // wxUSE_CHECKBOX
+
+#if wxUSE_RADIOBUTTON
+            wxRadioButton *radiobtn = wxDynamicCast(this, wxRadioButton);
+            if ( radiobtn )
             {
                 if ( event.GetSetChecked() )
-                    ((wxRadioButton *) this)->SetValue(event.GetChecked());
+                    radiobtn->SetValue(event.GetChecked());
             }
-#endif // !wxGTK
+#endif // wxUSE_RADIOBUTTON
         }
     }
 }