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)
};
@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
}
}
+- (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 )
NSView* m_textView;
} ;
-@interface wxNSSecureTextField : NSSecureTextField
-{
-}
-@end
-
@implementation wxNSSecureTextField
+ (void)initialize
}
@end
-@interface wxNSTextView : NSTextView
-{
- wxNSTextScrollView* scrollView;
-}
-
-- (void)setScrollView: (wxNSTextScrollView *) sv;
-- (wxNSTextScrollView*) scrollView;
-
-@end
-
@implementation wxNSTextScrollView
+ (void)initialize
}
}
-- (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
}
}
+- (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];
[m_scrollView setDocumentView: tv];
[tv setDelegate: w];
- [tv setScrollView:sv];
+
+ InstallEventHandler(tv);
}
wxNSTextViewControl::~wxNSTextViewControl()
if (m_textView)
[m_textView setString: wxCFStringRef( st , m_wxPeer->GetFont().GetEncoding() ).AsNSString()];
}
+
void wxNSTextViewControl::Copy()
{
if (m_textView)
m_textField = (NSTextField*) w;
[m_textField setDelegate: w];
m_selStart = m_selEnd = 0;
+ m_hasEditor = [w isKindOfClass:[NSTextField class]];
}
wxNSTextFieldControl::~wxNSTextFieldControl()
// 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 ;
return impl->performDragOperation(sender, self, _cmd) ? YES:NO ;
}
+#endif
+
void wxOSX_mouseEvent(NSView* self, SEL _cmd, NSEvent *event)
{
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
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);
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);
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);
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;
}
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 );
}
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@:" )
m_osxView = NULL;
m_isFlipped = true;
m_lastKeyDownEvent = NULL;
+ m_hasEditor = false;
}
wxWidgetCocoaImpl::~wxWidgetCocoaImpl()
// 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;
}
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 ||
event1.SetEventObject( this );
wxPostEvent( GetEventHandler(), event1 );
}
+#endif
}
// ----------------------------------------------------------------------------