fixed wxMotif to compile in Unicode mode (this is not full Unicode support, all strin...
[wxWidgets.git] / src / motif / radiobox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/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 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxUSE_RADIOBOX
16
17 #ifdef __VMS
18 #define XtDisplay XTDISPLAY
19 #endif
20
21 #include "wx/radiobox.h"
22
23 #ifndef WX_PRECOMP
24 #include "wx/utils.h"
25 #include "wx/arrstr.h"
26 #endif
27
28 #ifdef __VMS__
29 #pragma message disable nosimpint
30 #endif
31 #include <Xm/Label.h>
32 #include <Xm/LabelG.h>
33 #include <Xm/ToggleB.h>
34 #include <Xm/ToggleBG.h>
35 #include <Xm/RowColumn.h>
36 #include <Xm/Frame.h>
37 #ifdef __VMS__
38 #pragma message enable nosimpint
39 #endif
40
41 #include "wx/motif/private.h"
42
43 void wxRadioBoxCallback (Widget w, XtPointer clientData,
44 XmToggleButtonCallbackStruct * cbs);
45
46 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
47
48 // Radio box item
49 void wxRadioBox::Init()
50 {
51 m_selectedButton = -1;
52 m_noItems = 0;
53 m_noRowsOrCols = 0;
54 m_labelWidget = (WXWidget) 0;
55 }
56
57 bool 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 if( !CreateControl( parent, id, pos, size, style, val, name ) )
64 return false;
65 PreCreation();
66
67 m_noItems = (unsigned int)n;
68 m_noRowsOrCols = majorDim;
69
70 SetMajorDim(majorDim == 0 ? n : majorDim, style);
71
72 Widget parentWidget = (Widget) parent->GetClientWidget();
73 Display* dpy = XtDisplay(parentWidget);
74
75 m_mainWidget = XtVaCreateWidget ("radioboxframe",
76 xmFrameWidgetClass, parentWidget,
77 XmNresizeHeight, True,
78 XmNresizeWidth, True,
79 NULL);
80
81 wxString label1(GetLabelText(title));
82
83 if (!label1.empty())
84 {
85 wxXmString text(label1);
86 m_labelWidget = (WXWidget)
87 XtVaCreateManagedWidget( label1.mb_str(),
88 #if wxUSE_GADGETS
89 style & wxCOLOURED ? xmLabelWidgetClass
90 : xmLabelGadgetClass,
91 (Widget)m_mainWidget,
92 #else
93 xmLabelWidgetClass, (Widget)m_mainWidget,
94 #endif
95 wxFont::GetFontTag(), m_font.GetFontTypeC(dpy),
96 XmNlabelString, text(),
97 // XmNframeChildType is not in Motif 1.2, nor in Lesstif,
98 // if it was compiled with 1.2 compatibility
99 // TODO: check this still looks OK for Motif 1.2.
100 #if (XmVersion > 1200)
101 XmNframeChildType, XmFRAME_TITLE_CHILD,
102 #else
103 XmNchildType, XmFRAME_TITLE_CHILD,
104 #endif
105 XmNchildVerticalAlignment, XmALIGNMENT_CENTER,
106 NULL);
107 }
108
109 Arg args[3];
110
111 XtSetArg (args[0], XmNorientation, ((style & wxHORIZONTAL) == wxHORIZONTAL ?
112 XmHORIZONTAL : XmVERTICAL));
113 XtSetArg (args[1], XmNnumColumns, GetMajorDim());
114 XtSetArg (args[2], XmNadjustLast, False);
115
116 Widget radioBoxWidget =
117 XmCreateRadioBox ((Widget)m_mainWidget, wxMOTIF_STR("radioBoxWidget"), args, 3);
118
119 m_radioButtons.reserve(n);
120 m_radioButtonLabels.reserve(n);
121
122 int i;
123 for (i = 0; i < n; i++)
124 {
125 wxString str(GetLabelText(choices[i]));
126 m_radioButtonLabels.push_back(str);
127 Widget radioItem = XtVaCreateManagedWidget (
128 str.mb_str(),
129 #if wxUSE_GADGETS
130 xmToggleButtonGadgetClass, radioBoxWidget,
131 #else
132 xmToggleButtonWidgetClass, radioBoxWidget,
133 #endif
134 wxFont::GetFontTag(), m_font.GetFontTypeC(dpy),
135 NULL);
136 m_radioButtons.push_back((WXWidget)radioItem);
137 XtAddCallback (radioItem, XmNvalueChangedCallback,
138 (XtCallbackProc) wxRadioBoxCallback,
139 (XtPointer) this);
140 }
141
142 SetSelection (0);
143
144 XtRealizeWidget((Widget)m_mainWidget);
145 XtManageChild (radioBoxWidget);
146 XtManageChild ((Widget)m_mainWidget);
147
148 PostCreation();
149 AttachWidget (parent, m_mainWidget, NULL, pos.x, pos.y, size.x, size.y);
150
151 return true;
152 }
153
154 bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& title,
155 const wxPoint& pos, const wxSize& size,
156 const wxArrayString& choices,
157 int majorDim, long style,
158 const wxValidator& val, const wxString& name)
159 {
160 wxCArrayString chs(choices);
161 return Create(parent, id, title, pos, size, chs.GetCount(),
162 chs.GetStrings(), majorDim, style, val, name);
163 }
164
165 wxRadioBox::~wxRadioBox()
166 {
167 DetachWidget(m_mainWidget);
168 XtDestroyWidget((Widget) m_mainWidget);
169
170 m_mainWidget = (WXWidget) 0;
171 }
172
173 void wxRadioBox::SetString(unsigned int item, const wxString& label)
174 {
175 if (!IsValid(item))
176 return;
177
178 Widget widget = (Widget)m_radioButtons[item];
179 if (!label.empty())
180 {
181 wxString label1(GetLabelText(label));
182 wxXmString text( label1 );
183 m_radioButtonLabels[item] = label1;
184 XtVaSetValues (widget,
185 XmNlabelString, text(),
186 XmNlabelType, XmSTRING,
187 NULL);
188 }
189 }
190
191 void wxRadioBox::SetSelection(int n)
192 {
193 if (!IsValid(n))
194 return;
195
196 m_selectedButton = n;
197
198 m_inSetValue = true;
199
200 XmToggleButtonSetState ((Widget) m_radioButtons[n], True, False);
201
202 for (unsigned int i = 0; i < m_noItems; i++)
203 if (i != (unsigned int)n)
204 XmToggleButtonSetState ((Widget) m_radioButtons[i], False, False);
205
206 m_inSetValue = false;
207 }
208
209 // Get single selection, for single choice list items
210 int wxRadioBox::GetSelection() const
211 {
212 return m_selectedButton;
213 }
214
215 // Find string for position
216 wxString wxRadioBox::GetString(unsigned int n) const
217 {
218 if (!IsValid(n))
219 return wxEmptyString;
220 return m_radioButtonLabels[n];
221 }
222
223 void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
224 {
225 bool managed = XtIsManaged((Widget) m_mainWidget);
226
227 if (managed)
228 XtUnmanageChild ((Widget) m_mainWidget);
229
230 int xx = x; int yy = y;
231 AdjustForParentClientOrigin(xx, yy, sizeFlags);
232
233 if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
234 XtVaSetValues ((Widget) m_mainWidget, XmNx, xx, NULL);
235 if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
236 XtVaSetValues ((Widget) m_mainWidget, XmNy, yy, NULL);
237
238 if (width > 0)
239 XtVaSetValues ((Widget) m_mainWidget, XmNwidth, width, NULL);
240 if (height > 0)
241 XtVaSetValues ((Widget) m_mainWidget, XmNheight, height, NULL);
242
243 if (managed)
244 XtManageChild ((Widget) m_mainWidget);
245 }
246
247 // Enable a specific button
248 bool wxRadioBox::Enable(unsigned int n, bool enable)
249 {
250 if (!IsValid(n))
251 return false;
252
253 XtSetSensitive ((Widget) m_radioButtons[n], (Boolean) enable);
254 return true;
255 }
256
257 // Enable all controls
258 bool wxRadioBox::Enable(bool enable)
259 {
260 if ( !wxControl::Enable(enable) )
261 return false;
262
263 for (unsigned int i = 0; i < m_noItems; i++)
264 XtSetSensitive ((Widget) m_radioButtons[i], (Boolean) enable);
265
266 return true;
267 }
268
269 bool wxRadioBox::Show(bool show)
270 {
271 // TODO: show/hide all children
272 return wxControl::Show(show);
273 }
274
275 // Show a specific button
276 bool wxRadioBox::Show(unsigned int n, bool show)
277 {
278 // This method isn't complete, and we try do do our best...
279 // It's main purpose isn't for allowing Show/Unshow dynamically,
280 // but rather to provide a way to design wxRadioBox such:
281 //
282 // o Val1 o Val2 o Val3
283 // o Val4 o Val6
284 // o Val7 o Val8 o Val9
285 //
286 // In my case, this is a 'direction' box, and the Show(5,False) is
287 // coupled with an Enable(5,False)
288 //
289 if (!IsValid(n))
290 return false;
291
292 XtVaSetValues ((Widget) m_radioButtons[n],
293 XmNindicatorOn, (unsigned char) show,
294 NULL);
295
296 // Please note that this is all we can do: removing the label
297 // if switching to unshow state. However, when switching
298 // to the on state, it's the prog. resp. to call SetString(item,...)
299 // after this call!!
300 if (!show)
301 wxRadioBox::SetString (n, " ");
302
303 return true;
304 }
305
306 // For single selection items only
307 wxString wxRadioBox::GetStringSelection () const
308 {
309 int sel = GetSelection ();
310 if (sel != wxNOT_FOUND)
311 return this->GetString((unsigned int)sel);
312 else
313 return wxEmptyString;
314 }
315
316 bool wxRadioBox::SetStringSelection (const wxString& s)
317 {
318 int sel = FindString (s);
319 if (sel > -1)
320 {
321 SetSelection (sel);
322 return true;
323 }
324 else
325 return false;
326 }
327
328 void wxRadioBox::Command (wxCommandEvent & event)
329 {
330 SetSelection (event.GetInt());
331 ProcessCommand (event);
332 }
333
334 void wxRadioBox::ChangeFont(bool keepOriginalSize)
335 {
336 wxWindow::ChangeFont(keepOriginalSize);
337
338 for (unsigned int i = 0; i < m_noItems; i++)
339 {
340 WXWidget radioButton = m_radioButtons[i];
341
342 XtVaSetValues ((Widget) radioButton,
343 wxFont::GetFontTag(), m_font.GetFontTypeC(XtDisplay((Widget) GetTopWidget())),
344 NULL);
345 }
346 }
347
348 void wxRadioBox::ChangeBackgroundColour()
349 {
350 wxWindow::ChangeBackgroundColour();
351
352 wxColour colour = *wxBLACK;
353 WXPixel selectPixel = colour.AllocColour(XtDisplay((Widget)m_mainWidget));
354
355 for (unsigned int i = 0; i < m_noItems; i++)
356 {
357 WXWidget radioButton = m_radioButtons[i];
358
359 wxDoChangeBackgroundColour(radioButton, m_backgroundColour, true);
360
361 XtVaSetValues ((Widget) radioButton,
362 XmNselectColor, selectPixel,
363 NULL);
364 }
365 }
366
367 void wxRadioBox::ChangeForegroundColour()
368 {
369 wxWindow::ChangeForegroundColour();
370
371 for (unsigned int i = 0; i < m_noItems; i++)
372 {
373 WXWidget radioButton = m_radioButtons[i];
374
375 wxDoChangeForegroundColour(radioButton, m_foregroundColour);
376 }
377 }
378
379 void wxRadioBoxCallback (Widget w, XtPointer clientData,
380 XmToggleButtonCallbackStruct * cbs)
381 {
382 if (!cbs->set)
383 return;
384
385 wxRadioBox *item = (wxRadioBox *) clientData;
386 int sel = -1;
387 unsigned int i;
388 const wxWidgetArray& buttons = item->GetRadioButtons();
389 for (i = 0; i < item->GetCount(); i++)
390 if (((Widget)buttons[i]) == w)
391 sel = (int)i;
392 item->SetSel(sel);
393
394 if (item->InSetValue())
395 return;
396
397 wxCommandEvent event (wxEVT_COMMAND_RADIOBOX_SELECTED, item->GetId());
398 event.SetInt(sel);
399 event.SetString(item->GetStringSelection());
400 event.SetEventObject(item);
401 item->ProcessCommand (event);
402 }
403
404 #endif // wxUSE_RADIOBOX