X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/84c5131950767b011faa9cbab9ef389923d17597..081d8d96db3bfe4dc490a6244b17184366846738:/src/gtk1/menu.cpp diff --git a/src/gtk1/menu.cpp b/src/gtk1/menu.cpp index 5e3f79fba5..062d90778f 100644 --- a/src/gtk1/menu.cpp +++ b/src/gtk1/menu.cpp @@ -25,6 +25,7 @@ #endif // wxUSE_ACCEL #include "wx/gtk1/private.h" +#include "wx/gtk1/private/mnemonics.h" #include @@ -141,21 +142,21 @@ static void DoCommonMenuCallbackCode(wxMenu *menu, wxMenuEvent& event) if (handler && handler->ProcessEvent(event)) return; - wxWindow *win = menu->GetInvokingWindow(); + wxWindow *win = menu->GetWindow(); if (win) - win->GetEventHandler()->ProcessEvent( event ); + win->HandleWindowEvent( event ); } extern "C" { -static void gtk_menu_open_callback( GtkWidget *widget, wxMenu *menu ) +static void gtk_menu_open_callback( GtkWidget *WXUNUSED(widget), wxMenu *menu ) { wxMenuEvent event(wxEVT_MENU_OPEN, -1, menu); DoCommonMenuCallbackCode(menu, event); } -static void gtk_menu_close_callback( GtkWidget *widget, wxMenuBar *menubar ) +static void gtk_menu_close_callback( GtkWidget *WXUNUSED(widget), wxMenuBar *menubar ) { if ( !menubar->GetMenuCount() ) { @@ -181,10 +182,9 @@ void wxMenuBar::Init(size_t n, wxMenu *menus[], const wxString titles[], long st // the parent window is known after wxFrame::SetMenu() m_needParent = false; m_style = style; - m_invokingWindow = (wxWindow*) NULL; - if (!PreCreation( (wxWindow*) NULL, wxDefaultPosition, wxDefaultSize ) || - !CreateBase( (wxWindow*) NULL, -1, wxDefaultPosition, wxDefaultSize, style, wxDefaultValidator, wxT("menubar") )) + if (!PreCreation( NULL, wxDefaultPosition, wxDefaultSize ) || + !CreateBase( NULL, -1, wxDefaultPosition, wxDefaultSize, style, wxDefaultValidator, wxT("menubar") )) { wxFAIL_MSG( wxT("wxMenuBar creation failed") ); return; @@ -241,10 +241,8 @@ wxMenuBar::~wxMenuBar() { } -static void wxMenubarUnsetInvokingWindow( wxMenu *menu, wxWindow *win ) +static void DetachFromFrame( wxMenu *menu, wxWindow *win ) { - menu->SetInvokingWindow( (wxWindow*) NULL ); - wxWindow *top_frame = win; while (top_frame->GetParent() && !(top_frame->IsTopLevel())) top_frame = top_frame->GetParent(); @@ -257,15 +255,13 @@ static void wxMenubarUnsetInvokingWindow( wxMenu *menu, wxWindow *win ) { wxMenuItem *menuitem = node->GetData(); if (menuitem->IsSubMenu()) - wxMenubarUnsetInvokingWindow( menuitem->GetSubMenu(), win ); + DetachFromFrame( menuitem->GetSubMenu(), win ); node = node->GetNext(); } } -static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win ) +static void AttachToFrame( wxMenu *menu, wxWindow *win ) { - menu->SetInvokingWindow( win ); - wxWindow *top_frame = win; while (top_frame->GetParent() && !(top_frame->IsTopLevel())) top_frame = top_frame->GetParent(); @@ -280,14 +276,15 @@ static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win ) { wxMenuItem *menuitem = node->GetData(); if (menuitem->IsSubMenu()) - wxMenubarSetInvokingWindow( menuitem->GetSubMenu(), win ); + AttachToFrame( menuitem->GetSubMenu(), win ); node = node->GetNext(); } } -void wxMenuBar::SetInvokingWindow( wxWindow *win ) +void wxMenuBar::Attach( wxFrame *win ) { - m_invokingWindow = win; + wxMenuBarBase::Attach(win); + wxWindow *top_frame = win; while (top_frame->GetParent() && !(top_frame->IsTopLevel())) top_frame = top_frame->GetParent(); @@ -301,15 +298,14 @@ void wxMenuBar::SetInvokingWindow( wxWindow *win ) while (node) { wxMenu *menu = node->GetData(); - wxMenubarSetInvokingWindow( menu, win ); + AttachToFrame( menu, win ); node = node->GetNext(); } } -void wxMenuBar::UnsetInvokingWindow( wxWindow *win ) +void wxMenuBar::Detach() { - m_invokingWindow = (wxWindow*) NULL; - wxWindow *top_frame = win; + wxWindow *top_frame = m_menuBarFrame; while (top_frame->GetParent() && !(top_frame->IsTopLevel())) top_frame = top_frame->GetParent(); @@ -320,9 +316,11 @@ void wxMenuBar::UnsetInvokingWindow( wxWindow *win ) while (node) { wxMenu *menu = node->GetData(); - wxMenubarUnsetInvokingWindow( menu, win ); + DetachFromFrame( menu, top_frame ); node = node->GetNext(); } + + wxMenuBarBase::Detach(); } bool wxMenuBar::Append( wxMenu *menu, const wxString &title ) @@ -370,11 +368,9 @@ bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title, int pos) GTK_SIGNAL_FUNC(gtk_menu_open_callback), (gpointer)menu ); - // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables - // addings menu later on. - if (m_invokingWindow) + if (m_menuBarFrame) { - wxMenubarSetInvokingWindow( menu, m_invokingWindow ); + AttachToFrame( menu, m_menuBarFrame ); // OPTIMISE ME: we should probably cache this, or pass it // directly, but for now this is a minimal @@ -382,10 +378,7 @@ bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title, int pos) // see (and refactor :) similar code in Remove // below. - wxFrame *frame = wxDynamicCast( m_invokingWindow, wxFrame ); - - if( frame ) - frame->UpdateMenuBarSize(); + m_menuBarFrame->UpdateMenuBarSize(); } return true; @@ -410,7 +403,7 @@ wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title) wxMenu *menuOld = Remove(pos); if ( menuOld && !Insert(pos, menu, title) ) { - return (wxMenu*) NULL; + return NULL; } // either Insert() succeeded or Remove() failed and menuOld is NULL @@ -421,7 +414,7 @@ wxMenu *wxMenuBar::Remove(size_t pos) { wxMenu *menu = wxMenuBarBase::Remove(pos); if ( !menu ) - return (wxMenu*) NULL; + return NULL; gtk_menu_item_remove_submenu( GTK_MENU_ITEM(menu->m_owner) ); gtk_container_remove(GTK_CONTAINER(m_menubar), menu->m_owner); @@ -429,13 +422,10 @@ wxMenu *wxMenuBar::Remove(size_t pos) gtk_widget_destroy( menu->m_owner ); menu->m_owner = NULL; - if (m_invokingWindow) + if (m_menuBarFrame) { // OPTIMISE ME: see comment in GtkAppend - wxFrame *frame = wxDynamicCast( m_invokingWindow, wxFrame ); - - if( frame ) - frame->UpdateMenuBarSize(); + m_menuBarFrame->UpdateMenuBarSize(); } return menu; @@ -443,7 +433,7 @@ wxMenu *wxMenuBar::Remove(size_t pos) static int FindMenuItemRecursive( const wxMenu *menu, const wxString &menuString, const wxString &itemString ) { - if (wxMenuItem::GetLabelText(wxConvertFromGTKToWXLabel(menu->GetTitle())) == wxMenuItem::GetLabelText(menuString)) + if (wxMenuItem::GetLabelText(menu->GetTitle()) == wxMenuItem::GetLabelText(menuString)) { int res = menu->FindItem( itemString ); if (res != wxNOT_FOUND) @@ -510,7 +500,7 @@ wxMenuItem* wxMenuBar::FindItem( int id, wxMenu **menuForItem ) const if ( menuForItem ) { - *menuForItem = result ? result->GetMenu() : (wxMenu *)NULL; + *menuForItem = result ? result->GetMenu() : NULL; } return result; @@ -536,7 +526,7 @@ wxString wxMenuBar::GetMenuLabel( size_t pos ) const wxMenu* menu = node->GetData(); - return wxConvertFromGTKToWXLabel(menu->GetTitle()); + return menu->GetTitle(); } void wxMenuBar::SetMenuLabel( size_t pos, const wxString& label ) @@ -578,8 +568,8 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) int id = menu->FindMenuIdByMenuItem(widget); /* should find it for normal (not popup) menu */ - wxASSERT_MSG( (id != -1) || (menu->GetInvokingWindow() != NULL), - _T("menu item not found in gtk_menu_clicked_callback") ); + wxASSERT_MSG( (id != -1) || (menu->GetWindow() != NULL), + wxT("menu item not found in gtk_menu_clicked_callback") ); if (!menu->IsEnabled(id)) return; @@ -619,7 +609,7 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) // FIXME: why do we have to call wxFrame::GetEventHandler() directly here? // normally wxMenu::SendEvent() should be enough, if it doesn't work - // in wxGTK then we have a bug in wxMenu::GetInvokingWindow() which + // in wxGTK then we have a bug in wxMenu::GetWindow() which // should be fixed instead of working around it here... if (frame) { @@ -632,7 +622,7 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) commandEvent.SetInt(item->IsChecked()); commandEvent.SetEventObject(menu); - frame->GetEventHandler()->ProcessEvent(commandEvent); + frame->HandleWindowEvent(commandEvent); } else { @@ -665,8 +655,8 @@ static void gtk_menu_hilight_callback( GtkWidget *widget, wxMenu *menu ) if (handler && handler->ProcessEvent(event)) return; - wxWindow *win = menu->GetInvokingWindow(); - if (win) win->GetEventHandler()->ProcessEvent( event ); + wxWindow *win = menu->GetWindow(); + if (win) win->HandleWindowEvent( event ); } } @@ -693,9 +683,9 @@ static void gtk_menu_nolight_callback( GtkWidget *widget, wxMenu *menu ) if (handler && handler->ProcessEvent(event)) return; - wxWindow *win = menu->GetInvokingWindow(); + wxWindow *win = menu->GetWindow(); if (win) - win->GetEventHandler()->ProcessEvent( event ); + win->HandleWindowEvent( event ); } } @@ -740,8 +730,8 @@ wxMenuItem::wxMenuItem(wxMenu *parentMenu, void wxMenuItem::Init() { - m_labelWidget = (GtkWidget *) NULL; - m_menuItem = (GtkWidget *) NULL; + m_labelWidget = NULL; + m_menuItem = NULL; DoSetText(m_text); } @@ -751,50 +741,12 @@ wxMenuItem::~wxMenuItem() // don't delete menu items, the menus take care of that } -// return the menu item text without any menu accels -/* static */ -wxString wxMenuItemBase::GetLabelText(const wxString& text) -{ - // The argument to this function will now always be in wxWidgets standard label - // format, not GTK+ format, so we do what the other ports do. - - return wxStripMenuCodes(text); - -#if 0 - wxString label; - - for ( const wxChar *pc = text.c_str(); *pc; pc++ ) - { - if ( *pc == wxT('\t')) - break; - - if ( *pc == wxT('_') ) - { - // GTK 1.2 escapes "xxx_xxx" to "xxx__xxx" - pc++; - label += *pc; - continue; - } - - if ( (*pc == wxT('&')) && (*(pc+1) != wxT('&')) ) - { - // wxMSW escapes "&" - // "&" is doubled to indicate "&" instead of accelerator - continue; - } - - label += *pc; - } - - // wxPrintf( wxT("GetLabelText(): text %s label %s\n"), text.c_str(), label.c_str() ); - - return label; -#endif -} - wxString wxMenuItem::GetItemLabel() const { - return wxConvertFromGTKToWXLabel(m_text); + wxString label = wxConvertFromGTKToWXLabel(m_text); + if (!m_hotKey.IsEmpty()) + label = label + wxT("\t") + m_hotKey; + return label; } void wxMenuItem::SetItemLabel( const wxString& string ) @@ -910,7 +862,7 @@ wxAcceleratorEntry *wxMenuItem::GetAccel() const if ( !GetHotKey() ) { // nothing - return (wxAcceleratorEntry *)NULL; + return NULL; } // accelerator parsing code looks for them after a TAB, so insert a dummy @@ -940,7 +892,7 @@ void wxMenuItem::Check( bool check ) break; default: - wxFAIL_MSG( _T("can't check this item") ); + wxFAIL_MSG( wxT("can't check this item") ); } } @@ -976,7 +928,7 @@ void wxMenu::Init() // our back by GTK+ e.g. when it is removed from menubar: gtk_widget_ref(m_menu); - m_owner = (GtkWidget*) NULL; + m_owner = NULL; // Tearoffs are entries, just like separators. So if we want this // menu to be a tear-off one, we just append a tearoff entry @@ -1013,6 +965,11 @@ wxMenu::~wxMenu() } } +wxString wxMenu::GetTitle() const +{ + return wxConvertMnemonicsFromGTK(wxMenuBase::GetTitle()); +} + bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos) { GtkWidget *menuItem; @@ -1027,7 +984,7 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos) } else if (mitem->GetBitmap().Ok()) { - text = mitem->wxMenuItembase::GetItemLabel(); + text = mitem->wxMenuItemBase::GetItemLabel(); const wxBitmap *bitmap = &mitem->GetBitmap(); // TODO @@ -1075,7 +1032,7 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos) } default: - wxFAIL_MSG( _T("unexpected menu item kind") ); + wxFAIL_MSG( wxT("unexpected menu item kind") ); // fall through case wxITEM_NORMAL: @@ -1129,12 +1086,6 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos) gtk_menu_item_set_submenu( GTK_MENU_ITEM(menuItem), mitem->GetSubMenu()->m_menu ); gtk_widget_show( mitem->GetSubMenu()->m_menu ); - - // if adding a submenu to a menu already existing in the menu bar, we - // must set invoking window to allow processing events from this - // submenu - if ( m_invokingWindow ) - wxMenubarSetInvokingWindow(mitem->GetSubMenu(), m_invokingWindow); } else { @@ -1189,7 +1140,7 @@ wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item) wxMenuItem *wxMenu::DoRemove(wxMenuItem *item) { if ( !wxMenuBase::DoRemove(item) ) - return (wxMenuItem *)NULL; + return NULL; // TODO: this code doesn't delete the item factory item and this seems // impossible as of GTK 1.2.6. @@ -1495,23 +1446,6 @@ void gtk_pop_hide_callback( GtkWidget *WXUNUSED(widget), bool* is_waiting ) *is_waiting = false; } -WXDLLIMPEXP_CORE void SetInvokingWindow( wxMenu *menu, wxWindow* win ) -{ - menu->SetInvokingWindow( win ); - - wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst(); - while (node) - { - wxMenuItem *menuitem = node->GetData(); - if (menuitem->IsSubMenu()) - { - SetInvokingWindow( menuitem->GetSubMenu(), win ); - } - - node = node->GetNext(); - } -} - extern "C" WXDLLIMPEXP_CORE void wxPopupMenuPositionCallback( GtkMenu *menu, gint *x, gint *y, @@ -1541,8 +1475,6 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) // the same code in taskbar.cpp as well. This // is ugly code duplication, I know. - SetInvokingWindow( menu, this ); - menu->UpdateUI(); bool is_waiting = true; @@ -1573,8 +1505,8 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y ) gtk_menu_popup( GTK_MENU(menu->m_menu), - (GtkWidget *) NULL, // parent menu shell - (GtkWidget *) NULL, // parent menu item + NULL, // parent menu shell + NULL, // parent menu item posfunc, // function to position it userdata, // client data 0, // button used to activate it