]> git.saurik.com Git - wxWidgets.git/commitdiff
adding events to single line textcontrols (password is not fully supported)
authorStefan Csomor <csomor@advancedconcepts.ch>
Thu, 11 Jun 2009 06:40:24 +0000 (06:40 +0000)
committerStefan Csomor <csomor@advancedconcepts.ch>
Thu, 11 Jun 2009 06:40:24 +0000 (06:40 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@60993 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/osx/cocoa/private.h
src/osx/cocoa/nonownedwnd.mm
src/osx/cocoa/textctrl.mm
src/osx/cocoa/window.mm
src/osx/textctrl_osx.cpp

index 38f82d00e9c6b462cfbbb4a85b5572b0bddf0afd..fb8f330b3db9bdab472ea32900895dd9f024b715 100644 (file)
@@ -155,6 +155,9 @@ protected:
     WXWidget m_osxView;
     NSEvent* m_lastKeyDownEvent;
     bool m_isFlipped;
+    // if it the control has an editor, that editor will already send some
+    // events, don't resend them 
+    bool m_hasEditor;
     
     DECLARE_DYNAMIC_CLASS_NO_COPY(wxWidgetCocoaImpl)
 };
@@ -244,9 +247,34 @@ protected :
 
     @end
 
+    @interface wxNSTextFieldEditor : NSTextView
+    {
+        NSEvent* lastKeyDownEvent;
+    }
+
+    @end
+
     @interface wxNSTextField : NSTextField
+    {
+        wxNSTextFieldEditor* fieldEditor;
+    }
+
+    - (wxNSTextFieldEditor*) fieldEditor;
+    - (void) setFieldEditor:(wxNSTextFieldEditor*) fieldEditor;
+
+    @end
+
+    @interface wxNSSecureTextField : NSSecureTextField
     {
     }
+
+    @end
+
+
+    @interface wxNSTextView : NSTextView
+    {
+    }
+    
     @end
 
     @interface wxNSMenu : NSMenu
index 2823a386cc80363feba5a8e2c355acc22920c9e3..c2bf25e06b772601dd900ab6fc120ef85baee267 100644 (file)
@@ -291,6 +291,26 @@ typedef void (*wxOSX_NoResponderHandlerPtr)(NSView* self, SEL _cmd, SEL selector
     }
 }
 
+- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)anObject
+{
+    wxUnusedVar(sender);
+
+    if ([anObject isKindOfClass:[wxNSTextField class]])
+    {
+        wxNSTextField* tf = (wxNSTextField*) anObject;
+        wxNSTextFieldEditor* editor = [tf fieldEditor];
+        if ( editor == nil )
+        {
+            editor = [[wxNSTextFieldEditor alloc] init];
+            [editor setFieldEditor:YES];
+            [tf setFieldEditor:editor];
+        }
+        return editor;
+    }
+
+    return nil;
+}
+
 @end
 
 IMPLEMENT_DYNAMIC_CLASS( wxNonOwnedWindowCocoaImpl , wxNonOwnedWindowImpl )
index 6814c6cdd58d8d4fcc8cfb306b0241540aae7ae4..03e04f248894adb70d81404774c0096d31e9a101 100644 (file)
@@ -78,11 +78,6 @@ protected :
     NSView* m_textView;
 } ;
 
-@interface wxNSSecureTextField : NSSecureTextField
-{
-}
-@end
-
 @implementation wxNSSecureTextField 
 
 + (void)initialize
@@ -128,16 +123,6 @@ protected :
 }
 @end
 
-@interface wxNSTextView : NSTextView
-{
-    wxNSTextScrollView* scrollView;
-}
-
-- (void)setScrollView: (wxNSTextScrollView *) sv;
-- (wxNSTextScrollView*) scrollView;
-
-@end
-
 @implementation wxNSTextScrollView
 
 + (void)initialize
@@ -150,79 +135,60 @@ protected :
     }
 }
 
-- (void)textDidChange:(NSNotification *)aNotification
+@end
+
+@implementation wxNSTextFieldEditor
+
+- (void) keyDown:(NSEvent*) event
 {
-    wxUnusedVar(aNotification);
-    wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
-    if ( impl )
-    {
-        wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
-        if ( wxpeer ) {
-            wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, wxpeer->GetId());
-            event.SetEventObject( wxpeer );
-            event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
-            wxpeer->HandleWindowEvent( event );
-        }
-    }
+    wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( [self delegate] );
+    lastKeyDownEvent = event;
+    if ( impl == NULL || !impl->DoHandleKeyEvent(event) )
+        [super keyDown:event];
+    lastKeyDownEvent = nil;
 }
 
