]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/wincmn.cpp
allow to change the event propagation level (modified patch 743086)
[wxWidgets.git] / src / common / wincmn.cpp
index 383c61e8fa112b6d18a7f86ae65e77a1db9c0680..2043e41e43d00e86aa88d3ba75ab8513520757b4 100644 (file)
@@ -114,7 +114,6 @@ void wxWindowBase::InitBase()
     // no window yet, no parent nor children
     m_parent = (wxWindow *)NULL;
     m_windowId = -1;
     // no window yet, no parent nor children
     m_parent = (wxWindow *)NULL;
     m_windowId = -1;
-    m_children.DeleteContents( FALSE ); // don't auto delete node data
 
     // no constraints on the minimal window size
     m_minWidth =
 
     // no constraints on the minimal window size
     m_minWidth =
@@ -263,7 +262,7 @@ wxWindowBase::~wxWindowBase()
 
     // Just in case we've loaded a top-level window via LoadNativeDialog but
     // we weren't a dialog class
 
     // Just in case we've loaded a top-level window via LoadNativeDialog but
     // we weren't a dialog class
-    wxTopLevelWindows.DeleteObject(this);
+    wxTopLevelWindows.DeleteObject((wxWindow*)this);
 
     wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") );
 
 
     wxASSERT_MSG( GetChildren().GetCount() == 0, wxT("children not destroyed") );
 
@@ -344,7 +343,7 @@ bool wxWindowBase::Close(bool force)
 
 bool wxWindowBase::DestroyChildren()
 {
 
 bool wxWindowBase::DestroyChildren()
 {
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( ;; )
     {
         // we iterate until the list becomes empty
     for ( ;; )
     {
         // we iterate until the list becomes empty
@@ -520,7 +519,7 @@ wxSize wxWindowBase::DoGetBestSize() const
         int maxX = 0,
             maxY = 0;
 
         int maxX = 0,
             maxY = 0;
 
-        for ( wxWindowList::Node *node = GetChildren().GetFirst();
+        for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
               node;
               node = node->GetNext() )
         {
               node;
               node = node->GetNext() )
         {
@@ -554,7 +553,7 @@ wxSize wxWindowBase::DoGetBestSize() const
         int maxX = 0,
             maxY = 0;
 
         int maxX = 0,
             maxY = 0;
 
-        for ( wxWindowList::Node *node = GetChildren().GetFirst();
+        for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
               node;
               node = node->GetNext() )
         {
               node;
               node = node->GetNext() )
         {
@@ -708,9 +707,9 @@ void wxWindowBase::AddChild(wxWindowBase *child)
     // this should never happen and it will lead to a crash later if it does
     // because RemoveChild() will remove only one node from the children list
     // and the other(s) one(s) will be left with dangling pointers in them
     // this should never happen and it will lead to a crash later if it does
     // because RemoveChild() will remove only one node from the children list
     // and the other(s) one(s) will be left with dangling pointers in them
-    wxASSERT_MSG( !GetChildren().Find(child), _T("AddChild() called twice") );
+    wxASSERT_MSG( !GetChildren().Find((wxWindow*)child), _T("AddChild() called twice") );
 
 
-    GetChildren().Append(child);
+    GetChildren().Append((wxWindow*)child);
     child->SetParent(this);
 }
 
     child->SetParent(this);
 }
 
@@ -718,8 +717,8 @@ void wxWindowBase::RemoveChild(wxWindowBase *child)
 {
     wxCHECK_RET( child, wxT("can't remove a NULL child") );
 
 {
     wxCHECK_RET( child, wxT("can't remove a NULL child") );
 
-    GetChildren().DeleteObject(child);
-    child->SetParent((wxWindow *)NULL);
+    GetChildren().DeleteObject((wxWindow *)child);
+    child->SetParent(NULL);
 }
 
 bool wxWindowBase::Reparent(wxWindowBase *newParent)
 }
 
 bool wxWindowBase::Reparent(wxWindowBase *newParent)
@@ -738,7 +737,7 @@ bool wxWindowBase::Reparent(wxWindowBase *newParent)
     }
     else
     {
     }
     else
     {
-        wxTopLevelWindows.DeleteObject(this);
+        wxTopLevelWindows.DeleteObject((wxWindow *)this);
     }
 
     // add it to the new one
     }
 
     // add it to the new one
@@ -748,7 +747,7 @@ bool wxWindowBase::Reparent(wxWindowBase *newParent)
     }
     else
     {
     }
     else
     {
-        wxTopLevelWindows.Append(this);
+        wxTopLevelWindows.Append((wxWindow *)this);
     }
 
     return TRUE;
     }
 
     return TRUE;
