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,
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)
};
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;
}
{
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
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)
void wxMenuItem::Init()
{
- m_startRadioGroup =
- m_endRadioGroup = -1;
+ m_radioGroup.start = -1;
+ m_isRadioGroupStart = FALSE;
#if wxUSE_OWNER_DRAWN
// set default menu colors
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
// -----------------
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"));
#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 )
{