]> git.saurik.com Git - wxWidgets.git/blob - src/mac/classic/radiobox.cpp
Consistent wxWindow::Enable with wxRadioBox::Enable for control and its items. wxRadi...
[wxWidgets.git] / src / mac / classic / 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 if ( !wxControl::Create(parent, id, pos, size, style, val, name) )
116 return false;
117
118 int i;
119
120 m_noItems = n;
121 m_noRowsOrCols = majorDim;
122 m_radioButtonCycle = NULL;
123
124 if (majorDim==0)
125 m_majorDim = n ;
126 else
127 m_majorDim = majorDim ;
128
129 Rect bounds ;
130 Str255 title ;
131
132 MacPreControlCreate( parent , id , wxStripMenuCodes(label) , pos , size ,style, val , name , &bounds , title ) ;
133
134 m_macControl = (WXWidget) ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1,
135 kControlGroupBoxTextTitleProc , (long) this ) ;
136
137 for (i = 0; i < n; i++)
138 {
139 wxRadioButton *radBtn = new wxRadioButton
140 (
141 this,
142 wxID_ANY,
143 wxStripMenuCodes(choices[i]),
144 wxPoint(5,20*i+10),
145 wxDefaultSize,
146 i == 0 ? wxRB_GROUP : 0
147 );
148 if ( i == 0 )
149 m_radioButtonCycle = radBtn ;
150 // m_radioButtonCycle=radBtn->AddInCycle(m_radioButtonCycle);
151 }
152
153 SetSelection(0);
154 MacPostControlCreate() ;
155
156 return true;
157 }
158
159
160 //-------------------------------------------------------------------------------------
161 // ¥ Enable(bool)
162 //-------------------------------------------------------------------------------------
163 // Enables or disables the entire radiobox
164
165 bool wxRadioBox::Enable(bool enable)
166 {
167 int i;
168 wxRadioButton *current;
169
170 if (!wxControl::Enable(enable))
171 return false;
172
173 current = m_radioButtonCycle;
174 for (i = 0; i < m_noItems; i++) {
175 current->Enable(enable);
176 current = current->NextInCycle();
177 }
178 return true;
179 }
180
181 //-------------------------------------------------------------------------------------
182 // ¥ Enable(int, bool)
183 //-------------------------------------------------------------------------------------
184 // Enables or disables an given button
185
186 bool wxRadioBox::Enable(int item, bool enable)
187 {
188 int i;
189 wxRadioButton *current;
190
191 if ((item < 0) || (item >= m_noItems))
192 return false;
193
194 i = 0;
195 current = m_radioButtonCycle;
196 while (i != item) {
197 i++;
198 current = current->NextInCycle();
199 }
200 return current->Enable(enable);
201 }
202
203 //-------------------------------------------------------------------------------------
204 // ¥ GetLabel()
205 //-------------------------------------------------------------------------------------
206 // Returns the radiobox label
207
208 wxString wxRadioBox::GetLabel() const
209 {
210 return wxControl::GetLabel();
211 }
212
213 //-------------------------------------------------------------------------------------
214 // ¥ GetLabel(int)
215 //-------------------------------------------------------------------------------------
216 // Returns the label for the given button
217
218 wxString wxRadioBox::GetString(int item) const
219 {
220 int i;
221 wxRadioButton *current;
222
223 if ((item < 0) || (item >= m_noItems))
224 return wxEmptyString;
225
226 i = 0;
227 current = m_radioButtonCycle;
228 while (i != item) {
229 i++;
230 current = current->NextInCycle();
231 }
232 return current->GetLabel();
233 }
234
235 //-------------------------------------------------------------------------------------
236 // ¥ GetSelection
237 //-------------------------------------------------------------------------------------
238 // Returns the zero-based position of the selected button
239
240 int wxRadioBox::GetSelection() const
241 {
242 int i;
243 wxRadioButton *current;
244
245 i=0;
246 current=m_radioButtonCycle;
247 while (!current->GetValue()) {
248 i++;
249 current=current->NextInCycle();
250 }
251
252 return i;
253 }
254
255 //-------------------------------------------------------------------------------------
256 // ¥ Number
257 //-------------------------------------------------------------------------------------
258 // Returns the number of buttons in the radiobox
259 //
260 // inline defined
261 //
262
263 //-------------------------------------------------------------------------------------
264 // ¥ SetLabel(const wxString&)
265 //-------------------------------------------------------------------------------------
266 // Sets the radiobox label
267
268 void wxRadioBox::SetLabel(const wxString& label)
269 {
270 return wxControl::SetLabel(label);
271 }
272
273 //-------------------------------------------------------------------------------------
274 // ¥ SetLabel(int, const wxString&)
275 //-------------------------------------------------------------------------------------
276 // Sets the label of a given button
277
278 void wxRadioBox::SetString(int item,const wxString& label)
279 {
280 int i;
281 wxRadioButton *current;
282
283 if ((item < 0) || (item >= m_noItems))
284 return;
285 i=0;
286 current=m_radioButtonCycle;
287 while (i!=item) {
288 i++;
289 current=current->NextInCycle();
290 }
291 return current->SetLabel(label);
292 }
293
294 //-------------------------------------------------------------------------------------
295 // ¥ SetSelection
296 //-------------------------------------------------------------------------------------
297 // Sets a button by passing the desired position. This does not cause
298 // wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
299
300 void wxRadioBox::SetSelection(int item)
301 {
302 int i;
303 wxRadioButton *current;
304
305 if ((item < 0) || (item >= m_noItems))
306 return;
307 i=0;
308 current=m_radioButtonCycle;
309 while (i!=item) {
310 i++;
311 current=current->NextInCycle();
312 }
313 current->SetValue(true);
314
315 }
316
317 //-------------------------------------------------------------------------------------
318 // ¥ Show(bool)
319 //-------------------------------------------------------------------------------------
320 // Shows or hides the entire radiobox
321
322 bool wxRadioBox::Show(bool show)
323 {
324 int i;
325 wxRadioButton *current;
326
327 wxControl::Show(show);
328
329 current=m_radioButtonCycle;
330 for (i=0;i<m_noItems;i++) {
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 void wxRadioBox::Show(int item, bool show)
343 {
344 int i;
345 wxRadioButton *current;
346
347 if ((item < 0) || (item >= m_noItems))
348 return;
349 i=0;
350 current=m_radioButtonCycle;
351 while (i!=item) {
352 i++;
353 current=current->NextInCycle();
354 }
355 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 == -1) && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
412 x_offset = x_current;
413 if ((y == -1)&& !(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 SetFont(GetParent()->GetFont());
424 GetTextExtent(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), &charWidth, &charHeight);
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 + charHeight/2) + charHeight ;
439 totWidth = GetColumnCount() * (maxWidth + charWidth) + charWidth;
440
441 // only change our width/height if asked for
442 if ( width == -1 )
443 {
444 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
445 width = totWidth ;
446 else
447 width = widthOld;
448 }
449
450 if ( height == -1 )
451 {
452 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
453 height = totHeight ;
454 else
455 height = heightOld;
456 }
457
458 wxControl::DoSetSize(x_offset,y_offset,width,height,wxSIZE_AUTO);
459
460 // arrange radiobuttons
461
462 int x_start,y_start;
463
464
465 x_start = charWidth;
466 y_start = 15 ;
467 if ( UMAGetSystemVersion() >= 0x1030 )
468 {
469 //need to add a few more pixels for the top border on panther
470 y_start = y_start + 5; //how many exactly should this be to meet the HIG?
471 }
472 x_offset = x_start;
473 y_offset = y_start;
474
475 current=m_radioButtonCycle;
476 for ( i = 0 ; i < m_noItems; i++)
477 {
478 if (i&&((i%m_majorDim)==0)) // not to do for the zero button!
479 {
480 if (m_windowStyle & wxRA_VERTICAL)
481 {
482 x_offset += maxWidth + charWidth;
483 y_offset = y_start;
484 }
485 else
486 {
487 x_offset = x_start;
488 y_offset += maxHeight ; /*+ charHeight/2;*/
489 }
490 }
491
492 current->SetSize(x_offset,y_offset,eachWidth[i],eachHeight[i]);
493 current=current->NextInCycle();
494
495 if (m_windowStyle & wxRA_SPECIFY_ROWS)
496 y_offset += maxHeight ; /*+ charHeight/2;*/
497 else
498 x_offset += maxWidth + charWidth;
499 }
500 }
501
502 wxSize wxRadioBox::DoGetBestSize() const
503 {
504 int charWidth, charHeight;
505 int maxWidth, maxHeight;
506 int eachWidth, eachHeight;
507 int totWidth, totHeight;
508
509 wxFont font = GetParent()->GetFont();
510 GetTextExtent(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
511 &charWidth, &charHeight, NULL, NULL, &font);
512 charWidth /= 52;
513
514 maxWidth = -1;
515 maxHeight = -1;
516
517 for (int i = 0 ; i < m_noItems; i++)
518 {
519 GetTextExtent(GetString(i), &eachWidth, &eachHeight);
520 eachWidth = (int)(eachWidth + RADIO_SIZE) ;
521 eachHeight = (int)((3 * eachHeight) / 2);
522 if (maxWidth < eachWidth) maxWidth = eachWidth;
523 if (maxHeight < eachHeight) maxHeight = eachHeight;
524 }
525
526 totHeight = GetRowCount() * (maxHeight + charHeight/2) + charHeight ;
527 totWidth = GetColumnCount() * (maxWidth + charWidth) + charWidth;
528
529 if ( UMAGetSystemVersion() >= 0x1030 )
530 {
531 //need to add a few more pixels for the static boxborder on panther
532 totHeight = totHeight + 10; //how many exactly should this be to meet the HIG?
533 }
534 // handle radio box title as well
535 GetTextExtent(GetTitle(), &eachWidth, NULL);
536 eachWidth = (int)(eachWidth + RADIO_SIZE) + 3 * charWidth ;
537 if (totWidth < eachWidth)
538 totWidth = eachWidth;
539
540 return wxSize(totWidth, totHeight);
541 }
542 //-------------------------------------------------------------------------------------
543 // ¥ GetNumVer
544 //-------------------------------------------------------------------------------------
545 // return the number of buttons in the vertical direction
546
547 int wxRadioBox::GetRowCount() const
548 {
549 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
550 {
551 return m_majorDim;
552 }
553 else
554 {
555 return (m_noItems + m_majorDim - 1)/m_majorDim;
556 }
557 }
558
559 //-------------------------------------------------------------------------------------
560 // ¥ GetNumHor
561 //-------------------------------------------------------------------------------------
562 // return the number of buttons in the horizontal direction
563
564 int wxRadioBox::GetColumnCount() const
565 {
566 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
567 {
568 return (m_noItems + m_majorDim - 1)/m_majorDim;
569 }
570 else
571 {
572 return m_majorDim;
573 }
574 }