]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/radiobox.cpp
Explicitly forward non-command events along to the native control first.
[wxWidgets.git] / src / mac / carbon / radiobox.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/mac/carbon/radiobox.cpp
3// Purpose: wxRadioBox
4// Author: Stefan Csomor
5// Modified by: JS Lair (99/11/15) first implementation
6// Created: 1998-01-01
7// RCS-ID: $Id$
8// Copyright: (c) Stefan Csomor
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#if wxUSE_RADIOBOX
15
16#include "wx/radiobox.h"
17
18#ifndef WX_PRECOMP
19 #include "wx/radiobut.h"
20 #include "wx/arrstr.h"
21#endif
22
23#include "wx/mac/uma.h"
24
25IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
26
27
28BEGIN_EVENT_TABLE(wxRadioBox, wxControl)
29 EVT_RADIOBUTTON( wxID_ANY , wxRadioBox::OnRadioButton )
30END_EVENT_TABLE()
31
32
33void wxRadioBox::OnRadioButton( wxCommandEvent &outer )
34{
35 if ( outer.IsChecked() )
36 {
37 wxCommandEvent event( wxEVT_COMMAND_RADIOBOX_SELECTED, m_windowId );
38 int i = GetSelection() ;
39 event.SetInt(i);
40 event.SetString(GetString(i));
41 event.SetEventObject( this );
42 ProcessCommand(event);
43 }
44}
45
46wxRadioBox::wxRadioBox()
47{
48 m_noItems = 0;
49 m_noRowsOrCols = 0;
50 m_radioButtonCycle = NULL;
51}
52
53wxRadioBox::~wxRadioBox()
54{
55 m_isBeingDeleted = true;
56
57 wxRadioButton *next, *current;
58
59 current = m_radioButtonCycle->NextInCycle();
60 if (current != NULL)
61 {
62 while (current != m_radioButtonCycle)
63 {
64 next = current->NextInCycle();
65 delete current;
66
67 current = next;
68 }
69
70 delete current;
71 }
72}
73
74// Create the radiobox for two-step construction
75
76bool wxRadioBox::Create( wxWindow *parent,
77 wxWindowID id, const wxString& label,
78 const wxPoint& pos, const wxSize& size,
79 const wxArrayString& choices,
80 int majorDim, long style,
81 const wxValidator& val, const wxString& name )
82{
83 wxCArrayString chs(choices);
84
85 return Create(
86 parent, id, label, pos, size, chs.GetCount(),
87 chs.GetStrings(), majorDim, style, val, name);
88}
89
90bool wxRadioBox::Create( wxWindow *parent,
91 wxWindowID id, const wxString& label,
92 const wxPoint& pos, const wxSize& size,
93 int n, const wxString choices[],
94 int majorDim, long style,
95 const wxValidator& val, const wxString& name )
96{
97 m_macIsUserPane = false ;
98
99 if ( !wxControl::Create( parent, id, pos, size, style, val, name ) )
100 return false;
101
102 int i;
103
104 m_noItems = (unsigned int)n;
105 m_noRowsOrCols = majorDim;
106 m_radioButtonCycle = NULL;
107
108 SetMajorDim( majorDim == 0 ? n : majorDim, style );
109
110 m_label = label;
111
112 Rect bounds = wxMacGetBoundsForControl( this, pos, size );
113 if ( bounds.right <= bounds.left )
114 bounds.right = bounds.left + 100;
115 if ( bounds.bottom <= bounds.top )
116 bounds.bottom = bounds.top + 100;
117
118 m_peer = new wxMacControl( this );
119
120 OSStatus err = CreateGroupBoxControl(
121 MAC_WXHWND(parent->MacGetTopLevelWindowRef()),
122 &bounds, CFSTR("") , true /*primary*/,
123 m_peer->GetControlRefAddr() );
124 verify_noerr( err );
125
126 for (i = 0; i < n; i++)
127 {
128 wxRadioButton *radBtn = new wxRadioButton(
129 this,
130 wxID_ANY,
131 GetLabelText(choices[i]),
132 wxPoint( 5, 20 * i + 10 ),
133 wxDefaultSize,
134 i == 0 ? wxRB_GROUP : 0 );
135
136 if ( i == 0 )
137 m_radioButtonCycle = radBtn;
138// m_radioButtonCycle = radBtn->AddInCycle( m_radioButtonCycle );
139 }
140
141 SetSelection( 0 );
142 MacPostControlCreate( pos, size );
143
144 return true;
145}
146
147// Enables or disables the entire radiobox
148//
149bool wxRadioBox::Enable(bool enable)
150{
151 wxRadioButton *current;
152
153 if (!wxControl::Enable( enable ))
154 return false;
155
156 current = m_radioButtonCycle;
157 for (unsigned int i = 0; i < m_noItems; i++)
158 {
159 current->Enable( enable );
160 current = current->NextInCycle();
161 }
162
163 return true;
164}
165
166// Enables or disables an given button
167//
168bool wxRadioBox::Enable(unsigned int item, bool enable)
169{
170 if (!IsValid( item ))
171 return false;
172
173 unsigned int i = 0;
174 wxRadioButton *current = m_radioButtonCycle;
175 while (i != item)
176 {
177 i++;
178 current = current->NextInCycle();
179 }
180
181 return current->Enable( enable );
182}
183
184// Returns the radiobox label
185//
186wxString wxRadioBox::GetLabel() const
187{
188 return wxControl::GetLabel();
189}
190
191// Returns the label for the given button
192//
193wxString wxRadioBox::GetString(unsigned int item) const
194{
195 wxRadioButton *current;
196
197 if (!IsValid( item ))
198 return wxEmptyString;
199
200 unsigned int i = 0;
201 current = m_radioButtonCycle;
202 while (i != item)
203 {
204 i++;
205 current = current->NextInCycle();
206 }
207
208 return current->GetLabel();
209}
210
211// Returns the zero-based position of the selected button
212//
213int wxRadioBox::GetSelection() const
214{
215 int i;
216 wxRadioButton *current;
217
218 i = 0;
219 current = m_radioButtonCycle;
220 while (!current->GetValue())
221 {
222 i++;
223 current = current->NextInCycle();
224 }
225
226 return i;
227}
228
229// Sets the radiobox label
230//
231void wxRadioBox::SetLabel(const wxString& label)
232{
233 return wxControl::SetLabel( label );
234}
235
236// Sets the label of a given button
237//
238void wxRadioBox::SetString(unsigned int item,const wxString& label)
239{
240 if (!IsValid( item ))
241 return;
242
243 unsigned int i = 0;
244 wxRadioButton *current = m_radioButtonCycle;
245 while (i != item)
246 {
247 i++;
248 current = current->NextInCycle();
249 }
250
251 return current->SetLabel( label );
252}
253
254// Sets a button by passing the desired position. This does not cause
255// wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
256//
257void wxRadioBox::SetSelection(int item)
258{
259 int i;
260 wxRadioButton *current;
261
262 if (!IsValid( item ))
263 return;
264
265 i = 0;
266 current = m_radioButtonCycle;
267 while (i != item)
268 {
269 i++;
270 current = current->NextInCycle();
271 }
272
273 current->SetValue( true );
274}
275
276// Shows or hides the entire radiobox
277//
278bool wxRadioBox::Show(bool show)
279{
280 wxRadioButton *current;
281
282 current = m_radioButtonCycle;
283 for (unsigned int i=0; i<m_noItems; i++)
284 {
285 current->Show( show );
286 current = current->NextInCycle();
287 }
288
289 wxControl::Show( show );
290
291 return true;
292}
293
294// Shows or hides the given button
295//
296bool wxRadioBox::Show(unsigned int item, bool show)
297{
298 if (!IsValid( item ))
299 return false;
300
301 unsigned int i = 0;
302 wxRadioButton *current = m_radioButtonCycle;
303 while (i != item)
304 {
305 i++;
306 current = current->NextInCycle();
307 }
308
309 return current->Show( show );
310}
311
312// Simulates the effect of the user issuing a command to the item
313//
314void wxRadioBox::Command( wxCommandEvent& event )
315{
316 SetSelection( event.GetInt() );
317 ProcessCommand( event );
318}
319
320// Sets the selected button to receive keyboard input
321//
322void wxRadioBox::SetFocus()
323{
324 wxRadioButton *current;
325
326 current = m_radioButtonCycle;
327 while (!current->GetValue())
328 {
329 current = current->NextInCycle();
330 }
331
332 current->SetFocus();
333}
334
335// Simulates the effect of the user issuing a command to the item
336//
337#define RADIO_SIZE 20
338
339void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
340{
341 int i;
342 wxRadioButton *current;
343
344 // define the position
345
346 int x_current, y_current;
347 int x_offset, y_offset;
348 int widthOld, heightOld;
349
350 GetSize( &widthOld, &heightOld );
351 GetPosition( &x_current, &y_current );
352
353 x_offset = x;
354 y_offset = y;
355 if (!(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
356 {
357 if (x == wxDefaultCoord)
358 x_offset = x_current;
359 if (y == wxDefaultCoord)
360 y_offset = y_current;
361 }
362
363 // define size
364 int charWidth, charHeight;
365 int maxWidth, maxHeight;
366 int eachWidth[128], eachHeight[128];
367 int totWidth, totHeight;
368
369 GetTextExtent(
370 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
371 &charWidth, &charHeight );
372
373 charWidth /= 52;
374
375 maxWidth = -1;
376 maxHeight = -1;
377 for (unsigned int i = 0 ; i < m_noItems; i++)
378 {
379 GetTextExtent(GetString(i), &eachWidth[i], &eachHeight[i] );
380 eachWidth[i] = (int)(eachWidth[i] + RADIO_SIZE);
381 eachHeight[i] = (int)((3 * eachHeight[i]) / 2);
382
383 if (maxWidth < eachWidth[i])
384 maxWidth = eachWidth[i];
385 if (maxHeight < eachHeight[i])
386 maxHeight = eachHeight[i];
387 }
388
389 totHeight = GetRowCount() * maxHeight;
390 totWidth = GetColumnCount() * (maxWidth + charWidth);
391
392 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) ) ;
393
394 // change the width / height only when specified
395 if ( width == wxDefaultCoord )
396 {
397 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
398 width = sz.x;
399 else
400 width = widthOld;
401 }
402
403 if ( height == wxDefaultCoord )
404 {
405 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
406 height = sz.y;
407 else
408 height = heightOld;
409 }
410
411 wxControl::DoSetSize( x_offset, y_offset, width, height, wxSIZE_AUTO );
412
413 // arrange radio buttons
414 int x_start, y_start;
415
416 x_start = 0;
417 y_start = 0;
418
419 x_offset = x_start;
420 y_offset = y_start;
421
422 current = m_radioButtonCycle;
423 for (i = 0 ; i < (int)m_noItems; i++)
424 {
425 // not to do for the zero button!
426 if ((i > 0) && ((i % GetMajorDim()) == 0))
427 {
428 if (m_windowStyle & wxRA_SPECIFY_ROWS)
429 {
430 x_offset += maxWidth + charWidth;
431 y_offset = y_start;
432 }
433 else
434 {
435 x_offset = x_start;
436 y_offset += maxHeight ; //+ charHeight / 2
437 }
438 }
439
440 current->SetSize( x_offset, y_offset, eachWidth[i], eachHeight[i]);
441 current = current->NextInCycle();
442
443 if (m_windowStyle & wxRA_SPECIFY_ROWS)
444 y_offset += maxHeight ; // + charHeight / 2
445 else
446 x_offset += maxWidth + charWidth;
447 }
448}
449
450wxSize wxRadioBox::DoGetBestSize() const
451{
452 int charWidth, charHeight;
453 int maxWidth, maxHeight;
454 int eachWidth, eachHeight;
455 int totWidth, totHeight;
456
457 wxFont font = GetFont(); // GetParent()->GetFont()
458 GetTextExtent(
459 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
460 &charWidth, &charHeight, NULL, NULL, &font );
461
462 charWidth /= 52;
463
464 maxWidth = -1;
465 maxHeight = -1;
466
467 for (unsigned int i = 0 ; i < m_noItems; i++)
468 {
469 GetTextExtent(GetString(i), &eachWidth, &eachHeight, NULL, NULL, &font );
470 eachWidth = (int)(eachWidth + RADIO_SIZE);
471 eachHeight = (int)((3 * eachHeight) / 2);
472 if (maxWidth < eachWidth)
473 maxWidth = eachWidth;
474 if (maxHeight < eachHeight)
475 maxHeight = eachHeight;
476 }
477
478 totHeight = GetRowCount() * maxHeight;
479 totWidth = GetColumnCount() * (maxWidth + charWidth);
480
481 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) );
482 totWidth = sz.x;
483 totHeight = sz.y;
484
485 // handle radio box title as well
486 GetTextExtent( GetLabel(), &eachWidth, NULL );
487 eachWidth = (int)(eachWidth + RADIO_SIZE) + 3 * charWidth;
488 if (totWidth < eachWidth)
489 totWidth = eachWidth;
490
491 return wxSize( totWidth, totHeight );
492}
493
494#endif // wxUSE_RADIOBOX