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