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