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