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