diff --git a/Makefile.in b/Makefile.in index f5d86179ca..82c179b5f4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3537,7 +3537,6 @@ COND_TOOLKIT_OSX_IPHONE_GUI_HDR = \ wx/generic/icon.h \ wx/generic/imaglist.h \ wx/osx/iphone/chkconf.h \ - wx/osx/iphone/evtloop.h \ wx/osx/iphone/private.h \ wx/generic/region.h \ wx/osx/sound.h @@ -5691,7 +5690,9 @@ COND_TOOLKIT_OSX_IPHONE___GUI_SRC_OBJECTS = \ monodll_iphone_settings.o \ monodll_sound_osx.o \ monodll_core_sound.o \ - monodll_iphone_statbmp.o + monodll_iphone_statbmp.o \ + monodll_iphone_menuitem.o \ + monodll_iphone_menu.o @COND_TOOLKIT_OSX_IPHONE@__GUI_SRC_OBJECTS = $(COND_TOOLKIT_OSX_IPHONE___GUI_SRC_OBJECTS) COND_TOOLKIT_QT___GUI_SRC_OBJECTS = \ monodll_taskbarcmn.o \ @@ -7670,7 +7671,9 @@ COND_TOOLKIT_OSX_IPHONE___GUI_SRC_OBJECTS_1 = \ monolib_iphone_settings.o \ monolib_sound_osx.o \ monolib_core_sound.o \ - monolib_iphone_statbmp.o + monolib_iphone_statbmp.o \ + monolib_iphone_menuitem.o \ + monolib_iphone_menu.o @COND_TOOLKIT_OSX_IPHONE@__GUI_SRC_OBJECTS_1 = $(COND_TOOLKIT_OSX_IPHONE___GUI_SRC_OBJECTS_1) COND_TOOLKIT_QT___GUI_SRC_OBJECTS_1 = \ monolib_taskbarcmn.o \ @@ -9795,7 +9798,9 @@ COND_TOOLKIT_OSX_IPHONE___GUI_SRC_OBJECTS_2 = \ coredll_iphone_settings.o \ coredll_sound_osx.o \ coredll_core_sound.o \ - coredll_iphone_statbmp.o + coredll_iphone_statbmp.o \ + coredll_iphone_menuitem.o \ + coredll_iphone_menu.o @COND_TOOLKIT_OSX_IPHONE@__GUI_SRC_OBJECTS_2 = $(COND_TOOLKIT_OSX_IPHONE___GUI_SRC_OBJECTS_2) COND_TOOLKIT_QT___GUI_SRC_OBJECTS_2 = \ coredll_taskbarcmn.o \ @@ -11510,7 +11515,9 @@ COND_TOOLKIT_OSX_IPHONE___GUI_SRC_OBJECTS_3 = \ corelib_iphone_settings.o \ corelib_sound_osx.o \ corelib_core_sound.o \ - corelib_iphone_statbmp.o + corelib_iphone_statbmp.o \ + corelib_iphone_menuitem.o \ + corelib_iphone_menu.o @COND_TOOLKIT_OSX_IPHONE@__GUI_SRC_OBJECTS_3 = $(COND_TOOLKIT_OSX_IPHONE___GUI_SRC_OBJECTS_3) COND_TOOLKIT_QT___GUI_SRC_OBJECTS_3 = \ corelib_taskbarcmn.o \ @@ -16659,6 +16666,12 @@ monodll_iphone_settings.o: $(srcdir)/src/osx/iphone/settings.mm $(MONODLL_ODEP) monodll_iphone_statbmp.o: $(srcdir)/src/osx/iphone/statbmp.mm $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/statbmp.mm +monodll_iphone_menuitem.o: $(srcdir)/src/osx/iphone/menuitem.mm $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/menuitem.mm + +monodll_iphone_menu.o: $(srcdir)/src/osx/iphone/menu.mm $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/menu.mm + monodll_qt_accel.o: $(srcdir)/src/qt/accel.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/accel.cpp @@ -21912,6 +21925,12 @@ monolib_iphone_settings.o: $(srcdir)/src/osx/iphone/settings.mm $(MONOLIB_ODEP) monolib_iphone_statbmp.o: $(srcdir)/src/osx/iphone/statbmp.mm $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/statbmp.mm +monolib_iphone_menuitem.o: $(srcdir)/src/osx/iphone/menuitem.mm $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/menuitem.mm + +monolib_iphone_menu.o: $(srcdir)/src/osx/iphone/menu.mm $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/menu.mm + monolib_qt_accel.o: $(srcdir)/src/qt/accel.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/accel.cpp @@ -27822,6 +27841,12 @@ coredll_iphone_settings.o: $(srcdir)/src/osx/iphone/settings.mm $(COREDLL_ODEP) coredll_iphone_statbmp.o: $(srcdir)/src/osx/iphone/statbmp.mm $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/statbmp.mm +coredll_iphone_menuitem.o: $(srcdir)/src/osx/iphone/menuitem.mm $(COREDLL_ODEP) + $(CXXC) -c -o $@ $(COREDLL_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/menuitem.mm + +coredll_iphone_menu.o: $(srcdir)/src/osx/iphone/menu.mm $(COREDLL_ODEP) + $(CXXC) -c -o $@ $(COREDLL_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/menu.mm + coredll_qt_accel.o: $(srcdir)/src/qt/accel.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/accel.cpp @@ -32064,6 +32089,12 @@ corelib_iphone_settings.o: $(srcdir)/src/osx/iphone/settings.mm $(CORELIB_ODEP) corelib_iphone_statbmp.o: $(srcdir)/src/osx/iphone/statbmp.mm $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/statbmp.mm +corelib_iphone_menuitem.o: $(srcdir)/src/osx/iphone/menuitem.mm $(CORELIB_ODEP) + $(CXXC) -c -o $@ $(CORELIB_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/menuitem.mm + +corelib_iphone_menu.o: $(srcdir)/src/osx/iphone/menu.mm $(CORELIB_ODEP) + $(CXXC) -c -o $@ $(CORELIB_OBJCXXFLAGS) $(srcdir)/src/osx/iphone/menu.mm + corelib_qt_accel.o: $(srcdir)/src/qt/accel.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/accel.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index b0633e6049..b5c240db5f 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -2695,6 +2695,8 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/osx/sound_osx.cpp src/osx/core/sound.cpp src/osx/iphone/statbmp.mm + src/osx/iphone/menuitem.mm + src/osx/iphone/menu.mm diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake index 7dfedeebcf..f3db68b0bd 100644 --- a/build/cmake/files.cmake +++ b/build/cmake/files.cmake @@ -2565,6 +2565,8 @@ set(OSX_IPHONE_SRC src/osx/sound_osx.cpp src/osx/core/sound.cpp src/osx/iphone/statbmp.mm + src/osx/iphone/menuitem.mm + src/osx/iphone/menu.mm ) set(OSX_IPHONE_HDR diff --git a/build/files b/build/files index 469036da6d..759ab54db1 100644 --- a/build/files +++ b/build/files @@ -2533,6 +2533,8 @@ OSX_IPHONE_SRC = src/osx/iphone/dialog.mm src/osx/iphone/evtloop.mm src/osx/iphone/gauge.mm + src/osx/iphone/menu.mm + src/osx/iphone/menuitem.mm src/osx/iphone/msgdlg.mm src/osx/iphone/nonownedwnd.mm src/osx/iphone/scrolbar.mm diff --git a/build/osx/wxiphone.xcodeproj/project.pbxproj b/build/osx/wxiphone.xcodeproj/project.pbxproj index 175ff3d04e..5f78a8530d 100644 --- a/build/osx/wxiphone.xcodeproj/project.pbxproj +++ b/build/osx/wxiphone.xcodeproj/project.pbxproj @@ -227,6 +227,8 @@ 3E99016BDE043A08B4D6B3CE /* htmprint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 194ADD28300E329E80F7892E /* htmprint.cpp */; }; 3EB6B8528A0D3B6CADAE1256 /* archive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02D2E8B5C89939CE90B99E2B /* archive.cpp */; }; 3ED6F4B64C283232A79423CF /* dircmn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EC9B6DFBF2F73917A99361C5 /* dircmn.cpp */; }; + 400DE11324A9D41800F526FE /* menuitem.mm in Sources */ = {isa = PBXBuildFile; fileRef = 400DE11124A9D41800F526FE /* menuitem.mm */; }; + 400DE11424A9D41800F526FE /* menu.mm in Sources */ = {isa = PBXBuildFile; fileRef = 400DE11224A9D41800F526FE /* menu.mm */; }; 403FBA20CEFE3EAFB4E6B905 /* dir.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F7332A03D93D3DABB050615D /* dir.cpp */; }; 4040AE89BF9F34668091064A /* dragimgg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A67053D16D63C588E555C84 /* dragimgg.cpp */; }; 41943A8F82723027A151A468 /* fileconf.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 61DA2A4C0D143CBE804BB8A1 /* fileconf.cpp */; }; @@ -1058,6 +1060,8 @@ 3FB6D34C3029357EB64AECAA /* scrlwing.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = scrlwing.cpp; path = ../../src/generic/scrlwing.cpp; sourceTree = ""; }; 3FEBA7AC7F743EE88352AEBC /* htmlwin.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = htmlwin.cpp; path = ../../src/html/htmlwin.cpp; sourceTree = ""; }; 400275BE019D3E5BA47988BE /* inffast.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = inffast.c; path = ../../src/zlib/inffast.c; sourceTree = ""; }; + 400DE11124A9D41800F526FE /* menuitem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = menuitem.mm; path = ../../src/osx/iphone/menuitem.mm; sourceTree = ""; }; + 400DE11224A9D41800F526FE /* menu.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = menu.mm; path = ../../src/osx/iphone/menu.mm; sourceTree = ""; }; 4048A3523EC03409BD899BEF /* xtixml.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = xtixml.cpp; path = ../../src/common/xtixml.cpp; sourceTree = ""; }; 40586C8986443431A64EB066 /* LexLisp.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LexLisp.cxx; path = ../../src/stc/scintilla/lexers/LexLisp.cxx; sourceTree = ""; }; 4071FF90F1D4336C836B2AE4 /* tif_pixarlog.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = tif_pixarlog.c; path = ../../src/tiff/libtiff/tif_pixarlog.c; sourceTree = ""; }; @@ -2024,6 +2028,8 @@ 83B878A16ABC396E8C03A15E /* dialog.mm */, 8D2549709E0133C9A267E3A5 /* evtloop.mm */, 98A7F0605AAC3D28A8C9F253 /* gauge.mm */, + 400DE11224A9D41800F526FE /* menu.mm */, + 400DE11124A9D41800F526FE /* menuitem.mm */, 33CFE51FD6F0362092DF1A85 /* msgdlg.mm */, AECB45CEAC093CE4AB4B7E45 /* nonownedwnd.mm */, CC2E24773D853A77B9FEFA4C /* scrolbar.mm */, @@ -2824,7 +2830,7 @@ isa = PBXProject; attributes = { }; - buildConfigurationList = A66311F47C8832F6A58105B6 /* Build configuration list for PBXProject "wxiphone" */; + buildConfigurationList = A66311F47C8832F6A58105B6 /* Build configuration list for PBXProject "wxiPhone" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 1; @@ -3045,6 +3051,7 @@ 774EB9F3F7E93A379E1F7551 /* graphics.cpp in Sources */, 5792675690843C6AA4125A72 /* font.cpp in Sources */, BDAB44F5D017395D9D3A1F23 /* frame.cpp in Sources */, + 400DE11324A9D41800F526FE /* menuitem.mm in Sources */, 27E2EABB117334CD89CFD2A4 /* mdi.cpp in Sources */, 73AA68AB9F1236ED9F1FBB2E /* metafile.cpp in Sources */, 805CCAE64D023561AD334B53 /* popupwin.cpp in Sources */, @@ -3294,6 +3301,7 @@ 8AA341CCFB8E3F6AB3523595 /* splash.cpp in Sources */, 98F52D5224B438DFA8887E06 /* timectrlg.cpp in Sources */, 77BC918AF05C30E8A0BD27F8 /* tipdlg.cpp in Sources */, + 400DE11424A9D41800F526FE /* menu.mm in Sources */, 060E095718B03EF98C754799 /* treelist.cpp in Sources */, 82FA4AA043213728AC266700 /* wizard.cpp in Sources */, EC3D181D65F33E09A675FFF2 /* addremovectrl.cpp in Sources */, @@ -3771,7 +3779,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - A66311F47C8832F6A58105B6 /* Build configuration list for PBXProject "wxiphone" */ = { + A66311F47C8832F6A58105B6 /* Build configuration list for PBXProject "wxiPhone" */ = { isa = XCConfigurationList; buildConfigurations = ( 55C93151F6053EBCBDD70DF9 /* Debug */, diff --git a/include/wx/defs.h b/include/wx/defs.h index 4081892144..e25b1e8a52 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -2772,6 +2772,8 @@ typedef WX_NSPasteboard OSXPasteboard; #elif wxOSX_USE_IPHONE +DECLARE_WXCOCOA_OBJC_CLASS(UIMenu); +DECLARE_WXCOCOA_OBJC_CLASS(UIMenuItem); DECLARE_WXCOCOA_OBJC_CLASS(UIWindow); DECLARE_WXCOCOA_OBJC_CLASS(UImage); DECLARE_WXCOCOA_OBJC_CLASS(UIView); @@ -2786,6 +2788,7 @@ DECLARE_WXCOCOA_OBJC_CLASS(UIPasteboard); typedef WX_UIWindow WXWindow; typedef WX_UIView WXWidget; typedef WX_UIImage WXImage; +typedef WX_UIMenu WXHMENU; typedef WX_EAGLContext WXGLContext; typedef WX_NSString WXGLPixelFormat; typedef WX_UIWebView OSXWebViewPtr; diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp index 0d91f7fc75..65da9f35b6 100644 --- a/samples/minimal/minimal.cpp +++ b/samples/minimal/minimal.cpp @@ -147,7 +147,7 @@ MyFrame::MyFrame(const wxString& title) // set the frame icon SetIcon(wxICON(sample)); -#if wxUSE_MENUS +#if wxUSE_MENUBAR // create a menu bar wxMenu *fileMenu = new wxMenu; @@ -164,14 +164,14 @@ MyFrame::MyFrame(const wxString& title) // ... and attach this menu bar to the frame SetMenuBar(menuBar); -#else // !wxUSE_MENUS +#else // !wxUSE_MENUBAR // If menus are not available add a button to access the about box wxSizer* sizer = new wxBoxSizer(wxHORIZONTAL); wxButton* aboutBtn = new wxButton(this, wxID_ANY, "About..."); aboutBtn->Bind(wxEVT_BUTTON, &MyFrame::OnAbout, this); sizer->Add(aboutBtn, wxSizerFlags().Center()); SetSizer(sizer); -#endif // wxUSE_MENUS/!wxUSE_MENUS +#endif // wxUSE_MENUBAR/!wxUSE_MENUBAR #if wxUSE_STATUSBAR // create a status bar just for fun (by default with 1 pane only) diff --git a/src/osx/iphone/menu.mm b/src/osx/iphone/menu.mm new file mode 100644 index 0000000000..b64aaf3fa6 --- /dev/null +++ b/src/osx/iphone/menu.mm @@ -0,0 +1,324 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/osx/iphone/menu.mm +// Purpose: wxMenu +// Author: Stefan Csomor +// Modified by: +// Created: 1998-01-01 +// Copyright: (c) Stefan Csomor +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// headers & declarations +// ============================================================================ + +// wxWidgets headers +// ----------------- + +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/log.h" +#include "wx/app.h" +#include "wx/utils.h" +#include "wx/frame.h" +#include "wx/menuitem.h" +#include "wx/dialog.h" +#endif + +#include "wx/menu.h" + +#include "wx/osx/private.h" + +// other standard headers +// ---------------------- +#include +/* +@implementation wxUIMenu + +- (id) initWithTitle:(NSString*) title +{ + if ( self = [super initWithTitle:title] ) + { + impl = NULL; + } + return self; +} + +- (void)setImplementation: (wxMenuImpl *) theImplementation +{ + impl = theImplementation; +} + +- (wxMenuImpl*) implementation +{ + return impl; +} + +@end +*/ +// this is more compatible, as it is also called for command-key shortcuts +// and under 10.4, we are not getting a 'close' event however... +#define wxOSX_USE_NEEDSUPDATE_HOOK 1 + +@interface wxUIMenuController : NSObject // TODO wxIOS +{ +} + +#if wxOSX_USE_NEEDSUPDATE_HOOK +- (void)menuNeedsUpdate:(UIMenu*)smenu; +#else +- (void)menuWillOpen:(UIMenu *)menu; +#endif +- (void)menuDidClose:(UIMenu *)menu; +- (void)menu:(UIMenu *)menu willHighlightItem:(UIMenuItem *)item; + +@end + +@implementation wxUIMenuController + +- (id) init +{ + self = [super init]; + return self; +} + +/* +#if wxOSX_USE_NEEDSUPDATE_HOOK +- (void)menuNeedsUpdate:(UIMenu*)smenu +{ + wxUIMenu* menu = (wxUIMenu*) smenu; + wxMenuImpl* menuimpl = [menu implementation]; + if ( menuimpl ) + { + wxMenu* wxpeer = (wxMenu*) menuimpl->GetWXPeer(); + if ( wxpeer ) + wxpeer->HandleMenuOpened(); + } +} +#else +- (void)menuWillOpen:(UIMenu *)smenu +{ + wxUIMenu* menu = (wxUIMenu*) smenu; + wxMenuImpl* menuimpl = [menu implementation]; + if ( menuimpl ) + { + wxMenu* wxpeer = (wxMenu*) menuimpl->GetWXPeer(); + if ( wxpeer ) + wxpeer->HandleMenuOpened(); + } +} +#endif + +- (void)menuDidClose:(UIMenu *)smenu +{ + wxUIMenu* menu = (wxUIMenu*) smenu; + wxMenuImpl* menuimpl = [menu implementation]; + if ( menuimpl ) + { + wxMenu* wxpeer = (wxMenu*) menuimpl->GetWXPeer(); + if ( wxpeer ) + wxpeer->HandleMenuClosed(); + } +} + +- (void)menu:(UIMenu *)smenu willHighlightItem:(UIMenuItem *)item +{ + wxUIMenu* menu = (wxUIMenu*) smenu; + wxMenuImpl* menuimpl = [menu implementation]; + if ( menuimpl ) + { + wxMenuItem* menuitem = nullptr; + wxMenu* wxpeer = (wxMenu*) menuimpl->GetWXPeer(); + + if ( [ item isKindOfClass:[wxUIMenuItem class] ] ) + { + wxMenuItemImpl* menuitemimpl = (wxMenuItemImpl*) [ (wxUIMenuItem*) item implementation ]; + if ( menuitemimpl ) + { + menuitem = menuitemimpl->GetWXPeer(); + } + } + + if ( wxpeer ) + { + wxpeer->HandleMenuItemHighlighted( menuitem ); + } + } +} +*/ + +@end + +class wxMenuCocoaImpl : public wxMenuImpl +{ +public : + wxMenuCocoaImpl( wxMenu* peer , UIMenu* menu) : wxMenuImpl(peer), m_osxMenu(wxCFRetain(menu)) + { + /* + static wxUIMenuController* controller = NULL; + if ( controller == NULL ) + { + controller = [[wxUIMenuController alloc] init]; + } + [menu setDelegate:controller]; + [m_osxMenu setImplementation:this]; + // gc aware + if ( m_osxMenu ) + CFRetain(m_osxMenu); + [m_osxMenu release]; + */ + } + + virtual ~wxMenuCocoaImpl(); + + virtual void InsertOrAppend(wxMenuItem *pItem, size_t pos) wxOVERRIDE + { + UIMenuElement* uimenuitem = (UIMenuElement*) pItem->GetPeer()->GetHMenuItem(); + m_children.push_back(uimenuitem); + /* + // make sure a call of SetSubMenu is also reflected (occurring after Create) + // update the native menu item accordingly + + if ( pItem->IsSubMenu() ) + { + wxMenu* wxsubmenu = pItem->GetSubMenu(); + WXHMENU nssubmenu = wxsubmenu->GetHMenu(); + if ( [nsmenuitem submenu] != nssubmenu ) + { + wxsubmenu->GetPeer()->SetTitle( pItem->GetItemLabelText() ); + [nsmenuitem setSubmenu:nssubmenu]; + } + } + + if ( pos == (size_t) -1 ) + [m_osxMenu addItem:nsmenuitem ]; + else + [m_osxMenu insertItem:nsmenuitem atIndex:pos]; + */ + } + + virtual void Remove( wxMenuItem *pItem ) wxOVERRIDE + { + // [m_osxMenu removeItem:(UIMenuItem*) pItem->GetPeer()->GetHMenuItem()]; + } + + virtual void MakeRoot() wxOVERRIDE + { + } + + virtual void Enable( bool WXUNUSED(enable) ) + { + } + + virtual void SetTitle( const wxString& text ) wxOVERRIDE + { + // wxCFStringRef cfText(text); + // [m_osxMenu setTitle:cfText.AsNSString()]; + } + + virtual void PopUp( wxWindow *win, int x, int y ) wxOVERRIDE + { +#if 0 // TODO wxIOS + UIView *view = win->GetPeer()->GetWXWidget(); + + wxPoint screenPoint(x,y); + NSPoint pointInView = wxToNSPoint(view, win->ScreenToClient( screenPoint )); + + // action and validation methods are not called from macos for modal dialogs + // when using popUpMenuPositioningItem therefore we fall back to the older method + if ( wxDialog::OSXHasModalDialogsOpen() ) + { + // we don't want plug-ins interfering + m_osxMenu.allowsContextMenuPlugIns = NO; + + wxTopLevelWindow* tlw = static_cast(wxGetTopLevelParent(win)); + NSWindow* nsWindow = tlw->GetWXWindow(); + NSRect nsrect = NSZeroRect; + nsrect.origin = wxToNSPoint( NULL, screenPoint ); + nsrect = [nsWindow convertRectFromScreen:nsrect]; + + NSEvent* rightClick = [NSEvent mouseEventWithType:NSRightMouseDown + location:nsrect.origin + modifierFlags:0 + timestamp:0 + windowNumber:[nsWindow windowNumber] + context:nil + eventNumber:0 + clickCount:1 + pressure:0]; + + [UIMenu popUpContextMenu:m_osxMenu withEvent:rightClick forView:view]; + } + else + { + [m_osxMenu popUpMenuPositioningItem:nil atLocation:pointInView inView:view]; + } +#endif + } + + virtual void GetMenuBarDimensions(int &x, int &y, int &width, int &height) const wxOVERRIDE + { +#if 0 // TODO wxIOS + NSRect r = [(NSScreen*)[[NSScreen screens] objectAtIndex:0] frame]; + height = [m_osxMenu menuBarHeight]; + x = r.origin.x; + y = r.origin.y; + width = r.size.width; +#endif + } + + void DisableAutoEnable() + { + /* + [m_osxMenu setAutoenablesItems:NO]; + + wxMenu* menu = GetWXPeer(); + for ( wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst(); + node; + node = node->GetNext() ) + { + const wxMenuItem* const item = node->GetData(); + if ( item->IsSubMenu() ) + { + wxMenuCocoaImpl* subimpl = dynamic_cast(item->GetSubMenu()->GetPeer()); + if ( subimpl ) + subimpl->DisableAutoEnable(); + } + } +*/ + } + + WXHMENU GetHMenu() wxOVERRIDE { + if ( m_osxMenu == nil ) + { + m_osxMenu.reset( [UIMenu menuWithTitle:wxCFStringRef(m_peer->GetTitle()).AsNSString() children:m_children] ); + } + return m_osxMenu; + } + + static wxMenuImpl* Create( wxMenu* peer, const wxString& title ); + static wxMenuImpl* CreateRootMenu( wxMenu* peer ); +protected : + wxCFRef m_osxMenu; + wxCFMutableArrayRef m_children; + +/* + UIMenu* menu = [[UIMenu menuWithTitle:cfText.AsNSString() children:]; +*/ + +} ; + +wxMenuCocoaImpl::~wxMenuCocoaImpl() +{ + // [m_osxMenu setDelegate:nil]; + // [m_osxMenu setImplementation:nil]; + // gc aware +} + +wxMenuImpl* wxMenuImpl::Create( wxMenu* peer, const wxString& title ) +{ + wxCFStringRef cfText( title ); + wxMenuImpl* c = new wxMenuCocoaImpl( peer, nil ); + return c; + } diff --git a/src/osx/iphone/menuitem.mm b/src/osx/iphone/menuitem.mm new file mode 100644 index 0000000000..cdc1e35e02 --- /dev/null +++ b/src/osx/iphone/menuitem.mm @@ -0,0 +1,330 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/osx/iphone/menuitem.mm +// Purpose: wxMenuItem implementation +// Author: Stefan Csomor +// Modified by: +// Created: 1998-01-01 +// Copyright: (c) Stefan Csomor +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#include "wx/wxprec.h" + +#include "wx/menuitem.h" +#include "wx/stockitem.h" + +#ifndef WX_PRECOMP + #include "wx/app.h" + #include "wx/log.h" + #include "wx/menu.h" +#endif // WX_PRECOMP + +#include "wx/osx/private.h" + +// a mapping from wx ids to standard osx actions in order to support the native menu item handling +// if a new mapping is added, make sure the wxNonOwnedWindowController has a handler for this action as well + +struct Mapping +{ + int menuid; + SEL action; +}; + +Mapping sActionToWXMapping[] = +{ +// as we don't have NSUndoManager support we must not use the native actions +#if 0 + { wxID_UNDO, @selector(undo:) }, + { wxID_REDO, @selector(redo:) }, +#endif + { wxID_CUT, @selector(cut:) }, + { wxID_COPY, @selector(copy:) }, + { wxID_PASTE, @selector(paste:) }, + { wxID_CLEAR, @selector(delete:) }, + { wxID_SELECTALL, @selector(selectAll:) }, + { 0, NULL } +}; + +int wxOSXGetIdFromSelector(SEL action ) +{ + int i = 0 ; + while ( sActionToWXMapping[i].action != nil ) + { + if ( sActionToWXMapping[i].action == action ) + return sActionToWXMapping[i].menuid; + ++i; + } + + return 0; +} + +SEL wxOSXGetSelectorFromID(int menuId ) +{ + int i = 0 ; + while ( sActionToWXMapping[i].action != nil ) + { + if ( sActionToWXMapping[i].menuid == menuId ) + return sActionToWXMapping[i].action; + ++i; + } + + return nil; +} + +/* +void wxMacCocoaMenuItemSetAccelerator( UIMenuItem* menuItem, wxAcceleratorEntry* entry ) +{ + if ( entry == NULL ) + { + [menuItem setKeyEquivalent:@""]; + return; + } + +#if 0 // TODO wxIOS wxUSE_ACCEL + unsigned int modifiers = 0 ; + int key = entry->GetKeyCode() ; + if ( key ) + { + if (entry->GetFlags() & wxACCEL_CTRL) + modifiers |= NSCommandKeyMask; + + if (entry->GetFlags() & wxACCEL_RAW_CTRL) + modifiers |= NSControlKeyMask; + + if (entry->GetFlags() & wxACCEL_ALT) + modifiers |= NSAlternateKeyMask ; + + // this may be ignored later for alpha chars + + if (entry->GetFlags() & wxACCEL_SHIFT) + modifiers |= NSShiftKeyMask ; + + unichar shortcut = 0; + if ( key >= WXK_F1 && key <= WXK_F15 ) + { + shortcut = NSF1FunctionKey + ( key - WXK_F1 ); + } + else + { + switch ( key ) + { + case WXK_CLEAR : + shortcut = NSDeleteCharacter ; + break ; + + case WXK_PAGEUP : + shortcut = NSPageUpFunctionKey ; + break ; + + case WXK_PAGEDOWN : + shortcut = NSPageDownFunctionKey ; + break ; + + case WXK_NUMPAD_LEFT : + modifiers |= NSNumericPadKeyMask; + wxFALLTHROUGH; + case WXK_LEFT : + shortcut = NSLeftArrowFunctionKey ; + break ; + + case WXK_NUMPAD_UP : + modifiers |= NSNumericPadKeyMask; + wxFALLTHROUGH; + case WXK_UP : + shortcut = NSUpArrowFunctionKey ; + break ; + + case WXK_NUMPAD_RIGHT : + modifiers |= NSNumericPadKeyMask; + wxFALLTHROUGH; + case WXK_RIGHT : + shortcut = NSRightArrowFunctionKey ; + break ; + + case WXK_NUMPAD_DOWN : + modifiers |= NSNumericPadKeyMask; + wxFALLTHROUGH; + case WXK_DOWN : + shortcut = NSDownArrowFunctionKey ; + break ; + + case WXK_HOME : + shortcut = NSHomeFunctionKey ; + break ; + + case WXK_END : + shortcut = NSEndFunctionKey ; + break ; + + case WXK_NUMPAD_ENTER : + shortcut = NSEnterCharacter; + break; + + case WXK_BACK : + case WXK_RETURN : + case WXK_TAB : + case WXK_ESCAPE : + default : + if(entry->GetFlags() & wxACCEL_SHIFT) + shortcut = toupper(key); + else + shortcut = tolower(key); + break ; + } + } + + [menuItem setKeyEquivalent:[NSString stringWithCharacters:&shortcut length:1]]; + [menuItem setKeyEquivalentModifierMask:modifiers]; + } +#endif // wxUSE_ACCEL +} + +*/ + +class wxMenuItemCocoaImpl : public wxMenuItemImpl +{ +public : + wxMenuItemCocoaImpl( wxMenuItem* peer, UIMenuElement* item ) : wxMenuItemImpl(peer), m_osxMenuItem(wxCFRetain(item)) + { + } + + ~wxMenuItemCocoaImpl(); + + void SetBitmap( const wxBitmap& bitmap ) wxOVERRIDE + { + } + + void Enable( bool enable ) wxOVERRIDE + { + UIMenuElement* menuElement = m_osxMenuItem.get(); + if ( [menuElement isKindOfClass:UIAction.class] ) + { + UIAction* action = (UIAction*) menuElement; + if ( enable ) + action.attributes = action.attributes & ~UIMenuElementAttributesDisabled; + else + action.attributes = action.attributes | UIMenuElementAttributesDisabled; + } + } + + void Check( bool check ) wxOVERRIDE + { + UIMenuElement* menuElement = m_osxMenuItem.get(); + if ( [menuElement isKindOfClass:UIAction.class] ) + { + UIAction* action = (UIAction*) menuElement; + action.state = check ? UIMenuElementStateOn : UIMenuElementStateOff; + } + } + + void Hide( bool hide ) wxOVERRIDE + { + UIMenuElement* menuElement = m_osxMenuItem.get(); + if ( [menuElement isKindOfClass:UIAction.class] ) + { + UIAction* action = (UIAction*) menuElement; + if ( hide ) + action.attributes = action.attributes | UIMenuElementAttributesHidden; + else + action.attributes = action.attributes & ~UIMenuElementAttributesHidden; + } + } + + void SetLabel( const wxString& text, wxAcceleratorEntry *entry ) wxOVERRIDE + { + // recreate, it's readonly + } + + bool DoDefault() wxOVERRIDE; + + void * GetHMenuItem() wxOVERRIDE { return m_osxMenuItem; } + +protected : + wxCFRef m_osxMenuItem ; +} ; + +wxMenuItemCocoaImpl::~wxMenuItemCocoaImpl() +{ +} + +bool wxMenuItemCocoaImpl::DoDefault() +{ + bool handled=false; + int menuid = m_peer->GetId(); + +#if 0 // TODO wxIOS + NSApplication *theNSApplication = [NSApplication sharedApplication]; + if (menuid == wxID_OSX_HIDE) + { + [theNSApplication hide:nil]; + handled=true; + } + else if (menuid == wxID_OSX_HIDEOTHERS) + { + [theNSApplication hideOtherApplications:nil]; + handled=true; + } + else if (menuid == wxID_OSX_SHOWALL) + { + [theNSApplication unhideAllApplications:nil]; + handled=true; + } + else if (menuid == wxApp::s_macExitMenuItemId) + { + wxTheApp->ExitMainLoop(); + } +#endif + return handled; +} + +wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu, + int menuid, + const wxString& text, + wxAcceleratorEntry *entry, + const wxString& WXUNUSED(strHelp), + wxItemKind kind, + wxMenu *pSubMenu ) +{ + wxMenuItemImpl* c = NULL; + UIMenuElement* item = nil; + + if ( kind == wxITEM_SEPARATOR ) + { + // TODO new version of item = [[UIMenuItem separatorItem] retain]; + } + else + { + wxCFStringRef cfText(text); + + if ( pSubMenu ) + { + pSubMenu->GetPeer()->SetTitle( text ); + UIMenu* submenu = pSubMenu->GetHMenu(); + item = submenu; + } + else + { + // currently in the iOS 14 Beta UICommands trigger a layout violation so stick with UIActions for the time being + if ( entry ) + { + // TODO UIKeyCommand* command = [UIKeyCommand commandWithTitle ...] + + UIAction* menuitem = [UIAction actionWithTitle:cfText.AsNSString() image:nil identifier:nil + handler: ^( UIAction* action) { peer->GetMenu()->HandleCommandProcess(peer);} ]; + item = menuitem; + } + else + { + /* + UICommand* command = [UICommand commandWithTitle:cfText.AsNSString() image:nil action:@selector(menuItemAction:) propertyList:nil]; + */ + + UIAction* menuitem = [UIAction actionWithTitle:cfText.AsNSString() image:nil identifier:nil + handler: ^( UIAction* action) { peer->GetMenu()->HandleCommandProcess(peer);} ]; + item = menuitem; + } + } + } + c = new wxMenuItemCocoaImpl( peer, item ); + return c; +}