]> git.saurik.com Git - wxWidgets.git/blob - src/mac/radiobox.cpp
don't allow clicking disabled buttons
[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 = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1,
121 kControlGroupBoxTextTitleProc , (long) this ) ;
122
123 for (i = 0; i < n; i++)
124 {
125 wxRadioButton *radBtn = new wxRadioButton(this, NewControlId(),choices[i],wxPoint(5,20*i+10),
126 wxDefaultSize , i == 0 ? wxRB_GROUP : 0 ) ;
127 if ( i == 0 )
128 m_radioButtonCycle = radBtn ;
129 // m_radioButtonCycle=radBtn->AddInCycle(m_radioButtonCycle);
130 }
131
132 SetSelection(0);
133 MacPostControlCreate() ;
134
135 return TRUE;
136 }
137
138
139 #pragma mark -
140 #pragma mark ### Specific functions (reference v2) ###
141
142 //-------------------------------------------------------------------------------------
143 // ¥ Enable(bool)
144 //-------------------------------------------------------------------------------------
145 // Enables or disables the entire radiobox
146
147 bool wxRadioBox::Enable(bool enable)
148 {
149 int i;
150 wxRadioButton *current;
151
152 if (!wxControl::Enable(enable))
153 return (false);
154
155 current=m_radioButtonCycle;
156 for (i=0;i<m_noItems;i++) {
157 current->Enable(enable);
158 current=current->NextInCycle();
159 }
160 return (true);
161 }
162
163 //-------------------------------------------------------------------------------------
164 // ¥ Enable(int, bool)
165 //-------------------------------------------------------------------------------------
166 // Enables or disables an given button
167
168 void wxRadioBox::Enable(int item, bool enable)
169 {
170 int i;
171 wxRadioButton *current;
172
173 if ((item < 0) || (item >= m_noItems))
174 return;
175 i=0;
176 current=m_radioButtonCycle;
177 while (i!=item) {
178 i++;
179 current=current->NextInCycle();
180 }
181 }
182
183 //-------------------------------------------------------------------------------------
184 // ¥ GetLabel()
185 //-------------------------------------------------------------------------------------
186 // Returns the radiobox label
187
188 wxString wxRadioBox::GetLabel() const
189 {
190 return wxControl::GetLabel();
191 }
192
193 //-------------------------------------------------------------------------------------
194 // ¥ GetLabel(int)
195 //-------------------------------------------------------------------------------------
196 // Returns the label for the given button
197
198 wxString wxRadioBox::GetString(int item) const
199 {
200 int i;
201 wxRadioButton *current;
202
203 if ((item < 0) || (item >= m_noItems))
204 return wxString("");
205 i=0;
206 current=m_radioButtonCycle;
207 while (i!=item) {
208 i++;
209 current=current->NextInCycle();
210 }
211 return current->GetLabel();
212 }
213
214 //-------------------------------------------------------------------------------------
215 // ¥ GetSelection
216 //-------------------------------------------------------------------------------------
217 // Returns the zero-based position of the selected button
218
219 int wxRadioBox::GetSelection() const
220 {
221 int i;
222 wxRadioButton *current;
223
224 i=0;
225 current=m_radioButtonCycle;
226 while (!current->GetValue()) {
227 i++;
228 current=current->NextInCycle();
229 }
230
231 return i;
232 }
233
234 //-------------------------------------------------------------------------------------
235 // ¥ Number
236 //-------------------------------------------------------------------------------------
237 // Returns the number of buttons in the radiobox
238 //
239 // inline defined
240 //
241
242 //-------------------------------------------------------------------------------------
243 // ¥ SetLabel(const wxString&)
244 //-------------------------------------------------------------------------------------
245 // Sets the radiobox label
246
247 void wxRadioBox::SetLabel(const wxString& label)
248 {
249 return wxControl::SetLabel(label);
250 }
251
252 //-------------------------------------------------------------------------------------
253 // ¥ SetLabel(int, const wxString&)
254 //-------------------------------------------------------------------------------------
255 // Sets the label of a given button
256
257 void wxRadioBox::SetString(int item,const wxString& label)
258 {
259 int i;
260 wxRadioButton *current;
261
262 if ((item < 0) || (item >= m_noItems))
263 return;
264 i=0;
265 current=m_radioButtonCycle;
266 while (i!=item) {
267 i++;
268 current=current->NextInCycle();
269 }
270 return current->SetLabel(label);
271 }
272
273 //-------------------------------------------------------------------------------------
274 // ¥ SetSelection
275 //-------------------------------------------------------------------------------------
276 // Sets a button by passing the desired position. This does not cause
277 // wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
278
279 void wxRadioBox::SetSelection(int item)
280 {
281 int i;
282 wxRadioButton *current;
283
284 if ((item < 0) || (item >= m_noItems))
285 return;
286 i=0;
287 current=m_radioButtonCycle;
288 while (i!=item) {
289 i++;
290 current=current->NextInCycle();
291 }
292 current->SetValue(true);
293
294 }
295
296 //-------------------------------------------------------------------------------------
297 // ¥ Show(bool)
298 //-------------------------------------------------------------------------------------
299 // Shows or hides the entire radiobox
300
301 bool wxRadioBox::Show(bool show)
302 {
303 int i;
304 wxRadioButton *current;
305
306 wxControl::Show(show);
307
308 current=m_radioButtonCycle;
309 for (i=0;i<m_noItems;i++) {
310 current->Show(show);
311 current=current->NextInCycle();
312 }
313 return true;
314 }
315
316 //-------------------------------------------------------------------------------------
317 // ¥ Show(int, bool)
318 //-------------------------------------------------------------------------------------
319 // Shows or hides the given button
320
321 void wxRadioBox::Show(int item, bool show)
322 {
323 int i;
324 wxRadioButton *current;
325
326 if ((item < 0) || (item >= m_noItems))
327 return;
328 i=0;
329 current=m_radioButtonCycle;
330 while (i!=item) {
331 i++;
332 current=current->NextInCycle();
333 }
334 current->Show(show);
335 }
336
337 #pragma mark -
338 #pragma mark ### Other external functions ###
339
340 //-------------------------------------------------------------------------------------
341 // ¥ Command
342 //-------------------------------------------------------------------------------------
343 // Simulates the effect of the user issuing a command to the item
344
345 void wxRadioBox::Command (wxCommandEvent & event)
346 {
347 SetSelection (event.GetInt());
348 ProcessCommand (event);
349 }
350
351 //-------------------------------------------------------------------------------------
352 // ¥ SetFocus
353 //-------------------------------------------------------------------------------------
354 // Sets the selected button to receive keyboard input
355
356 void wxRadioBox::SetFocus()
357 {
358 int i;
359 wxRadioButton *current;
360
361 i=0;
362 current=m_radioButtonCycle;
363 while (!current->GetValue()) {
364 i++;
365 current=current->NextInCycle();
366 }
367 current->SetFocus();
368 }
369
370
371 #pragma mark -
372 #pragma mark ### Internal functions ###
373
374 //-------------------------------------------------------------------------------------
375 // ¥ DoSetSize
376 //-------------------------------------------------------------------------------------
377 // Simulates the effect of the user issuing a command to the item
378
379 #define RADIO_SIZE 40
380
381 void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
382 {
383 int i;
384 wxRadioButton *current;
385
386 // define the position
387
388 int x_current, y_current;
389 int x_offset,y_offset;
390 int widthOld, heightOld;
391 GetSize(&widthOld, &heightOld);
392
393 x_offset = x;
394 y_offset = y;
395 GetPosition(&x_current, &y_current);
396 if ((x == -1) && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
397 x_offset = x_current;
398 if ((y == -1)&& !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
399 y_offset = y_current;
400
401 // define size
402
403 int charWidth,charHeight;
404 int maxWidth,maxHeight;
405 int eachWidth[128],eachHeight[128];
406 int totWidth,totHeight;
407
408 SetFont(GetParent()->GetFont());
409 GetTextExtent(wxString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), &charWidth, &charHeight);
410 charWidth/=52;
411
412 maxWidth=-1;
413 maxHeight=-1;
414 for (i = 0 ; i < m_noItems; i++)
415 {
416 GetTextExtent(GetString(i), &eachWidth[i], &eachHeight[i]);
417 eachWidth[i] = (int)(eachWidth[i] + RADIO_SIZE);
418 eachHeight[i] = (int)((3*eachHeight[i])/2);
419 if (maxWidth<eachWidth[i]) maxWidth = eachWidth[i];
420 if (maxHeight<eachHeight[i]) maxHeight = eachHeight[i];
421 }
422
423 totHeight = GetRowCount() * (maxHeight + charHeight/2) + charHeight*3/2;
424 totWidth = GetColumnCount() * (maxWidth + charWidth) + charWidth;
425
426 // only change our width/height if asked for
427 if ( width == -1 )
428 {
429 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
430 width = totWidth ;
431 else
432 width = widthOld;
433 }
434
435 if ( height == -1 )
436 {
437 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
438 height = totHeight ;
439 else
440 height = heightOld;
441 }
442
443 wxControl::DoSetSize(x_offset,y_offset,width,height,wxSIZE_AUTO);
444
445 // arrange radiobuttons
446
447 int x_start,y_start;
448
449
450 x_start = charWidth;
451 y_start = 15 ;
452 x_offset = x_start;
453 y_offset = y_start;
454
455 current=m_radioButtonCycle;
456 for ( i = 0 ; i < m_noItems; i++)
457 {
458 if (i&&((i%m_majorDim)==0)) // not to do for the zero button!
459 {
460 if (m_windowStyle & wxRA_VERTICAL)
461 {
462 x_offset += maxWidth + charWidth;
463 y_offset = y_start;
464 }
465 else
466 {
467 x_offset = x_start;
468 y_offset += maxHeight ; /*+ charHeight/2;*/
469 }
470 }
471
472 current->SetSize(x_offset,y_offset,eachWidth[i],eachHeight[i]);
473 current=current->NextInCycle();
474
475 if (m_windowStyle & wxRA_SPECIFY_ROWS)
476 y_offset += maxHeight ; /*+ charHeight/2;*/
477 else
478 x_offset += maxWidth + charWidth;
479 }
480 }
481
482 wxSize wxRadioBox::DoGetBestSize() const
483 {
484 int charWidth, charHeight;
485 int maxWidth, maxHeight;
486 int eachWidth, eachHeight;
487 int totWidth, totHeight;
488
489 wxFont font = GetParent()->GetFont();
490 GetTextExtent(wxString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
491 &charWidth, &charHeight, NULL, NULL, &font);
492 charWidth /= 52;
493
494 maxWidth = -1;
495 maxHeight = -1;
496
497 // handle radio box title as well
498 GetTextExtent(GetTitle(), &eachWidth, NULL);
499 eachWidth = (int)(eachWidth + RADIO_SIZE);
500 if (maxWidth < eachWidth) maxWidth = eachWidth;
501
502 for (int i = 0 ; i < m_noItems; i++)
503 {
504 GetTextExtent(GetString(i), &eachWidth, &eachHeight);
505 eachWidth = (int)(eachWidth + RADIO_SIZE) ;
506 eachHeight = (int)((3 * eachHeight) / 2);
507 if (maxWidth < eachWidth) maxWidth = eachWidth;
508 if (maxHeight < eachHeight) maxHeight = eachHeight;
509 }
510
511 totHeight = GetRowCount() * (maxHeight + charHeight/2) + charHeight * 3/2;
512 totWidth = GetColumnCount() * (maxWidth + charWidth) + charWidth;
513 return wxSize(totWidth, totHeight);
514 }
515 //-------------------------------------------------------------------------------------
516 // ¥ GetNumVer
517 //-------------------------------------------------------------------------------------
518 // return the number of buttons in the vertical direction
519
520 int wxRadioBox::GetRowCount() const
521 {
522 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
523 {
524 return m_majorDim;
525 }
526 else
527 {
528 return (m_noItems + m_majorDim - 1)/m_majorDim;
529 }
530 }
531
532 //-------------------------------------------------------------------------------------
533 // ¥ GetNumHor
534 //-------------------------------------------------------------------------------------
535 // return the number of buttons in the horizontal direction
536
537 int wxRadioBox::GetColumnCount() const
538 {
539 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
540 {
541 return (m_noItems + m_majorDim - 1)/m_majorDim;
542 }
543 else
544 {
545 return m_majorDim;
546 }
547 }
548
549
550
551
552