quite ugly workaround, but even the engineers at WWDC couldn't give me a better alter...
[wxWidgets.git] / src / osx / cocoa / radiobut.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/osx/cocoa/radiobut.mm
3 // Purpose:     wxRadioButton
4 // Author:      Stefan Csomor
5 // Modified by:
6 // Created:     ??/??/98
7 // RCS-ID:      $Id$
8 // Copyright:   (c) AUTHOR
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #if wxUSE_RADIOBTN
15
16 #include "wx/radiobut.h"
17 #include "wx/osx/private.h"
18
19 // ugly workaround for the fact that since 10.8 is treating all subviews of a view
20 // which share the same action selector as a group and sets their value automatically
21 // so we are creating <maxAlternateActions> different selectors and iterate through them
22 // as we are assigning their selectors as actions
23
24 #include <objc/objc-runtime.h>
25
26 const int maxAlternateActions = 100;
27 NSString* alternateActionsSelector = @"controlAction%d:";
28
29 extern void wxOSX_controlAction(NSView* self, SEL _cmd, id sender);
30
31 @interface wxNSRadioButton : NSButton
32 {
33     NSTrackingRectTag rectTag;
34 }
35
36 @end
37
38 @implementation wxNSRadioButton
39 + (void)initialize
40 {
41     static BOOL initialized = NO;
42     if (!initialized)
43     {
44         initialized = YES;
45         wxOSXCocoaClassAddWXMethods( self );
46         for ( int i = 1 ; i <= maxAlternateActions ; i++ )
47         {
48             class_addMethod(self, NSSelectorFromString([NSString stringWithFormat: alternateActionsSelector, i]), (IMP) wxOSX_controlAction, "v@:@" );
49         }
50     }
51 }
52
53 - (void) setState: (NSInteger) v
54 {
55     [super setState:v];
56     //    [[self cell] setState:v];
57 }
58
59 - (int) intValue
60 {
61     switch ( [self state] )
62     {
63         case NSOnState:
64             return 1;
65         case NSMixedState:
66             return 2;
67         default:
68             return 0;
69     }
70 }
71
72 - (void) setIntValue: (int) v
73 {
74     switch( v )
75     {
76         case 2:
77             [self setState:NSMixedState];
78             break;
79         case 1:
80             [self setState:NSOnState];
81             break;
82         default :
83             [self setState:NSOffState];
84             break;
85     }
86 }
87
88 - (void) setTrackingTag: (NSTrackingRectTag)tag
89 {
90     rectTag = tag;
91 }
92
93 - (NSTrackingRectTag) trackingTag
94 {
95     return rectTag;
96 }
97
98 @end
99
100 wxWidgetImplType* wxWidgetImpl::CreateRadioButton( wxWindowMac* wxpeer,
101                                     wxWindowMac* WXUNUSED(parent),
102                                     wxWindowID WXUNUSED(id),
103                                     const wxString& WXUNUSED(label),
104                                     const wxPoint& pos,
105                                     const wxSize& size,
106                                     long WXUNUSED(style),
107                                     long WXUNUSED(extraStyle))
108 {
109     NSRect r = wxOSXGetFrameForControl( wxpeer, pos , size ) ;
110     wxNSRadioButton* v = [[wxNSRadioButton alloc] initWithFrame:r];
111
112     [v setButtonType:NSRadioButton];
113
114     static int alternateAction = 1;
115  
116     [v setAction: NSSelectorFromString([NSString stringWithFormat: alternateActionsSelector, alternateAction])];
117     if ( ++alternateAction > maxAlternateActions )
118         alternateAction = 1;
119
120     wxWidgetCocoaImpl* c = new wxWidgetCocoaImpl( wxpeer, v );
121     return c;
122 }
123
124 #endif