]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/menucmn.cpp
XML import corrections
[wxWidgets.git] / src / common / menucmn.cpp
index 74d5fd843dd779214bcf9a3b63750adab2782a6b..517142f4e2256a6f31fa2660b79ad329c0cc8b03 100644 (file)
@@ -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<wxMenuItemList::compatibility_iterator>( 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<wxMenuInfoHelperList::compatibility_iterator>( 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);
@@ -453,30 +652,17 @@ bool wxMenuBase::SendEvent(int id, int checked)
 
     bool processed = false;
 
-    // Try the menu's event handler
-    // if ( !processed )
-    {
-        wxEvtHandler *handler = GetEventHandler();
-        if ( handler )
-            processed = handler->SafelyProcessEvent(event);
-    }
+    // Try the menu's event handler first
+    wxEvtHandler *handler = GetEventHandler();
+    if ( handler )
+        processed = handler->SafelyProcessEvent(event);
 
-    // Try the window the menu was popped up from (and up through the
-    // hierarchy)
+    // Try the window the menu was popped up from or its menu bar belongs to
     if ( !processed )
     {
-        const wxMenuBase *menu = this;
-        while ( menu )
-        {
-            wxWindow *win = menu->GetInvokingWindow();
-            if ( win )
-            {
-                processed = win->HandleWindowEvent(event);
-                break;
-            }
-
-            menu = menu->GetParent();
-        }
+        wxWindow * const win = GetWindow();
+        if ( win )
+            processed = win->HandleWindowEvent(event);
     }
 
     return processed;
@@ -526,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();
 }
 
 // ----------------------------------------------------------------------------