#include <objc/objc-runtime.h>
+// Get the window with the focus
+
+NSView* GetViewFromResponder( NSResponder* responder )
+{
+ NSView* view = nil;
+ if ( [responder isKindOfClass:[NSTextView class]] )
+ {
+ NSView* delegate = [(NSTextView*)responder delegate];
+ if ( [delegate isKindOfClass:[NSTextField class] ] )
+ view = delegate;
+ else
+ 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 ;
NSTrackingRectTag rectTag;
}
-- (BOOL) canBecomeKeyView;
// the tracking tag is needed to track mouse enter / exit events
- (void) setTrackingTag: (NSTrackingRectTag)tag;
- (NSTrackingRectTag) trackingTag;
retval = WXK_TAB;
break;
- default :
+ case 75: // /
+ retval = WXK_NUMPAD_DIVIDE;
+ break;
+ case 67: // *
+ retval = WXK_NUMPAD_MULTIPLY;
+ break;
+ case 78: // -
+ retval = WXK_NUMPAD_SUBTRACT;
+ break;
+ case 69: // +
+ retval = WXK_NUMPAD_ADD;
+ break;
+ case 76: // Enter
+ retval = WXK_NUMPAD_ENTER;
+ break;
+ case 65: // .
+ retval = WXK_NUMPAD_DECIMAL;
+ break;
+ case 82: // 0
+ retval = WXK_NUMPAD0;
+ break;
+ case 83: // 1
+ retval = WXK_NUMPAD1;
+ break;
+ case 84: // 2
+ retval = WXK_NUMPAD2;
+ break;
+ case 85: // 3
+ retval = WXK_NUMPAD3;
+ break;
+ case 86: // 4
+ retval = WXK_NUMPAD4;
+ break;
+ case 87: // 5
+ retval = WXK_NUMPAD5;
+ break;
+ case 88: // 6
+ retval = WXK_NUMPAD6;
+ break;
+ case 89: // 7
+ retval = WXK_NUMPAD7;
+ break;
+ case 91: // 8
+ retval = WXK_NUMPAD8;
+ break;
+ case 92: // 9
+ retval = WXK_NUMPAD9;
+ break;
+ default:
+ //retval = [event keyCode];
break;
}
return retval;
wxevent.m_rawFlags = modifiers;
wxevent.SetTimestamp( [nsEvent timestamp] * 1000.0 ) ;
- switch (eventType)
- {
- case NSKeyDown :
- wxevent.SetEventType( wxEVT_KEY_DOWN ) ;
- break;
- case NSKeyUp :
- wxevent.SetEventType( wxEVT_KEY_UP ) ;
- break;
- case NSFlagsChanged :
- // setup common code here
- break;
- default :
- break ;
- }
wxString chars;
if ( eventType != NSFlagsChanged )
{
- NSString* nschars = [nsEvent characters];
+ NSString* nschars = (wxevent.GetEventType() != wxEVT_CHAR) ? [nsEvent charactersIgnoringModifiers] : [nsEvent characters];
if ( charString )
{
// if charString is set, it did not come from key up / key down
long keyval = 0;
if (wxevent.GetEventType() != wxEVT_CHAR)
+ {
keyval = wxOSXTranslateCocoaKey(nsEvent) ;
+ switch (eventType)
+ {
+ case NSKeyDown :
+ wxevent.SetEventType( wxEVT_KEY_DOWN ) ;
+ break;
+ case NSKeyUp :
+ wxevent.SetEventType( wxEVT_KEY_UP ) ;
+ break;
+ case NSFlagsChanged :
+ switch (keyval)
+ {
+ case WXK_CONTROL:
+ wxevent.SetEventType( wxevent.m_controlDown ? wxEVT_KEY_DOWN : wxEVT_KEY_UP);
+ break;
+ case WXK_SHIFT:
+ wxevent.SetEventType( wxevent.m_shiftDown ? wxEVT_KEY_DOWN : wxEVT_KEY_UP);
+ break;
+ case WXK_ALT:
+ wxevent.SetEventType( wxevent.m_altDown ? wxEVT_KEY_DOWN : wxEVT_KEY_UP);
+ break;
+ case WXK_COMMAND:
+ wxevent.SetEventType( wxevent.m_metaDown ? wxEVT_KEY_DOWN : wxEVT_KEY_UP);
+ break;
+ }
+ break;
+ default :
+ break ;
+ }
+ }
if ( !keyval )
{
wxevent.SetEventType( wxEVT_MOUSEWHEEL ) ;
wxevent.m_wheelDelta = 10;
wxevent.m_linesPerAction = 1;
- NSLog(@"deltaX %f, deltaY %f",[nsEvent deltaX], [nsEvent deltaY]);
- if ( abs([nsEvent deltaX]) > abs([nsEvent deltaY]) )
+
+ if ( fabs([nsEvent deltaX]) > fabs([nsEvent deltaY]) )
{
wxevent.m_wheelAxis = 1;
wxevent.m_wheelRotation = [nsEvent deltaX] * 10.0;
}
}
-- (BOOL) canBecomeKeyView
-{
- return YES;
-}
-
- (void) setTrackingTag: (NSTrackingRectTag)tag
{
rectTag = tag;
return impl->performDragOperation(sender, self, _cmd) ? YES:NO ;
}
+#endif
+
void wxOSX_mouseEvent(NSView* self, SEL _cmd, NSEvent *event)
{
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
impl->controlDoubleAction(self, _cmd, sender);
}
-unsigned int wxWidgetCocoaImpl::draggingEntered(void* s, WXWidget slf, void *_cmd)
+unsigned int wxWidgetCocoaImpl::draggingEntered(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
NSPasteboard *pboard = [sender draggingPasteboard];
return NSDragOperationNone;
wxDragResult result = wxDragNone;
- wxPoint pt = wxFromNSPoint( m_osxView, [sender draggingLocation] );
+ NSPoint nspoint = [m_osxView convertPoint:[sender draggingLocation] fromView:nil];
+ wxPoint pt = wxFromNSPoint( m_osxView, nspoint );
if ( sourceDragMask & NSDragOperationLink )
result = wxDragLink;
return nsresult;
}
-void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget slf, void *_cmd)
+void wxWidgetCocoaImpl::draggingExited(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
NSPasteboard *pboard = [sender draggingPasteboard];
CFRelease(pboardRef);
}
-unsigned int wxWidgetCocoaImpl::draggingUpdated(void* s, WXWidget slf, void *_cmd)
+unsigned int wxWidgetCocoaImpl::draggingUpdated(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
NSPasteboard *pboard = [sender draggingPasteboard];
return NSDragOperationNone;
wxDragResult result = wxDragNone;
- wxPoint pt = wxFromNSPoint( m_osxView, [sender draggingLocation] );
+ NSPoint nspoint = [m_osxView convertPoint:[sender draggingLocation] fromView:nil];
+ wxPoint pt = wxFromNSPoint( m_osxView, nspoint );
if ( sourceDragMask & NSDragOperationLink )
result = wxDragLink;
return nsresult;
}
-bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget slf, void *_cmd)
+bool wxWidgetCocoaImpl::performDragOperation(void* s, WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{
id <NSDraggingInfo>sender = (id <NSDraggingInfo>) s;
wxWindow* wxpeer = GetWXPeer();
wxDropTarget* target = wxpeer->GetDropTarget();
wxDragResult result = wxDragNone;
- wxPoint pt = wxFromNSPoint( m_osxView, [sender draggingLocation] );
+ NSPoint nspoint = [m_osxView convertPoint:[sender draggingLocation] fromView:nil];
+ wxPoint pt = wxFromNSPoint( m_osxView, nspoint );
if ( sourceDragMask & NSDragOperationLink )
result = wxDragLink;
PasteboardRef pboardRef;
PasteboardCreate((CFStringRef)[pboard name], &pboardRef);
target->SetCurrentDragPasteboard(pboardRef);
- result = target->OnData(pt.x, pt.y, result);
+
+ if (target->OnDrop(pt.x, pt.y))
+ result = target->OnData(pt.x, pt.y, result);
+
CFRelease(pboardRef);
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);
{
if ( !DoHandleMouseEvent(event) )
{
- wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
- superimpl(slf, (SEL)_cmd, event);
+ // for plain NSView mouse events would propagate to parents otherwise
+ if (!m_wxPeer->MacIsUserPane())
+ {
+ wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
+ superimpl(slf, (SEL)_cmd, 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_TextEventHandlerPtr superimpl = (wxOSX_TextEventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
+ superimpl(slf, (SEL)_cmd, text);
}
m_lastKeyDownEvent = NULL;
}
bool wxWidgetCocoaImpl::acceptsFirstResponder(WXWidget slf, void *_cmd)
{
- // FIXME: We need to find a way to query AcceptsFocus here, but when we do it
- // it calls native APIs which lead us back here and into a loop.
- wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
- return superimpl(slf, (SEL)_cmd);
+ if ( m_wxPeer->MacIsUserPane() )
+ return m_wxPeer->AcceptsFocus();
+ else
+ {
+ wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
+ return superimpl(slf, (SEL)_cmd);
+ }
}
bool wxWidgetCocoaImpl::becomeFirstResponder(WXWidget slf, void *_cmd)
{
wxOSX_FocusHandlerPtr superimpl = (wxOSX_FocusHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
// get the current focus before running becomeFirstResponder
- NSResponder* currentResponder = [[NSApp keyWindow] firstResponder];
- NSView* otherView = (currentResponder != nil && [currentResponder isKindOfClass:[NSView class]]) ? (NSView*) currentResponder : NULL;
+ 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
- NSResponder* currentResponder = [[NSApp keyWindow] firstResponder];
- NSView* otherView = (currentResponder != nil && [currentResponder isKindOfClass:[NSView class]]) ? (NSView*) currentResponder : NULL;
+ // note that this value isn't reliable, it might return the same view that
+ // is resigning
+ NSView* otherView = FindFocus();
wxWidgetImpl* otherWindow = FindFromWXWidget(otherView);
- if ( r )
+ // NSTextViews have an editor as true responder, therefore the might get the
+ // resign notification if their editor takes over, don't trigger any event then
+ if ( r && !m_hasEditor)
+ {
DoNotifyFocusEvent( false, otherWindow );
+ }
return r;
}
}
}
-bool wxWidgetCocoaImpl::isFlipped(WXWidget slf, void *_cmd)
+bool wxWidgetCocoaImpl::isFlipped(WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
{
return m_isFlipped;
}
#define OSX_DEBUG_DRAWING 0
-void wxWidgetCocoaImpl::drawRect(void* rect, WXWidget slf, void *_cmd)
+void wxWidgetCocoaImpl::drawRect(void* rect, WXWidget slf, void *WXUNUSED(_cmd))
{
CGContextRef context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort];
CGContextSaveGState( context );
CGContextRestoreGState( context );
}
-void wxWidgetCocoaImpl::controlAction( WXWidget slf, void *_cmd, void *sender)
+void wxWidgetCocoaImpl::controlAction( WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd), void *WXUNUSED(sender))
{
wxWindow* wxpeer = (wxWindow*) GetWXPeer();
if ( wxpeer )
wxpeer->OSXHandleClicked(0);
}
-void wxWidgetCocoaImpl::controlDoubleAction( WXWidget slf, void *_cmd, void *sender)
+void wxWidgetCocoaImpl::controlDoubleAction( WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd), void *WXUNUSED(sender))
{
}
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()
{
}
-void wxWidgetCocoaImpl::ScrollRect( const wxRect *rect, int dx, int dy )
+void wxWidgetCocoaImpl::ScrollRect( const wxRect *WXUNUSED(rect), int WXUNUSED(dx), int WXUNUSED(dy) )
{
#if 1
SetNeedsDisplay() ;
wxWindowMac* parent = GetWXPeer()->GetParent();
// under Cocoa we might have a contentView in the wxParent to which we have to
// adjust the coordinates
- if (parent)
+ if (parent && [m_osxView superview] != parent->GetHandle() )
{
int cx = 0,cy = 0,cw = 0,ch = 0;
if ( parent->GetPeer() )
bool wxWidgetCocoaImpl::HasFocus() const
{
- return ( [[m_osxView window] firstResponder] == m_osxView );
+ return ( FindFocus() == m_osxView );
}
bool wxWidgetCocoaImpl::SetFocus()
return false;
[[m_osxView window] makeFirstResponder: m_osxView] ;
+ [[m_osxView window] makeKeyAndOrderFront:nil] ;
return true;
}
{
if ( [m_osxView respondsToSelector:@selector(setTitle:) ] )
{
- wxCFStringRef cf( title , m_wxPeer->GetFont().GetEncoding() );
+ wxCFStringRef cf( title , encoding );
[m_osxView setTitle:cf.AsNSString()];
}
else if ( [m_osxView respondsToSelector:@selector(setStringValue:) ] )
{
- wxCFStringRef cf( title , m_wxPeer->GetFont().GetEncoding() );
+ wxCFStringRef cf( title , encoding );
[m_osxView setStringValue:cf.AsNSString()];
}
}
}
}
-void wxWidgetCocoaImpl::SetupTabs( const wxNotebook& notebook)
+void wxWidgetCocoaImpl::SetupTabs( const wxNotebook& WXUNUSED(notebook))
{
// implementation in subclass
}
{
}
-void wxWidgetCocoaImpl::SetScrollThumb( wxInt32 val, wxInt32 view )
+void wxWidgetCocoaImpl::SetScrollThumb( wxInt32 WXUNUSED(val), wxInt32 WXUNUSED(view) )
{
}
void wxWidgetCocoaImpl::SetFont(wxFont const& font, wxColour const&, long, bool)
{
if ([m_osxView respondsToSelector:@selector(setFont:)])
-#if wxOSX_USE_CORE_TEXT
- [m_osxView setFont: (NSFont*)font.MacGetCTFont()];
-#else
-
-#endif
+ [m_osxView setFont: font.OSXGetNSFont()];
}
void wxWidgetCocoaImpl::InstallEventHandler( WXWidget control )
bool wxWidgetCocoaImpl::DoHandleCharEvent(NSEvent *event, NSString *text)
{
- wxKeyEvent wxevent(wxEVT_KEY_DOWN);
+ wxKeyEvent wxevent(wxEVT_CHAR);
SetupKeyEvent( wxevent, event, text );
wxevent.SetEventObject(GetWXPeer());
// 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;
- [m_osxView interpretKeyEvents:[NSArray arrayWithObject: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;
}
// Factory methods
//
-wxWidgetImpl* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer, wxWindowMac* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
- long style, long extraStyle)
+wxWidgetImpl* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer, wxWindowMac* WXUNUSED(parent),
+ wxWindowID WXUNUSED(id), const wxPoint& pos, const wxSize& size,
+ long WXUNUSED(style), long WXUNUSED(extraStyle))
{
NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
wxNSView* v = [[wxNSView alloc] initWithFrame:r];