]> git.saurik.com Git - wxWidgets.git/blame - src/osx/radiobox_osx.cpp
move wxGridCellRenderer::Draw before other derived classes implementations (no real...
[wxWidgets.git] / src / osx / radiobox_osx.cpp
CommitLineData
489468fe 1/////////////////////////////////////////////////////////////////////////////
524c47aa 2// Name: src/osx/radiobox.cpp
489468fe
SC
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
524c47aa 23#include "wx/osx/private.h"
489468fe
SC
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{
c6212a0c 55 SendDestroyEvent();
489468fe
SC
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_labelOrig = m_label = label;
111
524c47aa 112 m_peer = wxWidgetImpl::CreateGroupBox( this, parent, id, label, pos, size, style, GetExtraStyle() );
489468fe
SC
113
114 for (i = 0; i < n; i++)
115 {
116 wxRadioButton *radBtn = new wxRadioButton(
117 this,
118 wxID_ANY,
119 GetLabelText(choices[i]),
120 wxPoint( 5, 20 * i + 10 ),
121 wxDefaultSize,
122 i == 0 ? wxRB_GROUP : 0 );
123
124 if ( i == 0 )
125 m_radioButtonCycle = radBtn;
126// m_radioButtonCycle = radBtn->AddInCycle( m_radioButtonCycle );
127 }
128
129 SetSelection( 0 );
130 MacPostControlCreate( pos, size );
131
132 return true;
133}
134
135// Enables or disables the entire radiobox
136//
137bool wxRadioBox::Enable(bool enable)
138{
139 wxRadioButton *current;
140
141 if (!wxControl::Enable( enable ))
142 return false;
143
144 current = m_radioButtonCycle;
145 for (unsigned int i = 0; i < m_noItems; i++)
146 {
147 current->Enable( enable );
148 current = current->NextInCycle();
149 }
150
151 return true;
152}
153
154// Enables or disables an given button
155//
156bool wxRadioBox::Enable(unsigned int item, bool enable)
157{
158 if (!IsValid( item ))
159 return false;
160
161 unsigned int i = 0;
162 wxRadioButton *current = m_radioButtonCycle;
163 while (i != item)
164 {
165 i++;
166 current = current->NextInCycle();
167 }
168
169 return current->Enable( enable );
170}
171
172bool wxRadioBox::IsItemEnabled(unsigned int item) const
173{
174 if (!IsValid( item ))
175 return false;
176
177 unsigned int i = 0;
178 wxRadioButton *current = m_radioButtonCycle;
179 while (i != item)
180 {
181 i++;
182 current = current->NextInCycle();
183 }
184
185 return current->IsEnabled();
186}
187
188// Returns the radiobox label
189//
190wxString wxRadioBox::GetLabel() const
191{
192 return wxControl::GetLabel();
193}
194
195// Returns the label for the given button
196//
197wxString wxRadioBox::GetString(unsigned int item) const
198{
199 wxRadioButton *current;
200
201 if (!IsValid( item ))
202 return wxEmptyString;
203
204 unsigned int i = 0;
205 current = m_radioButtonCycle;
206 while (i != item)
207 {
208 i++;
209 current = current->NextInCycle();
210 }
211
212 return current->GetLabel();
213}
214
215// Returns the zero-based position of the selected button
216//
217int wxRadioBox::GetSelection() const
218{
219 int i;
220 wxRadioButton *current;
221
222 i = 0;
223 current = m_radioButtonCycle;
224 while (!current->GetValue())
225 {
226 i++;
227 current = current->NextInCycle();
228 }
229
230 return i;
231}
232
233// Sets the radiobox label
234//
235void wxRadioBox::SetLabel(const wxString& label)
236{
237 return wxControl::SetLabel( label );
238}
239
240// Sets the label of a given button
241//
242void wxRadioBox::SetString(unsigned int item,const wxString& label)
243{
244 if (!IsValid( item ))
245 return;
246
247 unsigned int i = 0;
248 wxRadioButton *current = m_radioButtonCycle;
249 while (i != item)
250 {
251 i++;
252 current = current->NextInCycle();
253 }
254
255 return current->SetLabel( label );
256}
257
258// Sets a button by passing the desired position. This does not cause
259// wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
260//
261void wxRadioBox::SetSelection(int item)
262{
263 int i;
264 wxRadioButton *current;
265
266 if (!IsValid( item ))
267 return;
268
269 i = 0;
270 current = m_radioButtonCycle;
271 while (i != item)
272 {
273 i++;
274 current = current->NextInCycle();
275 }
276
277 current->SetValue( true );
278}
279
280// Shows or hides the entire radiobox
281//
282bool wxRadioBox::Show(bool show)
283{
284 wxRadioButton *current;
285
286 current = m_radioButtonCycle;
287 for (unsigned int i=0; i<m_noItems; i++)
288 {
289 current->Show( show );
290 current = current->NextInCycle();
291 }
292
293 wxControl::Show( show );
294
295 return true;
296}
297
298// Shows or hides the given button
299//
300bool wxRadioBox::Show(unsigned int item, bool show)
301{
302 if (!IsValid( item ))
303 return false;
304
305 unsigned int i = 0;
306 wxRadioButton *current = m_radioButtonCycle;
307 while (i != item)
308 {
309 i++;
310 current = current->NextInCycle();
311 }
312
313 return current->Show( show );
314}
315
316bool wxRadioBox::IsItemShown(unsigned int item) const
317{
318 if (!IsValid( item ))
319 return false;
320
321 unsigned int i = 0;
322 wxRadioButton *current = m_radioButtonCycle;
323 while (i != item)
324 {
325 i++;
326 current = current->NextInCycle();
327 }
328
329 return current->IsShown();
330}
331
332
333// Simulates the effect of the user issuing a command to the item
334//
335void wxRadioBox::Command( wxCommandEvent& event )
336{
337 SetSelection( event.GetInt() );
338 ProcessCommand( event );
339}
340
341// Sets the selected button to receive keyboard input
342//
343void wxRadioBox::SetFocus()
344{
345 wxRadioButton *current;
346
347 current = m_radioButtonCycle;
348 while (!current->GetValue())
349 {
350 current = current->NextInCycle();
351 }
352
353 current->SetFocus();
354}
355
356// Simulates the effect of the user issuing a command to the item
357//
358#define RADIO_SIZE 20
359
360void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
361{
362 int i;
363 wxRadioButton *current;
364
365 // define the position
366
367 int x_current, y_current;
368 int x_offset, y_offset;
369 int widthOld, heightOld;
370
371 GetSize( &widthOld, &heightOld );
372 GetPosition( &x_current, &y_current );
373
374 x_offset = x;
375 y_offset = y;
376 if (!(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
377 {
378 if (x == wxDefaultCoord)
379 x_offset = x_current;
380 if (y == wxDefaultCoord)
381 y_offset = y_current;
382 }
383
384 // define size
385 int charWidth, charHeight;
386 int maxWidth, maxHeight;
387 int eachWidth[128], eachHeight[128];
388 int totWidth, totHeight;
389
390 GetTextExtent(
391 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
392 &charWidth, &charHeight );
393
394 charWidth /= 52;
395
396 maxWidth = -1;
397 maxHeight = -1;
398 for (unsigned int i = 0 ; i < m_noItems; i++)
399 {
400 GetTextExtent(GetString(i), &eachWidth[i], &eachHeight[i] );
401 eachWidth[i] = (int)(eachWidth[i] + RADIO_SIZE);
0c530e5a 402 eachHeight[i] = (int) eachHeight[i];
489468fe
SC
403
404 if (maxWidth < eachWidth[i])
405 maxWidth = eachWidth[i];
406 if (maxHeight < eachHeight[i])
407 maxHeight = eachHeight[i];
408 }
409
0c530e5a 410 totHeight = GetRowCount() * maxHeight + (GetRowCount() - 1) * maxHeight / 2;
489468fe
SC
411 totWidth = GetColumnCount() * (maxWidth + charWidth);
412
413 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) ) ;
c6212a0c 414
489468fe
SC
415 // change the width / height only when specified
416 if ( width == wxDefaultCoord )
417 {
418 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
419 width = sz.x;
420 else
421 width = widthOld;
422 }
423
424 if ( height == wxDefaultCoord )
425 {
426 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
427 height = sz.y;
428 else
429 height = heightOld;
430 }
431
432 wxControl::DoSetSize( x_offset, y_offset, width, height, wxSIZE_AUTO );
433
434 // arrange radio buttons
435 int x_start, y_start;
436
0c530e5a
SC
437 x_start = ( width - sz.x ) / 2;
438 y_start = ( height - sz.y ) / 2;
489468fe
SC
439
440 x_offset = x_start;
441 y_offset = y_start;
442
443 current = m_radioButtonCycle;
444 for (i = 0 ; i < (int)m_noItems; i++)
445 {
446 // not to do for the zero button!
447 if ((i > 0) && ((i % GetMajorDim()) == 0))
448 {
449 if (m_windowStyle & wxRA_SPECIFY_ROWS)
450 {
451 x_offset += maxWidth + charWidth;
452 y_offset = y_start;
453 }
454 else
455 {
456 x_offset = x_start;
0c530e5a 457 y_offset += 3 * maxHeight / 2 ; //+ charHeight / 2
489468fe
SC
458 }
459 }
460
461 current->SetSize( x_offset, y_offset, eachWidth[i], eachHeight[i]);
462 current = current->NextInCycle();
463
464 if (m_windowStyle & wxRA_SPECIFY_ROWS)
0c530e5a 465 y_offset += 3 * maxHeight / 2 ; // + charHeight / 2
489468fe
SC
466 else
467 x_offset += maxWidth + charWidth;
468 }
469}
470
471wxSize wxRadioBox::DoGetBestSize() const
472{
473 int charWidth, charHeight;
474 int maxWidth, maxHeight;
475 int eachWidth, eachHeight;
476 int totWidth, totHeight;
477
478 wxFont font = GetFont(); // GetParent()->GetFont()
479 GetTextExtent(
480 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
481 &charWidth, &charHeight, NULL, NULL, &font );
482
483 charWidth /= 52;
484
485 maxWidth = -1;
486 maxHeight = -1;
487
488 for (unsigned int i = 0 ; i < m_noItems; i++)
489 {
490 GetTextExtent(GetString(i), &eachWidth, &eachHeight, NULL, NULL, &font );
491 eachWidth = (int)(eachWidth + RADIO_SIZE);
0c530e5a 492 eachHeight = (int)eachHeight;
489468fe
SC
493 if (maxWidth < eachWidth)
494 maxWidth = eachWidth;
495 if (maxHeight < eachHeight)
496 maxHeight = eachHeight;
497 }
498
0c530e5a 499 totHeight = GetRowCount() * maxHeight + (GetRowCount() - 1) * maxHeight / 2;
489468fe
SC
500 totWidth = GetColumnCount() * (maxWidth + charWidth);
501
502 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) );
503 totWidth = sz.x;
504 totHeight = sz.y;
c6212a0c 505
0c530e5a
SC
506 // optimum size is an additional 5 pt border to all sides
507 totWidth += 10;
508 totHeight += 10;
489468fe
SC
509
510 // handle radio box title as well
511 GetTextExtent( GetLabel(), &eachWidth, NULL );
512 eachWidth = (int)(eachWidth + RADIO_SIZE) + 3 * charWidth;
513 if (totWidth < eachWidth)
514 totWidth = eachWidth;
515
516 return wxSize( totWidth, totHeight );
517}
518
bbd8f8af
SC
519bool wxRadioBox::SetFont(const wxFont& font)
520{
521 bool retval = wxWindowBase::SetFont( font );
522
523 // dont' update the native control, it has its own small font
524
525 return retval;
526}
527
489468fe 528#endif // wxUSE_RADIOBOX