@@ -988,7 +987,7 @@ wxWindow *wxWindowBase::FindWindow( long id )
         return (wxWindow *)this;
 
     wxWindowBase *res = (wxWindow *)NULL;
         return (wxWindow *)this;
 
     wxWindowBase *res = (wxWindow *)NULL;
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
     {
         wxWindowBase *child = node->GetData();
     for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
     {
         wxWindowBase *child = node->GetData();
@@ -1004,7 +1003,7 @@ wxWindow *wxWindowBase::FindWindow( const wxString& name )
         return (wxWindow *)this;
 
     wxWindowBase *res = (wxWindow *)NULL;
         return (wxWindow *)this;
 
     wxWindowBase *res = (wxWindow *)NULL;
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
     {
         wxWindow *child = node->GetData();
     for ( node = m_children.GetFirst(); node && !res; node = node->GetNext() )
     {
         wxWindow *child = node->GetData();
@@ -1060,7 +1059,7 @@ wxWindow *wxFindWindowRecursively(const wxWindow *parent,
             return (wxWindow *)parent;
 
         // It wasn't, so check all its children
             return (wxWindow *)parent;
 
         // It wasn't, so check all its children
-        for ( wxWindowList::Node * node = parent->GetChildren().GetFirst();
+        for ( wxWindowList::compatibility_iterator node = parent->GetChildren().GetFirst();
               node;
               node = node->GetNext() )
         {
               node;
               node = node->GetNext() )
         {
@@ -1090,7 +1089,7 @@ wxWindow *wxFindWindowHelper(const wxWindow *parent,
     }
 
     // start at very top of wx's windows
     }
 
     // start at very top of wx's windows
-    for ( wxWindowList::Node * node = wxTopLevelWindows.GetFirst();
+    for ( wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst();
           node;
           node = node->GetNext() )
     {
           node;
           node = node->GetNext() )
     {
@@ -1142,7 +1141,7 @@ void wxWindowBase::MakeModal(bool modal)
     // Disable all other windows
     if ( IsTopLevel() )
     {
     // Disable all other windows
     if ( IsTopLevel() )
     {
-        wxWindowList::Node *node = wxTopLevelWindows.GetFirst();
+        wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetFirst();
         while (node)
         {
             wxWindow *win = node->GetData();
         while (node)
         {
             wxWindow *win = node->GetData();
@@ -1159,7 +1158,7 @@ bool wxWindowBase::Validate()
 #if wxUSE_VALIDATORS
     bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
 
 #if wxUSE_VALIDATORS
     bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
 
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
         wxWindowBase *child = node->GetData();
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
         wxWindowBase *child = node->GetData();
@@ -1184,7 +1183,7 @@ bool wxWindowBase::TransferDataToWindow()
 #if wxUSE_VALIDATORS
     bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
 
 #if wxUSE_VALIDATORS
     bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
 
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
         wxWindowBase *child = node->GetData();
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
         wxWindowBase *child = node->GetData();
@@ -1218,7 +1217,7 @@ bool wxWindowBase::TransferDataFromWindow()
 #if wxUSE_VALIDATORS
     bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
 
 #if wxUSE_VALIDATORS
     bool recurse = (GetExtraStyle() & wxWS_EX_VALIDATE_RECURSIVELY) != 0;
 
-    wxWindowList::Node *node;
+    wxWindowList::compatibility_iterator node;
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
         wxWindow *child = node->GetData();
     for ( node = m_children.GetFirst(); node; node = node->GetNext() )
     {
         wxWindow *child = node->GetData();
@@ -1409,15 +1408,15 @@ void wxWindowBase::AddConstraintReference(wxWindowBase *otherWin)
 {
     if ( !m_constraintsInvolvedIn )
         m_constraintsInvolvedIn = new wxWindowList;
 {
     if ( !m_constraintsInvolvedIn )
         m_constraintsInvolvedIn = new wxWindowList;
-    if ( !m_constraintsInvolvedIn->Find(otherWin) )
-        m_constraintsInvolvedIn->Append(otherWin);
+    if ( !m_constraintsInvolvedIn->Find((wxWindow *)otherWin) )
+        m_constraintsInvolvedIn->Append((wxWindow *)otherWin);
 }
 
 // REMOVE back-pointer to other windows we're involved with.
 void wxWindowBase::RemoveConstraintReference(wxWindowBase *otherWin)
 {
     if ( m_constraintsInvolvedIn )
 }
 
 // REMOVE back-pointer to other windows we're involved with.
 void wxWindowBase::RemoveConstraintReference(wxWindowBase *otherWin)
 {
     if ( m_constraintsInvolvedIn )
-        m_constraintsInvolvedIn->DeleteObject(otherWin);
+        m_constraintsInvolvedIn->DeleteObject((wxWindow *)otherWin);
 }
 
 // Reset any constraints that mention this window
 }
 
 // Reset any constraints that mention this window
@@ -1425,7 +1424,7 @@ void wxWindowBase::DeleteRelatedConstraints()
 {
     if ( m_constraintsInvolvedIn )
     {
 {
     if ( m_constraintsInvolvedIn )
     {
-        wxWindowList::Node *node = m_constraintsInvolvedIn->GetFirst();
+        wxWindowList::compatibility_iterator node = m_constraintsInvolvedIn->GetFirst();
         while (node)
         {
             wxWindow *win = node->GetData();
         while (node)
         {
             wxWindow *win = node->GetData();
@@ -1444,8 +1443,8 @@ void wxWindowBase::DeleteRelatedConstraints()
                 constr->centreY.ResetIfWin(this);
             }
 
                 constr->centreY.ResetIfWin(this);
             }
 
-            wxWindowList::Node *next = node->GetNext();
-            delete node;
+            wxWindowList::compatibility_iterator next = node->GetNext();
+            m_constraintsInvolvedIn->Erase(node);
             node = next;
         }
 
             node = next;
         }
 
@@ -1559,7 +1558,7 @@ bool wxWindowBase::DoPhase(int phase)
         int noChanges = 0;
 
         // loop over all children setting their constraints
         int noChanges = 0;
 
         // loop over all children setting their constraints
-        for ( wxWindowList::Node *node = GetChildren().GetFirst();
+        for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
               node;
               node = node->GetNext() )
         {
               node;
               node = node->GetNext() )
         {
@@ -1612,7 +1611,7 @@ void wxWindowBase::ResetConstraints()
         constr->centreY.SetDone(FALSE);
     }
 
         constr->centreY.SetDone(FALSE);
     }
 
-    wxWindowList::Node *node = GetChildren().GetFirst();
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
     while (node)
     {
         wxWindow *win = node->GetData();
     while (node)
     {
         wxWindow *win = node->GetData();
@@ -1654,7 +1653,7 @@ void wxWindowBase::SetConstraintSizes(bool recurse)
 
     if ( recurse )
     {
 
     if ( recurse )
     {
-        wxWindowList::Node *node = GetChildren().GetFirst();
+        wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
         while (node)
         {
             wxWindow *win = node->GetData();
         while (node)
         {
             wxWindow *win = node->GetData();
@@ -1770,42 +1769,46 @@ void wxWindowBase::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags) co
 // do Update UI processing for child controls
 // ----------------------------------------------------------------------------
 
 // do Update UI processing for child controls
 // ----------------------------------------------------------------------------
 
-// TODO: should this be implemented for the child window rather
-// than the parent? Then you can override it e.g. for wxCheckBox
-// to do the Right Thing rather than having to assume a fixed number
-// of control classes.
-void wxWindowBase::UpdateWindowUI()
+void wxWindowBase::UpdateWindowUI(long flags)
 {
 {
-#if wxUSE_CONTROLS
     wxUpdateUIEvent event(GetId());
     event.m_eventObject = this;
 
     if ( GetEventHandler()->ProcessEvent(event) )
     {
     wxUpdateUIEvent event(GetId());
     event.m_eventObject = this;
 
     if ( GetEventHandler()->ProcessEvent(event) )
     {
-        if ( event.GetSetEnabled() )
-            Enable(event.GetEnabled());
+        DoUpdateWindowUI(event);
+    }
 
 
-        if ( event.GetSetText() )
+    if (flags & wxUPDATE_UI_RECURSE)
+    {
+        wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+        while (node)
         {
         {
-            wxControl *control = wxDynamicCastThis(wxControl);
-            if ( control )
-            {
-#if wxUSE_TEXTCTRL
-                wxTextCtrl *text = wxDynamicCast(control, wxTextCtrl);
-                if ( text )
-                {
-                       if ( event.GetText() != text->GetValue() )
-                       text->SetValue(event.GetText());
-                }
-                else
-#endif // wxUSE_TEXTCTRL
-                               {
-                                       if ( event.GetText() != control->GetLabel() )
-                       control->SetLabel(event.GetText());
-                }
-            }
+            wxWindow* child = (wxWindow*) node->GetData();
+            child->UpdateWindowUI(flags);
+            node = node->GetNext();
         }
         }
+    }
+}
 
 
+// do the window-specific processing after processing the update event
+// TODO: take specific knowledge out of this function and
+// put in each control's base class. Unfortunately we don't
+// yet have base implementation files for wxCheckBox and wxRadioButton.
+void wxWindowBase::DoUpdateWindowUI(wxUpdateUIEvent& event)
+{
+    if ( event.GetSetEnabled() )
+        Enable(event.GetEnabled());
+    
+#if wxUSE_CONTROLS
+    if ( event.GetSetText() )
+    {
+        wxControl *control = wxDynamicCastThis(wxControl);
+        if ( control )
+        {
+            if ( event.GetText() != control->GetLabel() )
+                control->SetLabel(event.GetText());
+        }
 #if wxUSE_CHECKBOX
         wxCheckBox *checkbox = wxDynamicCastThis(wxCheckBox);
         if ( checkbox )
 #if wxUSE_CHECKBOX
         wxCheckBox *checkbox = wxDynamicCastThis(wxCheckBox);
         if ( checkbox )
@@ -1823,9 +1826,26 @@ void wxWindowBase::UpdateWindowUI()
                 radiobtn->SetValue(event.GetChecked());
         }
 #endif // wxUSE_RADIOBTN
                 radiobtn->SetValue(event.GetChecked());
         }
 #endif // wxUSE_RADIOBTN
+    }    
+#endif
+}
+
+#if 0
+// call internal idle recursively
+// may be obsolete (wait until OnIdle scheme stabilises)
+void wxWindowBase::ProcessInternalIdle()
+{
+    OnInternalIdle();
+
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+    while (node)
+    {
+        wxWindow *child = node->GetData();
+        child->ProcessInternalIdle();
+        node = node->GetNext();
     }
     }
-#endif // wxUSE_CONTROLS
 }
 }
+#endif
 
 // ----------------------------------------------------------------------------
 // dialog units translations
 
 // ----------------------------------------------------------------------------
 // dialog units translations
@@ -1864,7 +1884,7 @@ wxPoint wxWindowBase::ConvertDialogToPixels(const wxPoint& pt)
 // propagate the colour change event to the subwindows
 void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& event)
 {
 // propagate the colour change event to the subwindows
 void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& event)
 {
-    wxWindowList::Node *node = GetChildren().GetFirst();
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
     while ( node )
     {
         // Only propagate to non-top-level windows
     while ( node )
     {
         // Only propagate to non-top-level windows
@@ -1880,10 +1900,15 @@ void wxWindowBase::OnSysColourChanged(wxSysColourChangedEvent& event)
     }
 }
 
     }
 }
 
-// the default action is to populate dialog with data when it's created
+// the default action is to populate dialog with data when it's created,
+// and nudge the UI into displaying itself correctly in case
+// we've turned the wxUpdateUIEvents frequency down low.
 void wxWindowBase::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
 {
     TransferDataToWindow();
 void wxWindowBase::OnInitDialog( wxInitDialogEvent &WXUNUSED(event) )
 {
     TransferDataToWindow();
+    
+    // Update the UI at this point
+    UpdateWindowUI(wxUPDATE_UI_RECURSE);
 }
 
 // process Ctrl-Alt-mclick
 }
 
 // process Ctrl-Alt-mclick
@@ -1981,6 +2006,7 @@ wxAccessible* wxWindowBase::CreateAccessible()
 
 #endif
 
 
 #endif
 
+#if !wxUSE_STL
 // ----------------------------------------------------------------------------
 // list classes implementation
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // list classes implementation
 // ----------------------------------------------------------------------------
@@ -1989,14 +2015,15 @@ void wxWindowListNode::DeleteData()
 {
     delete (wxWindow *)GetData();
 }
 {
     delete (wxWindow *)GetData();
 }
+#endif
 
 // ----------------------------------------------------------------------------
 // borders
 // ----------------------------------------------------------------------------
 
 
 // ----------------------------------------------------------------------------
 // borders
 // ----------------------------------------------------------------------------
 
-wxBorder wxWindowBase::GetBorder() const
+wxBorder wxWindowBase::GetBorder(long flags) const
 {
 {
-    wxBorder border = (wxBorder)(m_windowStyle & wxBORDER_MASK);
+    wxBorder border = (wxBorder)(flags & wxBORDER_MASK);
     if ( border == wxBORDER_DEFAULT )
     {
         border = GetDefaultBorder();
     if ( border == wxBORDER_DEFAULT )
     {
         border = GetDefaultBorder();
@@ -2083,6 +2110,24 @@ void wxWindowBase::ReleaseMouse()
                GetCapture());
 }
 
                GetCapture());
 }
 
+#if wxUSE_HOTKEY
+
+bool
+wxWindowBase::RegisterHotKey(int WXUNUSED(hotkeyId),
+                             int WXUNUSED(modifiers),
+                             int WXUNUSED(keycode))
+{
+    // not implemented
+    return false;
+}
+
+bool wxWindowBase::UnregisterHotKey(int WXUNUSED(hotkeyId))
+{
+    // not implemented
+    return false;
+}
+
+#endif // wxUSE_HOTKEY
 
 void wxWindowBase::SendDestroyEvent()
 {
 
 void wxWindowBase::SendDestroyEvent()
 {
@@ -2118,10 +2163,9 @@ bool wxWindowBase::TryValidator(wxEvent& event)
 
 bool wxWindowBase::TryParent(wxEvent& event)
 {
 
 bool wxWindowBase::TryParent(wxEvent& event)
 {
-    // Carry on up the parent-child hierarchy, but only if event is a command
-    // event: it wouldn't make sense for a parent to receive a child's size
-    // event, for example
-    if ( event.IsCommandEvent() )
+    // carry on up the parent-child hierarchy if the propgation count hasn't
+    // reached zero yet
+    if ( event.ShouldPropagate() )
     {
         // honour the requests to stop propagation at this window: this is
         // used by the dialogs, for example, to prevent processing the events
     {
         // honour the requests to stop propagation at this window: this is
         // used by the dialogs, for example, to prevent processing the events
@@ -2131,7 +2175,11 @@ bool wxWindowBase::TryParent(wxEvent& event)
         {
             wxWindow *parent = GetParent();
             if ( parent && !parent->IsBeingDeleted() )
         {
             wxWindow *parent = GetParent();
             if ( parent && !parent->IsBeingDeleted() )
+            {
+                wxPropagateOnce propagateOnce(event);
+
                 return parent->GetEventHandler()->ProcessEvent(event);
                 return parent->GetEventHandler()->ProcessEvent(event);
+            }
         }
     }
 
         }
     }
 
@@ -2230,7 +2278,7 @@ wxAccStatus wxWindowAccessible::Navigate(wxNavDir navDir, int fromId,
     case wxNAVDIR_DOWN:
     case wxNAVDIR_NEXT:
         {
     case wxNAVDIR_DOWN:
     case wxNAVDIR_NEXT:
         {
-            wxWindowList::Node *node = NULL;
+            wxWindowList::compatibility_iterator node = NULL;
             if (fromId == 0)
             {
                 // Can't navigate to sibling of this window
             if (fromId == 0)
             {
                 // Can't navigate to sibling of this window
@@ -2243,7 +2291,7 @@ wxAccStatus wxWindowAccessible::Navigate(wxNavDir navDir, int fromId,
             else
             {
                 if (fromId <= (int) GetWindow()->GetChildren().GetCount())
             else
             {
                 if (fromId <= (int) GetWindow()->GetChildren().GetCount())
-                    node = (wxWindowList::Node*) GetWindow()->GetChildren().Nth(fromId-1);
+                    node = GetWindow()->GetChildren().Nth(fromId-1);
             }
 
             if (node && node->GetNext())
             }
 
             if (node && node->GetNext())
@@ -2259,7 +2307,7 @@ wxAccStatus wxWindowAccessible::Navigate(wxNavDir navDir, int fromId,
     case wxNAVDIR_UP:
     case wxNAVDIR_PREVIOUS:
         {
     case wxNAVDIR_UP:
     case wxNAVDIR_PREVIOUS:
         {
-            wxWindowList::Node *node = NULL;
+            wxWindowList::compatibility_iterator node = NULL;
             if (fromId == 0)
             {
                 // Can't navigate to sibling of this window
             if (fromId == 0)
             {
                 // Can't navigate to sibling of this window
@@ -2272,7 +2320,7 @@ wxAccStatus wxWindowAccessible::Navigate(wxNavDir navDir, int fromId,
             else
             {
                 if (fromId <= (int) GetWindow()->GetChildren().GetCount())
             else
             {
                 if (fromId <= (int) GetWindow()->GetChildren().GetCount())
-                    node = (wxWindowList::Node*) GetWindow()->GetChildren().Nth(fromId-1);
+                    node = GetWindow()->GetChildren().Nth(fromId-1);
             }
 
             if (node && node->GetPrevious())
             }
 
             if (node && node->GetPrevious())