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