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