Implement minimal wxMenu support for iOS

A separate change later will add features using iOS 14 specific API and
iOS 13 (and earlier) fallback for them.
This commit is contained in:
Stefan Csomor
2020-07-14 18:06:39 +02:00
committed by Vadim Zeitlin
parent ff24484952
commit 7812657cbf
9 changed files with 712 additions and 10 deletions

View File

@@ -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

View File

@@ -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
</set>
<set var="OSX_IPHONE_HDR" hints="files">

View File

@@ -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

View File

@@ -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

View File

@@ -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 = "<group>"; };
3FEBA7AC7F743EE88352AEBC /* htmlwin.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = htmlwin.cpp; path = ../../src/html/htmlwin.cpp; sourceTree = "<group>"; };
400275BE019D3E5BA47988BE /* inffast.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = inffast.c; path = ../../src/zlib/inffast.c; sourceTree = "<group>"; };
400DE11124A9D41800F526FE /* menuitem.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = menuitem.mm; path = ../../src/osx/iphone/menuitem.mm; sourceTree = "<group>"; };
400DE11224A9D41800F526FE /* menu.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = menu.mm; path = ../../src/osx/iphone/menu.mm; sourceTree = "<group>"; };
4048A3523EC03409BD899BEF /* xtixml.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = xtixml.cpp; path = ../../src/common/xtixml.cpp; sourceTree = "<group>"; };
40586C8986443431A64EB066 /* LexLisp.cxx */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LexLisp.cxx; path = ../../src/stc/scintilla/lexers/LexLisp.cxx; sourceTree = "<group>"; };
4071FF90F1D4336C836B2AE4 /* tif_pixarlog.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = tif_pixarlog.c; path = ../../src/tiff/libtiff/tif_pixarlog.c; sourceTree = "<group>"; };
@@ -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 */,

View File

@@ -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;

View File

@@ -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)

324
src/osx/iphone/menu.mm Normal file
View File

@@ -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 <string.h>
/*
@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 <UIMenuDelegate>
{
}
#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<wxTopLevelWindow*>(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<wxMenuCocoaImpl*>(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<UIMenu*> m_osxMenu;
wxCFMutableArrayRef<UIMenuElement*> 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;
}

330
src/osx/iphone/menuitem.mm Normal file
View File

@@ -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<UIMenuElement*> 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;
}