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