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