]> git.saurik.com Git - wxWidgets.git/blame - src/cocoa/radiobox.mm
moved wxFileConfig test to config directory together with wxConfig test
[wxWidgets.git] / src / cocoa / radiobox.mm
CommitLineData
da0634c1 1/////////////////////////////////////////////////////////////////////////////
8228b893 2// Name: src/cocoa/radiobox.mm
da0634c1
DE
3// Purpose: wxRadioBox
4// Author: David Elliott
5// Modified by:
6// Created: 2003/02/15
8228b893 7// RCS-ID: $Id$
da0634c1 8// Copyright: (c) 2003 David Elliott
9ed97552 9// (c) 2007 Software 2000 Ltd.
1a87edf2 10// Licence: wxWidgets licence
da0634c1
DE
11/////////////////////////////////////////////////////////////////////////////
12
449c5673 13#include "wx/wxprec.h"
16c81607
RN
14
15#if wxUSE_RADIOBOX
16
cc11cc69
WS
17#include "wx/radiobox.h"
18
449c5673
DE
19#ifndef WX_PRECOMP
20 #include "wx/app.h"
584ad2a3 21 #include "wx/arrstr.h"
449c5673 22#endif //WX_PRECOMP
da0634c1 23
9ed97552
DE
24#include "wx/cocoa/string.h"
25#include "wx/cocoa/autorelease.h"
26
829a2e95 27#include "wx/cocoa/objc/NSView.h"
9ed97552
DE
28#import <AppKit/NSButton.h>
29#import <AppKit/NSBox.h>
30#import <AppKit/NSMatrix.h>
548dd93d 31
da0634c1
DE
32IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
33BEGIN_EVENT_TABLE(wxRadioBox, wxControl)
34END_EVENT_TABLE()
259502c6
DE
35
36void wxRadioBox::AssociateNSBox(WX_NSBox cocoaObjcClass)
37{
38 NSMatrix *radioBox = [(WX_NSBox)cocoaObjcClass contentView];
39 // Associate the NSMatrix (the NSBox's contentView) with the wxCocoaNSControl MI base class.
40 AssociateNSControl(radioBox);
41 // Set the target/action.. we don't really need to unset these
42 [radioBox setTarget:wxCocoaNSControl::sm_cocoaTarget];
43 [radioBox setAction:@selector(wxNSControlAction:)];
44}
45
46void wxRadioBox::DisassociateNSBox(WX_NSBox cocoaObjcClass)
47{
48 DisassociateNSControl([(WX_NSBox)cocoaObjcClass contentView]);
49}
50
51WX_IMPLEMENT_COCOA_OWNER(wxRadioBox,NSBox,NSView,NSView)
da0634c1 52
584ad2a3
MB
53bool wxRadioBox::Create(wxWindow *parent, wxWindowID winid,
54 const wxString& title,
55 const wxPoint& pos,
56 const wxSize& size,
57 const wxArrayString& choices,
58 int majorDim,
59 long style, const wxValidator& validator,
60 const wxString& name)
61{
62 wxCArrayString chs(choices);
63
64 return Create(parent, winid, title, pos, size, chs.GetCount(),
65 chs.GetStrings(), majorDim, style, validator, name);
66}
67
da0634c1
DE
68bool wxRadioBox::Create(wxWindow *parent, wxWindowID winid,
69 const wxString& title,
70 const wxPoint& pos,
71 const wxSize& size,
72 int n, const wxString choices[],
73 int majorDim,
74 long style, const wxValidator& validator,
75 const wxString& name)
76{
9ed97552
DE
77 // We autorelease heavily so we want our own pool
78 wxAutoNSAutoreleasePool pool;
79
da0634c1
DE
80 if(!CreateControl(parent,winid,pos,size,style,validator,name))
81 return false;
9ed97552
DE
82
83 majorDim = majorDim == 0 ? n : majorDim;
84 // TODO: Don't forget to call SetMajorDim
85 // We can't yet as we can't implement GetCount() until after
86 // we make the NSMatrix.
87 int minorDim = (n + majorDim - 1) / majorDim;
88
89
90 // Create a prototype cell for use with the NSMatrix build
91 NSCell *currCell = [[NSButtonCell alloc] initTextCell:@""];
92 [(NSButtonCell*)currCell setButtonType:NSRadioButton];
93
94 // Build up an array of all cells plus any extra empty cells
95 NSMutableArray *allCells = [NSMutableArray arrayWithCapacity:n];
96 for(int i=0; i<n; ++i)
97 {
4c1a4c41 98 [currCell setTitle: wxNSStringWithWxString(wxStripMenuCodes(choices[i], wxStrip_Mnemonics))];
9ed97552
DE
99 [allCells addObject: currCell];
100 [currCell release];
101 // NOTE: We can still safely message currCell as the array has retained it.
102 currCell = [currCell copy];
103 }
104 [currCell release];
105
106 // NOTE: Although an image cell with no image is documented to return NSZeroSize from
107 // the cellSize method, the documentation is WRONG. It will actually return a huge size
108 // (thousands) which makes every cell in the matrix that big. Not good.
109 // Be safe and initialize a text cell with an empty string. That always works.
110 currCell = [[NSCell alloc] initTextCell:@""];
4c1a4c41 111 [currCell setEnabled:NO]; // Don't allow user to select this cell
9ed97552
DE
112 for(int i=n; i < majorDim * minorDim; ++i)
113 {
114 [allCells addObject: currCell];
115 // NOTE: Use the same instance.. this should work and save some heap allocations.
9ed97552
DE
116#if 0
117 [currCell release];
118 currCell = [currCell copy];
119#endif
120 }
121 [currCell release];
122 currCell = NULL;
123
124 // Although the documentation on addColumnWithCells:/addRowWithCells: explicitly
125 // states that it will determine the initial dimension upon the first call if
126 // the initial size is 0x0 it LIES. It will fail an assertion in the code
127 // if you use the simpler initWithFrame: initializer.
128 // Therefore, we specify the major dimension and leave the minor dimension as 0
129 // so that we can add the rows/columns without failing the assertion.
130 NSMatrix* radioBox = [[NSMatrix alloc]
131 initWithFrame:NSZeroRect
132 mode:NSRadioModeMatrix
133 cellClass:nil
134 numberOfRows:style&wxRA_SPECIFY_COLS?0:majorDim
135 numberOfColumns:style&wxRA_SPECIFY_COLS?majorDim:0
136 ];
137
138 SEL addMajorWithCellsSelector;
139 // If column count is the major dimension then we add by row
140 if( style & wxRA_SPECIFY_COLS )
141 addMajorWithCellsSelector = @selector(addRowWithCells:);
142 // If row count is the major dimension then we add by column
143 else
144 addMajorWithCellsSelector = @selector(addColumnWithCells:);
145
146 for(int i=0; i<minorDim; ++i)
147 {
148 [radioBox
149 performSelector:addMajorWithCellsSelector
150 withObject:[allCells subarrayWithRange:NSMakeRange(i*majorDim, majorDim)]];
151 }
152
259502c6 153 NSBox *theBox = [[NSBox alloc] initWithFrame:MakeDefaultNSRect(size)];
9ed97552
DE
154
155 // Replace the box's content view with the NSMatrix we just created
259502c6
DE
156 // IMPORTANT: This must be done before calling SetNSBox.
157 [theBox setContentView:radioBox];
9ed97552
DE
158 [radioBox release]; // The NSBox retains it for us.
159
259502c6
DE
160 SetNSBox(theBox);
161 [theBox release];
162
163
4c1a4c41 164 [GetNSBox() setTitle:wxNSStringWithWxString(wxStripMenuCodes(title, wxStrip_Mnemonics))];
9ed97552
DE
165// [GetNSBox() setBorderType:NSLineBorder]; // why??
166
167 SetMajorDim(majorDim, style);
168
da0634c1
DE
169 if(m_parent)
170 m_parent->CocoaAddChild(this);
9ed97552
DE
171
172 // Do the sizer dance
173 [GetNSBox() sizeToFit];
174 SetInitialFrameRect(pos, size);
8d656ea9 175
da0634c1
DE
176 return true;
177}
178
179wxRadioBox::~wxRadioBox()
180{
259502c6 181 DisassociateNSBox(GetNSBox());
da0634c1
DE
182}
183
9ed97552
DE
184WX_NSMatrix wxRadioBox::GetNSMatrix() const
185{
186 return (NSMatrix*)[(NSBox*)m_cocoaNSView contentView];
187}
188
da0634c1
DE
189 // selection
190void wxRadioBox::SetSelection(int n)
191{
4c1a4c41
DE
192 int r = GetRowForIndex(n);
193 int c = GetColumnForIndex(n);
194 [GetNSMatrix() selectCellAtRow:r column:c];
da0634c1
DE
195}
196
197int wxRadioBox::GetSelection() const
198{
4c1a4c41
DE
199 NSMatrix *radioBox = GetNSMatrix();
200 NSInteger r = [radioBox selectedRow];
201 NSInteger c = [radioBox selectedColumn];
202 if(m_windowStyle & wxRA_SPECIFY_COLS)
203 return r * GetMajorDim() + c;
204 else
205 return c * GetMajorDim() + r;
da0634c1
DE
206}
207
208 // string access
aa61d352 209unsigned int wxRadioBox::GetCount() const
da0634c1 210{
9ed97552
DE
211 NSMatrix *radioBox = GetNSMatrix();
212 NSInteger rowCount, columnCount;
213 [radioBox getNumberOfRows:&rowCount columns:&columnCount];
214
215 // FIXME: This is wrong if padding cells were made
216 return rowCount * columnCount;
da0634c1
DE
217}
218
aa61d352 219wxString wxRadioBox::GetString(unsigned int n) const
da0634c1 220{
4c1a4c41
DE
221 int r = GetRowForIndex(n);
222 int c = GetColumnForIndex(n);
223 // FIXME: Cocoa stores the mnemonic-stripped title.
224 return wxStringWithNSString([[GetNSMatrix() cellAtRow:r column:c] title]);
da0634c1
DE
225}
226
aa61d352 227void wxRadioBox::SetString(unsigned int n, const wxString& label)
da0634c1 228{
4c1a4c41
DE
229 int r = GetRowForIndex(n);
230 int c = GetColumnForIndex(n);
231 [[GetNSMatrix() cellAtRow:r column:c] setTitle:wxNSStringWithWxString(wxStripMenuCodes(label, wxStrip_Mnemonics))];
da0634c1
DE
232}
233
234 // change the individual radio button state
aa61d352 235bool wxRadioBox::Enable(unsigned int n, bool enable)
da0634c1 236{
4c1a4c41
DE
237 int r = GetRowForIndex(n);
238 int c = GetColumnForIndex(n);
239 NSCell *cell = [GetNSMatrix() cellAtRow:r column:c];
240 if(cell == nil)
241 return false;
242 bool wasEnabled = [cell isEnabled];
243 [cell setEnabled:enable];
244 return (wasEnabled && !enable) || (!wasEnabled && enable);
da0634c1
DE
245}
246
aa61d352 247bool wxRadioBox::Show(unsigned int n, bool show)
da0634c1 248{
789f6795 249 // TODO
4c1a4c41
DE
250 // NOTE: Cocoa has no visible state for cells so we'd need to replace the
251 // cell with a dummy one to hide it or alternatively subclass NSButtonCell
252 // and add the behavior.
789f6795 253 return false;
da0634c1
DE
254}
255
9a165f54
DE
256wxSize wxRadioBox::DoGetBestSize() const
257{
9ed97552
DE
258 // The NSBox responds to sizeToFit by sending sizeToFit to its contentView
259 // which is the NSMatrix and does the right thing.
260 return wxControl::DoGetBestSize();
9a165f54
DE
261}
262
259502c6
DE
263void wxRadioBox::CocoaTarget_action(void)
264{
265 wxCommandEvent event(wxEVT_COMMAND_RADIOBOX_SELECTED, GetId());
266 InitCommandEvent(event);
267 event.SetInt(GetSelection()); // i.e. SetSelection.
268 Command(event);
269}
270
16c81607 271#endif