X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d9e403cc40c289cf77950f3b5ac1dd057cdd142c..70ddb200c10bb6f1075f4a39452fdcf77f84fdf5:/src/gtk1/menu.cpp diff --git a/src/gtk1/menu.cpp b/src/gtk1/menu.cpp index 34cec7b657..16a8f31d6c 100644 --- a/src/gtk1/menu.cpp +++ b/src/gtk1/menu.cpp @@ -161,6 +161,25 @@ static wxString wxReplaceUnderscore( const wxString& title ) return str; } +//----------------------------------------------------------------------------- +// activate message from GTK +//----------------------------------------------------------------------------- + +static void gtk_menu_open_callback( GtkWidget *widget, wxMenu *menu ) +{ + if (g_isIdle) wxapp_install_idle_handler(); + + wxMenuEvent event( wxEVT_MENU_OPEN, -1 ); + event.SetEventObject( menu ); + + wxEvtHandler* handler = menu->GetEventHandler(); + if (handler && handler->ProcessEvent(event)) + return; + + wxWindow *win = menu->GetInvokingWindow(); + if (win) win->GetEventHandler()->ProcessEvent( event ); +} + //----------------------------------------------------------------------------- // wxMenuBar //----------------------------------------------------------------------------- @@ -357,7 +376,7 @@ bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title) buf << wxT('/') << str.c_str(); // local buffer in multibyte form - char cbuf[400]; + char cbuf[400]; strcpy(cbuf, wxGTK_CONV(buf) ); GtkItemFactoryEntry entry; @@ -368,7 +387,7 @@ bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title) entry.item_type = (char *)""; gtk_item_factory_create_item( m_factory, &entry, (gpointer) this, 2 ); // what is 2 ? - // in order to get the pointer to the item we need the item text _without_ underscores + // in order to get the pointer to the item we need the item text _without_ underscores wxString tmp = wxT("
/"); const wxChar *pc; for ( pc = str; *pc != wxT('\0'); pc++ ) @@ -392,6 +411,10 @@ bool wxMenuBar::GtkAppend(wxMenu *menu, const wxString& title) #endif + gtk_signal_connect( GTK_OBJECT(menu->m_owner), "activate", + 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) @@ -471,10 +494,10 @@ static wxMenu *CopyMenu (wxMenu *menu) else menucopy->Append (itemid, text, CopyMenu(submenu), menu->GetHelpString(itemid)); - + node = node->GetNext(); } - + return menucopy; } @@ -684,7 +707,7 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) if (item->IsCheckable()) { bool isReallyChecked = item->IsChecked(), - isInternallyChecked = item->wxMenuItemBase::IsChecked(); + isInternallyChecked = item->wxMenuItemBase::IsChecked(); // ensure that the internal state is always consistent with what is // shown on the screen @@ -697,11 +720,36 @@ static void gtk_menu_clicked_callback( GtkWidget *widget, wxMenu *menu ) { return; } + } + - // the user pressed on the menu item: report the event below + // Is this menu on a menubar? (possibly nested) + wxFrame* frame = NULL; + wxMenu* pm = menu; + while ( pm && !frame ) + { + if ( pm->IsAttached() ) + frame = pm->GetMenuBar()->GetFrame(); + pm = pm->GetParent(); } - menu->SendEvent(id, item->IsCheckable() ? item->IsChecked() : -1); + 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); + commandEvent.SetEventObject(frame); + if (item->IsCheckable()) + commandEvent.SetInt(item->IsChecked()); + + frame->GetEventHandler()->ProcessEvent(commandEvent); + } + else + { + // otherwise let the menu have it + menu->SendEvent(id, item->IsCheckable() ? item->IsChecked() : -1); + } } //----------------------------------------------------------------------------- @@ -722,7 +770,8 @@ static void gtk_menu_hilight_callback( GtkWidget *widget, wxMenu *menu ) wxMenuEvent event( wxEVT_MENU_HIGHLIGHT, id ); event.SetEventObject( menu ); - if (menu->GetEventHandler()->ProcessEvent(event)) + wxEvtHandler* handler = menu->GetEventHandler(); + if (handler && handler->ProcessEvent(event)) return; wxWindow *win = menu->GetInvokingWindow(); @@ -747,7 +796,8 @@ static void gtk_menu_nolight_callback( GtkWidget *widget, wxMenu *menu ) wxMenuEvent event( wxEVT_MENU_HIGHLIGHT, -1 ); event.SetEventObject( menu ); - if (menu->GetEventHandler()->ProcessEvent(event)) + wxEvtHandler* handler = menu->GetEventHandler(); + if (handler && handler->ProcessEvent(event)) return; wxWindow *win = menu->GetInvokingWindow(); @@ -839,10 +889,10 @@ wxString wxMenuItemBase::GetLabelFromText(const wxString& text) // "&" is doubled to indicate "&" instead of accelerator continue; } - + label += *pc; } - + // wxPrintf( L"text %s label %s\n", text.c_str(), label.c_str() ); return label; @@ -857,7 +907,7 @@ void wxMenuItem::SetText( const wxString& str ) wxString label1 = wxStripMenuCodes(str.BeforeFirst('\t')); if (oldLabel == label1) return; - + DoSetText(str); if (m_menuItem) @@ -876,7 +926,7 @@ void wxMenuItem::SetText( const wxString& str ) if (m_text[n] != wxT('\\')) tmp += m_text[n]; } - + gtk_label_set_text_with_mnemonic( GTK_LABEL(label), wxGTK_CONV(tmp) ); #else // set new text @@ -936,9 +986,9 @@ void wxMenuItem::DoSetText( const wxString& str ) } ++pc; } - + // wxPrintf( L"str %s m_text %s\n", str.c_str(), m_text.c_str() ); - + m_hotKey = wxT(""); if(*pc == wxT('\t')) @@ -1168,7 +1218,7 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) gtk_signal_connect( GTK_OBJECT(menuItem), "activate", GTK_SIGNAL_FUNC(gtk_menu_clicked_callback), (gpointer)this ); - + gtk_menu_append( GTK_MENU(m_menu), menuItem ); gtk_widget_show( menuItem ); @@ -1254,7 +1304,7 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) wxString path( mitem->GetFactoryPath() ); menuItem = gtk_item_factory_get_widget( m_factory, wxGTK_CONV( path ) ); - + if (!menuItem) wxLogError( wxT("Wrong menu path: %s\n"), path.c_str() ); } @@ -1262,7 +1312,7 @@ bool wxMenu::GtkAppend(wxMenuItem *mitem) if ( !mitem->IsSeparator() ) { wxASSERT_MSG( menuItem, wxT("invalid menuitem") ); - + gtk_signal_connect( GTK_OBJECT(menuItem), "select", GTK_SIGNAL_FUNC(gtk_menu_hilight_callback), (gpointer)this );