]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
* wxDataStreams use wxUint now.
[wxWidgets.git] / src / common / wincmn.cpp
index fd7ded32acbc7a10716bbb0e39957b0126a75b6b..2665e8d0ec4db857086d5373590a1eda156759ad 100644 (file)
 // headers
 // ----------------------------------------------------------------------------
 
 // headers
 // ----------------------------------------------------------------------------
 
+#ifdef __GNUG__
+    #pragma implementation "windowbase.h"
+#endif
+
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
     #include "wx/tooltip.h"
 #endif // wxUSE_TOOLTIPS
 
     #include "wx/tooltip.h"
 #endif // wxUSE_TOOLTIPS
 
+#if wxUSE_CARET
+    #include "wx/caret.h"
+#endif // wxUSE_CARET
+
 // ----------------------------------------------------------------------------
 // static data
 // ----------------------------------------------------------------------------
 
 // ----------------------------------------------------------------------------
 // static data
 // ----------------------------------------------------------------------------
 
-int wxWindowBase::ms_lastControlId = 0;
+int wxWindowBase::ms_lastControlId = -200;
 
 IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler)
 
 
 IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler)
 
@@ -78,7 +86,6 @@ END_EVENT_TABLE()
 void wxWindowBase::InitBase()
 {
     // no window yet, no parent nor children
 void wxWindowBase::InitBase()
 {
     // no window yet, no parent nor children
-//    m_widget = (WXWidget)0;
     m_parent = (wxWindow *)NULL;
     m_windowId = -1;
     m_children.DeleteContents( FALSE ); // don't auto delete node data
     m_parent = (wxWindow *)NULL;
     m_windowId = -1;
     m_children.DeleteContents( FALSE ); // don't auto delete node data
@@ -100,8 +107,10 @@ void wxWindowBase::InitBase()
     // the default event handler is just this window
     m_eventHandler = this;
 
     // the default event handler is just this window
     m_eventHandler = this;
 
+#if wxUSE_VALIDATORS
     // no validator
     m_windowValidator = (wxValidator *) NULL;
     // no validator
     m_windowValidator = (wxValidator *) NULL;
+#endif // wxUSE_VALIDATORS
 
     // use the system default colours
     wxSystemSettings settings;
 
     // use the system default colours
     wxSystemSettings settings;
@@ -133,6 +142,10 @@ void wxWindowBase::InitBase()
 #if wxUSE_TOOLTIPS
     m_tooltip = (wxToolTip *)NULL;
 #endif // wxUSE_TOOLTIPS
 #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
 }
 
 // common part of window creation process
@@ -176,10 +189,27 @@ wxWindowBase::~wxWindowBase()
     // we weren't a dialog class
     wxTopLevelWindows.DeleteObject(this);
 
     // we weren't a dialog class
     wxTopLevelWindows.DeleteObject(this);
 
-    DestroyChildren();
+    wxASSERT_MSG( GetChildren().GetCount() == 0, _T("children not destroyed") );
 
 
+    // make sure that there are no dangling pointers left pointing to us
+    wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
+    if ( panel )
+    {
+        if ( panel->GetLastFocus() == this )
+        {
+            panel->SetLastFocus((wxWindow *)NULL);
+        }
+    }
+
+#if wxUSE_CARET
+    if ( m_caret )
+        delete m_caret;
+#endif // wxUSE_CARET
+
+#if wxUSE_VALIDATORS
     if ( m_windowValidator )
         delete m_windowValidator;
     if ( m_windowValidator )
         delete m_windowValidator;
+#endif // wxUSE_VALIDATORS
 
     if ( m_clientObject )
         delete m_clientObject;
 
     if ( m_clientObject )
         delete m_clientObject;
@@ -241,13 +271,21 @@ bool wxWindowBase::Close(bool force)
 bool wxWindowBase::DestroyChildren()
 {
     wxWindowList::Node *node;
 bool wxWindowBase::DestroyChildren()
 {
     wxWindowList::Node *node;
-    for ( node = GetChildren().GetFirst(); node; node = node->GetNext() )
+    for ( ;; )
     {
     {
+        // we iterate until the list becomes empty
+        node = GetChildren().GetFirst();
+        if ( !node )
+            break;
+
         wxWindow *child = node->GetData();
         wxWindow *child = node->GetData();
-        if ( child )
-        {
-            delete child;
-        }
+
+        wxASSERT_MSG( child, _T("children list contains empty nodes") );
+
+        delete child;
+
+        wxASSERT_MSG( !GetChildren().Find(child),
+                      _T("child didn't remove itself using RemoveChild()") );
     }
 
     return TRUE;
     }
 
     return TRUE;
@@ -288,16 +326,52 @@ void wxWindowBase::Centre(int direction)
     Move(new_x, new_y);
 }
 
     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;
 
 // 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();
     {
         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);
         int wx, wy, ww, wh;
         win->GetPosition(&wx, &wy);
         win->GetSize(&ww, &wh);
@@ -305,8 +379,6 @@ void wxWindowBase::Fit()
             maxX = wx + ww;
         if ( wy + wh > maxY )
             maxY = wy + wh;
             maxX = wx + ww;
         if ( wy + wh > maxY )
             maxY = wy + wh;
-
-        node = node->GetNext();
     }
 
     // leave a margin
     }
 
     // leave a margin
