From: Kevin Ollivier Date: Sun, 22 Feb 2009 18:25:36 +0000 (+0000) Subject: Landing basic EVT_CHAR support, along with the rest of EVT_TEXT support fix. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/f0e0116ea8494ef1144de17b58bc19e6d7633883 Landing basic EVT_CHAR support, along with the rest of EVT_TEXT support fix. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59090 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index a3c3eb6e15..80845cfd8c 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -124,7 +124,8 @@ public : void InstallEventHandler( WXWidget control = NULL ); virtual bool DoHandleMouseEvent(NSEvent *event); - virtual bool DoHandleKeyEvent(NSEvent *event); + virtual bool DoHandleKeyEvent(NSEvent *event); + virtual bool DoHandleCharEvent(NSEvent *event, NSString *text); virtual void DoNotifyFocusEvent(bool receivedFocus); void SetFlipped(bool flipped); @@ -138,6 +139,7 @@ public : virtual bool performDragOperation(void* sender, WXWidget slf, void* _cmd); virtual void mouseEvent(WX_NSEvent event, WXWidget slf, void* _cmd); virtual void keyEvent(WX_NSEvent event, WXWidget slf, void* _cmd); + virtual void insertText(NSString* text, WXWidget slf, void* _cmd); virtual bool performKeyEquivalent(WX_NSEvent event, WXWidget slf, void* _cmd); virtual bool becomeFirstResponder(WXWidget slf, void* _cmd); virtual bool resignFirstResponder(WXWidget slf, void* _cmd); @@ -150,6 +152,7 @@ public : protected: WXWidget m_osxView; + NSEvent* m_lastKeyDownEvent; bool m_isFlipped; DECLARE_DYNAMIC_CLASS_NO_COPY(wxWidgetCocoaImpl) @@ -242,8 +245,11 @@ protected : @interface wxNSTextField : NSTextField { + wxWidgetCocoaImpl* impl; } + - (void) setImplementation:(wxWidgetCocoaImpl*) item; + - (wxWidgetCocoaImpl*) implementation; @end @interface wxNSMenu : NSMenu diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index bc16a9de0f..b8c955563d 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -51,7 +51,6 @@ NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const // the tracking tag is needed to track mouse enter / exit events - (void) setTrackingTag: (NSTrackingRectTag)tag; - (NSTrackingRectTag) trackingTag; - @end // wxNSView @interface NSView(PossibleMethods) @@ -131,7 +130,7 @@ long wxOSXTranslateCocoaKey( int unichar ) return retval; } -void SetupKeyEvent( wxKeyEvent &wxevent , NSEvent * nsEvent ) +void SetupKeyEvent( wxKeyEvent &wxevent , NSEvent * nsEvent, NSString* charString = NULL ) { UInt32 modifiers = [nsEvent modifierFlags] ; int eventType = [nsEvent type]; @@ -164,6 +163,9 @@ void SetupKeyEvent( wxKeyEvent &wxevent , NSEvent * nsEvent ) if ( eventType != NSFlagsChanged ) { NSString* nschars = [nsEvent characters]; + if ( charString ) + nschars = charString; + if ( nschars ) { wxCFStringRef cfchars((CFStringRef)[nschars retain]); @@ -444,6 +446,15 @@ void wxOSX_keyEvent(NSView* self, SEL _cmd, NSEvent *event) impl->keyEvent(event, self, _cmd); } +void wxOSX_insertText(NSView* self, SEL _cmd, NSString* text) +{ + wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self ); + if (impl == NULL) + return; + + impl->insertText(text, self, _cmd); +} + BOOL wxOSX_performKeyEquivalent(NSView* self, SEL _cmd, NSEvent *event) { wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self ); @@ -673,22 +684,28 @@ void wxWidgetCocoaImpl::mouseEvent(WX_NSEvent event, WXWidget slf, void *_cmd) void wxWidgetCocoaImpl::keyEvent(WX_NSEvent event, WXWidget slf, void *_cmd) { - if ( !DoHandleKeyEvent(event) ) + if ( [[slf window] firstResponder] != slf || !DoHandleKeyEvent(event) ) { wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd]; superimpl(slf, (SEL)_cmd, event); } } -bool wxWidgetCocoaImpl::performKeyEquivalent(WX_NSEvent event, WXWidget slf, void *_cmd) +void wxWidgetCocoaImpl::insertText(NSString* text, WXWidget slf, void *_cmd) { - if ( !DoHandleKeyEvent(event) ) + if (m_lastKeyDownEvent && !DoHandleCharEvent(m_lastKeyDownEvent, text) ) { - wxOSX_PerformKeyEventHandlerPtr superimpl = (wxOSX_PerformKeyEventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd]; - return superimpl(slf, (SEL)_cmd, event); + wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:@selector(insertText:)]; + superimpl(slf, @selector(insertText:), text); } + m_lastKeyDownEvent = NULL; +} - return YES; + +bool wxWidgetCocoaImpl::performKeyEquivalent(WX_NSEvent event, WXWidget slf, void *_cmd) +{ + wxOSX_PerformKeyEventHandlerPtr superimpl = (wxOSX_PerformKeyEventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd]; + return superimpl(slf, (SEL)_cmd, event); } bool wxWidgetCocoaImpl::becomeFirstResponder(WXWidget slf, void *_cmd) @@ -849,6 +866,8 @@ void wxOSXCocoaClassAddWXMethods(Class c) wxOSX_CLASS_ADD_METHOD(c, @selector(keyDown:), (IMP) wxOSX_keyEvent, "v@:@" ) wxOSX_CLASS_ADD_METHOD(c, @selector(keyUp:), (IMP) wxOSX_keyEvent, "v@:@" ) wxOSX_CLASS_ADD_METHOD(c, @selector(flagsChanged:), (IMP) wxOSX_keyEvent, "v@:@" ) + + wxOSX_CLASS_ADD_METHOD(c, @selector(insertText:), (IMP) wxOSX_insertText, "v@:@" ) wxOSX_CLASS_ADD_METHOD(c, @selector(performKeyEquivalent:), (IMP) wxOSX_performKeyEquivalent, "v@:@" ) @@ -907,6 +926,7 @@ void wxWidgetCocoaImpl::Init() { m_osxView = NULL; m_isFlipped = true; + m_lastKeyDownEvent = NULL; } wxWidgetCocoaImpl::~wxWidgetCocoaImpl() @@ -1249,12 +1269,36 @@ void wxWidgetCocoaImpl::InstallEventHandler( WXWidget control ) } } +static bool g_inKeyEvent = false; + +bool wxWidgetCocoaImpl::DoHandleCharEvent(NSEvent *event, NSString *text) +{ + wxKeyEvent wxevent(wxEVT_KEY_DOWN); + SetupKeyEvent( wxevent, event, text ); + + wxevent.SetEventType(wxEVT_CHAR); + + return GetWXPeer()->OSXHandleKeyEvent(wxevent); +} + bool wxWidgetCocoaImpl::DoHandleKeyEvent(NSEvent *event) { + wxASSERT_MSG(!g_inKeyEvent, "Re-entering key handler...\n"); + g_inKeyEvent = true; wxKeyEvent wxevent(wxEVT_KEY_DOWN); SetupKeyEvent( wxevent, event ); + + bool result = GetWXPeer()->OSXHandleKeyEvent(wxevent); - return GetWXPeer()->OSXHandleKeyEvent(wxevent); + // this will fire higher level events, like insertText, to help + // us handle EVT_CHAR, etc. + if ([event type] == NSKeyDown) + { + m_lastKeyDownEvent = event; + [m_osxView interpretKeyEvents:[NSArray arrayWithObject:event]]; + } + g_inKeyEvent = false; + return result; } bool wxWidgetCocoaImpl::DoHandleMouseEvent(NSEvent *event)