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