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