]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/radiobox.cpp
porting forward scrolling fix
[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
ab0f37b9 110 m_labelOrig = 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
6239ee05
SC
184bool wxRadioBox::IsItemEnabled(unsigned int item) const
185{
186 if (!IsValid( item ))
187 return false;
188
189 unsigned int i = 0;
190 wxRadioButton *current = m_radioButtonCycle;
191 while (i != item)
192 {
193 i++;
194 current = current->NextInCycle();
195 }
196
197 return current->IsEnabled();
198}
199
1395ff56 200// Returns the radiobox label
43524b15 201//
1395ff56 202wxString wxRadioBox::GetLabel() const
e9576ca5 203{
1395ff56
UJ
204 return wxControl::GetLabel();
205}
e9576ca5 206
1395ff56 207// Returns the label for the given button
43524b15 208//
aa61d352 209wxString wxRadioBox::GetString(unsigned int item) const
1395ff56 210{
1395ff56 211 wxRadioButton *current;
1a87edf2 212
43524b15 213 if (!IsValid( item ))
427ff662 214 return wxEmptyString;
1a87edf2 215
aa61d352 216 unsigned int i = 0;
371fd015 217 current = m_radioButtonCycle;
43524b15
DS
218 while (i != item)
219 {
e40298d5
JS
220 i++;
221 current = current->NextInCycle();
371fd015 222 }
43524b15 223
1395ff56 224 return current->GetLabel();
e9576ca5
SC
225}
226
1395ff56 227// Returns the zero-based position of the selected button
43524b15 228//
e9576ca5
SC
229int wxRadioBox::GetSelection() const
230{
1395ff56
UJ
231 int i;
232 wxRadioButton *current;
1a87edf2 233
43524b15
DS
234 i = 0;
235 current = m_radioButtonCycle;
236 while (!current->GetValue())
237 {
e40298d5 238 i++;
43524b15 239 current = current->NextInCycle();
e40298d5 240 }
1a87edf2 241
1395ff56 242 return i;
e9576ca5
SC
243}
244
1395ff56 245// Sets the radiobox label
43524b15 246//
1395ff56 247void wxRadioBox::SetLabel(const wxString& label)
e9576ca5 248{
43524b15 249 return wxControl::SetLabel( label );
e9576ca5
SC
250}
251
1395ff56 252// Sets the label of a given button
43524b15 253//
aa61d352 254void wxRadioBox::SetString(unsigned int item,const wxString& label)
e9576ca5 255{
43524b15 256 if (!IsValid( item ))
1395ff56 257 return;
43524b15 258
aa61d352
VZ
259 unsigned int i = 0;
260 wxRadioButton *current = m_radioButtonCycle;
43524b15
DS
261 while (i != item)
262 {
e40298d5 263 i++;
43524b15 264 current = current->NextInCycle();
e40298d5 265 }
43524b15
DS
266
267 return current->SetLabel( label );
e9576ca5
SC
268}
269
1a87edf2 270// Sets a button by passing the desired position. This does not cause
1395ff56 271// wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
43524b15 272//
1395ff56 273void wxRadioBox::SetSelection(int item)
e9576ca5 274{
1395ff56
UJ
275 int i;
276 wxRadioButton *current;
1a87edf2 277
43524b15 278 if (!IsValid( item ))
1395ff56 279 return;
43524b15
DS
280
281 i = 0;
282 current = m_radioButtonCycle;
283 while (i != item)
284 {
e40298d5 285 i++;
43524b15 286 current = current->NextInCycle();
e40298d5 287 }
1a87edf2 288
43524b15 289 current->SetValue( true );
e9576ca5
SC
290}
291
1a87edf2 292// Shows or hides the entire radiobox
43524b15 293//
e9576ca5
SC
294bool wxRadioBox::Show(bool show)
295{
1395ff56 296 wxRadioButton *current;
1a87edf2 297
43524b15 298 current = m_radioButtonCycle;
aa61d352 299 for (unsigned int i=0; i<m_noItems; i++)
6cb0bfdf 300 {
43524b15
DS
301 current->Show( show );
302 current = current->NextInCycle();
e40298d5 303 }
43524b15
DS
304
305 wxControl::Show( show );
306
1395ff56 307 return true;
e9576ca5
SC
308}
309
1a87edf2 310// Shows or hides the given button
43524b15 311//
aa61d352 312bool wxRadioBox::Show(unsigned int item, bool show)
e9576ca5 313{
43524b15 314 if (!IsValid( item ))
6cb0bfdf 315 return false;
43524b15 316
aa61d352
VZ
317 unsigned int i = 0;
318 wxRadioButton *current = m_radioButtonCycle;
43524b15
DS
319 while (i != item)
320 {
e40298d5 321 i++;
43524b15 322 current = current->NextInCycle();
e40298d5 323 }
43524b15
DS
324
325 return current->Show( show );
e9576ca5
SC
326}
327
6239ee05
SC
328bool wxRadioBox::IsItemShown(unsigned int item) const
329{
330 if (!IsValid( item ))
331 return false;
332
333 unsigned int i = 0;
334 wxRadioButton *current = m_radioButtonCycle;
335 while (i != item)
336 {
337 i++;
338 current = current->NextInCycle();
339 }
340
341 return current->IsShown();
342}
343
344
1395ff56 345// Simulates the effect of the user issuing a command to the item
43524b15
DS
346//
347void wxRadioBox::Command( wxCommandEvent& event )
e9576ca5 348{
43524b15
DS
349 SetSelection( event.GetInt() );
350 ProcessCommand( event );
e9576ca5
SC
351}
352
1395ff56 353// Sets the selected button to receive keyboard input
43524b15 354//
1395ff56 355void wxRadioBox::SetFocus()
e9576ca5 356{
1395ff56 357 wxRadioButton *current;
1a87edf2 358
43524b15
DS
359 current = m_radioButtonCycle;
360 while (!current->GetValue())
361 {
43524b15 362 current = current->NextInCycle();
e40298d5 363 }
43524b15 364
e40298d5 365 current->SetFocus();
e9576ca5
SC
366}
367
1395ff56 368// Simulates the effect of the user issuing a command to the item
43524b15 369//
baf34314 370#define RADIO_SIZE 20
1395ff56
UJ
371
372void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
e9576ca5 373{
e40298d5
JS
374 int i;
375 wxRadioButton *current;
1a87edf2 376
e40298d5 377 // define the position
1a87edf2 378
e40298d5 379 int x_current, y_current;
43524b15 380 int x_offset, y_offset;
8208e181 381 int widthOld, heightOld;
43524b15
DS
382
383 GetSize( &widthOld, &heightOld );
384 GetPosition( &x_current, &y_current );
1a87edf2 385
e40298d5
JS
386 x_offset = x;
387 y_offset = y;
43524b15
DS
388 if (!(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
389 {
390 if (x == wxDefaultCoord)
391 x_offset = x_current;
392 if (y == wxDefaultCoord)
393 y_offset = y_current;
394 }
1a87edf2 395
e40298d5 396 // define size
43524b15
DS
397 int charWidth, charHeight;
398 int maxWidth, maxHeight;
399 int eachWidth[128], eachHeight[128];
400 int totWidth, totHeight;
1a87edf2 401
43524b15
DS
402 GetTextExtent(
403 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
404 &charWidth, &charHeight );
facd6764 405
43524b15 406 charWidth /= 52;
1a87edf2 407
43524b15
DS
408 maxWidth = -1;
409 maxHeight = -1;
aa61d352 410 for (unsigned int i = 0 ; i < m_noItems; i++)
e40298d5 411 {
aa61d352 412 GetTextExtent(GetString(i), &eachWidth[i], &eachHeight[i] );
e40298d5 413 eachWidth[i] = (int)(eachWidth[i] + RADIO_SIZE);
43524b15
DS
414 eachHeight[i] = (int)((3 * eachHeight[i]) / 2);
415
416 if (maxWidth < eachWidth[i])
417 maxWidth = eachWidth[i];
418 if (maxHeight < eachHeight[i])
419 maxHeight = eachHeight[i];
6cb0bfdf 420 }
1a87edf2 421
43524b15
DS
422 totHeight = GetRowCount() * maxHeight;
423 totWidth = GetColumnCount() * (maxWidth + charWidth);
facd6764 424
43524b15 425 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) ) ;
1a87edf2 426
43524b15 427 // change the width / height only when specified
6cb0bfdf 428 if ( width == wxDefaultCoord )
8208e181
SC
429 {
430 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
43524b15 431 width = sz.x;
8208e181
SC
432 else
433 width = widthOld;
434 }
1a87edf2 435
6cb0bfdf 436 if ( height == wxDefaultCoord )
8208e181
SC
437 {
438 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
43524b15 439 height = sz.y;
8208e181
SC
440 else
441 height = heightOld;
442 }
1a87edf2 443
43524b15 444 wxControl::DoSetSize( x_offset, y_offset, width, height, wxSIZE_AUTO );
1a87edf2 445
43524b15
DS
446 // arrange radio buttons
447 int x_start, y_start;
1a87edf2 448
facd6764 449 x_start = 0;
43524b15 450 y_start = 0;
facd6764 451
e40298d5
JS
452 x_offset = x_start;
453 y_offset = y_start;
1a87edf2 454
43524b15 455 current = m_radioButtonCycle;
c18353e5 456 for (i = 0 ; i < (int)m_noItems; i++)
e40298d5 457 {
43524b15
DS
458 // not to do for the zero button!
459 if ((i > 0) && ((i % GetMajorDim()) == 0))
e40298d5 460 {
3413cead 461 if (m_windowStyle & wxRA_SPECIFY_ROWS)
e40298d5
JS
462 {
463 x_offset += maxWidth + charWidth;
464 y_offset = y_start;
465 }
466 else
467 {
468 x_offset = x_start;
43524b15 469 y_offset += maxHeight ; //+ charHeight / 2
e40298d5
JS
470 }
471 }
1a87edf2 472
43524b15
DS
473 current->SetSize( x_offset, y_offset, eachWidth[i], eachHeight[i]);
474 current = current->NextInCycle();
1a87edf2 475
e40298d5 476 if (m_windowStyle & wxRA_SPECIFY_ROWS)
43524b15 477 y_offset += maxHeight ; // + charHeight / 2
e40298d5
JS
478 else
479 x_offset += maxWidth + charWidth;
480 }
e9576ca5
SC
481}
482
9453cf2b
SC
483wxSize wxRadioBox::DoGetBestSize() const
484{
485 int charWidth, charHeight;
486 int maxWidth, maxHeight;
487 int eachWidth, eachHeight;
488 int totWidth, totHeight;
1a87edf2 489
43524b15
DS
490 wxFont font = GetFont(); // GetParent()->GetFont()
491 GetTextExtent(
492 wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
493 &charWidth, &charHeight, NULL, NULL, &font );
facd6764 494
9453cf2b 495 charWidth /= 52;
1a87edf2 496
e40298d5
JS
497 maxWidth = -1;
498 maxHeight = -1;
1a87edf2 499
aa61d352 500 for (unsigned int i = 0 ; i < m_noItems; i++)
e40298d5 501 {
aa61d352 502 GetTextExtent(GetString(i), &eachWidth, &eachHeight, NULL, NULL, &font );
43524b15 503 eachWidth = (int)(eachWidth + RADIO_SIZE);
9453cf2b 504 eachHeight = (int)((3 * eachHeight) / 2);
43524b15
DS
505 if (maxWidth < eachWidth)
506 maxWidth = eachWidth;
507 if (maxHeight < eachHeight)
508 maxHeight = eachHeight;
9453cf2b 509 }
1a87edf2 510
43524b15
DS
511 totHeight = GetRowCount() * maxHeight;
512 totWidth = GetColumnCount() * (maxWidth + charWidth);
1a87edf2 513
43524b15
DS
514 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth, totHeight ) );
515 totWidth = sz.x;
516 totHeight = sz.y;
1a87edf2 517
c5bdc14f 518 // handle radio box title as well
43524b15
DS
519 GetTextExtent( GetLabel(), &eachWidth, NULL );
520 eachWidth = (int)(eachWidth + RADIO_SIZE) + 3 * charWidth;
1a87edf2 521 if (totWidth < eachWidth)
c5bdc14f 522 totWidth = eachWidth;
1a87edf2 523
43524b15 524 return wxSize( totWidth, totHeight );
9453cf2b 525}
ec7a8d02 526
8228b893 527#endif // wxUSE_RADIOBOX