X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ea9ae179ed35355be6ea645a8661b3a420c64a92..0d606991439a152cf0de0a18904be55685d81649:/src/osx/cocoa/window.mm diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index a5aaeac505..78cd6f99aa 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -4,7 +4,6 @@ // Author: Stefan Csomor // Modified by: // Created: 2008-06-20 -// RCS-ID: $Id$ // Copyright: (c) Stefan Csomor // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -17,6 +16,7 @@ #include "wx/log.h" #include "wx/textctrl.h" #include "wx/combobox.h" + #include "wx/radiobut.h" #endif #ifdef __WXMAC__ @@ -41,7 +41,7 @@ // Get the window with the focus -NSView* GetViewFromResponder( NSResponder* responder ) +NSView* wxOSXGetViewFromResponder( NSResponder* responder ) { NSView* view = nil; if ( [responder isKindOfClass:[NSTextView class]] ) @@ -64,16 +64,29 @@ NSView* GetFocusedViewInWindow( NSWindow* keyWindow ) { NSView* focusedView = nil; if ( keyWindow != nil ) - focusedView = GetViewFromResponder([keyWindow firstResponder]); + focusedView = wxOSXGetViewFromResponder([keyWindow firstResponder]); return focusedView; } WXWidget wxWidgetImpl::FindFocus() { - return GetFocusedViewInWindow( [NSApp keyWindow] ); + return GetFocusedViewInWindow( [NSApp keyWindow] );; } +wxWidgetImpl* wxWidgetImpl::FindBestFromWXWidget(WXWidget control) +{ + wxWidgetImpl* impl = FindFromWXWidget(control); + + // NSScrollViews can have their subviews like NSClipView + // therefore check and use the NSScrollView peer in that case + if ( impl == NULL && [[control superview] isKindOfClass:[NSScrollView class]]) + impl = FindFromWXWidget([control superview]); + + return impl; +} + + NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin ) { int x, y, w, h ; @@ -96,6 +109,22 @@ NSRect wxOSXGetFrameForControl( wxWindowMac* window , const wxPoint& pos , const @end // wxNSView +@interface wxNSView(TextInput) + +- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange; +- (void)doCommandBySelector:(SEL)aSelector; +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange; +- (void)unmarkText; +- (NSRange)selectedRange; +- (NSRange)markedRange; +- (BOOL)hasMarkedText; +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange; +- (NSArray*)validAttributesForMarkedText; +- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange; +- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint; + +@end + @interface NSView(PossibleMethods) - (void)setTitle:(NSString *)aString; - (void)setStringValue:(NSString *)aString; @@ -669,11 +698,15 @@ void wxWidgetCocoaImpl::SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEve wxevent.m_wheelDelta = 10; wxevent.m_linesPerAction = 1; + wxevent.m_columnsPerAction = 1; if ( fabs(deltaX) > fabs(deltaY) ) { + // wx conventions for horizontal are inverted from vertical (originating from native msw behavior) + // right and up are positive values, left and down are negative values, while on OSX right and down + // are negative and left and up are positive. wxevent.m_wheelAxis = wxMOUSE_WHEEL_HORIZONTAL; - wxevent.m_wheelRotation = (int)deltaX; + wxevent.m_wheelRotation = -(int)deltaX; } else { @@ -819,6 +852,71 @@ void wxWidgetCocoaImpl::SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEve @end // wxNSView +// We need to adopt NSTextInputClient protocol in order to interpretKeyEvents: to work. +// Currently, only insertText:(replacementRange:) is +// implemented here, and the rest of the methods are stubs. +// It is hoped that someday IME-related functionality is implemented in +// wxWidgets and the methods of this protocol are fully working. + +@implementation wxNSView(TextInput) + +void wxOSX_insertText(NSView* self, SEL _cmd, NSString* text); + +- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange +{ + wxOSX_insertText(self, @selector(insertText:), aString); +} + +- (void)doCommandBySelector:(SEL)aSelector +{ + // these are already caught in the keyEvent handler +} + +- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange +{ +} + +- (void)unmarkText +{ +} + +- (NSRange)selectedRange +{ + return NSMakeRange(NSNotFound, 0); +} + +- (NSRange)markedRange +{ + return NSMakeRange(NSNotFound, 0); +} + +- (BOOL)hasMarkedText +{ + return NO; +} + +- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange +{ + return nil; +} + +- (NSArray*)validAttributesForMarkedText +{ + return nil; +} + +- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange +{ + return NSMakeRect(0, 0, 0, 0); +} +- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint +{ + return NSNotFound; +} + +@end // wxNSView(TextInput) + + // // event handlers // @@ -1171,11 +1269,6 @@ bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget WXUNUSED(slf), vo return result != wxDragNone; } -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); -typedef BOOL (*wxOSX_FocusHandlerPtr)(NSView* self, SEL _cmd); - void wxWidgetCocoaImpl::mouseEvent(WX_NSEvent event, WXWidget slf, void *_cmd) { // we are getting moved events for all windows in the hierarchy, not something wx expects @@ -1349,14 +1442,9 @@ bool wxWidgetCocoaImpl::resignFirstResponder(WXWidget slf, void *_cmd) BOOL r = superimpl(slf, (SEL)_cmd); NSResponder * responder = wxNonOwnedWindowCocoaImpl::GetNextFirstResponder(); - NSView* otherView = GetViewFromResponder(responder); + NSView* otherView = wxOSXGetViewFromResponder(responder); - wxWidgetImpl* otherWindow = FindFromWXWidget(otherView); - - // NSScrollViews can have their subviews like NSClipView getting focus - // therefore check and use the NSScrollView peer in that case - if ( otherWindow == NULL && [[otherView superview] isKindOfClass:[NSScrollView class]]) - otherWindow = FindFromWXWidget([otherView superview]); + wxWidgetImpl* otherWindow = FindBestFromWXWidget(otherView); // It doesn't make sense to notify about the loss of focus if it's the same // control in the end, and just a different subview @@ -1698,6 +1786,17 @@ void wxWidgetCocoaImpl::SetVisibility( bool visible ) [m_osxView setHidden:(visible ? NO:YES)]; } +double wxWidgetCocoaImpl::GetContentScaleFactor() const +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + NSWindow* tlw = [m_osxView window]; + if ( [ tlw respondsToSelector:@selector(backingScaleFactor) ] ) + return [tlw backingScaleFactor]; + else +#endif + return 1.0; +} + // ---------------------------------------------------------------------------- // window animation stuff // ---------------------------------------------------------------------------- @@ -2515,7 +2614,13 @@ void wxWidgetCocoaImpl::InstallEventHandler( WXWidget control ) if ([c respondsToSelector:@selector(setAction:)]) { [c setTarget: c]; - [c setAction: @selector(controlAction:)]; + if ( dynamic_cast(GetWXPeer()) ) + { + // everything already set up + } + else + [c setAction: @selector(controlAction:)]; + if ([c respondsToSelector:@selector(setDoubleAction:)]) { [c setDoubleAction: @selector(controlDoubleAction:)]; @@ -2530,10 +2635,18 @@ void wxWidgetCocoaImpl::InstallEventHandler( WXWidget control ) bool wxWidgetCocoaImpl::DoHandleCharEvent(NSEvent *event, NSString *text) { - wxKeyEvent wxevent(wxEVT_CHAR); - SetupKeyEvent( wxevent, event, text ); + bool result = false; + + for (NSUInteger i = 0; i < [text length]; ++i) + { + wxKeyEvent wxevent(wxEVT_CHAR); + unichar c = [text characterAtIndex:i]; + SetupKeyEvent( wxevent, event, [NSString stringWithCharacters:&c length:1]); - return GetWXPeer()->OSXHandleKeyEvent(wxevent); + result = GetWXPeer()->OSXHandleKeyEvent(wxevent) || result; + } + + return result; } bool wxWidgetCocoaImpl::DoHandleKeyEvent(NSEvent *event)