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