-- (BOOL)textView:(NSTextView *)aTextView doCommandBySelector:(SEL)commandSelector
+- (void) keyUp:(NSEvent*) event
 {
-    wxUnusedVar(aTextView);
-    wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
-    if ( impl  )
-    {
-        wxWindow* wxpeer = (wxWindow*) impl->GetWXPeer();
-        if (commandSelector == @selector(insertNewline:))
-        {
-            if ( wxpeer && wxpeer->GetWindowStyle() & wxTE_PROCESS_ENTER ) 
-            {
-                wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, wxpeer->GetId());
-                event.SetEventObject( wxpeer );
-                event.SetString( static_cast<wxTextCtrl*>(wxpeer)->GetValue() );
-                wxpeer->HandleWindowEvent( event );
-            }
-        }
-    }
-    
-    return NO;
+    wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( [self delegate] );
+    if ( impl == NULL || !impl->DoHandleKeyEvent(event) )
+        [super keyUp:event];
 }
 
-- (void)textDidEndEditing:(NSNotification *)aNotification
+- (void) flagsChanged:(NSEvent*) event
 {
-    wxUnusedVar(aNotification);
-    wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
-    if ( impl )
-    {
-        impl->DoNotifyFocusEvent( false, NULL );
-    }
+    wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( [self delegate] );
+    if ( impl == NULL || !impl->DoHandleKeyEvent(event) )
+        [super flagsChanged:event];
 }
-@end
 
-@implementation wxNSTextView
+- (BOOL) performKeyEquivalent:(NSEvent*) event
+{
+    BOOL retval = [super performKeyEquivalent:event];
+    return retval;
+}
 
-- (BOOL) becomeFirstResponder
+- (void) insertText:(id) str
 {
-    BOOL val = [super becomeFirstResponder];
-    
-    if ( val )
+    wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( [self delegate] );
+    if ( impl == NULL || lastKeyDownEvent==nil || !impl->DoHandleCharEvent(lastKeyDownEvent, str) )
     {
-        wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( scrollView );
-        if (impl )
-            impl->DoNotifyFocusEvent( true, NULL );
-
+        [super insertText:str];
     }
-    return val;
 }
 
-- (void)setScrollView: (wxNSTextScrollView *) sv
-{
-    scrollView = sv;
-}
+@end
+
+@implementation wxNSTextView
 
-- (wxNSTextScrollView*) scrollView
++ (void)initialize
 {
-    return scrollView;
+    static BOOL initialized = NO;
+    if (!initialized) 
+    {
+        initialized = YES;
+        wxOSXCocoaClassAddWXMethods( self );
+    }
 }
 
 @end
@@ -239,6 +205,24 @@ protected :
     }
 }
 
+- (id) initWithFrame:(NSRect) frame
+{
+    self = [super initWithFrame:frame];
+    fieldEditor = nil;
+    return self;
+}
+
+- (void) setFieldEditor:(wxNSTextFieldEditor*) editor
+{
+    fieldEditor = editor;
+}
+
+- (wxNSTextFieldEditor*) fieldEditor
+{
+    return fieldEditor;
+}
+
+
 - (void) setEnabled:(BOOL) flag
 {
     [super setEnabled: flag];
@@ -329,7 +313,8 @@ wxNSTextViewControl::wxNSTextViewControl( wxTextCtrl *wxPeer, WXWidget w ) : wxW
     [m_scrollView setDocumentView: tv];
 
     [tv setDelegate: w];
-    [tv setScrollView:sv];
+    
+    InstallEventHandler(tv);    
 }
 
 wxNSTextViewControl::~wxNSTextViewControl()
