fixes to radio menu items
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14759 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -61,11 +61,9 @@ public:
|
|||||||
int GetRealId() const;
|
int GetRealId() const;
|
||||||
|
|
||||||
// mark item as belonging to the given radio group
|
// mark item as belonging to the given radio group
|
||||||
void SetRadioGroup(int start, int end)
|
void SetAsRadioGroupStart();
|
||||||
{
|
void SetRadioGroupStart(int start);
|
||||||
m_startRadioGroup = start;
|
void SetRadioGroupEnd(int end);
|
||||||
m_endRadioGroup = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compatibility only, don't use in new code
|
// compatibility only, don't use in new code
|
||||||
wxMenuItem(wxMenu *parentMenu,
|
wxMenuItem(wxMenu *parentMenu,
|
||||||
@@ -80,9 +78,17 @@ private:
|
|||||||
void Init();
|
void Init();
|
||||||
|
|
||||||
// the positions of the first and last items of the radio group this item
|
// the positions of the first and last items of the radio group this item
|
||||||
// belongs to or -1
|
// belongs to or -1: start is the radio group start and is valid for all
|
||||||
int m_startRadioGroup,
|
// but first radio group items (m_isRadioGroupStart == FALSE), end is valid
|
||||||
m_endRadioGroup;
|
// 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)
|
DECLARE_DYNAMIC_CLASS(wxMenuItem)
|
||||||
};
|
};
|
||||||
|
@@ -299,28 +299,6 @@ bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
|
|||||||
|
|
||||||
void wxMenu::EndRadioGroup()
|
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
|
// we're not inside a radio group any longer
|
||||||
m_startRadioGroup = -1;
|
m_startRadioGroup = -1;
|
||||||
}
|
}
|
||||||
@@ -329,12 +307,38 @@ bool wxMenu::DoAppend(wxMenuItem *item)
|
|||||||
{
|
{
|
||||||
wxCHECK_MSG( item, FALSE, _T("NULL item in wxMenu::DoAppend") );
|
wxCHECK_MSG( item, FALSE, _T("NULL item in wxMenu::DoAppend") );
|
||||||
|
|
||||||
|
bool check = FALSE;
|
||||||
|
|
||||||
if ( item->GetKind() == wxITEM_RADIO )
|
if ( item->GetKind() == wxITEM_RADIO )
|
||||||
{
|
{
|
||||||
|
int count = GetMenuItemCount();
|
||||||
|
|
||||||
if ( m_startRadioGroup == -1 )
|
if ( m_startRadioGroup == -1 )
|
||||||
{
|
{
|
||||||
// start a new radio group
|
// 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
|
else // not a radio item
|
||||||
@@ -342,7 +346,18 @@ bool wxMenu::DoAppend(wxMenuItem *item)
|
|||||||
EndRadioGroup();
|
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)
|
bool wxMenu::DoInsert(size_t pos, wxMenuItem *item)
|
||||||
|
@@ -112,8 +112,8 @@ wxMenuItem::wxMenuItem(wxMenu *parentMenu,
|
|||||||
|
|
||||||
void wxMenuItem::Init()
|
void wxMenuItem::Init()
|
||||||
{
|
{
|
||||||
m_startRadioGroup =
|
m_radioGroup.start = -1;
|
||||||
m_endRadioGroup = -1;
|
m_isRadioGroupStart = FALSE;
|
||||||
|
|
||||||
#if wxUSE_OWNER_DRAWN
|
#if wxUSE_OWNER_DRAWN
|
||||||
// set default menu colors
|
// set default menu colors
|
||||||
@@ -161,6 +161,30 @@ wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
|
|||||||
return wxStripMenuCodes(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
|
// change item state
|
||||||
// -----------------
|
// -----------------
|
||||||
|
|
||||||
@@ -197,15 +221,39 @@ void wxMenuItem::Check(bool check)
|
|||||||
if ( !check )
|
if ( !check )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// get the index of this item in the menu
|
||||||
const wxMenuItemList& items = m_parentMenu->GetMenuItems();
|
const wxMenuItemList& items = m_parentMenu->GetMenuItems();
|
||||||
int pos = items.IndexOf(this);
|
int pos = items.IndexOf(this);
|
||||||
wxCHECK_RET( pos != wxNOT_FOUND,
|
wxCHECK_RET( pos != wxNOT_FOUND,
|
||||||
_T("menuitem not found in the menu items list?") );
|
_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__
|
#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,
|
if ( !::CheckMenuRadioItem(hmenu,
|
||||||
m_startRadioGroup, // first group item
|
start, // the first radio group item
|
||||||
m_endRadioGroup, // last one
|
end, // the last one
|
||||||
pos, // the one to check
|
pos, // the one to check
|
||||||
MF_BYPOSITION | flags) )
|
MF_BYPOSITION | flags) )
|
||||||
{
|
{
|
||||||
@@ -214,8 +262,8 @@ void wxMenuItem::Check(bool check)
|
|||||||
#endif // __WIN32__
|
#endif // __WIN32__
|
||||||
|
|
||||||
// also uncheck all the other items in this radio group
|
// also uncheck all the other items in this radio group
|
||||||
wxMenuItemList::Node *node = items.Item(m_startRadioGroup);
|
wxMenuItemList::Node *node = items.Item(start);
|
||||||
for ( int n = m_startRadioGroup; n <= m_endRadioGroup && node; n++ )
|
for ( int n = start; n <= end && node; n++ )
|
||||||
{
|
{
|
||||||
if ( n != pos )
|
if ( n != pos )
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user