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