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