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