do VMS-specific X symbols redefinitions only once in wx/platform.h instead of doing...
[wxWidgets.git] / src / motif / radiobut.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/radiobut.cpp
3 // Purpose: wxRadioButton
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 #include "wx/radiobut.h"
16
17 #ifndef WX_PRECOMP
18 #include "wx/utils.h"
19 #endif
20
21 #ifdef __VMS__
22 #pragma message disable nosimpint
23 #endif
24 #include <Xm/ToggleB.h>
25 #include <Xm/ToggleBG.h>
26 #ifdef __VMS__
27 #pragma message enable nosimpint
28 #endif
29
30 #include "wx/motif/private.h"
31
32 void wxRadioButtonCallback (Widget w, XtPointer clientData,
33 XmToggleButtonCallbackStruct * cbs);
34
35 IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl)
36
37 wxRadioButton::wxRadioButton()
38 {
39 }
40
41 bool wxRadioButton::Create(wxWindow *parent, wxWindowID id,
42 const wxString& label,
43 const wxPoint& pos,
44 const wxSize& size, long style,
45 const wxValidator& validator,
46 const wxString& name)
47 {
48 if( !CreateControl( parent, id, pos, size, style, validator, name ) )
49 return false;
50 PreCreation();
51
52 Widget parentWidget = (Widget) parent->GetClientWidget();
53 Display* dpy = XtDisplay(parentWidget);
54
55 wxString label1(GetLabelText(label));
56
57 wxXmString text( label1 );
58
59 Widget radioButtonWidget = XtVaCreateManagedWidget ("toggle",
60 #if wxUSE_GADGETS
61 xmToggleButtonGadgetClass, parentWidget,
62 #else
63 xmToggleButtonWidgetClass, parentWidget,
64 #endif
65 wxFont::GetFontTag(), m_font.GetFontTypeC(dpy),
66 XmNlabelString, text(),
67 XmNfillOnSelect, True,
68 XmNindicatorType, XmONE_OF_MANY, // diamond-shape
69 NULL);
70
71 XtAddCallback (radioButtonWidget,
72 XmNvalueChangedCallback,
73 (XtCallbackProc)wxRadioButtonCallback,
74 (XtPointer)this);
75
76 m_mainWidget = (WXWidget) radioButtonWidget;
77
78 XtManageChild (radioButtonWidget);
79
80 PostCreation();
81 AttachWidget (parent, m_mainWidget, (WXWidget) NULL,
82 pos.x, pos.y, size.x, size.y);
83
84 //copied from mac/radiobut.cpp (from here till "return true;")
85 m_cycle = this ;
86
87 if (HasFlag(wxRB_GROUP))
88 {
89 AddInCycle( NULL ) ;
90 }
91 else
92 {
93 /* search backward for last group start */
94 wxRadioButton *chief = (wxRadioButton*) NULL;
95 wxWindowList::compatibility_iterator node = parent->GetChildren().GetLast();
96 while (node)
97 {
98 wxWindow *child = node->GetData();
99 if (child->IsKindOf( CLASSINFO( wxRadioButton ) ) )
100 {
101 chief = (wxRadioButton*) child;
102 if (child->HasFlag(wxRB_GROUP)) break;
103 }
104 node = node->GetPrevious();
105 }
106 AddInCycle( chief ) ;
107 }
108 return true;
109 }
110
111 void wxRadioButton::SetValue(bool value)
112 {
113 if (GetValue() == value)
114 return;
115
116 m_inSetValue = true;
117 XmToggleButtonSetState ((Widget) m_mainWidget, (Boolean) value, False);
118 m_inSetValue = false;
119
120 ClearSelections();
121 }
122
123 // Get single selection, for single choice list items
124 bool wxRadioButton::GetValue() const
125 {
126 return (XmToggleButtonGetState ((Widget) m_mainWidget) != 0);
127 }
128
129 void wxRadioButton::Command (wxCommandEvent & event)
130 {
131 SetValue ( (event.GetInt() != 0) );
132 ProcessCommand (event);
133 }
134
135 void wxRadioButton::ChangeBackgroundColour()
136 {
137 wxWindow::ChangeBackgroundColour();
138
139 // What colour should this be?
140 wxColour colour = *wxBLACK;
141 WXPixel selectPixel = colour.AllocColour(XtDisplay((Widget)m_mainWidget));
142
143 XtVaSetValues ((Widget) GetMainWidget(),
144 XmNselectColor, selectPixel,
145 NULL);
146 }
147
148 void wxRadioButtonCallback (Widget WXUNUSED(w), XtPointer clientData,
149 XmToggleButtonCallbackStruct * cbs)
150 {
151 if (!cbs->set)
152 return;
153
154 wxRadioButton *item = (wxRadioButton *) clientData;
155 if (item->InSetValue())
156 return;
157
158 //based on mac/radiobut.cpp
159 wxRadioButton* old = item->ClearSelections();
160 item->SetValue(true);
161
162 if ( old )
163 {
164 wxCommandEvent event(wxEVT_COMMAND_RADIOBUTTON_SELECTED,
165 old->GetId() );
166 event.SetEventObject(old);
167 event.SetInt( false );
168 old->ProcessCommand(event);
169 }
170 wxCommandEvent event2(wxEVT_COMMAND_RADIOBUTTON_SELECTED, item->GetId() );
171 event2.SetEventObject(item);
172 event2.SetInt( true );
173 item->ProcessCommand(event2);
174 }
175
176 wxRadioButton* wxRadioButton::AddInCycle(wxRadioButton *cycle)
177 {
178 if (cycle == NULL)
179 {
180 m_cycle = this;
181 }
182 else
183 {
184 wxRadioButton* current = cycle;
185 while ( current->m_cycle != cycle )
186 current = current->m_cycle;
187 m_cycle = cycle;
188 current->m_cycle = this;
189 }
190
191 return cycle;
192 }
193
194 wxRadioButton* wxRadioButton::ClearSelections()
195 {
196 wxRadioButton* cycle = NextInCycle();
197 wxRadioButton* old = 0;
198
199 if (cycle)
200 {
201 while (cycle != this)
202 {
203 if ( cycle->GetValue() )
204 {
205 old = cycle;
206 cycle->SetValue(false);
207 }
208 cycle = cycle->NextInCycle();
209 }
210 }
211
212 return old;
213 }
214
215 void wxRadioButton::RemoveFromCycle()
216 {
217 wxRadioButton* curr = NextInCycle();
218
219 while( curr )
220 {
221 if( curr->NextInCycle() == this )
222 {
223 curr->m_cycle = this->m_cycle;
224 return;
225 }
226
227 curr = curr->NextInCycle();
228 }
229 }