X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/937013e0fd914d4c42f9f5ec98da665986b93dfa..12bb29f5432174ecbd65549bda832d70d34a98ae:/src/gtk1/menu.cpp diff --git a/src/gtk1/menu.cpp b/src/gtk1/menu.cpp index 62906a4709..8449fc7a38 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,7 +142,7 @@ static void DoCommonMenuCallbackCode(wxMenu *menu, wxMenuEvent& event) if (handler && handler->ProcessEvent(event)) return; - wxWindow *win = menu->GetInvokingWindow(); + wxWindow *win = menu->GetWindow(); if (win) win->HandleWindowEvent( event ); } @@ -174,17 +175,14 @@ static void gtk_menu_close_callback( GtkWidget *WXUNUSED(widget), wxMenuBar *men // wxMenuBar //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxMenuBar,wxWindow) - void wxMenuBar::Init(size_t n, wxMenu *menus[], const wxString titles[], long style) { // 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 +239,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 +253,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 +274,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 +296,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 +314,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 +366,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 +376,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 +401,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 +412,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 +420,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 +431,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 +498,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 +524,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 +566,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,14 +607,14 @@ 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) { // If it is attached then let the frame send the event. // Don't call frame->ProcessCommand(id) because it toggles // checkable items and we've already done that above. - wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id); + wxCommandEvent commandEvent(wxEVT_MENU, id); commandEvent.SetEventObject(frame); if (item->IsCheckable()) commandEvent.SetInt(item->IsChecked()); @@ -665,7 +653,7 @@ static void gtk_menu_hilight_callback( GtkWidget *widget, wxMenu *menu ) if (handler && handler->ProcessEvent(event)) return; - wxWindow *win = menu->GetInvokingWindow(); + wxWindow *win = menu->GetWindow(); if (win) win->HandleWindowEvent( event ); } } @@ -693,7 +681,7 @@ 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->HandleWindowEvent( event ); } @@ -703,8 +691,6 @@ static void gtk_menu_nolight_callback( GtkWidget *widget, wxMenu *menu ) // wxMenuItem //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject) - wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu, int id, const wxString& name, @@ -740,8 +726,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,47 +737,6 @@ 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 { wxString label = wxConvertFromGTKToWXLabel(m_text); @@ -913,7 +858,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 @@ -943,7 +888,7 @@ void wxMenuItem::Check( bool check ) break; default: - wxFAIL_MSG( _T("can't check this item") ); + wxFAIL_MSG( wxT("can't check this item") ); } } @@ -969,8 +914,6 @@ bool wxMenuItem::IsChecked() const // wxMenu //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxMenu,wxEvtHandler) - void wxMenu::Init() { m_accel = gtk_accel_group_new(); @@ -979,7 +922,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 @@ -1016,6 +959,11 @@ wxMenu::~wxMenu() } } +wxString wxMenu::GetTitle() const +{ + return wxConvertMnemonicsFromGTK(wxMenuBase::GetTitle()); +} + bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos) { GtkWidget *menuItem; @@ -1028,7 +976,7 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem, int pos) // TODO menuItem = gtk_menu_item_new(); } - else if (mitem->GetBitmap().Ok()) + else if (mitem->GetBitmap().IsOk()) { text = mitem->wxMenuItemBase::GetItemLabel(); const wxBitmap *bitmap = &mitem->GetBitmap(); @@ -1078,7 +1026,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: @@ -1132,12 +1080,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 { @@ -1192,7 +1134,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. @@ -1498,23 +1440,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, @@ -1544,8 +1469,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; @@ -1576,8 +1499,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