]> git.saurik.com Git - wxWidgets.git/commitdiff
fixes to radio menu items
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 24 Mar 2002 01:24:16 +0000 (01:24 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 24 Mar 2002 01:24:16 +0000 (01:24 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14759 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/menuitem.h
src/msw/menu.cpp
src/msw/menuitem.cpp

index 33f293efdc8573ea337112959cfe06248b2c25a2..05a943f6f6a58d9396f7d6cce28116ee185111ad 100644 (file)
@@ -61,11 +61,9 @@ public:
     int GetRealId() const;
 
     // mark item as belonging to the given radio group
-    void SetRadioGroup(int start, int end)
-    {
-        m_startRadioGroup = start;
-        m_endRadioGroup = end;
-    }
+    void SetAsRadioGroupStart();
+    void SetRadioGroupStart(int start);
+    void SetRadioGroupEnd(int end);
 
     // compatibility only, don't use in new code
     wxMenuItem(wxMenu *parentMenu,
@@ -80,9 +78,17 @@ private:
     void Init();
 
     // the positions of the first and last items of the radio group this item
-    // belongs to or -1
-    int m_startRadioGroup,
-        m_endRadioGroup;
+    // belongs to or -1: start is the radio group start and is valid for all
+    // but first radio group items (m_isRadioGroupStart == FALSE), end is valid
+    // only for the first one
+    union
+    {
+        int start;
+        int end;
+    } m_radioGroup;
+
+    // does this item start a radio group?
+    bool m_isRadioGroupStart;
 
     DECLARE_DYNAMIC_CLASS(wxMenuItem)
 };
index 8a3769808200abcf593402344661062d262b3346..659634d90a13020b54d1434fa0ec6072b0d77d57 100644 (file)
@@ -299,28 +299,6 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
 
 void wxMenu::EndRadioGroup()
 {
-    if ( m_startRadioGroup == -1 )
-    {
-        // nothing to do
-        return;
-    }
-
-    wxMenuItemList::Node *nodeStart = GetMenuItems().Item(m_startRadioGroup);
-    wxCHECK_RET( nodeStart, _T("where is the radio group start item?") );
-
-    int endRadioGroup = GetMenuItemCount();
-
-    wxMenuItemList::Node *node = nodeStart;
-    for ( int n = m_startRadioGroup; n < endRadioGroup && node; n++ )
-    {
-        wxMenuItem *item = (wxMenuItem *)node->GetData();
-        item->SetRadioGroup(m_startRadioGroup, endRadioGroup - 1);
-
-        node = node->GetNext();
-    }
-
-    nodeStart->GetData()->Check(TRUE);
-
     // we're not inside a radio group any longer
     m_startRadioGroup = -1;
 }
@@ -329,12 +307,38 @@ bool wxMenu::DoAppend(wxMenuItem *item)
 {
     wxCHECK_MSG( item, FALSE, _T("NULL item in wxMenu::DoAppend") );
 
+    bool check = FALSE;
+
     if ( item->GetKind() == wxITEM_RADIO )
     {
+        int count = GetMenuItemCount();
+
         if ( m_startRadioGroup == -1 )
         {
             // start a new radio group
-            m_startRadioGroup = GetMenuItemCount();
+            m_startRadioGroup = count;
+
+            // for now it has just one element
+            item->SetAsRadioGroupStart();
+            item->SetRadioGroupEnd(m_startRadioGroup);
+
+            // ensure that we have a checked item in the radio group
+            check = TRUE;
+        }
+        else // extend the current radio group
+        {
+            // we need to update its end item
+            item->SetRadioGroupStart(m_startRadioGroup);
+            wxMenuItemList::Node *node = GetMenuItems().Item(m_startRadioGroup);
+
+            if ( node )
+            {
+                node->GetData()->SetRadioGroupEnd(count);
+            }
+            else
+            {
+                wxFAIL_MSG( _T("where is the radio group start item?") );
+            }
         }
     }
     else // not a radio item
@@ -342,7 +346,18 @@ bool wxMenu::DoAppend(wxMenuItem *item)
         EndRadioGroup();
     }
 
-    return wxMenuBase::DoAppend(item) && DoInsertOrAppend(item);
+    if ( !wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item) )
+    {
+        return FALSE;
+    }
+
+    if ( check )
+    {
+        // check the item initially
+        item->Check(TRUE);
+    }
+
+    return TRUE;
 }
 
 bool wxMenu::DoInsert(size_t pos, wxMenuItem *item)
