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