// Author: Stefan Csomor
// Modified by:
// Created: 2008-06-20
-// RCS-ID: $Id$
// Copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/log.h"
#include "wx/textctrl.h"
#include "wx/combobox.h"
+ #include "wx/radiobut.h"
#endif
#ifdef __WXMAC__
// Get the window with the focus
-NSView* GetViewFromResponder( NSResponder* responder )
+NSView* wxOSXGetViewFromResponder( NSResponder* responder )
{
NSView* view = nil;
if ( [responder isKindOfClass:[NSTextView class]] )
{
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 ;
@end // wxNSView
+@interface wxNSView(TextInput) <NSTextInputClient>
+
+- (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;
case 48:
retval = WXK_TAB;
break;
-
- 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;
}
+
+ // Check for NUMPAD keys. For KEY_UP/DOWN events we need to use the
+ // WXK_NUMPAD constants, but for the CHAR event we want to use the
+ // standard ascii values
+ if ( eventType != wxEVT_CHAR )
+ {
+ switch( [event keyCode] )
+ {
+ 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;
}
@interface NSEvent (DeviceDelta)
- (CGFloat)deviceDeltaX;
- (CGFloat)deviceDeltaY;
+
+// 10.7+
+- (BOOL)hasPreciseScrollingDeltas;
+- (CGFloat)scrollingDeltaX;
+- (CGFloat)scrollingDeltaY;
@end
-void wxWidgetCocoaImpl::SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent )
+void wxWidgetCocoaImpl::SetupCoordinates(wxCoord &x, wxCoord &y, NSEvent* nsEvent)
{
- int eventType = [nsEvent type];
- UInt32 modifiers = [nsEvent modifierFlags] ;
-
NSPoint locationInWindow = [nsEvent locationInWindow];
// adjust coordinates for the window of the target view
{
if ( [nsEvent window] != nil )
locationInWindow = [[nsEvent window] convertBaseToScreen:locationInWindow];
-
+
if ( [m_osxView window] != nil )
locationInWindow = [[m_osxView window] convertScreenToBase:locationInWindow];
}
-
+
NSPoint locationInView = [m_osxView convertPoint:locationInWindow fromView:nil];
wxPoint locationInViewWX = wxFromNSPoint( m_osxView, locationInView );
+
+ x = locationInViewWX.x;
+ y = locationInViewWX.y;
+
+}
+
+void wxWidgetCocoaImpl::SetupMouseEvent( wxMouseEvent &wxevent , NSEvent * nsEvent )
+{
+ int eventType = [nsEvent type];
+ UInt32 modifiers = [nsEvent modifierFlags] ;
+
+ SetupCoordinates(wxevent.m_x, wxevent.m_y, nsEvent);
// these parameters are not given for all events
UInt32 button = [nsEvent buttonNumber];
UInt32 clickCount = 0;
- wxevent.m_x = locationInViewWX.x;
- wxevent.m_y = locationInViewWX.y;
wxevent.m_shiftDown = modifiers & NSShiftKeyMask;
wxevent.m_rawControlDown = modifiers & NSControlKeyMask;
wxevent.m_altDown = modifiers & NSAlternateKeyMask;
wxevent.SetEventType( wxEVT_MOUSEWHEEL ) ;
- // see http://developer.apple.com/qa/qa2005/qa1453.html
- // for more details on why we have to look for the exact type
-
- const EventRef cEvent = (EventRef) [nsEvent eventRef];
- bool isMouseScrollEvent = false;
- if ( cEvent )
- isMouseScrollEvent = ::GetEventKind(cEvent) == kEventMouseScroll;
-
- if ( isMouseScrollEvent )
+ if ( UMAGetSystemVersion() >= 0x1070 )
{
- deltaX = [nsEvent deviceDeltaX];
- deltaY = [nsEvent deviceDeltaY];
+ if ( [nsEvent hasPreciseScrollingDeltas] )
+ {
+ deltaX = [nsEvent scrollingDeltaX];
+ deltaY = [nsEvent scrollingDeltaY];
+ }
+ else
+ {
+ deltaX = [nsEvent scrollingDeltaX] * 10;
+ deltaY = [nsEvent scrollingDeltaY] * 10;
+ }
}
else
{
- deltaX = ([nsEvent deltaX] * 10);
- deltaY = ([nsEvent deltaY] * 10);
+ const EventRef cEvent = (EventRef) [nsEvent eventRef];
+ // see http://developer.apple.com/qa/qa2005/qa1453.html
+ // for more details on why we have to look for the exact type
+
+ bool isMouseScrollEvent = false;
+ if ( cEvent )
+ isMouseScrollEvent = ::GetEventKind(cEvent) == kEventMouseScroll;
+
+ if ( isMouseScrollEvent )
+ {
+ deltaX = [nsEvent deviceDeltaX];
+ deltaY = [nsEvent deviceDeltaY];
+ }
+ else
+ {
+ deltaX = ([nsEvent deltaX] * 10);
+ deltaY = ([nsEvent deltaY] * 10);
+ }
}
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
{
}
[super removeTrackingRect:tag];
}
+
+#if wxOSX_USE_NATIVE_FLIPPED
+- (BOOL)isFlipped
+{
+ return YES;
+}
+#endif
+
+- (BOOL) canBecomeKeyView
+{
+ wxWidgetCocoaImpl* viewimpl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
+ if ( viewimpl && viewimpl->IsUserPane() && viewimpl->GetWXPeer() )
+ return viewimpl->GetWXPeer()->AcceptsFocus();
+ return NO;
+}
+
@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
//
return impl->resignFirstResponder(self, _cmd);
}
+#if !wxOSX_USE_NATIVE_FLIPPED
+
BOOL wxOSX_isFlipped(NSView* self, SEL _cmd)
{
wxWidgetCocoaImpl* impl = (wxWidgetCocoaImpl* ) wxWidgetImpl::FindFromWXWidget( self );
return impl->isFlipped(self, _cmd) ? YES:NO;
}
+#endif
+
typedef void (*wxOSX_DrawRectHandlerPtr)(NSView* self, SEL _cmd, NSRect rect);
void wxOSX_drawRect(NSView* self, SEL _cmd, NSRect rect)
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
+ // therefore we only handle it for the deepest child in the hierarchy
+ if ( [event type] == NSMouseMoved )
+ {
+ NSView* hitview = [[[slf window] contentView] hitTest:[event locationInWindow]];
+ if ( hitview == NULL || hitview != slf)
+ return;
+ }
+
if ( !DoHandleMouseEvent(event) )
{
// for plain NSView mouse events would propagate to parents otherwise
- if (!IsUserPane())
+ // scrollwheel events have to be propagated if not handled in all cases
+ if (!IsUserPane() || [event type] == NSScrollWheel )
{
wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
superimpl(slf, (SEL)_cmd, event);
// super of built-ins keeps the mouse up, as wx expects this event, we have to synthesize it
-
- if ( [ event type] == NSLeftMouseDown )
+ // only trigger if at this moment the mouse is already up
+ if ( [ event type] == NSLeftMouseDown && !wxGetMouseState().LeftIsDown() )
{
wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
SetupMouseEvent(wxevent , event) ;
void wxWidgetCocoaImpl::cursorUpdate(WX_NSEvent event, WXWidget slf, void *_cmd)
{
- NSCursor *cursor = (NSCursor*)GetWXPeer()->GetCursor().GetHCURSOR();
- if (cursor == NULL)
+ if ( !SetupCursor(event) )
{
wxOSX_EventHandlerPtr superimpl = (wxOSX_EventHandlerPtr) [[slf superclass] instanceMethodForSelector:(SEL)_cmd];
- superimpl(slf, (SEL)_cmd, event);
+ superimpl(slf, (SEL)_cmd, event);
}
- else
+ }
+
+bool wxWidgetCocoaImpl::SetupCursor(WX_NSEvent event)
+{
+ extern wxCursor gGlobalCursor;
+
+ if ( gGlobalCursor.IsOk() )
{
- [cursor set];
+ gGlobalCursor.MacInstall();
+ return true;
+ }
+ else
+ {
+ wxWindow* cursorTarget = GetWXPeer();
+ wxCoord x,y;
+ SetupCoordinates(x, y, event);
+ wxPoint cursorPoint( x , y ) ;
+
+ while ( cursorTarget && !cursorTarget->MacSetupCursor( cursorPoint ) )
+ {
+ // at least in GTK cursor events are not propagated either ...
+#if 1
+ cursorTarget = NULL;
+#else
+ cursorTarget = cursorTarget->GetParent() ;
+ if ( cursorTarget )
+ cursorPoint += cursorTarget->GetPosition();
+#endif
+ }
+
+ return cursorTarget != NULL;
}
}
-
-
void wxWidgetCocoaImpl::keyEvent(WX_NSEvent event, WXWidget slf, void *_cmd)
{
if ( [event type] == NSKeyDown )
{
wxEvtHandler * const handler = m_wxPeer->GetEventHandler();
- wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
+ wxCommandEvent command_event( wxEVT_MENU, command );
command_event.SetEventObject( wxevent.GetEventObject() );
handled = handler->ProcessEvent( command_event );
if ( !handled )
{
// accelerators can also be used with buttons, try them too
- command_event.SetEventType(wxEVT_COMMAND_BUTTON_CLICKED);
+ command_event.SetEventType(wxEVT_BUTTON);
handled = handler->ProcessEvent( command_event );
}
}
{
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);
+
+ NSResponder * responder = wxNonOwnedWindowCocoaImpl::GetNextFirstResponder();
+ NSView* otherView = wxOSXGetViewFromResponder(responder);
- // It doesn't make sense to notify about the loss of focus if we're not
- // really losing it and the window which has just gained focus is the same
- // one as this window itself. Of course, this should never happen in the
- // first place but somehow it does in wxGrid code and without this check we
- // enter into an infinite recursion, see #12267.
+ 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
if ( otherWindow == this )
return 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)
return r;
}
-bool wxWidgetCocoaImpl::isFlipped(WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd))
+#if !wxOSX_USE_NATIVE_FLIPPED
+
+bool wxWidgetCocoaImpl::isFlipped(WXWidget slf, void *WXUNUSED(_cmd))
{
return m_isFlipped;
}
+#endif
#define OSX_DEBUG_DRAWING 0
// preparing the update region
wxRegion updateRgn;
+
+ // since adding many rects to a region is a costly process, by default use the bounding rect
+#if 0
const NSRect *rects;
NSInteger count;
-
[slf getRectsBeingDrawn:&rects count:&count];
for ( int i = 0 ; i < count ; ++i )
{
updateRgn.Union(wxFromNSRect(slf, rects[i]));
}
-
+#else
+ updateRgn.Union(wxFromNSRect(slf,*(NSRect*)rect));
+#endif
+
wxWindow* wxpeer = GetWXPeer();
if ( wxpeer->MacGetLeftBorderSize() != 0 || wxpeer->MacGetTopBorderSize() != 0 )
CGContextStrokePath(context);
#endif
- if ( !m_isFlipped )
+ if ( ![slf isFlipped] )
{
CGContextTranslateCTM( context, 0, [m_osxView bounds].size.height );
CGContextScaleCTM( context, 1, -1 );
CGContextSaveGState( context );
}
// as we called restore above, we have to flip again if necessary
- if ( !m_isFlipped )
+ if ( ![slf isFlipped] )
{
CGContextTranslateCTM( context, 0, [m_osxView bounds].size.height );
CGContextScaleCTM( context, 1, -1 );
{
wxWindow* wxpeer = (wxWindow*) GetWXPeer();
if ( wxpeer )
+ {
+ wxpeer->OSXSimulateFocusEvents();
wxpeer->OSXHandleClicked(0);
+ }
}
void wxWidgetCocoaImpl::controlDoubleAction( WXWidget WXUNUSED(slf), void *WXUNUSED(_cmd), void *WXUNUSED(sender))
wxOSX_CLASS_ADD_METHOD(c, @selector(becomeFirstResponder), (IMP) wxOSX_becomeFirstResponder, "c@:" )
wxOSX_CLASS_ADD_METHOD(c, @selector(resignFirstResponder), (IMP) wxOSX_resignFirstResponder, "c@:" )
+#if !wxOSX_USE_NATIVE_FLIPPED
wxOSX_CLASS_ADD_METHOD(c, @selector(isFlipped), (IMP) wxOSX_isFlipped, "c@:" )
+#endif
wxOSX_CLASS_ADD_METHOD(c, @selector(drawRect:), (IMP) wxOSX_drawRect, "v@:{_NSRect={_NSPoint=ff}{_NSSize=ff}}" )
wxOSX_CLASS_ADD_METHOD(c, @selector(controlAction:), (IMP) wxOSX_controlAction, "v@:@" )
void wxWidgetCocoaImpl::Init()
{
m_osxView = NULL;
+#if !wxOSX_USE_NATIVE_FLIPPED
m_isFlipped = true;
+#endif
m_lastKeyDownEvent = NULL;
m_hasEditor = false;
}
[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
// ----------------------------------------------------------------------------
wxUnusedVar(progress);
m_win->SendSizeEvent();
- m_win->MacOnInternalSize();
}
- (void)animationDidEnd:(NSAnimation*)animation
// refresh it once again after the end to ensure that everything is in
// place
win->SendSizeEvent();
- win->MacOnInternalSize();
}
[anim setDelegate:nil];
return true;
}
+void wxWidgetCocoaImpl::SetDropTarget(wxDropTarget* target)
+{
+ [m_osxView unregisterDraggedTypes];
+
+ if ( target == NULL )
+ return;
+
+ wxDataObject* dobj = target->GetDataObject();
+
+ if( dobj )
+ {
+ CFMutableArrayRef typesarray = CFArrayCreateMutable(kCFAllocatorDefault,0,&kCFTypeArrayCallBacks);
+ dobj->AddSupportedTypes(typesarray);
+ NSView* targetView = m_osxView;
+ if ( [m_osxView isKindOfClass:[NSScrollView class] ] )
+ targetView = [(NSScrollView*) m_osxView documentView];
+
+ [targetView registerForDraggedTypes:(NSArray*)typesarray];
+ CFRelease(typesarray);
+ }
+}
void wxWidgetCocoaImpl::RemoveFromParent()
{
NSView* container = parent->GetWXWidget() ;
wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
[container addSubview:m_osxView];
+
+ if( m_wxPeer->IsFrozen() )
+ [[m_osxView window] disableFlushWindow];
}
void wxWidgetCocoaImpl::SetBackgroundColour( const wxColour &col )
if ([cell respondsToSelector:@selector(setControlSize:)])
[cell setControlSize:size];
}
+
+ // we need to propagate this to inner views as well
+ if ( [m_osxView isKindOfClass:[NSScrollView class] ] )
+ {
+ NSView* targetView = [(NSScrollView*) m_osxView documentView];
+
+ if ( [targetView respondsToSelector:@selector(setControlSize:)] )
+ [targetView setControlSize:size];
+ else if ([targetView respondsToSelector:@selector(cell)])
+ {
+ id cell = [(id)targetView cell];
+ if ([cell respondsToSelector:@selector(setControlSize:)])
+ [cell setControlSize:size];
+ }
+ }
}
void wxWidgetCocoaImpl::SetFont(wxFont const& font, wxColour const&col, long, bool)
{
- if ([m_osxView respondsToSelector:@selector(setFont:)])
- [m_osxView setFont: font.OSXGetNSFont()];
- if ([m_osxView respondsToSelector:@selector(setTextColor:)])
- [m_osxView setTextColor:[NSColor colorWithCalibratedRed:(CGFloat) (col.Red() / 255.0)
+ NSView* targetView = m_osxView;
+ if ( [m_osxView isKindOfClass:[NSScrollView class] ] )
+ targetView = [(NSScrollView*) m_osxView documentView];
+
+ if ([targetView respondsToSelector:@selector(setFont:)])
+ [targetView setFont: font.OSXGetNSFont()];
+ if ([targetView respondsToSelector:@selector(setTextColor:)])
+ [targetView setTextColor:[NSColor colorWithCalibratedRed:(CGFloat) (col.Red() / 255.0)
green:(CGFloat) (col.Green() / 255.0)
blue:(CGFloat) (col.Blue() / 255.0)
alpha:(CGFloat) (col.Alpha() / 255.0)]];
if ([c respondsToSelector:@selector(setAction:)])
{
[c setTarget: c];
- [c setAction: @selector(controlAction:)];
+ if ( dynamic_cast<wxRadioButton*>(GetWXPeer()) )
+ {
+ // everything already set up
+ }
+ else
+ [c setAction: @selector(controlAction:)];
+
if ([c respondsToSelector:@selector(setDoubleAction:)])
{
[c setDoubleAction: @selector(controlDoubleAction:)];
}
NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited|NSTrackingCursorUpdate|NSTrackingMouseMoved|NSTrackingActiveAlways|NSTrackingInVisibleRect;
- NSTrackingArea* area = [[NSTrackingArea alloc] initWithRect: NSZeroRect options: options owner: m_osxView userInfo: nil];
+ NSTrackingArea* area = [[NSTrackingArea alloc] initWithRect: NSZeroRect options: options owner: m_osxView userInfo: nil];
[m_osxView addTrackingArea: area];
[area release];
}
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)
{
wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
SetupMouseEvent(wxevent , event) ;
- return GetWXPeer()->HandleWindowEvent(wxevent);
+ bool result = GetWXPeer()->HandleWindowEvent(wxevent);
+
+ (void)SetupCursor(event);
+
+ return result;
}
void wxWidgetCocoaImpl::DoNotifyFocusEvent(bool receivedFocus, wxWidgetImpl* otherWindow)
event.SetWindow(otherWindow->GetWXPeer());
thisWindow->HandleWindowEvent(event) ;
}
- else // !receivedFocuss
+ else // !receivedFocus
{
#if wxUSE_CARET
if ( thisWindow->GetCaret() )
void wxWidgetCocoaImpl::CaptureMouse()
{
- [[m_osxView window] disableCursorRects];
+ // TODO remove if we don't get into problems with cursor settings
+ // [[m_osxView window] disableCursorRects];
}
void wxWidgetCocoaImpl::ReleaseMouse()
{
- [[m_osxView window] enableCursorRects];
+ // TODO remove if we don't get into problems with cursor settings
+ // [[m_osxView window] enableCursorRects];
}
+#if !wxOSX_USE_NATIVE_FLIPPED
+
void wxWidgetCocoaImpl::SetFlipped(bool flipped)
{
m_isFlipped = flipped;
}
+#endif
+
+void wxWidgetCocoaImpl::SetDrawingEnabled(bool enabled)
+{
+ if ( enabled )
+ {
+ [[m_osxView window] enableFlushWindow];
+ [m_osxView setNeedsDisplay:YES];
+ }
+ else
+ {
+ [[m_osxView window] disableFlushWindow];
+ }
+}
//
// Factory methods
//
NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
wxNSView* v = [[wxNSView alloc] initWithFrame:r];
- // temporary hook for dnd
- [v registerForDraggedTypes:[NSArray arrayWithObjects:
- NSStringPboardType, NSFilenamesPboardType, NSTIFFPboardType, NSPICTPboardType, NSPDFPboardType, nil]];
-
wxWidgetCocoaImpl* c = new wxWidgetCocoaImpl( wxpeer, v, false, true );
return c;
}
{
NSView* cv = [tlw contentView];
c = new wxWidgetCocoaImpl( now, cv, true );
- // increase ref count, because the impl destructor will decrement it again
- CFRetain(cv);
- if ( !now->IsShown() )
- [cv setHidden:NO];
-
+ if ( cv != nil )
+ {
+ // increase ref count, because the impl destructor will decrement it again
+ CFRetain(cv);
+ if ( !now->IsShown() )
+ [cv setHidden:NO];
+ }
}
else
{