@@ -358,6 +343,7 @@ void wxNSTextViewControl::SetStringValue( const wxString &str)
     if (m_textView)
         [m_textView setString: wxCFStringRef( st , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
 }
+
 void wxNSTextViewControl::Copy() 
 {
     if (m_textView)
@@ -443,6 +429,7 @@ wxNSTextFieldControl::wxNSTextFieldControl( wxTextCtrl *wxPeer, WXWidget w ) : w
     m_textField = (NSTextField*) w;
     [m_textField setDelegate: w];
     m_selStart = m_selEnd = 0;
+    m_hasEditor = [w isKindOfClass:[NSTextField class]];
 }
 
 wxNSTextFieldControl::~wxNSTextFieldControl()
index 88d7166c49b47419b763908b9d042bb6af967679..e5e4b7e3b464bf930dd66cdfc0ec84cd4dbf2ee7 100644 (file)
 
 // Get the window with the focus
 
-WXWidget wxWidgetImpl::FindFocus()
+NSView* GetViewFromResponder( NSResponder* responder )
 {
-    NSView* focusedView = nil;
-    NSWindow* keyWindow = [[NSApplication sharedApplication] keyWindow];
-    if ( keyWindow != nil )
+    NSView* view = nil;
+    if ( [responder isKindOfClass:[NSTextView class]] )
     {
-        NSResponder* responder = [keyWindow firstResponder];
-        if ( [responder isKindOfClass:[NSTextView class]] && 
-            [keyWindow fieldEditor:NO forObject:nil] != nil )
-        {
-            focusedView = [(NSTextView*)responder delegate];
-        }
+        NSView* delegate =  [(NSTextView*)responder delegate];
+        if ( [delegate isKindOfClass:[NSTextField class] ] )
+            view = delegate;
         else
-        {
-            if ( [responder isKindOfClass:[NSView class]] )
-                focusedView = (NSView*) responder;
-        }
+            view =  (NSView*) responder;
     }
+    else
+    {
+        if ( [responder isKindOfClass:[NSView class]] )
+            view = (NSView*) responder;
+    }
+    return view;
+}
+
+NSView* GetFocusedViewInWindow( NSWindow* keyWindow )
+{
+    NSView* focusedView = nil;
+    if ( keyWindow != nil )
+        focusedView = GetViewFromResponder([keyWindow firstResponder]);
+
     return focusedView;
 }
 
+WXWidget wxWidgetImpl::FindFocus()
+{
+    return GetFocusedViewInWindow( [[NSApplication sharedApplication] keyWindow] );
+}
+
 NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin )
 {
     int x, y, w, h ;
@@ -583,6 +595,8 @@ BOOL wxOSX_performDragOperation( id self, SEL _cmd, id <NSDraggingInfo> sender )
     return impl->performDragOperation(sender, self, _cmd) ? YES:NO ;
 }
 
+#endif
+
 void wxOSX_mouseEvent(NSView* self, SEL _cmd, NSEvent *event) 
 {
     wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
@@ -835,8 +849,6 @@ bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget WXUNUSED(slf), vo
     return result != wxDragNone;
 }
 
-#endif
-
 typedef void (*wxOSX_TextEventHandlerPtr)(NSView* self, SEL _cmd, NSString *event);
 typedef void (*wxOSX_EventHandlerPtr)(NSView* self, SEL _cmd, NSEvent *event);
 typedef BOOL (*wxOSX_PerformKeyEventHandlerPtr)(NSView* self, SEL _cmd, NSEvent *event);
