]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/radiobox.cpp
applied patch 923858 (fixes crash in zlib streams)
[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_macControl = (WXWidget) ::NewControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()) , &bounds , "\p" , true , 0 , 0 , 1,
141 kControlGroupBoxTextTitleProc , (long) this ) ;
142
143 for (i = 0; i < n; i++)
144 {
145 wxRadioButton *radBtn = new wxRadioButton
146 (
147 this,
148 wxID_ANY,
149 wxStripMenuCodes(choices[i]),
150 wxPoint(5,20*i+10),
151 wxDefaultSize,
152 i == 0 ? wxRB_GROUP : 0
153 );
154 if ( i == 0 )
155 m_radioButtonCycle = radBtn ;
156 // m_radioButtonCycle=radBtn->AddInCycle(m_radioButtonCycle);
157 }
158
159 SetSelection(0);
160 MacPostControlCreate(pos,size) ;
161
162 return TRUE;
163 }
164
165
166 //-------------------------------------------------------------------------------------
167 // ¥ Enable(bool)
168 //-------------------------------------------------------------------------------------
169 // Enables or disables the entire radiobox
170
171 bool wxRadioBox::Enable(bool enable)
172 {
173 int i;
174 wxRadioButton *current;
175
176 if (!wxControl::Enable(enable))
177 return false;
178
179 current = m_radioButtonCycle;
180 for (i = 0; i < m_noItems; i++) {
181 current->Enable(enable);
182 current = current->NextInCycle();
183 }
184 return true;
185 }
186
187 //-------------------------------------------------------------------------------------
188 // ¥ Enable(int, bool)
189 //-------------------------------------------------------------------------------------
190 // Enables or disables an given button
191
192 void wxRadioBox::Enable(int item, bool enable)
193 {
194 int i;
195 wxRadioButton *current;
196
197 if ((item < 0) || (item >= m_noItems))
198 return;
199
200 i = 0;
201 current = m_radioButtonCycle;
202 while (i != item) {
203 i++;
204 current = current->NextInCycle();
205 }
206 current->Enable(enable);
207 }
208
209 //-------------------------------------------------------------------------------------
210 // ¥ GetLabel()
211 //-------------------------------------------------------------------------------------
212 // Returns the radiobox label
213
214 wxString wxRadioBox::GetLabel() const
215 {
216 return wxControl::GetLabel();
217 }
218
219 //-------------------------------------------------------------------------------------
220 // ¥ GetLabel(int)
221 //-------------------------------------------------------------------------------------
222 // Returns the label for the given button
223
224 wxString wxRadioBox::GetString(int item) const
225 {
226 int i;
227 wxRadioButton *current;
228
229 if ((item < 0) || (item >= m_noItems))
230 return wxEmptyString;
231
232 i = 0;
233 current = m_radioButtonCycle;
234 while (i != item) {
235 i++;
236 current = current->NextInCycle();
237 }
238 return current->GetLabel();
239 }
240
241 //-------------------------------------------------------------------------------------
242 // ¥ GetSelection
243 //-------------------------------------------------------------------------------------
244 // Returns the zero-based position of the selected button
245
246 int wxRadioBox::GetSelection() const
247 {
248 int i;
249 wxRadioButton *current;
250
251 i=0;
252 current=m_radioButtonCycle;
253 while (!current->GetValue()) {
254 i++;
255 current=current->NextInCycle();
256 }
257
258 return i;
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::SetString(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 // ¥ Show(bool)
325 //-------------------------------------------------------------------------------------
326 // Shows or hides the entire radiobox
327
328 bool wxRadioBox::Show(bool show)
329 {
330 int i;
331 wxRadioButton *current;
332
333 wxControl::Show(show);
334
335 current=m_radioButtonCycle;
336 for (i=0;i<m_noItems;i++) {
337 current->Show(show);
338 current=current->NextInCycle();
339 }
340 return true;
341 }
342
343 //-------------------------------------------------------------------------------------
344 // ¥ Show(int, bool)
345 //-------------------------------------------------------------------------------------
346 // Shows or hides the given button
347
348 void wxRadioBox::Show(int item, bool show)
349 {
350 int i;
351 wxRadioButton *current;
352
353 if ((item < 0) || (item >= m_noItems))
354 return;
355 i=0;
356 current=m_radioButtonCycle;
357 while (i!=item) {
358 i++;
359 current=current->NextInCycle();
360 }
361 current->Show(show);
362 }
363
364 //-------------------------------------------------------------------------------------
365 // ¥ Command
366 //-------------------------------------------------------------------------------------
367 // Simulates the effect of the user issuing a command to the item
368
369 void wxRadioBox::Command (wxCommandEvent & event)
370 {
371 SetSelection (event.GetInt());
372 ProcessCommand (event);
373 }
374
375 //-------------------------------------------------------------------------------------
376 // ¥ SetFocus
377 //-------------------------------------------------------------------------------------
378 // Sets the selected button to receive keyboard input
379
380 void wxRadioBox::SetFocus()
381 {
382 int i;
383 wxRadioButton *current;
384
385 i=0;
386 current=m_radioButtonCycle;
387 while (!current->GetValue()) {
388 i++;
389 current=current->NextInCycle();
390 }
391 current->SetFocus();
392 }
393
394
395 //-------------------------------------------------------------------------------------
396 // ¥ DoSetSize
397 //-------------------------------------------------------------------------------------
398 // Simulates the effect of the user issuing a command to the item
399
400 #define RADIO_SIZE 20
401
402 void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
403 {
404 int i;
405 wxRadioButton *current;
406
407 // define the position
408
409 int x_current, y_current;
410 int x_offset,y_offset;
411 int widthOld, heightOld;
412 GetSize(&widthOld, &heightOld);
413
414 x_offset = x;
415 y_offset = y;
416 GetPosition(&x_current, &y_current);
417 if ((x == -1) && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
418 x_offset = x_current;
419 if ((y == -1)&& !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
420 y_offset = y_current;
421
422 // define size
423
424 int charWidth,charHeight;
425 int maxWidth,maxHeight;
426 int eachWidth[128],eachHeight[128];
427 int totWidth,totHeight;
428
429 GetTextExtent(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), &charWidth, &charHeight);
430
431 charWidth/=52;
432
433 maxWidth=-1;
434 maxHeight=-1;
435 for (i = 0 ; i < m_noItems; i++)
436 {
437 GetTextExtent(GetString(i), &eachWidth[i], &eachHeight[i]);
438 eachWidth[i] = (int)(eachWidth[i] + RADIO_SIZE);
439 eachHeight[i] = (int)((3*eachHeight[i])/2);
440 if (maxWidth<eachWidth[i]) maxWidth = eachWidth[i];
441 if (maxHeight<eachHeight[i]) maxHeight = eachHeight[i];
442 }
443
444 totHeight = GetRowCount() * ( maxHeight ) ;
445 totWidth = GetColumnCount() * (maxWidth + charWidth) ;
446
447 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth , totHeight ) ) ;
448
449 // only change our width/height if asked for
450 if ( width == -1 )
451 {
452 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
453 width = sz.x ;
454 else
455 width = widthOld;
456 }
457
458 if ( height == -1 )
459 {
460 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
461 height = sz.y ;
462 else
463 height = heightOld;
464 }
465
466 wxControl::DoSetSize(x_offset,y_offset,width,height,wxSIZE_AUTO);
467
468 // arrange radiobuttons
469
470 int x_start,y_start;
471
472
473 x_start = 0;
474 y_start = 0 ;
475
476 x_offset = x_start;
477 y_offset = y_start;
478
479 current=m_radioButtonCycle;
480 for ( i = 0 ; i < m_noItems; i++)
481 {
482 if (i&&((i%m_majorDim)==0)) // not to do for the zero button!
483 {
484 if (m_windowStyle & wxRA_VERTICAL)
485 {
486 x_offset += maxWidth + charWidth;
487 y_offset = y_start;
488 }
489 else
490 {
491 x_offset = x_start;
492 y_offset += maxHeight ; /*+ charHeight/2;*/
493 }
494 }
495
496 current->SetSize(x_offset,y_offset,eachWidth[i],eachHeight[i]);
497 current=current->NextInCycle();
498
499 if (m_windowStyle & wxRA_SPECIFY_ROWS)
500 y_offset += maxHeight ; /*+ charHeight/2;*/
501 else
502 x_offset += maxWidth + charWidth;
503 }
504 }
505
506 wxSize wxRadioBox::DoGetBestSize() const
507 {
508 int charWidth, charHeight;
509 int maxWidth, maxHeight;
510 int eachWidth, eachHeight;
511 int totWidth, totHeight;
512
513 wxFont font = GetParent()->GetFont();
514 GetTextExtent(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
515 &charWidth, &charHeight, NULL, NULL, &font);
516
517 charWidth /= 52;
518
519 maxWidth = -1;
520 maxHeight = -1;
521
522 for (int i = 0 ; i < m_noItems; i++)
523 {
524 GetTextExtent(GetString(i), &eachWidth, &eachHeight,NULL, NULL, &font);
525 eachWidth = (int)(eachWidth + RADIO_SIZE) ;
526 eachHeight = (int)((3 * eachHeight) / 2);
527 if (maxWidth < eachWidth) maxWidth = eachWidth;
528 if (maxHeight < eachHeight) maxHeight = eachHeight;
529 }
530
531 totHeight = GetRowCount() * (maxHeight ) ;
532 totWidth = GetColumnCount() * (maxWidth + charWidth) ;
533
534 wxSize sz = DoGetSizeFromClientSize( wxSize( totWidth , totHeight ) ) ;
535 totWidth = sz.x ;
536 totHeight = sz.y ;
537
538 // handle radio box title as well
539 GetTextExtent(GetTitle(), &eachWidth, NULL);
540 eachWidth = (int)(eachWidth + RADIO_SIZE) + 3 * charWidth ;
541 if (totWidth < eachWidth)
542 totWidth = eachWidth;
543
544 return wxSize(totWidth, totHeight);
545 }
546 //-------------------------------------------------------------------------------------
547 // ¥ GetNumVer
548 //-------------------------------------------------------------------------------------
549 // return the number of buttons in the vertical direction
550
551 int wxRadioBox::GetRowCount() const
552 {
553 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
554 {
555 return m_majorDim;
556 }
557 else
558 {
559 return (m_noItems + m_majorDim - 1)/m_majorDim;
560 }
561 }
562
563 //-------------------------------------------------------------------------------------
564 // ¥ GetNumHor
565 //-------------------------------------------------------------------------------------
566 // return the number of buttons in the horizontal direction
567
568 int wxRadioBox::GetColumnCount() const
569 {
570 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
571 {
572 return (m_noItems + m_majorDim - 1)/m_majorDim;
573 }
574 else
575 {
576 return m_majorDim;
577 }
578 }
579
580
581
582
583