quite ugly workaround, but even the engineers at WWDC couldn't give me a better alternative, fixes #14968

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74189 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor
2013-06-12 21:23:45 +00:00
parent 0afeb753e0
commit 2ec5dba394
2 changed files with 95 additions and 7 deletions

View File

@@ -16,6 +16,87 @@
#include "wx/radiobut.h"
#include "wx/osx/private.h"
// ugly workaround for the fact that since 10.8 is treating all subviews of a view
// which share the same action selector as a group and sets their value automatically
// so we are creating <maxAlternateActions> different selectors and iterate through them
// as we are assigning their selectors as actions
#include <objc/objc-runtime.h>
const int maxAlternateActions = 100;
NSString* alternateActionsSelector = @"controlAction%d:";
extern void wxOSX_controlAction(NSView* self, SEL _cmd, id sender);
@interface wxNSRadioButton : NSButton
{
NSTrackingRectTag rectTag;
}
@end
@implementation wxNSRadioButton
+ (void)initialize
{
static BOOL initialized = NO;
if (!initialized)
{
initialized = YES;
wxOSXCocoaClassAddWXMethods( self );
for ( int i = 1 ; i <= maxAlternateActions ; i++ )
{
class_addMethod(self, NSSelectorFromString([NSString stringWithFormat: alternateActionsSelector, i]), (IMP) wxOSX_controlAction, "v@:@" );
}
}
}
- (void) setState: (NSInteger) v
{
[super setState:v];
// [[self cell] setState:v];
}
- (int) intValue
{
switch ( [self state] )
{
case NSOnState:
return 1;
case NSMixedState:
return 2;
default:
return 0;
}
}
- (void) setIntValue: (int) v
{
switch( v )
{
case 2:
[self setState:NSMixedState];
break;
case 1:
[self setState:NSOnState];
break;
default :
[self setState:NSOffState];
break;
}
}
- (void) setTrackingTag: (NSTrackingRectTag)tag
{
rectTag = tag;
}
- (NSTrackingRectTag) trackingTag
{
return rectTag;
}
@end
wxWidgetImplType* wxWidgetImpl::CreateRadioButton( wxWindowMac* wxpeer,
wxWindowMac* WXUNUSED(parent),
wxWindowID WXUNUSED(id),
@@ -26,10 +107,16 @@ wxWidgetImplType* wxWidgetImpl::CreateRadioButton( wxWindowMac* wxpeer,
long WXUNUSED(extraStyle))
{
NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
wxNSButton* v = [[wxNSButton alloc] initWithFrame:r];
wxNSRadioButton* v = [[wxNSRadioButton alloc] initWithFrame:r];
[v setButtonType:NSRadioButton];
static int alternateAction = 1;
[v setAction: NSSelectorFromString([NSString stringWithFormat: alternateActionsSelector, alternateAction])];
if ( ++alternateAction > maxAlternateActions )
alternateAction = 1;
wxWidgetCocoaImpl* c = new wxWidgetCocoaImpl( wxpeer, v );
return c;
}

View File

@@ -1185,11 +1185,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
@@ -2524,7 +2519,13 @@ void wxWidgetCocoaImpl::InstallEventHandler( WXWidget control )
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:)];