]> git.saurik.com Git - wxWidgets.git/blame - src/motif/radiobox.cpp
debug check for infinite loop in InitializeClasses() added
[wxWidgets.git] / src / motif / radiobox.cpp
CommitLineData
4bb6408c
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: radiobox.cpp
3// Purpose: wxRadioBox
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
af0bb3b1 9// Licence: wxWindows licence
4bb6408c
JS
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "radiobox.h"
14#endif
15
16#include "wx/radiobox.h"
a4294b78
JS
17#include "wx/utils.h"
18
338dd992
JJ
19#ifdef __VMS__
20#pragma message disable nosimpint
21#endif
a4294b78
JS
22#include <Xm/Label.h>
23#include <Xm/LabelG.h>
24#include <Xm/ToggleB.h>
25#include <Xm/ToggleBG.h>
26#include <Xm/RowColumn.h>
27#include <Xm/Form.h>
9838df2c 28#include <Xm/Frame.h>
338dd992
JJ
29#ifdef __VMS__
30#pragma message enable nosimpint
31#endif
a4294b78 32
3096bd2f 33#include "wx/motif/private.h"
a4294b78
JS
34
35void wxRadioBoxCallback (Widget w, XtPointer clientData,
af0bb3b1 36 XmToggleButtonCallbackStruct * cbs);
4bb6408c
JS
37
38#if !USE_SHARED_LIBRARY
39IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
40#endif
41
42// Radio box item
43wxRadioBox::wxRadioBox()
44{
45 m_selectedButton = -1;
46 m_noItems = 0;
47 m_noRowsOrCols = 0;
48 m_majorDim = 0 ;
a4294b78
JS
49
50 m_formWidget = (WXWidget) 0;
9838df2c 51 m_frameWidget = (WXWidget) 0;
a4294b78
JS
52 m_labelWidget = (WXWidget) 0;
53 m_radioButtons = (WXWidget*) NULL;
54 m_radioButtonLabels = (wxString*) NULL;
4bb6408c
JS
55}
56
57bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& title,
58 const wxPoint& pos, const wxSize& size,
59 int n, const wxString choices[],
60 int majorDim, long style,
61 const wxValidator& val, const wxString& name)
62{
63 m_selectedButton = -1;
64 m_noItems = n;
9838df2c
JS
65 m_formWidget = (WXWidget) 0;
66 m_frameWidget = (WXWidget) 0;
a4294b78
JS
67 m_labelWidget = (WXWidget) 0;
68 m_radioButtons = (WXWidget*) NULL;
69 m_radioButtonLabels = (wxString*) NULL;
0d57be45
JS
70 m_backgroundColour = parent->GetBackgroundColour();
71 m_foregroundColour = parent->GetForegroundColour();
da175b2c 72 m_font = parent->GetFont();
4bb6408c
JS
73
74 SetName(name);
75 SetValidator(val);
76
77 parent->AddChild(this);
78
79 m_windowStyle = (long&)style;
80
81 if (id == -1)
82 m_windowId = NewControlId();
83 else
84 m_windowId = id;
85
86 m_noRowsOrCols = majorDim;
87
88 if (majorDim==0)
89 m_majorDim = n ;
90 else
91 m_majorDim = majorDim ;
92
a4294b78
JS
93 Widget parentWidget = (Widget) parent->GetClientWidget();
94
95 wxString label1(wxStripMenuCodes(title));
96
31528cd3 97 Widget formWidget = XtVaCreateManagedWidget (name.c_str(),
af0bb3b1
VZ
98 xmFormWidgetClass, parentWidget,
99 XmNmarginHeight, 0,
100 XmNmarginWidth, 0,
101 NULL);
a4294b78
JS
102
103 m_formWidget = (WXWidget) formWidget;
104
da175b2c 105 XmFontList fontList = (XmFontList) m_font.GetFontList(1.0, XtDisplay(parentWidget));
a4294b78
JS
106 if (label1 != "")
107 {
31528cd3
VZ
108 wxXmString text(label1);
109 (void)XtVaCreateManagedWidget(label1.c_str(),
a4294b78 110#if wxUSE_GADGETS
31528cd3
VZ
111 style & wxCOLOURED ? xmLabelWidgetClass
112 : xmLabelGadgetClass,
af0bb3b1 113 formWidget,
a4294b78 114#else
af0bb3b1 115 xmLabelWidgetClass, formWidget,
a4294b78 116#endif
ea57084d 117 XmNfontList, fontList,
98300330 118 XmNlabelString, text(),
af0bb3b1 119 NULL);
a4294b78
JS
120 }
121
9838df2c 122 Widget frameWidget = XtVaCreateManagedWidget ("frame",
af0bb3b1 123 xmFrameWidgetClass, formWidget,
9838df2c 124 XmNshadowType, XmSHADOW_IN,
af0bb3b1
VZ
125// XmNmarginHeight, 0,
126// XmNmarginWidth, 0,
127 NULL);
9838df2c
JS
128
129 m_frameWidget = (WXWidget) frameWidget;
130
a4294b78
JS
131 Arg args[3];
132
978db70e 133 m_majorDim = (n + m_majorDim - 1) / m_majorDim;
a4294b78
JS
134
135 XtSetArg (args[0], XmNorientation, ((style & wxHORIZONTAL) == wxHORIZONTAL ?
af0bb3b1 136 XmHORIZONTAL : XmVERTICAL));
98300330 137 XtSetArg (args[1], XmNnumColumns, m_majorDim);
a4294b78 138
9838df2c 139 Widget radioBoxWidget = XmCreateRadioBox (frameWidget, "radioBoxWidget", args, 2);
a4294b78 140 m_mainWidget = (WXWidget) radioBoxWidget;
4bb6408c 141
a4294b78
JS
142
143 if (m_labelWidget)
af0bb3b1
VZ
144 XtVaSetValues ((Widget) m_labelWidget,
145 XmNtopAttachment, XmATTACH_FORM,
146 XmNleftAttachment, XmATTACH_FORM,
147 XmNalignment, XmALIGNMENT_BEGINNING,
148 NULL);
a4294b78
JS
149
150 XtVaSetValues (radioBoxWidget,
af0bb3b1
VZ
151 XmNtopAttachment, m_labelWidget ? XmATTACH_WIDGET : XmATTACH_FORM,
152 XmNtopWidget, m_labelWidget ? (Widget) m_labelWidget : formWidget,
153 XmNbottomAttachment, XmATTACH_FORM,
154 XmNleftAttachment, XmATTACH_FORM,
155 XmNrightAttachment, XmATTACH_FORM,
156 NULL);
a4294b78
JS
157
158 // if (style & wxFLAT)
159 // XtVaSetValues (radioBoxWidget, XmNborderWidth, 1, NULL);
160
161 m_radioButtons = new WXWidget[n];
162 m_radioButtonLabels = new wxString[n];
163 int i;
164 for (i = 0; i < n; i++)
165 {
166 wxString str(wxStripMenuCodes(choices[i]));
167 m_radioButtonLabels[i] = str;
168 m_radioButtons[i] = (WXWidget) XtVaCreateManagedWidget ((char*) (const char*) str,
169#if wxUSE_GADGETS
af0bb3b1 170 xmToggleButtonGadgetClass, radioBoxWidget,
a4294b78 171#else
af0bb3b1 172 xmToggleButtonWidgetClass, radioBoxWidget,
a4294b78 173#endif
ea57084d 174 XmNfontList, fontList,
af0bb3b1 175 NULL);
338dd992
JJ
176#ifdef __VMS__
177#pragma message disable voiincconext
178 // VMS gives here the compiler warning:
179 // conversion from pointer to function to void* permitted
180 // as an extension
181#endif
a4294b78 182 XtAddCallback ((Widget) m_radioButtons[i], XmNvalueChangedCallback, (XtCallbackProc) wxRadioBoxCallback,
af0bb3b1 183 (XtCallbackProc) this);
338dd992
JJ
184#ifdef __VMS__
185#pragma message enable voiincconext
186#endif
a4294b78 187
a4294b78
JS
188 }
189 SetSelection (0);
190
da175b2c 191 m_font = parent->GetFont();
4b5f3fe6
JS
192 ChangeFont(FALSE);
193
9838df2c 194 // XtManageChild((Widget) m_formWidget);
a4294b78
JS
195 XtManageChild (radioBoxWidget);
196
197 SetCanAddEventHandler(TRUE);
198 AttachWidget (parent, m_mainWidget, m_formWidget, pos.x, pos.y, size.x, size.y);
199
0d57be45 200 ChangeBackgroundColour();
a4294b78
JS
201
202 return TRUE;
4bb6408c
JS
203}
204
205
206wxRadioBox::~wxRadioBox()
207{
a4294b78
JS
208 delete[] m_radioButtonLabels;
209 delete[] m_radioButtons;
15d5ab67 210
b412f9be 211 DetachWidget(m_formWidget);
15d5ab67
JS
212 DetachWidget(m_mainWidget);
213
214 if (m_labelWidget)
215 XtDestroyWidget((Widget) m_labelWidget);
216 XtDestroyWidget((Widget) m_mainWidget);
217 XtDestroyWidget((Widget) m_formWidget);
218
219 m_mainWidget = (WXWidget) 0;
220 m_formWidget = (WXWidget) 0;
221 m_labelWidget = (WXWidget) 0;
4bb6408c
JS
222}
223
224wxString wxRadioBox::GetLabel(int item) const
225{
a4294b78
JS
226 if (item < 0 || item >= m_noItems)
227 return wxEmptyString;
228
229 Widget widget = (Widget) m_radioButtons[item];
230 XmString text;
231 char *s;
232 XtVaGetValues (widget,
af0bb3b1
VZ
233 XmNlabelString, &text,
234 NULL);
a4294b78
JS
235
236 if (XmStringGetLtoR (text, XmSTRING_DEFAULT_CHARSET, &s))
237 {
238 // Should we free 'text'???
239 XmStringFree(text);
240 wxString str(s);
241 XtFree (s);
242 return str;
243 }
244 else
245 {
246 XmStringFree(text);
247 return wxEmptyString;
248 }
4bb6408c
JS
249}
250
251void wxRadioBox::SetLabel(int item, const wxString& label)
252{
a4294b78
JS
253 if (item < 0 || item >= m_noItems)
254 return;
255
256 Widget widget = (Widget) m_radioButtons[item];
257 if (label != "")
258 {
259 wxString label1(wxStripMenuCodes(label));
260 XmString text = XmStringCreateSimple ((char*) (const char*) label1);
261 XtVaSetValues (widget,
af0bb3b1
VZ
262 XmNlabelString, text,
263 XmNlabelType, XmSTRING,
264 NULL);
a4294b78
JS
265 XmStringFree (text);
266 }
4bb6408c
JS
267}
268
269int wxRadioBox::FindString(const wxString& s) const
270{
a4294b78
JS
271 int i;
272 for (i = 0; i < m_noItems; i++)
273 if (s == m_radioButtonLabels[i])
274 return i;
4bb6408c
JS
275 return -1;
276}
277
278void wxRadioBox::SetSelection(int n)
279{
280 if ((n < 0) || (n >= m_noItems))
281 return;
4bb6408c
JS
282
283 m_selectedButton = n;
a4294b78
JS
284
285 m_inSetValue = TRUE;
286
287 XmToggleButtonSetState ((Widget) m_radioButtons[n], TRUE, FALSE);
288
289 int i;
290 for (i = 0; i < m_noItems; i++)
291 if (i != n)
292 XmToggleButtonSetState ((Widget) m_radioButtons[i], FALSE, FALSE);
293
294 m_inSetValue = FALSE;
4bb6408c
JS
295}
296
297// Get single selection, for single choice list items
298int wxRadioBox::GetSelection() const
299{
300 return m_selectedButton;
301}
302
303// Find string for position
304wxString wxRadioBox::GetString(int n) const
305{
a4294b78
JS
306 if ((n < 0) || (n >= m_noItems))
307 return wxEmptyString;
308 return m_radioButtonLabels[n];
4bb6408c
JS
309}
310
bfc6fde4 311void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
4bb6408c 312{
a4294b78 313 bool managed = XtIsManaged((Widget) m_formWidget);
4bb6408c 314
a4294b78
JS
315 if (managed)
316 XtUnmanageChild ((Widget) m_formWidget);
4bb6408c 317
a4294b78
JS
318 int xx = x; int yy = y;
319 AdjustForParentClientOrigin(xx, yy, sizeFlags);
4bb6408c 320
a4294b78
JS
321 if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
322 XtVaSetValues ((Widget) m_formWidget, XmNleftAttachment, XmATTACH_SELF,
af0bb3b1 323 XmNx, xx, NULL);
a4294b78
JS
324 if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
325 XtVaSetValues ((Widget) m_formWidget, XmNtopAttachment, XmATTACH_SELF,
af0bb3b1 326 XmNy, yy, NULL);
4bb6408c 327
a4294b78
JS
328 // Must set the actual RadioBox to be desired size MINUS label size
329 Dimension labelWidth = 0, labelHeight = 0, actualWidth = 0, actualHeight = 0;
4bb6408c 330
a4294b78
JS
331 if (m_labelWidget)
332 XtVaGetValues ((Widget) m_labelWidget, XmNwidth, &labelWidth, XmNheight, &labelHeight, NULL);
4bb6408c 333
a4294b78
JS
334 actualWidth = width;
335 actualHeight = height - labelHeight;
336
337 if (width > -1)
338 {
339 XtVaSetValues ((Widget) m_mainWidget, XmNwidth, actualWidth, NULL);
340 }
341 if (height > -1)
342 {
343 XtVaSetValues ((Widget) m_mainWidget, XmNheight, actualHeight, NULL);
344 }
345 if (managed)
346 XtManageChild ((Widget) m_formWidget);
4bb6408c
JS
347}
348
349// Enable a specific button
a4294b78 350void wxRadioBox::Enable(int n, bool enable)
4bb6408c 351{
a4294b78
JS
352 if ((n < 0) || (n >= m_noItems))
353 return;
354
355 XtSetSensitive ((Widget) m_radioButtons[n], (Boolean) enable);
4bb6408c
JS
356}
357
358// Enable all controls
af0bb3b1 359bool wxRadioBox::Enable(bool enable)
4bb6408c 360{
af0bb3b1
VZ
361 if ( !wxControl::Enable(enable) )
362 return FALSE;
4bb6408c 363
a4294b78
JS
364 int i;
365 for (i = 0; i < m_noItems; i++)
366 XtSetSensitive ((Widget) m_radioButtons[i], (Boolean) enable);
af0bb3b1
VZ
367
368 return TRUE;
4bb6408c
JS
369}
370
9838df2c
JS
371bool wxRadioBox::Show(bool show)
372{
373 // TODO: show/hide all children
374 return wxControl::Show(show);
375}
376
4bb6408c 377// Show a specific button
a4294b78 378void wxRadioBox::Show(int n, bool show)
4bb6408c 379{
a4294b78
JS
380 // This method isn't complete, and we try do do our best...
381 // It's main purpose isn't for allowing Show/Unshow dynamically,
382 // but rather to provide a way to design wxRadioBox such:
383 //
384 // o Val1 o Val2 o Val3
385 // o Val4 o Val6
386 // o Val7 o Val8 o Val9
387 //
388 // In my case, this is a 'direction' box, and the Show(5,False) is
389 // coupled with an Enable(5,False)
390 //
391 if ((n < 0) || (n >= m_noItems))
392 return;
393
394 XtVaSetValues ((Widget) m_radioButtons[n],
395 XmNindicatorOn, (unsigned char) show,
396 NULL);
397
398 // Please note that this is all we can do: removing the label
399 // if switching to unshow state. However, when switching
400 // to the on state, it's the prog. resp. to call SetLabel(item,...)
401 // after this call!!
402 if (!show)
403 wxRadioBox::SetLabel (n, " ");
4bb6408c
JS
404}
405
406// For single selection items only
407wxString wxRadioBox::GetStringSelection () const
408{
409 int sel = GetSelection ();
410 if (sel > -1)
411 return this->GetString (sel);
412 else
413 return wxString("");
414}
415
416bool wxRadioBox::SetStringSelection (const wxString& s)
417{
418 int sel = FindString (s);
419 if (sel > -1)
420 {
421 SetSelection (sel);
422 return TRUE;
423 }
424 else
425 return FALSE;
426}
427
428void wxRadioBox::Command (wxCommandEvent & event)
429{
430 SetSelection (event.m_commandInt);
431 ProcessCommand (event);
432}
433
4b5f3fe6 434void wxRadioBox::ChangeFont(bool keepOriginalSize)
0d57be45 435{
94b49b93
JS
436 wxWindow::ChangeFont(keepOriginalSize);
437
da175b2c 438 XmFontList fontList = (XmFontList) m_font.GetFontList(1.0, XtDisplay((Widget) GetTopWidget()));
94b49b93
JS
439
440 int i;
441 for (i = 0; i < m_noItems; i++)
442 {
443 WXWidget radioButton = m_radioButtons[i];
444
445 XtVaSetValues ((Widget) radioButton,
446 XmNfontList, fontList,
af0bb3b1 447 XmNtopAttachment, XmATTACH_FORM,
94b49b93
JS
448 NULL);
449 }
0d57be45
JS
450}
451
452void wxRadioBox::ChangeBackgroundColour()
453{
94b49b93
JS
454 wxWindow::ChangeBackgroundColour();
455
9838df2c
JS
456 DoChangeBackgroundColour((Widget) m_frameWidget, m_backgroundColour);
457
458 int selectPixel = wxBLACK->AllocColour(wxGetDisplay());
459
94b49b93
JS
460 int i;
461 for (i = 0; i < m_noItems; i++)
462 {
463 WXWidget radioButton = m_radioButtons[i];
464
465 DoChangeBackgroundColour(radioButton, m_backgroundColour, TRUE);
9838df2c
JS
466
467 XtVaSetValues ((Widget) radioButton,
468 XmNselectColor, selectPixel,
469 NULL);
94b49b93 470 }
0d57be45
JS
471}
472
473void wxRadioBox::ChangeForegroundColour()
474{
94b49b93
JS
475 wxWindow::ChangeForegroundColour();
476
477 int i;
478 for (i = 0; i < m_noItems; i++)
479 {
480 WXWidget radioButton = m_radioButtons[i];
481
482 DoChangeForegroundColour(radioButton, m_foregroundColour);
483 }
0d57be45
JS
484}
485
a4294b78 486void wxRadioBoxCallback (Widget w, XtPointer clientData,
af0bb3b1 487 XmToggleButtonCallbackStruct * cbs)
a4294b78
JS
488{
489 if (!cbs->set)
490 return;
491
492 wxRadioBox *item = (wxRadioBox *) clientData;
493 int sel = -1;
494 int i;
495 for (i = 0; i < item->Number(); i++)
496 if (item->GetRadioButtons() && ((Widget) (item->GetRadioButtons()[i]) == w))
497 sel = i;
498 item->SetSel(sel);
499
500 if (item->InSetValue())
501 return;
502
503 wxCommandEvent event (wxEVT_COMMAND_RADIOBOX_SELECTED, item->GetId());
504 event.m_commandInt = sel;
505 event.SetEventObject(item);
506 item->ProcessCommand (event);
507}
4bb6408c 508