]> git.saurik.com Git - wxWidgets.git/blob - src/motif/radiobox.cpp
listbox kbd handling buglet corrected (event.Skip() called even when no
[wxWidgets.git] / src / motif / radiobox.cpp
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"
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
28 void wxRadioBoxCallback (Widget w, XtPointer clientData,
29 XmToggleButtonCallbackStruct * cbs);
30
31 #if !USE_SHARED_LIBRARY
32 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
33 #endif
34
35 // Radio box item
36 wxRadioBox::wxRadioBox()
37 {
38 m_selectedButton = -1;
39 m_noItems = 0;
40 m_noRowsOrCols = 0;
41 m_majorDim = 0 ;
42
43 m_formWidget = (WXWidget) 0;
44 m_labelWidget = (WXWidget) 0;
45 m_radioButtons = (WXWidget*) NULL;
46 m_radioButtonLabels = (wxString*) NULL;
47 }
48
49 bool 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;
57 m_labelWidget = (WXWidget) 0;
58 m_radioButtons = (WXWidget*) NULL;
59 m_radioButtonLabels = (wxString*) NULL;
60 m_backgroundColour = parent->GetBackgroundColour();
61 m_foregroundColour = parent->GetForegroundColour();
62 m_windowFont = parent->GetFont();
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
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
97 XmFontList fontList = (XmFontList) m_windowFont.GetFontList(1.0, XtDisplay(parentWidget));
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
109 XmNfontList, fontList,
110 XmNlabelString, text,
111 NULL);
112
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;
126
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
158 XmNfontList, fontList,
159 NULL);
160 XtAddCallback ((Widget) m_radioButtons[i], XmNvalueChangedCallback, (XtCallbackProc) wxRadioBoxCallback,
161 (XtCallbackProc) this);
162
163 }
164 SetSelection (0);
165
166 m_windowFont = parent->GetFont();
167 ChangeFont(FALSE);
168
169 XtManageChild (radioBoxWidget);
170
171 SetCanAddEventHandler(TRUE);
172 AttachWidget (parent, m_mainWidget, m_formWidget, pos.x, pos.y, size.x, size.y);
173
174 ChangeBackgroundColour();
175
176 return TRUE;
177 }
178
179
180 wxRadioBox::~wxRadioBox()
181 {
182 delete[] m_radioButtonLabels;
183 delete[] m_radioButtons;
184 }
185
186 wxString wxRadioBox::GetLabel(int item) const
187 {
188 if (item < 0 || item >= m_noItems)
189 return wxEmptyString;
190
191 Widget widget = (Widget) m_radioButtons[item];
192 XmString text;
193 char *s;
194 XtVaGetValues (widget,
195 XmNlabelString, &text,
196 NULL);
197
198 if (XmStringGetLtoR (text, XmSTRING_DEFAULT_CHARSET, &s))
199 {
200 // Should we free 'text'???
201 XmStringFree(text);
202 wxString str(s);
203 XtFree (s);
204 return str;
205 }
206 else
207 {
208 XmStringFree(text);
209 return wxEmptyString;
210 }
211 }
212
213 void wxRadioBox::SetLabel(int item, const wxString& label)
214 {
215 if (item < 0 || item >= m_noItems)
216 return;
217
218 Widget widget = (Widget) m_radioButtons[item];
219 if (label != "")
220 {
221 wxString label1(wxStripMenuCodes(label));
222 XmString text = XmStringCreateSimple ((char*) (const char*) label1);
223 XtVaSetValues (widget,
224 XmNlabelString, text,
225 XmNlabelType, XmSTRING,
226 NULL);
227 XmStringFree (text);
228 }
229 }
230
231 int wxRadioBox::FindString(const wxString& s) const
232 {
233 int i;
234 for (i = 0; i < m_noItems; i++)
235 if (s == m_radioButtonLabels[i])
236 return i;
237 return -1;
238 }
239
240 void wxRadioBox::SetSelection(int n)
241 {
242 if ((n < 0) || (n >= m_noItems))
243 return;
244
245 m_selectedButton = n;
246
247 m_inSetValue = TRUE;
248
249 XmToggleButtonSetState ((Widget) m_radioButtons[n], TRUE, FALSE);
250
251 int i;
252 for (i = 0; i < m_noItems; i++)
253 if (i != n)
254 XmToggleButtonSetState ((Widget) m_radioButtons[i], FALSE, FALSE);
255
256 m_inSetValue = FALSE;
257 }
258
259 // Get single selection, for single choice list items
260 int wxRadioBox::GetSelection() const
261 {
262 return m_selectedButton;
263 }
264
265 // Find string for position
266 wxString wxRadioBox::GetString(int n) const
267 {
268 if ((n < 0) || (n >= m_noItems))
269 return wxEmptyString;
270 return m_radioButtonLabels[n];
271 }
272
273 void wxRadioBox::SetSize(int x, int y, int width, int height, int sizeFlags)
274 {
275 bool managed = XtIsManaged((Widget) m_formWidget);
276
277 if (managed)
278 XtUnmanageChild ((Widget) m_formWidget);
279
280 int xx = x; int yy = y;
281 AdjustForParentClientOrigin(xx, yy, sizeFlags);
282
283 if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
284 XtVaSetValues ((Widget) m_formWidget, XmNleftAttachment, XmATTACH_SELF,
285 XmNx, xx, NULL);
286 if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
287 XtVaSetValues ((Widget) m_formWidget, XmNtopAttachment, XmATTACH_SELF,
288 XmNy, yy, NULL);
289
290 // Must set the actual RadioBox to be desired size MINUS label size
291 Dimension labelWidth = 0, labelHeight = 0, actualWidth = 0, actualHeight = 0;
292
293 if (m_labelWidget)
294 XtVaGetValues ((Widget) m_labelWidget, XmNwidth, &labelWidth, XmNheight, &labelHeight, NULL);
295
296 actualWidth = width;
297 actualHeight = height - labelHeight;
298
299 if (width > -1)
300 {
301 XtVaSetValues ((Widget) m_mainWidget, XmNwidth, actualWidth, NULL);
302 }
303 if (height > -1)
304 {
305 XtVaSetValues ((Widget) m_mainWidget, XmNheight, actualHeight, NULL);
306 }
307 if (managed)
308 XtManageChild ((Widget) m_formWidget);
309 }
310
311 // Enable a specific button
312 void wxRadioBox::Enable(int n, bool enable)
313 {
314 if ((n < 0) || (n >= m_noItems))
315 return;
316
317 XtSetSensitive ((Widget) m_radioButtons[n], (Boolean) enable);
318 }
319
320 // Enable all controls
321 void wxRadioBox::Enable(bool enable)
322 {
323 wxControl::Enable(enable);
324
325 int i;
326 for (i = 0; i < m_noItems; i++)
327 XtSetSensitive ((Widget) m_radioButtons[i], (Boolean) enable);
328 }
329
330 // Show a specific button
331 void wxRadioBox::Show(int n, bool show)
332 {
333 // This method isn't complete, and we try do do our best...
334 // It's main purpose isn't for allowing Show/Unshow dynamically,
335 // but rather to provide a way to design wxRadioBox such:
336 //
337 // o Val1 o Val2 o Val3
338 // o Val4 o Val6
339 // o Val7 o Val8 o Val9
340 //
341 // In my case, this is a 'direction' box, and the Show(5,False) is
342 // coupled with an Enable(5,False)
343 //
344 if ((n < 0) || (n >= m_noItems))
345 return;
346
347 XtVaSetValues ((Widget) m_radioButtons[n],
348 XmNindicatorOn, (unsigned char) show,
349 NULL);
350
351 // Please note that this is all we can do: removing the label
352 // if switching to unshow state. However, when switching
353 // to the on state, it's the prog. resp. to call SetLabel(item,...)
354 // after this call!!
355 if (!show)
356 wxRadioBox::SetLabel (n, " ");
357 }
358
359 // For single selection items only
360 wxString wxRadioBox::GetStringSelection () const
361 {
362 int sel = GetSelection ();
363 if (sel > -1)
364 return this->GetString (sel);
365 else
366 return wxString("");
367 }
368
369 bool wxRadioBox::SetStringSelection (const wxString& s)
370 {
371 int sel = FindString (s);
372 if (sel > -1)
373 {
374 SetSelection (sel);
375 return TRUE;
376 }
377 else
378 return FALSE;
379 }
380
381 void wxRadioBox::Command (wxCommandEvent & event)
382 {
383 SetSelection (event.m_commandInt);
384 ProcessCommand (event);
385 }
386
387 void wxRadioBox::ChangeFont(bool keepOriginalSize)
388 {
389 // TODO
390 }
391
392 void wxRadioBox::ChangeBackgroundColour()
393 {
394 // TODO
395 }
396
397 void wxRadioBox::ChangeForegroundColour()
398 {
399 // TODO
400 }
401
402 void wxRadioBoxCallback (Widget w, XtPointer clientData,
403 XmToggleButtonCallbackStruct * cbs)
404 {
405 if (!cbs->set)
406 return;
407
408 wxRadioBox *item = (wxRadioBox *) clientData;
409 int sel = -1;
410 int i;
411 for (i = 0; i < item->Number(); i++)
412 if (item->GetRadioButtons() && ((Widget) (item->GetRadioButtons()[i]) == w))
413 sel = i;
414 item->SetSel(sel);
415
416 if (item->InSetValue())
417 return;
418
419 wxCommandEvent event (wxEVT_COMMAND_RADIOBOX_SELECTED, item->GetId());
420 event.m_commandInt = sel;
421 event.SetEventObject(item);
422 item->ProcessCommand (event);
423 }
424