adding events to single line textcontrols (password is not fully supported)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@60993 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor
2009-06-11 06:40:24 +00:00
parent 0cd4552a99
commit 7cb2a24183
5 changed files with 162 additions and 101 deletions

View 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

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

View 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;
}
- (void) keyUp:(NSEvent*) event
{
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( [self delegate] );
if ( impl == NULL || !impl->DoHandleKeyEvent(event) )
[super keyUp:event];
}
- (void) flagsChanged:(NSEvent*) event
{
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( [self delegate] );
if ( impl == NULL || !impl->DoHandleKeyEvent(event) )
[super flagsChanged:event];
}
- (BOOL) performKeyEquivalent:(NSEvent*) event
{
BOOL retval = [super performKeyEquivalent:event];
return retval;
}
- (void) insertText:(id) str
{
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( [self delegate] );
if ( impl == NULL || lastKeyDownEvent==nil || !impl->DoHandleCharEvent(lastKeyDownEvent, str) )
{
[super insertText:str];
}
}
- (BOOL)textView:(NSTextView *)aTextView doCommandBySelector:(SEL)commandSelector
{
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;
}
- (void)textDidEndEditing:(NSNotification *)aNotification
{
wxUnusedVar(aNotification);
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
if ( impl )
{
impl->DoNotifyFocusEvent( false, NULL );
}
}
@end
@implementation wxNSTextView
- (BOOL) becomeFirstResponder
+ (void)initialize
{
BOOL val = [super becomeFirstResponder];
if ( val )
static BOOL initialized = NO;
if (!initialized)
{
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( scrollView );
if (impl )
impl->DoNotifyFocusEvent( true, NULL );
initialized = YES;
wxOSXCocoaClassAddWXMethods( self );
}
return val;
}
- (void)setScrollView: (wxNSTextScrollView *) sv
{
scrollView = sv;
}
- (wxNSTextScrollView*) scrollView
{
return scrollView;
}
@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()

View File

@@ -33,27 +33,39 @@
// 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
view = (NSView*) responder;
}
else
{
if ( [responder isKindOfClass:[NSView class]] )
focusedView = (NSView*) responder;
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 )
{
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;
}

View 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
}
// ----------------------------------------------------------------------------