]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
Removed USING_CONFIGURE define. As VZ pointed out, checking HAVE_CONFIG_H
[wxWidgets.git] / src / common / wincmn.cpp
index 34eb0c66ee1c5062c956be68bc83176916e61dbd..71028dc3acd102f1e4e64ed7fdae5cb2b412710f 100644 (file)
 // headers
 // ----------------------------------------------------------------------------
 
+#ifdef __GNUG__
+    #pragma implementation "windowbase.h"
+#endif
+
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
     #include "wx/tooltip.h"
 #endif // wxUSE_TOOLTIPS
 
+#if wxUSE_CARET
+    #include "wx/caret.h"
+#endif // wxUSE_CARET
+
 // ----------------------------------------------------------------------------
 // static data
 // ----------------------------------------------------------------------------
 
-int wxWindowBase::ms_lastControlId = 0;
+int wxWindowBase::ms_lastControlId = -200;
 
 IMPLEMENT_ABSTRACT_CLASS(wxWindowBase, wxEvtHandler)
 
@@ -78,7 +86,6 @@ END_EVENT_TABLE()
 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
@@ -100,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;
@@ -133,13 +142,17 @@ 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
 bool wxWindowBase::CreateBase(wxWindowBase *parent,
                               wxWindowID id,
-                              const wxPoint& pos,
-                              const wxSize& size,
+                              const wxPoint& WXUNUSED(pos),
+                              const wxSize& WXUNUSED(size),
                               long style,
                               const wxString& name)
 {
@@ -176,10 +189,27 @@ wxWindowBase::~wxWindowBase()
     // 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;
+#endif // wxUSE_VALIDATORS
 
     if ( m_clientObject )
         delete m_clientObject;
@@ -241,14 +271,21 @@ bool wxWindowBase::Close(bool force)
 bool wxWindowBase::DestroyChildren()
 {
     wxWindowList::Node *node;
-    for ( node = m_children.GetFirst(); node; node = node->GetNext() )
+    for ( ;; )
     {
+        // we iterate until the list becomes empty
+        node = GetChildren().GetFirst();
+        if ( !node )
+            break;
+
         wxWindow *child = node->GetData();
-        if ( child )
-        {
-            delete child;
-            delete node;
-        }
+
+        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;
@@ -289,16 +326,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);
@@ -306,8 +379,6 @@ void wxWindowBase::Fit()
             maxX = wx + ww;
         if ( wy + wh > maxY )
             maxY = wy + wh;
-
-        node = node->GetNext();
     }
 
     // leave a margin
@@ -357,6 +428,14 @@ bool wxWindowBase::Enable(bool enable)
         return FALSE;
     }
 }
+// ----------------------------------------------------------------------------
+// RTTI
+// ----------------------------------------------------------------------------
+
+bool wxWindowBase::IsTopLevel() const
+{
+    return wxDynamicCast(this, wxFrame) || wxDynamicCast(this, wxDialog);
+}
 
 // ----------------------------------------------------------------------------
 // reparenting the window
@@ -494,6 +573,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
 // ----------------------------------------------------------------------------
@@ -508,6 +606,7 @@ void wxWindowBase::SetValidator(const wxValidator& validator)
     if ( m_windowValidator )
         m_windowValidator->SetWindow(this) ;
 }
+#endif // wxUSE_VALIDATORS
 
 // ----------------------------------------------------------------------------
 // update region testing
@@ -565,27 +664,42 @@ wxWindow *wxWindowBase::FindWindow( const wxString& name )
 
 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() )
     {
@@ -603,12 +717,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() )
     {
@@ -619,6 +735,7 @@ bool wxWindowBase::TransferDataFromWindow()
             return FALSE;
         }
     }
+#endif // wxUSE_VALIDATORS
 
     return TRUE;
 }
@@ -853,7 +970,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 )
@@ -897,7 +1014,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();
     }
@@ -954,7 +1071,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();
         }
@@ -965,8 +1082,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;
@@ -1098,22 +1214,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
         }
     }
 }
@@ -1126,9 +1250,11 @@ wxPoint wxWindowBase::ConvertPixelsToDialog(const wxPoint& pt)
 {
     int charWidth = GetCharWidth();
     int charHeight = GetCharHeight();
-    wxPoint pt2;
-    pt2.x = (int) ((pt.x * 4) / charWidth) ;
-    pt2.y = (int) ((pt.y * 8) / charHeight) ;
+    wxPoint pt2(-1, -1);
+    if (pt.x != -1)
+        pt2.x = (int) ((pt.x * 4) / charWidth) ;
+    if (pt.y != -1)
+        pt2.y = (int) ((pt.y * 8) / charHeight) ;
 
     return pt2;
 }
@@ -1137,9 +1263,11 @@ wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt)
 {
     int charWidth = GetCharWidth();
     int charHeight = GetCharHeight();
-    wxPoint pt2;
-    pt2.x = (int) ((pt.x * charWidth) / 4) ;
-    pt2.y = (int) ((pt.y * charHeight) / 8) ;
+    wxPoint pt2(-1, -1);
+    if (pt.x != -1)
+        pt2.x = (int) ((pt.x * charWidth) / 4) ;
+    if (pt.y != -1)
+        pt2.y = (int) ((pt.y * charHeight) / 8) ;
 
     return pt2;
 }