@@ -356,6 +428,14 @@ bool wxWindowBase::Enable(bool enable)
         return FALSE;
     }
 }
         return FALSE;
     }
 }
+// ----------------------------------------------------------------------------
+// RTTI
+// ----------------------------------------------------------------------------
+
+bool wxWindowBase::IsTopLevel() const
+{
+    return wxDynamicCast(this, wxFrame) || wxDynamicCast(this, wxDialog);
+}
 
 // ----------------------------------------------------------------------------
 // reparenting the window
 
 // ----------------------------------------------------------------------------
 // reparenting the window
@@ -493,6 +573,25 @@ bool wxWindowBase::SetFont(const wxFont& font)
     return TRUE;
 }
 
     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
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // validators
 // ----------------------------------------------------------------------------
@@ -507,6 +606,7 @@ void wxWindowBase::SetValidator(const wxValidator& validator)
     if ( m_windowValidator )
         m_windowValidator->SetWindow(this) ;
 }
     if ( m_windowValidator )
         m_windowValidator->SetWindow(this) ;
 }
+#endif // wxUSE_VALIDATORS
 
 // ----------------------------------------------------------------------------
 // update region testing
 
 // ----------------------------------------------------------------------------
 // update region testing
@@ -562,29 +662,44 @@ wxWindow *wxWindowBase::FindWindow( const wxString& name )
 // dialog oriented functions
 // ----------------------------------------------------------------------------
 
 // 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()
 {
 }
 
 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();
     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;
         }
     }
         {
             return FALSE;
         }
     }
+#endif // wxUSE_VALIDATORS
 
     return TRUE;
 }
 
 bool wxWindowBase::TransferDataToWindow()
 {
 
     return TRUE;
 }
 
 bool wxWindowBase::TransferDataToWindow()
 {
+#if wxUSE_VALIDATORS
     wxWindowList::Node *node;
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
     wxWindowList::Node *node;
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
@@ -602,12 +717,14 @@ bool wxWindowBase::TransferDataToWindow()
             return FALSE;
         }
     }
             return FALSE;
         }
     }
+#endif // wxUSE_VALIDATORS
 
     return TRUE;
 }
 
 bool wxWindowBase::TransferDataFromWindow()
 {
 
     return TRUE;
 }
 
 bool wxWindowBase::TransferDataFromWindow()
 {
+#if wxUSE_VALIDATORS
     wxWindowList::Node *node;
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
     wxWindowList::Node *node;
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
@@ -618,6 +735,7 @@ bool wxWindowBase::TransferDataFromWindow()
             return FALSE;
         }
     }
             return FALSE;
         }
     }
+#endif // wxUSE_VALIDATORS
 
     return TRUE;
 }
 
     return TRUE;
 }
@@ -852,7 +970,7 @@ bool wxWindowBase::DoPhase(int phase)
         while (node)
         {
             wxWindow *child = node->GetData();
         while (node)
         {
             wxWindow *child = node->GetData();
-            if ( !child->IsKindOf(CLASSINFO(wxFrame)) && !child->IsKindOf(CLASSINFO(wxDialog)) )
+            if ( !child->IsTopLevel() )
             {
                 wxLayoutConstraints *constr = child->GetConstraints();
                 if ( constr )
             {
                 wxLayoutConstraints *constr = child->GetConstraints();
                 if ( constr )
@@ -896,7 +1014,7 @@ void wxWindowBase::ResetConstraints()
     while (node)
     {
         wxWindow *win = node->GetData();
     while (node)
     {
         wxWindow *win = node->GetData();
-        if ( !win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)) )
+        if ( !win->IsTopLevel() )
             win->ResetConstraints();
         node = node->GetNext();
     }
             win->ResetConstraints();
         node = node->GetNext();
     }
@@ -953,7 +1071,7 @@ void wxWindowBase::SetConstraintSizes(bool recurse)
         while (node)
         {
             wxWindow *win = node->GetData();
         while (node)
         {
             wxWindow *win = node->GetData();
-            if ( !win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog)) )
+            if ( !win->IsTopLevel() )
                 win->SetConstraintSizes();
             node = node->GetNext();
         }
                 win->SetConstraintSizes();
             node = node->GetNext();
         }
@@ -964,8 +1082,7 @@ void wxWindowBase::SetConstraintSizes(bool recurse)
 // this window.
 void wxWindowBase::TransformSizerToActual(int *x, int *y) const
 {
 // 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;
         return;
 
     int xp, yp;
@@ -1097,22 +1214,30 @@ void wxWindowBase::UpdateWindowUI()
             if ( event.GetSetEnabled() )
                 Enable(event.GetEnabled());
 
             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() )
             {
                 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() )
             {
                 if ( event.GetSetChecked() )
-                    ((wxRadioButton *) this)->SetValue(event.GetChecked());
+                    radiobtn->SetValue(event.GetChecked());
             }
             }
-#endif // !wxGTK
+#endif // wxUSE_RADIOBUTTON
         }
     }
 }
         }
     }
 }