1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "radiobox.h"
17 #define XtDisplay XTDISPLAY
22 #include "wx/radiobox.h"
26 #pragma message disable nosimpint
29 #include <Xm/LabelG.h>
30 #include <Xm/ToggleB.h>
31 #include <Xm/ToggleBG.h>
32 #include <Xm/RowColumn.h>
36 #pragma message enable nosimpint
39 #include "wx/motif/private.h"
41 void wxRadioBoxCallback (Widget w
, XtPointer clientData
,
42 XmToggleButtonCallbackStruct
* cbs
);
44 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox
, wxControl
)
47 wxRadioBox::wxRadioBox()
49 m_selectedButton
= -1;
54 m_radioButtons
= (WXWidget
*) NULL
;
55 m_radioButtonLabels
= (wxString
*) NULL
;
58 bool wxRadioBox::Create(wxWindow
*parent
, wxWindowID id
, const wxString
& title
,
59 const wxPoint
& pos
, const wxSize
& size
,
60 int n
, const wxString choices
[],
61 int majorDim
, long style
,
62 const wxValidator
& val
, const wxString
& name
)
64 m_selectedButton
= -1;
66 m_radioButtons
= (WXWidget
*) NULL
;
67 m_radioButtonLabels
= (wxString
*) NULL
;
68 m_backgroundColour
= parent
->GetBackgroundColour();
69 m_foregroundColour
= parent
->GetForegroundColour();
70 m_font
= parent
->GetFont();
75 parent
->AddChild(this);
77 m_windowStyle
= (long&)style
;
80 m_windowId
= NewControlId();
84 m_noRowsOrCols
= majorDim
;
89 m_majorDim
= majorDim
;
91 Widget parentWidget
= (Widget
) parent
->GetClientWidget();
93 m_mainWidget
= XtVaCreateWidget ("radioboxframe",
94 xmFrameWidgetClass
, parentWidget
,
95 XmNshadowType
, XmSHADOW_IN
,
96 XmNresizeHeight
, True
,
100 wxString
label1(wxStripMenuCodes(title
));
102 XmFontList fontList
= (XmFontList
) m_font
.GetFontList(1.0, XtDisplay(parentWidget
));
106 wxXmString
text(label1
);
107 (void)XtVaCreateManagedWidget(label1
.c_str(),
109 style
& wxCOLOURED
? xmLabelWidgetClass
110 : xmLabelGadgetClass
,
111 (Widget
)m_mainWidget
,
113 xmLabelWidgetClass
, (Widget
)m_mainWidget
,
115 XmNfontList
, fontList
,
116 XmNlabelString
, text(),
117 // XmNframeChildType is not in Motif 1.2, nor in Lesstif,
118 // if it was compiled with 1.2 compatibility
119 // TODO: check this still looks OK for Motif 1.2.
120 #if (XmVersion > 1200)
121 XmNframeChildType
, XmFRAME_TITLE_CHILD
,
123 XmNchildType
, XmFRAME_TITLE_CHILD
,
125 XmNchildVerticalAlignment
, XmALIGNMENT_CENTER
,
131 m_majorDim
= (n
+ m_majorDim
- 1) / m_majorDim
;
133 XtSetArg (args
[0], XmNorientation
, ((style
& wxHORIZONTAL
) == wxHORIZONTAL
?
134 XmHORIZONTAL
: XmVERTICAL
));
135 XtSetArg (args
[1], XmNnumColumns
, m_majorDim
);
137 Widget radioBoxWidget
= XmCreateRadioBox ((Widget
)m_mainWidget
, "radioBoxWidget", args
, 2);
139 // if (style & wxFLAT)
140 // XtVaSetValues (radioBoxWidget, XmNborderWidth, 1, NULL);
142 m_radioButtons
= new WXWidget
[n
];
143 m_radioButtonLabels
= new wxString
[n
];
145 for (i
= 0; i
< n
; i
++)
147 wxString
str(wxStripMenuCodes(choices
[i
]));
148 m_radioButtonLabels
[i
] = str
;
149 m_radioButtons
[i
] = (WXWidget
) XtVaCreateManagedWidget ((char*) (const char*) str
,
151 xmToggleButtonGadgetClass
, radioBoxWidget
,
153 xmToggleButtonWidgetClass
, radioBoxWidget
,
155 XmNfontList
, fontList
,
157 XtAddCallback ((Widget
) m_radioButtons
[i
], XmNvalueChangedCallback
, (XtCallbackProc
) wxRadioBoxCallback
,
161 m_font
= parent
->GetFont();
166 XtRealizeWidget((Widget
)m_mainWidget
);
167 XtManageChild (radioBoxWidget
);
168 XtManageChild ((Widget
)m_mainWidget
);
170 SetCanAddEventHandler(TRUE
);
171 AttachWidget (parent
, m_mainWidget
, NULL
, pos
.x
, pos
.y
, size
.x
, size
.y
);
173 ChangeBackgroundColour();
179 wxRadioBox::~wxRadioBox()
181 delete[] m_radioButtonLabels
;
182 delete[] m_radioButtons
;
184 DetachWidget(m_mainWidget
);
185 XtDestroyWidget((Widget
) m_mainWidget
);
187 m_mainWidget
= (WXWidget
) 0;
190 void wxRadioBox::SetString(int item
, const wxString
& label
)
192 if (item
< 0 || item
>= m_noItems
)
195 Widget widget
= (Widget
) m_radioButtons
[item
];
198 wxString
label1(wxStripMenuCodes(label
));
199 XmString text
= XmStringCreateSimple ((char*) (const char*) label1
);
200 XtVaSetValues (widget
,
201 XmNlabelString
, text
,
202 XmNlabelType
, XmSTRING
,
208 int wxRadioBox::FindString(const wxString
& s
) const
211 for (i
= 0; i
< m_noItems
; i
++)
212 if (s
== m_radioButtonLabels
[i
])
217 void wxRadioBox::SetSelection(int n
)
219 if ((n
< 0) || (n
>= m_noItems
))
222 m_selectedButton
= n
;
226 XmToggleButtonSetState ((Widget
) m_radioButtons
[n
], TRUE
, FALSE
);
229 for (i
= 0; i
< m_noItems
; i
++)
231 XmToggleButtonSetState ((Widget
) m_radioButtons
[i
], FALSE
, FALSE
);
233 m_inSetValue
= FALSE
;
236 // Get single selection, for single choice list items
237 int wxRadioBox::GetSelection() const
239 return m_selectedButton
;
242 // Find string for position
243 wxString
wxRadioBox::GetString(int n
) const
245 if ((n
< 0) || (n
>= m_noItems
))
246 return wxEmptyString
;
247 return m_radioButtonLabels
[n
];
250 void wxRadioBox::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
252 bool managed
= XtIsManaged((Widget
) m_mainWidget
);
255 XtUnmanageChild ((Widget
) m_mainWidget
);
257 int xx
= x
; int yy
= y
;
258 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
260 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
261 XtVaSetValues ((Widget
) m_mainWidget
, XmNx
, xx
, NULL
);
262 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
263 XtVaSetValues ((Widget
) m_mainWidget
, XmNy
, yy
, NULL
);
266 XtVaSetValues ((Widget
) m_mainWidget
, XmNwidth
, width
, NULL
);
268 XtVaSetValues ((Widget
) m_mainWidget
, XmNheight
, height
, NULL
);
271 XtManageChild ((Widget
) m_mainWidget
);
274 // Enable a specific button
275 void wxRadioBox::Enable(int n
, bool enable
)
277 if ((n
< 0) || (n
>= m_noItems
))
280 XtSetSensitive ((Widget
) m_radioButtons
[n
], (Boolean
) enable
);
283 // Enable all controls
284 bool wxRadioBox::Enable(bool enable
)
286 if ( !wxControl::Enable(enable
) )
290 for (i
= 0; i
< m_noItems
; i
++)
291 XtSetSensitive ((Widget
) m_radioButtons
[i
], (Boolean
) enable
);
296 bool wxRadioBox::Show(bool show
)
298 // TODO: show/hide all children
299 return wxControl::Show(show
);
302 // Show a specific button
303 void wxRadioBox::Show(int n
, bool show
)
305 // This method isn't complete, and we try do do our best...
306 // It's main purpose isn't for allowing Show/Unshow dynamically,
307 // but rather to provide a way to design wxRadioBox such:
309 // o Val1 o Val2 o Val3
311 // o Val7 o Val8 o Val9
313 // In my case, this is a 'direction' box, and the Show(5,False) is
314 // coupled with an Enable(5,False)
316 if ((n
< 0) || (n
>= m_noItems
))
319 XtVaSetValues ((Widget
) m_radioButtons
[n
],
320 XmNindicatorOn
, (unsigned char) show
,
323 // Please note that this is all we can do: removing the label
324 // if switching to unshow state. However, when switching
325 // to the on state, it's the prog. resp. to call SetString(item,...)
328 wxRadioBox::SetString (n
, " ");
331 // For single selection items only
332 wxString
wxRadioBox::GetStringSelection () const
334 int sel
= GetSelection ();
336 return this->GetString (sel
);
341 bool wxRadioBox::SetStringSelection (const wxString
& s
)
343 int sel
= FindString (s
);
353 void wxRadioBox::Command (wxCommandEvent
& event
)
355 SetSelection (event
.m_commandInt
);
356 ProcessCommand (event
);
359 void wxRadioBox::ChangeFont(bool keepOriginalSize
)
361 wxWindow::ChangeFont(keepOriginalSize
);
363 XmFontList fontList
= (XmFontList
) m_font
.GetFontList(1.0, XtDisplay((Widget
) GetTopWidget()));
366 for (i
= 0; i
< m_noItems
; i
++)
368 WXWidget radioButton
= m_radioButtons
[i
];
370 XtVaSetValues ((Widget
) radioButton
,
371 XmNfontList
, fontList
,
376 void wxRadioBox::ChangeBackgroundColour()
378 wxWindow::ChangeBackgroundColour();
380 int selectPixel
= wxBLACK
->AllocColour(wxGetDisplay());
383 for (i
= 0; i
< m_noItems
; i
++)
385 WXWidget radioButton
= m_radioButtons
[i
];
387 DoChangeBackgroundColour(radioButton
, m_backgroundColour
, TRUE
);
389 XtVaSetValues ((Widget
) radioButton
,
390 XmNselectColor
, selectPixel
,
395 void wxRadioBox::ChangeForegroundColour()
397 wxWindow::ChangeForegroundColour();
400 for (i
= 0; i
< m_noItems
; i
++)
402 WXWidget radioButton
= m_radioButtons
[i
];
404 DoChangeForegroundColour(radioButton
, m_foregroundColour
);
408 static int CalcOtherDim( int items
, int dim
)
410 return items
/ dim
+ ( items
% dim
? 1 : 0 );
413 int wxRadioBox::GetRowCount() const
415 return m_windowStyle
& wxRA_SPECIFY_ROWS
? m_noRowsOrCols
416 : CalcOtherDim( GetCount(), m_noRowsOrCols
);
419 int wxRadioBox::GetColumnCount() const
421 return m_windowStyle
& wxRA_SPECIFY_COLS
? m_noRowsOrCols
422 : CalcOtherDim( GetCount(), m_noRowsOrCols
);
425 void wxRadioBoxCallback (Widget w
, XtPointer clientData
,
426 XmToggleButtonCallbackStruct
* cbs
)
431 wxRadioBox
*item
= (wxRadioBox
*) clientData
;
434 for (i
= 0; i
< item
->GetCount(); i
++)
435 if (item
->GetRadioButtons() && ((Widget
) (item
->GetRadioButtons()[i
]) == w
))
439 if (item
->InSetValue())
442 wxCommandEvent
event (wxEVT_COMMAND_RADIOBOX_SELECTED
, item
->GetId());
444 event
.SetString(item
->GetStringSelection());
445 event
.SetEventObject(item
);
446 item
->ProcessCommand (event
);