// Author: Vadim Zeitlin
// Modified by:
// Created: 25.08.00
-// RCS-ID: $Id$
// Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
void SetLabel(const wxString& text)
{
+ m_originalLabel = text;
+
// remember the accel char (may be -1 if none)
m_indexAccel = wxControl::FindAccelIndex(text, &m_label);
// accessors
const wxString& GetLabel() const { return m_label; }
+ const wxString& GetOriginalLabel() const { return m_originalLabel; }
bool IsEnabled() const { return m_isEnabled; }
wxCoord GetWidth(wxMenuBar *menubar) const
{
}
wxString m_label;
+ wxString m_originalLabel;
wxCoord m_width;
int m_indexAccel;
bool m_isEnabled;
// wxWin macros
// ----------------------------------------------------------------------------
-IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
-IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxWindow)
-IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
-
BEGIN_EVENT_TABLE(wxPopupMenuWindow, wxPopupTransientWindow)
EVT_KEY_DOWN(wxPopupMenuWindow::OnKeyDown)
void wxPopupMenuWindow::ChangeCurrent(wxMenuItemIter node)
{
- if ( !m_nodeCurrent || (node != m_nodeCurrent) )
+ if ( !m_nodeCurrent || !node || (node != m_nodeCurrent) )
{
wxMenuItemIter nodeOldCurrent = m_nodeCurrent;
if ( nodeOldCurrent )
{
wxMenuItem *item = nodeOldCurrent->GetData();
- wxCHECK_RET( item, _T("no current item?") );
+ wxCHECK_RET( item, wxT("no current item?") );
// if it was the currently opened menu, close it
if ( item->IsSubMenu() && item->GetSubMenu()->IsShown() )
// check that the current item had been properly reset before
wxASSERT_MSG( !m_nodeCurrent ||
m_nodeCurrent == m_menu->GetMenuItems().GetFirst(),
- _T("menu current item preselected incorrectly") );
+ wxT("menu current item preselected incorrectly") );
wxPopupTransientWindow::Popup(focus);
wxPopupMenuWindow *win = menuParent->m_popupMenu;
// if we're shown, the parent menu must be also shown
- wxCHECK_RET( win, _T("parent menu is not shown?") );
+ wxCHECK_RET( win, wxT("parent menu is not shown?") );
if ( !::SetWindowPos(GetHwndOf(win), GetHwnd(),
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW) )
{
- wxLogLastError(_T("SetWindowPos(HWND_TOP)"));
+ wxLogLastError(wxT("SetWindowPos(HWND_TOP)"));
}
Refresh();
if ( HasOpenSubmenu() )
{
wxMenuItem *item = GetCurrentItem();
- wxCHECK_RET( item && item->IsSubMenu(), _T("where is our open submenu?") );
+ wxCHECK_RET( item && item->IsSubMenu(), wxT("where is our open submenu?") );
wxPopupMenuWindow *win = item->GetSubMenu()->m_popupMenu;
- wxCHECK_RET( win, _T("opened submenu is not opened?") );
+ wxCHECK_RET( win, wxT("opened submenu is not opened?") );
win->Dismiss();
OnSubmenuDismiss( false );
void wxPopupMenuWindow::RefreshItem(wxMenuItem *item)
{
- wxCHECK_RET( item, _T("can't refresh NULL item") );
+ wxCHECK_RET( item, wxT("can't refresh NULL item") );
- wxASSERT_MSG( IsShown(), _T("can't refresh menu which is not shown") );
+ wxASSERT_MSG( IsShown(), wxT("can't refresh menu which is not shown") );
// FIXME: -1 here because of SetLogicalOrigin(1, 1) in DoDraw()
RefreshRect(wxRect(0, item->GetPosition() - 1,
bmp = item->GetDisabledBitmap();
}
- if ( !bmp.Ok() )
+ if ( !bmp.IsOk() )
{
// strangely enough, for unchecked item we use the
// "checked" bitmap because this is the default one - this
dc,
y,
gi,
- item->GetLabel(),
+ item->GetItemLabelText(),
item->GetAccelString(),
bmp,
flags,
void wxPopupMenuWindow::ClickItem(wxMenuItem *item)
{
- wxCHECK_RET( item, _T("can't click NULL item") );
+ wxCHECK_RET( item, wxT("can't click NULL item") );
wxASSERT_MSG( !item->IsSeparator() && !item->IsSubMenu(),
- _T("can't click this item") );
+ wxT("can't click this item") );
wxMenu* menu = m_menu;
void wxPopupMenuWindow::OpenSubmenu(wxMenuItem *item, InputMethod how)
{
- wxCHECK_RET( item, _T("can't open NULL submenu") );
+ wxCHECK_RET( item, wxT("can't open NULL submenu") );
wxMenu *submenu = item->GetSubMenu();
- wxCHECK_RET( submenu, _T("can only open submenus!") );
+ wxCHECK_RET( submenu, wxT("can only open submenus!") );
// FIXME: should take into account the border width
submenu->Popup(ClientToScreen(wxPoint(0, item->GetPosition())),
{
wxPopupMenuWindow *win = menu->m_popupMenu;
- wxCHECK_MSG( win, false, _T("parent menu not shown?") );
+ wxCHECK_MSG( win, false, wxT("parent menu not shown?") );
pos = ClientToScreen(pos);
if ( win->GetMenuItemFromPoint(win->ScreenToClient(pos)) )
wxPopupMenuWindow *win = menuParent->m_popupMenu;
// if we're shown, the parent menu must be also shown
- wxCHECK_RET( win, _T("parent menu is not shown?") );
+ wxCHECK_RET( win, wxT("parent menu is not shown?") );
win->ProcessMouseMove(win->ScreenToClient(ptScreen));
}
if ( HasOpenSubmenu() )
{
wxMenuItem *item = GetCurrentItem();
- wxCHECK_RET( CanOpen(item), _T("where is our open submenu?") );
+ wxCHECK_RET( CanOpen(item), wxT("where is our open submenu?") );
wxPopupMenuWindow *win = item->GetSubMenu()->m_popupMenu;
- wxCHECK_RET( win, _T("submenu is opened but not shown?") );
+ wxCHECK_RET( win, wxT("submenu is opened but not shown?") );
// only handle this event if the mouse is not inside the submenu
wxPoint pt = ClientToScreen(event.GetPosition());
if ( HasOpenSubmenu() )
{
wxCHECK_MSG( CanOpen(item), false,
- _T("has open submenu but another item selected?") );
+ wxT("has open submenu but another item selected?") );
if ( item->GetSubMenu()->ProcessKeyDown(key) )
return true;
int idxAccel = item->GetAccelIndex();
if ( idxAccel != -1 &&
- wxTolower(item->GetLabel()[(size_t)idxAccel])
+ (wxChar)wxTolower(item->GetItemLabelText()[(size_t)idxAccel])
== chAccel )
{
// ok, found an item with this accel
}
else
{
- wxFAIL_MSG( _T("can't get geometry without window") );
+ wxFAIL_MSG( wxT("can't get geometry without window") );
}
}
void wxMenu::InvalidateGeometryInfo()
{
- if ( m_geometry )
- {
- delete m_geometry;
- m_geometry = NULL;
- }
+ wxDELETE(m_geometry);
}
// ----------------------------------------------------------------------------
#if wxUSE_ACCEL
AddAccelFor(item);
#endif // wxUSE_ACCEL
-
- // the submenus of a popup menu should have the same invoking window as it
- // has
- if ( m_invokingWindow && item->IsSubMenu() )
- {
- item->GetSubMenu()->SetInvokingWindow(m_invokingWindow);
- }
}
void wxMenu::EndRadioGroup()
}
else
{
- wxFAIL_MSG( _T("where is the radio group start item?") );
+ wxFAIL_MSG( wxT("where is the radio group start item?") );
}
}
}
{
wxMenuBase::Attach(menubar);
- wxCHECK_RET( m_menuBar, _T("menubar can't be NULL after attaching") );
+ wxCHECK_RET( m_menuBar, wxT("menubar can't be NULL after attaching") );
// unfortunately, we can't use m_menuBar->GetEventHandler() here because,
// if the menubar is currently showing a menu, its event handler is a
void wxMenu::Detach()
{
+ // After the menu is detached from the menu bar, it shouldn't send its
+ // events to it.
+ SetNextHandler(NULL);
+
wxMenuBase::Detach();
}
wxWindow *wxMenu::GetRootWindow() const
{
- if ( GetMenuBar() )
- {
- // simple case - a normal menu attached to the menubar
- return GetMenuBar();
- }
-
- // we're a popup menu but the trouble is that only the top level popup menu
- // has a pointer to the invoking window, so we must walk up the menu chain
- // if needed
- wxWindow *win = GetInvokingWindow();
- if ( win )
- {
- // we already have it
- return win;
- }
-
- wxMenu *menu = GetParent();
- while ( menu )
- {
- // We are a submenu of a menu of a menubar
- if (menu->GetMenuBar())
- return menu->GetMenuBar();
-
- win = menu->GetInvokingWindow();
- if ( win )
- break;
-
- menu = menu->GetParent();
- }
-
- // we're probably going to crash in the caller anyhow, but try to detect
- // this error as soon as possible
- wxASSERT_MSG( win, _T("menu without any associated window?") );
-
- // also remember it in this menu so that we don't have to search for it the
- // next time
- wxConstCast(this, wxMenu)->m_invokingWindow = win;
-
- return win;
+ return GetMenuBar() ? GetMenuBar() : GetInvokingWindow();
}
wxRenderer *wxMenu::GetRenderer() const
{
// we're going to crash without renderer!
- wxCHECK_MSG( m_popupMenu, NULL, _T("neither popup nor menubar menu?") );
+ wxCHECK_MSG( m_popupMenu, NULL, wxT("neither popup nor menubar menu?") );
return m_popupMenu->GetRenderer();
}
if ( IsShown() )
{
// this would be a bug in IsShown()
- wxCHECK_RET( m_popupMenu, _T("must have popup window if shown!") );
+ wxCHECK_RET( m_popupMenu, wxT("must have popup window if shown!") );
// recalc geometry to update the item height and such
(void)GetGeometryInfo();
}
else
{
- wxFAIL_MSG( _T("parent menu not shown?") );
+ wxFAIL_MSG( wxT("parent menu not shown?") );
}
// and if we dismiss everything, propagate to parent
}
else // popup menu
{
- wxCHECK_RET( m_invokingWindow, _T("what kind of menu is this?") );
-
- m_invokingWindow->DismissPopupMenu();
+ wxWindow * const win = GetInvokingWindow();
+ wxCHECK_RET( win, wxT("what kind of menu is this?") );
- // Why reset it here? We need it for sending the event to...
- // SetInvokingWindow(NULL);
+ win->DismissPopupMenu();
}
}
}
// always keep the focus at the originating window
wxWindow *focus = GetRootWindow();
- wxASSERT_MSG( focus, _T("no window to keep focus on?") );
+ wxASSERT_MSG( focus, wxT("no window to keep focus on?") );
// and show it
m_popupMenu->Popup(focus);
void wxMenu::Dismiss()
{
- wxCHECK_RET( IsShown(), _T("can't dismiss hidden menu") );
+ wxCHECK_RET( IsShown(), wxT("can't dismiss hidden menu") );
m_popupMenu->Dismiss();
}
bool wxMenu::ProcessKeyDown(int key)
{
wxCHECK_MSG( m_popupMenu, false,
- _T("can't process key events if not shown") );
+ wxT("can't process key events if not shown") );
return m_popupMenu->ProcessKeyDown(key);
}
return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
}
-/* static */
-wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
-{
- return wxStripMenuCodes(text);
-}
-
// ----------------------------------------------------------------------------
// wxMenuItem operations
// ----------------------------------------------------------------------------
m_indexAccel = wxControl::FindAccelIndex(m_text);
// will be empty if the text contains no TABs - ok
- m_strAccel = m_text.AfterFirst(_T('\t'));
+ m_strAccel = m_text.AfterFirst(wxT('\t'));
}
-void wxMenuItem::SetText(const wxString& text)
+void wxMenuItem::SetItemLabel(const wxString& text)
{
if ( text != m_text )
{
// first call the base class version to change m_text
// (and also check if we don't have a stock menu item)
- wxMenuItemBase::SetText(text);
+ wxMenuItemBase::SetItemLabel(text);
UpdateAccelInfo();
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?") );
+ wxT("menuitem not found in the menu items list?") );
// get the radio group range
int start,
void wxMenuItem::SetRadioGroupStart(int start)
{
wxASSERT_MSG( !m_isRadioGroupStart,
- _T("should only be called for the next radio items") );
+ wxT("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") );
+ wxT("should only be called for the first radio item") );
m_radioGroup.end = end;
}
void wxMenuBar::Attach(wxFrame *frame)
{
// maybe you really wanted to call Detach()?
- wxCHECK_RET( frame, _T("wxMenuBar::Attach(NULL) called") );
+ wxCHECK_RET( frame, wxT("wxMenuBar::Attach(NULL) called") );
wxMenuBarBase::Attach(frame);
void wxMenuBar::EnableTop(size_t pos, bool enable)
{
- wxCHECK_RET( pos < GetCount(), _T("invalid index in EnableTop") );
+ wxCHECK_RET( pos < GetCount(), wxT("invalid index in EnableTop") );
if ( enable != m_menuInfos[pos].IsEnabled() )
{
bool wxMenuBar::IsEnabledTop(size_t pos) const
{
- wxCHECK_MSG( pos < GetCount(), false, _T("invalid index in IsEnabledTop") );
+ wxCHECK_MSG( pos < GetCount(), false, wxT("invalid index in IsEnabledTop") );
return m_menuInfos[pos].IsEnabled();
}
-void wxMenuBar::SetLabelTop(size_t pos, const wxString& label)
+void wxMenuBar::SetMenuLabel(size_t pos, const wxString& label)
{
- wxCHECK_RET( pos < GetCount(), _T("invalid index in EnableTop") );
+ wxCHECK_RET( pos < GetCount(), wxT("invalid index in SetMenuLabel") );
- if ( label != m_menuInfos[pos].GetLabel() )
+ if ( label != m_menuInfos[pos].GetOriginalLabel() )
{
m_menuInfos[pos].SetLabel(label);
//else: nothing to do
}
-wxString wxMenuBar::GetLabelTop(size_t pos) const
+wxString wxMenuBar::GetMenuLabel(size_t pos) const
{
- wxCHECK_MSG( pos < GetCount(), wxEmptyString, _T("invalid index in GetLabelTop") );
+ wxCHECK_MSG( pos < GetCount(), wxEmptyString, wxT("invalid index in GetMenuLabel") );
- return m_menuInfos[pos].GetLabel();
+ return m_menuInfos[pos].GetOriginalLabel();
}
// ----------------------------------------------------------------------------
void wxMenuBar::RefreshItem(size_t pos)
{
wxCHECK_RET( pos != (size_t)-1,
- _T("invalid item in wxMenuBar::RefreshItem") );
+ wxT("invalid item in wxMenuBar::RefreshItem") );
if ( !IsCreated() )
{
wxRect wxMenuBar::GetItemRect(size_t pos) const
{
- wxASSERT_MSG( pos < GetCount(), _T("invalid menu bar item index") );
- wxASSERT_MSG( IsCreated(), _T("can't call this method yet") );
+ wxASSERT_MSG( pos < GetCount(), wxT("invalid menu bar item index") );
+ wxASSERT_MSG( IsCreated(), wxT("can't call this method yet") );
wxRect rect;
rect.x =
{
wxClientDC dc(wxConstCast(this, wxMenuBar));
dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
- dc.GetTextExtent(GetLabelTop(0), &size.x, &size.y);
+ dc.GetTextExtent(GetMenuLabel(0), &size.x, &size.y);
// adjust for the renderer we use
size = GetRenderer()->GetMenuBarItemSize(size);
void wxMenuBar::SelectMenu(size_t pos)
{
SetFocus();
- wxLogTrace(_T("mousecapture"), _T("Capturing mouse from wxMenuBar::SelectMenu"));
+ wxLogTrace(wxT("mousecapture"), wxT("Capturing mouse from wxMenuBar::SelectMenu"));
CaptureMouse();
DoSelectMenu(pos);
void wxMenuBar::DoSelectMenu(size_t pos)
{
- wxCHECK_RET( pos < GetCount(), _T("invalid menu index in DoSelectMenu") );
+ wxCHECK_RET( pos < GetCount(), wxT("invalid menu index in DoSelectMenu") );
int posOld = m_current;
void wxMenuBar::PopupMenu(size_t pos)
{
- wxCHECK_RET( pos < GetCount(), _T("invalid menu index in PopupCurrentMenu") );
+ wxCHECK_RET( pos < GetCount(), wxT("invalid menu index in PopupCurrentMenu") );
SetFocus();
DoSelectMenu(pos);
}
else // on item
{
- wxLogTrace(_T("mousecapture"), _T("Capturing mouse from wxMenuBar::OnLeftDown"));
+ wxLogTrace(wxT("mousecapture"), wxT("Capturing mouse from wxMenuBar::OnLeftDown"));
CaptureMouse();
// show it as selected
{
// we always maintain a valid current item while we're in modal
// state (i.e. have the capture)
- wxFAIL_MSG( _T("how did we manage to lose current item?") );
+ wxFAIL_MSG( wxT("how did we manage to lose current item?") );
return;
}
int idxAccel = info.GetAccelIndex();
if ( idxAccel != -1 &&
- wxTolower(info.GetLabel()[(size_t)idxAccel])
- == chAccel )
+ (wxChar)wxTolower(info.GetLabel()[(size_t)idxAccel]) == chAccel )
{
// ok, found an item with this accel
if ( idxFound == -1 )
void wxMenuBar::PopupCurrentMenu(bool selectFirst)
{
- wxCHECK_RET( m_current != -1, _T("no menu to popup") );
+ wxCHECK_RET( m_current != -1, wxT("no menu to popup") );
// forgot to call DismissMenu()?
- wxASSERT_MSG( !m_menuShown, _T("shouldn't show two menus at once!") );
+ wxASSERT_MSG( !m_menuShown, wxT("shouldn't show two menus at once!") );
// in any case, we should show it - even if we won't
m_shouldShowMenu = true;
// item, not to the right of it
wxRect rectItem = GetItemRect(m_current);
- m_menuShown->SetInvokingWindow(m_frameLast);
-
m_menuShown->Popup(ClientToScreen(rectItem.GetPosition()),
wxSize(0, rectItem.GetHeight()),
selectFirst);
void wxMenuBar::DismissMenu()
{
- wxCHECK_RET( m_menuShown, _T("can't dismiss menu if none is shown") );
+ wxCHECK_RET( m_menuShown, wxT("can't dismiss menu if none is shown") );
m_menuShown->Dismiss();
OnDismissMenu();
void wxMenuBar::OnDismiss()
{
if ( ReleaseMouseCapture() )
- wxLogTrace(_T("mousecapture"), _T("Releasing mouse from wxMenuBar::OnDismiss"));
+ {
+ wxLogTrace(wxT("mousecapture"), wxT("Releasing mouse from wxMenuBar::OnDismiss"));
+ }
if ( m_current != -1 )
{
bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
{
wxCHECK_MSG( !ms_evtLoopPopup, false,
- _T("can't show more than one popup menu at a time") );
+ wxT("can't show more than one popup menu at a time") );
#ifdef __WXMSW__
// we need to change the cursor before showing the menu as, apparently, no
Update();
#endif // 0
- menu->SetInvokingWindow(this);
-
- // wxLogDebug( "Name of invoking window %s", menu->GetInvokingWindow()->GetName().c_str() );
-
menu->Popup(ClientToScreen(wxPoint(x, y)), wxSize(0,0));
// this is not very useful if the menu was popped up because of the mouse
ms_evtLoopPopup = new wxEventLoop;
ms_evtLoopPopup->Run();
- delete ms_evtLoopPopup;
- ms_evtLoopPopup = NULL;
+ wxDELETE(ms_evtLoopPopup);
// remove the handler
PopEventHandler(true /* delete it */);
- menu->SetInvokingWindow(NULL);
-
#ifdef __WXMSW__
SetCursor(cursorOld);
#endif // __WXMSW__
void wxWindow::DismissPopupMenu()
{
- wxCHECK_RET( ms_evtLoopPopup, _T("no popup menu shown") );
+ wxCHECK_RET( ms_evtLoopPopup, wxT("no popup menu shown") );
ms_evtLoopPopup->Exit();
}