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