]> git.saurik.com Git - wxWidgets.git/blobdiff - src/cocoa/radiobox.mm
fix ownerdrawn button label drawing in ODS_NOACCEL case (#3519)
[wxWidgets.git] / src / cocoa / radiobox.mm
index c67639ccf10f7ed18592f810f9ae478de32d7274..6ce3aa2dd366e8a427808cef97ed03aa7d7c65e6 100644 (file)
@@ -24,6 +24,7 @@
 #include "wx/cocoa/string.h"
 #include "wx/cocoa/autorelease.h"
 
+#import <Foundation/NSArray.h>
 #include "wx/cocoa/objc/NSView.h"
 #import <AppKit/NSButton.h>
 #import <AppKit/NSBox.h>
 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
 BEGIN_EVENT_TABLE(wxRadioBox, wxControl)
 END_EVENT_TABLE()
-// WX_IMPLEMENT_COCOA_OWNER(wxRadioBox,NSTextField,NSControl,NSView)
+
+void wxRadioBox::AssociateNSBox(WX_NSBox cocoaObjcClass)
+{
+    NSMatrix *radioBox = [(WX_NSBox)cocoaObjcClass contentView];
+    // Associate the NSMatrix (the NSBox's contentView) with the wxCocoaNSControl MI base class.
+    AssociateNSControl(radioBox);
+    // Set the target/action.. we don't really need to unset these
+    [radioBox setTarget:wxCocoaNSControl::sm_cocoaTarget];
+    [radioBox setAction:@selector(wxNSControlAction:)];
+}
+
+void wxRadioBox::DisassociateNSBox(WX_NSBox cocoaObjcClass)
+{
+    DisassociateNSControl([(WX_NSBox)cocoaObjcClass contentView]);
+}
+
+WX_IMPLEMENT_COCOA_OWNER(wxRadioBox,NSBox,NSView,NSView)
 
 bool wxRadioBox::Create(wxWindow *parent, wxWindowID winid,
             const wxString& title,
@@ -79,7 +96,7 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowID winid,
     NSMutableArray *allCells = [NSMutableArray arrayWithCapacity:n];
     for(int i=0; i<n; ++i)
     {
-        [currCell setTitle: wxNSStringWithWxString(choices[i])];
+        CocoaSetLabelForObject(choices[i], currCell);
         [allCells addObject: currCell];
         [currCell release];
         // NOTE: We can still safely message currCell as the array has retained it.
@@ -92,12 +109,11 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowID winid,
     // (thousands) which makes every cell in the matrix that big. Not good.
     // Be safe and initialize a text cell with an empty string.  That always works.
     currCell = [[NSCell alloc] initTextCell:@""];
+    [currCell setEnabled:NO]; // Don't allow user to select this cell
     for(int i=n; i < majorDim * minorDim; ++i)
     {
         [allCells addObject: currCell];
         // NOTE: Use the same instance.. this should work and save some heap allocations.
-        // It will, however, make the selection rather indeterminate if the user clicks
-        // on the empty space.
 #if 0
        [currCell release];
        currCell = [currCell copy];
@@ -135,19 +151,27 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowID winid,
             withObject:[allCells subarrayWithRange:NSMakeRange(i*majorDim, majorDim)]];
     }
 
-    //make and set up an NSBox (TODO: Just derive from wxStaticBox)
-    SetNSView([[NSBox alloc] initWithFrame:MakeDefaultNSRect(size)]);
-    [m_cocoaNSView release];
+    NSBox *theBox = [[NSBox alloc] initWithFrame:MakeDefaultNSRect(size)];
 
     // Replace the box's content view with the NSMatrix we just created
-    [GetNSBox() setContentView:radioBox];
+    // IMPORTANT: This must be done before calling SetNSBox.
+    [theBox setContentView:radioBox];
     [radioBox release]; // The NSBox retains it for us.
 
-    [GetNSBox() setTitle:wxNSStringWithWxString(title)];
+    SetNSBox(theBox);
+    [theBox release];
+
+
+    CocoaSetLabelForObject(title, GetNSBox());
 //    [GetNSBox() setBorderType:NSLineBorder]; // why??
 
     SetMajorDim(majorDim, style);
 
+    // Set the selection to the first item if we have any items.
+    // This is for parity with other wx ports which do the same thing.
+    if(n > 0)
+        SetSelection(0);
+
     if(m_parent)
         m_parent->CocoaAddChild(this);
 
@@ -160,6 +184,7 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowID winid,
 
 wxRadioBox::~wxRadioBox()
 {
+    DisassociateNSBox(GetNSBox());
 }
 
 WX_NSMatrix wxRadioBox::GetNSMatrix() const
@@ -170,11 +195,20 @@ WX_NSMatrix wxRadioBox::GetNSMatrix() const
     // selection
 void wxRadioBox::SetSelection(int n)
 {
+    int r = GetRowForIndex(n);
+    int c = GetColumnForIndex(n);
+    [GetNSMatrix() selectCellAtRow:r column:c];
 }
 
 int wxRadioBox::GetSelection() const
 {
-    return 0;
+    NSMatrix *radioBox = GetNSMatrix();
+    NSInteger r = [radioBox selectedRow];
+    NSInteger c = [radioBox selectedColumn];
+    if(m_windowStyle & wxRA_SPECIFY_COLS)
+        return r * GetMajorDim() + c;
+    else
+        return c * GetMajorDim() + r;
 }
 
     // string access
@@ -190,23 +224,38 @@ unsigned int wxRadioBox::GetCount() const
 
 wxString wxRadioBox::GetString(unsigned int n) const
 {
-    return wxEmptyString;
+    int r = GetRowForIndex(n);
+    int c = GetColumnForIndex(n);
+    // FIXME: Cocoa stores the mnemonic-stripped title.
+    return wxStringWithNSString([[GetNSMatrix() cellAtRow:r column:c] title]);
 }
 
 void wxRadioBox::SetString(unsigned int n, const wxString& label)
 {
+    int r = GetRowForIndex(n);
+    int c = GetColumnForIndex(n);
+    CocoaSetLabelForObject(label, [GetNSMatrix() cellAtRow:r column:c]);
 }
 
     // change the individual radio button state
 bool wxRadioBox::Enable(unsigned int n, bool enable)
 {
-    // TODO
-    return false;
+    int r = GetRowForIndex(n);
+    int c = GetColumnForIndex(n);
+    NSCell *cell = [GetNSMatrix() cellAtRow:r column:c];
+    if(cell == nil)
+        return false;
+    bool wasEnabled = [cell isEnabled];
+    [cell setEnabled:enable];
+    return (wasEnabled && !enable) || (!wasEnabled && enable);
 }
 
 bool wxRadioBox::Show(unsigned int n, bool show)
 {
     // TODO
+    // NOTE: Cocoa has no visible state for cells so we'd need to replace the
+    // cell with a dummy one to hide it or alternatively subclass NSButtonCell
+    // and add the behavior.
     return false;
 }
 
@@ -217,4 +266,12 @@ wxSize wxRadioBox::DoGetBestSize() const
     return wxControl::DoGetBestSize();
 }
 
+void wxRadioBox::CocoaTarget_action(void)
+{
+    wxCommandEvent event(wxEVT_COMMAND_RADIOBOX_SELECTED, GetId());
+    InitCommandEvent(event);
+    event.SetInt(GetSelection()); // i.e. SetSelection.
+    Command(event);
+}
+
 #endif