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