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