index 39913347575956088e25ee3a5a399c0573b06cb5..f69a0a01f9fd07c4bb1bd77c76d81166754bd678 100644 (file)
@@ -112,8 +112,8 @@ wxMenuItem::wxMenuItem(wxMenu *parentMenu,
 
 void wxMenuItem::Init()
 {
-    m_startRadioGroup =
-    m_endRadioGroup = -1;
+    m_radioGroup.start = -1;
+    m_isRadioGroupStart = FALSE;
 
 #if  wxUSE_OWNER_DRAWN
     // set default menu colors
@@ -161,6 +161,30 @@ wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
     return wxStripMenuCodes(text);
 }
 
+// radio group stuff
+// -----------------
+
+void wxMenuItem::SetAsRadioGroupStart()
+{
+    m_isRadioGroupStart = TRUE;
+}
+
+void wxMenuItem::SetRadioGroupStart(int start)
+{
+    wxASSERT_MSG( !m_isRadioGroupStart,
+                  _T("should only be called for the next radio items") );
+
+    m_radioGroup.start = start;
+}
+
+void wxMenuItem::SetRadioGroupEnd(int end)
+{
+    wxASSERT_MSG( m_isRadioGroupStart,
+                  _T("should only be called for the first radio item") );
+
+    m_radioGroup.end = end;
+}
+
 // change item state
 // -----------------
 
@@ -197,16 +221,40 @@ void wxMenuItem::Check(bool check)
         if ( !check )
             return;
 
+        // get the index of this item in the menu
         const wxMenuItemList& items = m_parentMenu->GetMenuItems();
         int pos = items.IndexOf(this);
         wxCHECK_RET( pos != wxNOT_FOUND,
                      _T("menuitem not found in the menu items list?") );
 
+        // get the radio group range
+        int start,
+            end;
+
+        if ( m_isRadioGroupStart )
+        {
+            // we already have all information we need
+            start = pos;
+            end = m_radioGroup.end;
+        }
+        else // next radio group item
+        {
+            // get the radio group end from the start item
+            start = m_radioGroup.start;
+            end = items.Item(start)->GetData()->m_radioGroup.end;
+        }
+
 #ifdef __WIN32__
+        // calling CheckMenuRadioItem() with such parameters hangs my system
+        // (NT4 SP6) and I suspect this could happen to the others as well - so
+        // don't do it!
+        wxCHECK_RET( start != -1 && end != -1,
+                     _T("invalid ::CheckMenuRadioItem() parameter(s)") );
+
         if ( !::CheckMenuRadioItem(hmenu,
-                                   m_startRadioGroup,   // first group item
-                                   m_endRadioGroup,     // last one
-                                   pos,                 // the one to check
+                                   start,   // the first radio group item
+                                   end,     // the last one
+                                   pos,     // the one to check
                                    MF_BYPOSITION | flags) )
         {
             wxLogLastError(_T("CheckMenuRadioItem"));
@@ -214,8 +262,8 @@ void wxMenuItem::Check(bool check)
 #endif // __WIN32__
 
         // also uncheck all the other items in this radio group
-        wxMenuItemList::Node *node = items.Item(m_startRadioGroup);
-        for ( int n = m_startRadioGroup; n <= m_endRadioGroup && node; n++ )
+        wxMenuItemList::Node *node = items.Item(start);
+        for ( int n = start; n <= end && node; n++ )
         {
             if ( n != pos )
             {