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