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:
@@ -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
|
||||
|
@@ -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 )
|
||||
|
@@ -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 )
|
||||
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) )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
[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()
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user