]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/radiobox.cpp
fix for preserving the clip rgn (control redraws missing after switch to faster redra...
[wxWidgets.git] / src / mac / carbon / 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
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 m_isBeingDeleted = TRUE;
81
82 wxRadioButton *next,*current;
83
84 current=m_radioButtonCycle->NextInCycle();
85 next=current->NextInCycle();
86 while (current!=m_radioButtonCycle) {
87 delete current;
88 current=next;
89 next=current->NextInCycle();
90 }
91 delete current;
92 }
93
94 //-------------------------------------------------------------------------------------
95 // ¥ Create
96 //-------------------------------------------------------------------------------------
97 // Create the radiobox for two-step construction
98
99 bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& label,
100 const wxPoint& pos, const wxSize& size,
101 int n, const wxString choices[],
102 int majorDim, long style,
103 const wxValidator& val, const wxString& name)
104 {
105 if ( !wxControl::Create(parent, id, pos, size, style, val, name) )
106 return false;
107
108 int i;
109
110 m_noItems = n;
111 m_noRowsOrCols = majorDim;
112 m_radioButtonCycle = NULL;
113
114 if (majorDim==0)
115 m_majorDim = n ;
116 else
117 m_majorDim = majorDim ;
118
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 = ::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 #pragma mark -
152 #pragma mark ### Specific functions (reference v2) ###
153
154 //-------------------------------------------------------------------------------------
155 // ¥ Enable(bool)
156 //-------------------------------------------------------------------------------------
157 // Enables or disables the entire radiobox
158
159 bool wxRadioBox::Enable(bool enable)
160 {
161 int i;
162 wxRadioButton *current;
163
164 if (!wxControl::Enable(enable))
165 return false;
166
167 current = m_radioButtonCycle;
168 for (i = 0; i < m_noItems; i++) {
169 current->Enable(enable);
170 current = current->NextInCycle();
171 }
172 return true;
173 }
174
175 //-------------------------------------------------------------------------------------
176 // ¥ Enable(int, bool)
177 //-------------------------------------------------------------------------------------
178 // Enables or disables an given button
179
180 void wxRadioBox::Enable(int item, bool enable)
181 {
182 int i;
183 wxRadioButton *current;
184
185 if ((item < 0) || (item >= m_noItems))
186 return;
187
188 i = 0;
189 current = m_radioButtonCycle;
190 while (i != item) {
191 i++;
192 current = current->NextInCycle();
193 }
194 current->Enable(enable);
195 }
196
197 //-------------------------------------------------------------------------------------
198 // ¥ GetLabel()
199 //-------------------------------------------------------------------------------------
200 // Returns the radiobox label
201
202 wxString wxRadioBox::GetLabel() const
203 {
204 return wxControl::GetLabel();
205 }
206
207 //-------------------------------------------------------------------------------------
208 // ¥ GetLabel(int)
209 //-------------------------------------------------------------------------------------
210 // Returns the label for the given button
211
212 wxString wxRadioBox::GetString(int item) const
213 {
214 int i;
215 wxRadioButton *current;
216
217 if ((item < 0) || (item >= m_noItems))
218 return wxEmptyString;
219
220 i = 0;
221 current = m_radioButtonCycle;
222 while (i != item) {
223 i++;
224 current = current->NextInCycle();
225 }
226 return current->GetLabel();
227 }
228
229 //-------------------------------------------------------------------------------------
230 // ¥ GetSelection
231 //-------------------------------------------------------------------------------------
232 // Returns the zero-based position of the selected button
233
234 int wxRadioBox::GetSelection() const
235 {
236 int i;
237 wxRadioButton *current;
238
239 i=0;
240 current=m_radioButtonCycle;
241 while (!current->GetValue()) {
242 i++;
243 current=current->NextInCycle();
244 }
245
246 return i;
247 }
248
249 //-------------------------------------------------------------------------------------
250 // ¥ Number
251 //-------------------------------------------------------------------------------------
252 // Returns the number of buttons in the radiobox
253 //
254 // inline defined
255 //
256
257 //-------------------------------------------------------------------------------------
258 // ¥ SetLabel(const wxString&)
259 //-------------------------------------------------------------------------------------
260 // Sets the radiobox label
261
262 void wxRadioBox::SetLabel(const wxString& label)
263 {
264 return wxControl::SetLabel(label);
265 }
266
267 //-------------------------------------------------------------------------------------
268 // ¥ SetLabel(int, const wxString&)
269 //-------------------------------------------------------------------------------------
270 // Sets the label of a given button
271
272 void wxRadioBox::SetString(int item,const wxString& label)
273 {
274 int i;
275 wxRadioButton *current;
276
277 if ((item < 0) || (item >= m_noItems))
278 return;
279 i=0;
280 current=m_radioButtonCycle;
281 while (i!=item) {
282 i++;
283 current=current->NextInCycle();
284 }
285 return current->SetLabel(label);
286 }
287
288 //-------------------------------------------------------------------------------------
289 // ¥ SetSelection
290 //-------------------------------------------------------------------------------------
291 // Sets a button by passing the desired position. This does not cause
292 // wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
293
294 void wxRadioBox::SetSelection(int item)
295 {
296 int i;
297 wxRadioButton *current;
298
299 if ((item < 0) || (item >= m_noItems))
300 return;
301 i=0;
302 current=m_radioButtonCycle;
303 while (i!=item) {
304 i++;
305 current=current->NextInCycle();
306 }
307 current->SetValue(true);
308
309 }
310
311 //-------------------------------------------------------------------------------------
312 // ¥ Show(bool)
313 //-------------------------------------------------------------------------------------
314 // Shows or hides the entire radiobox
315
316 bool wxRadioBox::Show(bool show)
317 {
318 int i;
319 wxRadioButton *current;
320
321 wxControl::Show(show);
322
323 current=m_radioButtonCycle;
324 for (i=0;i<m_noItems;i++) {
325 current->Show(show);
326 current=current->NextInCycle();
327 }
328 return true;
329 }
330
331 //-------------------------------------------------------------------------------------
332 // ¥ Show(int, bool)
333 //-------------------------------------------------------------------------------------
334 // Shows or hides the given button
335
336 void wxRadioBox::Show(int item, bool show)
337 {
338 int i;
339 wxRadioButton *current;
340
341 if ((item < 0) || (item >= m_noItems))
342 return;
343 i=0;
344 current=m_radioButtonCycle;
345 while (i!=item) {
346 i++;
347 current=current->NextInCycle();
348 }
349 current->Show(show);
350 }
351
352 #pragma mark -
353 #pragma mark ### Other external functions ###
354
355 //-------------------------------------------------------------------------------------
356 // ¥ Command
357 //-------------------------------------------------------------------------------------
358 // Simulates the effect of the user issuing a command to the item
359
360 void wxRadioBox::Command (wxCommandEvent & event)
361 {
362 SetSelection (event.GetInt());
363 ProcessCommand (event);
364 }
365
366 //-------------------------------------------------------------------------------------
367 // ¥ SetFocus
368 //-------------------------------------------------------------------------------------
369 // Sets the selected button to receive keyboard input
370
371 void wxRadioBox::SetFocus()
372 {
373 int i;
374 wxRadioButton *current;
375
376 i=0;
377 current=m_radioButtonCycle;
378 while (!current->GetValue()) {
379 i++;
380 current=current->NextInCycle();
381 }
382 current->SetFocus();
383 }
384
385
386 #pragma mark -
387 #pragma mark ### Internal functions ###
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 x_offset = x_start;
468 y_offset = y_start;
469
470 current=m_radioButtonCycle;
471 for ( i = 0 ; i < m_noItems; i++)
472 {
473 if (i&&((i%m_majorDim)==0)) // not to do for the zero button!
474 {
475 if (m_windowStyle & wxRA_VERTICAL)
476 {
477 x_offset += maxWidth + charWidth;
478 y_offset = y_start;
479 }
480 else
481 {
482 x_offset = x_start;
483 y_offset += maxHeight ; /*+ charHeight/2;*/
484 }
485 }
486
487 current->SetSize(x_offset,y_offset,eachWidth[i],eachHeight[i]);
488 current=current->NextInCycle();
489
490 if (m_windowStyle & wxRA_SPECIFY_ROWS)
491 y_offset += maxHeight ; /*+ charHeight/2;*/
492 else
493 x_offset += maxWidth + charWidth;
494 }
495 }
496
497 wxSize wxRadioBox::DoGetBestSize() const
498 {
499 int charWidth, charHeight;
500 int maxWidth, maxHeight;
501 int eachWidth, eachHeight;
502 int totWidth, totHeight;
503
504 wxFont font = GetParent()->GetFont();
505 GetTextExtent(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
506 &charWidth, &charHeight, NULL, NULL, &font);
507 charWidth /= 52;
508
509 maxWidth = -1;
510 maxHeight = -1;
511
512 for (int i = 0 ; i < m_noItems; i++)
513 {
514 GetTextExtent(GetString(i), &eachWidth, &eachHeight);
515 eachWidth = (int)(eachWidth + RADIO_SIZE) ;
516 eachHeight = (int)((3 * eachHeight) / 2);
517 if (maxWidth < eachWidth) maxWidth = eachWidth;
518 if (maxHeight < eachHeight) maxHeight = eachHeight;
519 }
520
521 totHeight = GetRowCount() * (maxHeight + charHeight/2) + charHeight ;
522 totWidth = GetColumnCount() * (maxWidth + charWidth) + charWidth;
523
524 // handle radio box title as well
525 GetTextExtent(GetTitle(), &eachWidth, NULL);
526 eachWidth = (int)(eachWidth + RADIO_SIZE) + 3 * charWidth ;
527 if (totWidth < eachWidth)
528 totWidth = eachWidth;
529
530 return wxSize(totWidth, totHeight);
531 }
532 //-------------------------------------------------------------------------------------
533 // ¥ GetNumVer
534 //-------------------------------------------------------------------------------------
535 // return the number of buttons in the vertical direction
536
537 int wxRadioBox::GetRowCount() const
538 {
539 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
540 {
541 return m_majorDim;
542 }
543 else
544 {
545 return (m_noItems + m_majorDim - 1)/m_majorDim;
546 }
547 }
548
549 //-------------------------------------------------------------------------------------
550 // ¥ GetNumHor
551 //-------------------------------------------------------------------------------------
552 // return the number of buttons in the horizontal direction
553
554 int wxRadioBox::GetColumnCount() const
555 {
556 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
557 {
558 return (m_noItems + m_majorDim - 1)/m_majorDim;
559 }
560 else
561 {
562 return m_majorDim;
563 }
564 }
565
566
567
568
569