@@ -859,7 +871,7 @@ void wxWidgetCocoaImpl::mouseEvent(WX_NSEvent event, WXWidget slf, void *_cmd)
 
 void wxWidgetCocoaImpl::keyEvent(WX_NSEvent event, WXWidget slf, void *_cmd)
 {
-    if ( [[slf window] firstResponder] != slf || !DoHandleKeyEvent(event) )
+    if ( GetFocusedViewInWindow([slf window]) != slf || m_hasEditor || !DoHandleKeyEvent(event) )
     {
         wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
         superimpl(slf, (SEL)_cmd, event);
@@ -868,7 +880,7 @@ void wxWidgetCocoaImpl::keyEvent(WX_NSEvent event, WXWidget slf, void *_cmd)
 
 void wxWidgetCocoaImpl::insertText(NSString* text, WXWidget slf, void *_cmd)
 {
-    if (m_lastKeyDownEvent && !DoHandleCharEvent(m_lastKeyDownEvent, text) )
+    if ( m_lastKeyDownEvent==NULL || m_hasEditor || !DoHandleCharEvent(m_lastKeyDownEvent, text) )
     {
         wxOSX_TextEventHandlerPtr superimpl = (wxOSX_TextEventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
         superimpl(slf, (SEL)_cmd, text);
@@ -899,12 +911,14 @@ bool wxWidgetCocoaImpl::becomeFirstResponder(WXWidget slf, void *_cmd)
     wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
     // get the current focus before running becomeFirstResponder
     NSView* otherView = FindFocus(); 
+
     wxWidgetImpl* otherWindow = FindFromWXWidget(otherView);
     BOOL r = superimpl(slf, (SEL)_cmd);
     if ( r )
     {
         DoNotifyFocusEvent( true, otherWindow );
     }
+
     return r;
 }
 
@@ -913,11 +927,13 @@ bool wxWidgetCocoaImpl::resignFirstResponder(WXWidget slf, void *_cmd)
     wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
     BOOL r = superimpl(slf, (SEL)_cmd);
     // get the current focus after running resignFirstResponder
+    // note that this value isn't reliable, it might return the same view that
+    // is resigning
     NSView* otherView = FindFocus(); 
     wxWidgetImpl* otherWindow = FindFromWXWidget(otherView);
     // NSTextViews have an editor as true responder, therefore the might get the
-    // resign notification if their editor takes over, don't trigger any event hen
-    if ( r && otherWindow != this)
+    // resign notification if their editor takes over, don't trigger any event then
+    if ( r && !m_hasEditor)
     {
         DoNotifyFocusEvent( false, otherWindow );
     }
@@ -1067,7 +1083,7 @@ void wxOSXCocoaClassAddWXMethods(Class c)
     
     wxOSX_CLASS_ADD_METHOD(c, @selector(insertText:), (IMP) wxOSX_insertText, "v@:@" )
 
-    wxOSX_CLASS_ADD_METHOD(c, @selector(performKeyEquivalent:), (IMP) wxOSX_performKeyEquivalent, "v@:@" )
+    wxOSX_CLASS_ADD_METHOD(c, @selector(performKeyEquivalent:), (IMP) wxOSX_performKeyEquivalent, "c@:@" )
 
     wxOSX_CLASS_ADD_METHOD(c, @selector(acceptsFirstResponder), (IMP) wxOSX_acceptsFirstResponder, "c@:" )
     wxOSX_CLASS_ADD_METHOD(c, @selector(becomeFirstResponder), (IMP) wxOSX_becomeFirstResponder, "c@:" )
@@ -1125,6 +1141,7 @@ void wxWidgetCocoaImpl::Init()
     m_osxView = NULL;
     m_isFlipped = true;
     m_lastKeyDownEvent = NULL;
+    m_hasEditor = false;
 }
 
 wxWidgetCocoaImpl::~wxWidgetCocoaImpl()
@@ -1489,11 +1506,17 @@ bool wxWidgetCocoaImpl::DoHandleKeyEvent(NSEvent *event)
 
     // this will fire higher level events, like insertText, to help
     // us handle EVT_CHAR, etc.
-    if ([event type] == NSKeyDown)
+    if ( !m_hasEditor && [event type] == NSKeyDown)
     {
         m_lastKeyDownEvent = event;
         if ( !result )
-            [m_osxView interpretKeyEvents:[NSArray arrayWithObject:event]];
+        {
+            if ( [m_osxView isKindOfClass:[NSScrollView class] ] )
+                [[(NSScrollView*)m_osxView documentView] interpretKeyEvents:[NSArray arrayWithObject:event]];
+            else
+                [m_osxView interpretKeyEvents:[NSArray arrayWithObject:event]];
+            result = true;
+        }
     }
     return result;
 }
index 1059c4b6c676e09581150e2882afc3b70deaa3af..86de81f539285f31b8c4b5f1e4aa857c40f0915b 100644 (file)
@@ -580,6 +580,8 @@ void wxTextCtrl::OnChar(wxKeyEvent& event)
         event.Skip(true) ;
     }
 
+    // osx_cocoa sends its event upon insertText
+#if wxOSX_USE_CARBON
     if ( ( key >= 0x20 && key < WXK_START ) ||
          ( key >= WXK_NUMPAD0 && key <= WXK_DIVIDE ) ||
          key == WXK_RETURN ||
@@ -590,6 +592,7 @@ void wxTextCtrl::OnChar(wxKeyEvent& event)
         event1.SetEventObject( this );
         wxPostEvent( GetEventHandler(), event1 );
     }
+#endif
 }
 
 // ----------------------------------------------------------------------------