X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7739f9c947aa1d7ad2a0c70a112fed820f909d96..a7d696f13d3e38b5502999f0c19d482157881ae8:/src/common/menucmn.cpp diff --git a/src/common/menucmn.cpp b/src/common/menucmn.cpp index 0d2d14bf0a..517142f4e2 100644 --- a/src/common/menucmn.cpp +++ b/src/common/menucmn.cpp @@ -30,6 +30,7 @@ #include "wx/intl.h" #include "wx/log.h" #include "wx/menu.h" + #include "wx/frame.h" #endif #include "wx/stockitem.h" @@ -47,6 +48,176 @@ WX_DEFINE_LIST(wxMenuItemList) // implementation // ============================================================================ +// ---------------------------------------------------------------------------- +// XTI for wxMenu(Bar) +// ---------------------------------------------------------------------------- + +wxDEFINE_FLAGS( wxMenuStyle ) +wxBEGIN_FLAGS( wxMenuStyle ) +wxFLAGS_MEMBER(wxMENU_TEAROFF) +wxEND_FLAGS( wxMenuStyle ) + +wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxMenu, wxEvtHandler, "wx/menu.h") +wxCOLLECTION_TYPE_INFO( wxMenuItem *, wxMenuItemList ) ; + +#if wxUSE_EXTENDED_RTTI +template<> void wxCollectionToVariantArray( wxMenuItemList const &theList, + wxAnyList &value) +{ + wxListCollectionToAnyList( theList, value ) ; +} +#endif + +wxBEGIN_PROPERTIES_TABLE(wxMenu) +wxEVENT_PROPERTY( Select, wxEVT_COMMAND_MENU_SELECTED, wxCommandEvent) + +wxPROPERTY( Title, wxString, SetTitle, GetTitle, wxString(), \ + 0 /*flags*/, wxT("Helpstring"), wxT("group") ) + +wxREADONLY_PROPERTY_FLAGS( MenuStyle, wxMenuStyle, long, GetStyle, \ + wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, wxT("Helpstring"), \ + wxT("group")) // style + +wxPROPERTY_COLLECTION( MenuItems, wxMenuItemList, wxMenuItem*, Append, \ + GetMenuItems, 0 /*flags*/, wxT("Helpstring"), wxT("group")) +wxEND_PROPERTIES_TABLE() + +wxEMPTY_HANDLERS_TABLE(wxMenu) + +wxDIRECT_CONSTRUCTOR_2( wxMenu, wxString, Title, long, MenuStyle ) + +wxDEFINE_FLAGS( wxMenuBarStyle ) + +wxBEGIN_FLAGS( wxMenuBarStyle ) +wxFLAGS_MEMBER(wxMB_DOCKABLE) +wxEND_FLAGS( wxMenuBarStyle ) + +#if wxUSE_EXTENDED_RTTI +// the negative id would lead the window (its superclass !) to +// vetoe streaming out otherwise +bool wxMenuBarStreamingCallback( const wxObject *WXUNUSED(object), wxObjectWriter *, + wxObjectWriterCallback *, const wxStringToAnyHashMap & ) +{ + return true; +} +#endif + +wxIMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxMenuBar, wxWindow, "wx/menu.h", \ + wxMenuBarStreamingCallback) + + +#if wxUSE_EXTENDED_RTTI +WX_DEFINE_LIST( wxMenuInfoHelperList ) + +wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxMenuInfoHelper, wxObject, "wx/menu.h") + +wxBEGIN_PROPERTIES_TABLE(wxMenuInfoHelper) +wxREADONLY_PROPERTY( Menu, wxMenu*, GetMenu, wxEMPTY_PARAMETER_VALUE, \ + 0 /*flags*/, wxT("Helpstring"), wxT("group")) + +wxREADONLY_PROPERTY( Title, wxString, GetTitle, wxString(), \ + 0 /*flags*/, wxT("Helpstring"), wxT("group")) +wxEND_PROPERTIES_TABLE() + +wxEMPTY_HANDLERS_TABLE(wxMenuInfoHelper) + +wxCONSTRUCTOR_2( wxMenuInfoHelper, wxMenu*, Menu, wxString, Title ) + +wxCOLLECTION_TYPE_INFO( wxMenuInfoHelper *, wxMenuInfoHelperList ) ; + +template<> void wxCollectionToVariantArray( wxMenuInfoHelperList const &theList, + wxAnyList &value) +{ + wxListCollectionToAnyList( theList, value ) ; +} + +#endif + +wxBEGIN_PROPERTIES_TABLE(wxMenuBar) +wxPROPERTY_COLLECTION( MenuInfos, wxMenuInfoHelperList, wxMenuInfoHelper*, AppendMenuInfo, \ + GetMenuInfos, 0 /*flags*/, wxT("Helpstring"), wxT("group")) +wxEND_PROPERTIES_TABLE() + +wxEMPTY_HANDLERS_TABLE(wxMenuBar) + +wxCONSTRUCTOR_DUMMY( wxMenuBar ) + +#if wxUSE_EXTENDED_RTTI + +const wxMenuInfoHelperList& wxMenuBarBase::GetMenuInfos() const +{ + wxMenuInfoHelperList* list = const_cast< wxMenuInfoHelperList* > (& m_menuInfos); + WX_CLEAR_LIST( wxMenuInfoHelperList, *list); + for (size_t i = 0 ; i < GetMenuCount(); ++i) + { + wxMenuInfoHelper* info = new wxMenuInfoHelper(); + info->Create( GetMenu(i), GetMenuLabel(i)); + list->Append(info); + } + return m_menuInfos; +} + +#endif + +// ---------------------------------------------------------------------------- +// XTI for wxMenuItem +// ---------------------------------------------------------------------------- + +#if wxUSE_EXTENDED_RTTI + +bool wxMenuItemStreamingCallback( const wxObject *object, wxObjectWriter *, + wxObjectWriterCallback *, const wxStringToAnyHashMap & ) +{ + const wxMenuItem * mitem = wx_dynamic_cast(const wxMenuItem*, object); + if ( mitem->GetMenu() && !mitem->GetMenu()->GetTitle().empty() ) + { + // we don't stream out the first two items for menus with a title, + // they will be reconstructed + if ( mitem->GetMenu()->FindItemByPosition(0) == mitem || + mitem->GetMenu()->FindItemByPosition(1) == mitem ) + return false; + } + return true; +} + +#endif + +wxBEGIN_ENUM( wxItemKind ) +wxENUM_MEMBER( wxITEM_SEPARATOR ) +wxENUM_MEMBER( wxITEM_NORMAL ) +wxENUM_MEMBER( wxITEM_CHECK ) +wxENUM_MEMBER( wxITEM_RADIO ) +wxEND_ENUM( wxItemKind ) + +wxIMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxMenuItem, wxObject, "wx/menuitem.h", \ + wxMenuItemStreamingCallback) + +wxBEGIN_PROPERTIES_TABLE(wxMenuItem) +wxPROPERTY( Parent, wxMenu*, SetMenu, GetMenu, wxEMPTY_PARAMETER_VALUE, \ + 0 /*flags*/, wxT("Helpstring"), wxT("group") ) +wxPROPERTY( Id, int, SetId, GetId, wxEMPTY_PARAMETER_VALUE, \ + 0 /*flags*/, wxT("Helpstring"), wxT("group") ) +wxPROPERTY( ItemLabel, wxString, SetItemLabel, GetItemLabel, wxString(), \ + 0 /*flags*/, wxT("Helpstring"), wxT("group") ) +wxPROPERTY( Help, wxString, SetHelp, GetHelp, wxString(), \ + 0 /*flags*/, wxT("Helpstring"), wxT("group") ) +wxREADONLY_PROPERTY( Kind, wxItemKind, GetKind, wxEMPTY_PARAMETER_VALUE, \ + 0 /*flags*/, wxT("Helpstring"), wxT("group") ) +wxPROPERTY( SubMenu, wxMenu*, SetSubMenu, GetSubMenu, wxEMPTY_PARAMETER_VALUE, \ + 0 /*flags*/, wxT("Helpstring"), wxT("group") ) +wxPROPERTY( Enabled, bool, Enable, IsEnabled, wxAny((bool)true), \ + 0 /*flags*/, wxT("Helpstring"), wxT("group") ) +wxPROPERTY( Checked, bool, Check, IsChecked, wxAny((bool)false), \ + 0 /*flags*/, wxT("Helpstring"), wxT("group") ) +wxPROPERTY( Checkable, bool, SetCheckable, IsCheckable, wxAny((bool)false), \ + 0 /*flags*/, wxT("Helpstring"), wxT("group") ) +wxEND_PROPERTIES_TABLE() + +wxEMPTY_HANDLERS_TABLE(wxMenuItem) + +wxDIRECT_CONSTRUCTOR_6( wxMenuItem, wxMenu*, Parent, int, Id, wxString, \ + Text, wxString, Help, wxItemKind, Kind, wxMenu*, SubMenu ) + // ---------------------------------------------------------------------------- // wxMenuItemBase // ---------------------------------------------------------------------------- @@ -58,6 +229,39 @@ wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu, wxItemKind kind, wxMenu *subMenu) { + switch ( id ) + { + case wxID_ANY: + m_id = wxWindow::NewControlId(); + break; + + case wxID_SEPARATOR: + m_id = wxID_SEPARATOR; + + // there is a lot of existing code just doing Append(wxID_SEPARATOR) + // and it makes sense to omit the following optional parameters, + // including the kind one which doesn't default to wxITEM_SEPARATOR, + // of course, so override it here + kind = wxITEM_SEPARATOR; + break; + + case wxID_NONE: + // (popup) menu titles in wxMSW use this ID to indicate that + // it's not a real menu item, so we don't want the check below to + // apply to it + m_id = id; + break; + + default: + // ids are limited to 16 bits under MSW so portable code shouldn't + // use ids outside of this range (negative ids generated by wx are + // fine though) + wxASSERT_MSG( (id >= 0 && id < SHRT_MAX) || + (id >= wxID_AUTO_LOWEST && id <= wxID_AUTO_HIGHEST), + wxS("invalid id value") ); + m_id = id; + } + // notice that parentMenu can be NULL: the item can be attached to the menu // later with SetMenu() @@ -65,12 +269,7 @@ wxMenuItemBase::wxMenuItemBase(wxMenu *parentMenu, m_subMenu = subMenu; m_isEnabled = true; m_isChecked = false; - m_id = id; m_kind = kind; - if (m_id == wxID_ANY) - m_id = wxWindow::NewControlId(); - if (m_id == wxID_SEPARATOR) - m_kind = wxITEM_SEPARATOR; SetItemLabel(text); SetHelp(help); @@ -513,23 +712,18 @@ void wxMenuBase::SetInvokingWindow(wxWindow *win) m_invokingWindow = win; } -wxWindow *wxMenuBase::GetInvokingWindow() const +wxWindow *wxMenuBase::GetWindow() const { - // only the popup menu itself has a non-NULL invoking window so recurse - // upwards until we find it + // only the top level menus have non-NULL invoking window or a pointer to + // the menu bar so recurse upwards until we find it const wxMenuBase *menu = this; while ( menu->GetParent() ) { menu = menu->GetParent(); } - // menu is a top level menu here - return menu->m_invokingWindow; -} - -wxWindow *wxMenuBase::GetWindow() const -{ - return GetMenuBar() ? GetMenuBar()->GetFrame() : GetInvokingWindow(); + return menu->GetMenuBar() ? menu->GetMenuBar()->GetFrame() + : menu->GetInvokingWindow(); } // ----------------------------------------------------------------------------