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