1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "choice.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/choice.h"
21 #include <Xm/PushBG.h>
23 #include <Xm/RowColumn.h>
25 #include "wx/motif/private.h"
27 #if !USE_SHARED_LIBRARY
28 IMPLEMENT_DYNAMIC_CLASS(wxChoice
, wxControl
)
31 void wxChoiceCallback (Widget w
, XtPointer clientData
,
37 m_buttonWidget
= (WXWidget
) 0;
38 m_menuWidget
= (WXWidget
) 0;
39 m_widgetList
= (WXWidget
*) 0;
40 m_formWidget
= (WXWidget
) 0;
44 bool wxChoice::Create(wxWindow
*parent
, wxWindowID id
,
47 int n
, const wxString choices
[],
49 const wxValidator
& validator
,
53 SetValidator(validator
);
55 m_windowStyle
= style
;
56 m_buttonWidget
= (WXWidget
) 0;
57 m_menuWidget
= (WXWidget
) 0;
58 m_widgetList
= (WXWidget
*) 0;
59 m_formWidget
= (WXWidget
) 0;
62 if (parent
) parent
->AddChild(this);
65 m_windowId
= (int)NewControlId();
69 Widget parentWidget
= (Widget
) parent
->GetClientWidget();
71 m_formWidget
= (WXWidget
) XtVaCreateManagedWidget ((char*) (const char*) name
,
72 xmRowColumnWidgetClass
, parentWidget
,
75 XmNpacking
, XmPACK_TIGHT
,
76 XmNorientation
, XmHORIZONTAL
,
79 XtVaSetValues ((Widget
) m_formWidget
, XmNspacing
, 0, NULL
);
82 * Create the popup menu
84 m_menuWidget
= (WXWidget
) XmCreatePulldownMenu ((Widget
) m_formWidget
, "choiceMenu", NULL
, 0);
90 for (i
= 0; i
< n
; i
++)
100 XtSetArg (args
[argcnt
], XmNsubMenuId
, (Widget
) m_menuWidget
);
102 XtSetArg (args
[argcnt
], XmNmarginWidth
, 0);
104 XtSetArg (args
[argcnt
], XmNmarginHeight
, 0);
106 XtSetArg (args
[argcnt
], XmNpacking
, XmPACK_TIGHT
);
108 m_buttonWidget
= (WXWidget
) XmCreateOptionMenu ((Widget
) m_formWidget
, "choiceButton", args
, argcnt
);
110 m_mainWidget
= m_buttonWidget
;
112 XtManageChild ((Widget
) m_buttonWidget
);
114 // New code from Roland Haenel (roland_haenel@ac.cybercity.de)
115 // Some time ago, I reported a problem with wxChoice-items under
116 // Linux and Motif 2.0 (they caused sporadic GPFs). Now it seems
117 // that I have found the code responsible for this behaviour.
118 #if XmVersion >= 1002
120 Widget optionLabel
= XmOptionLabelGadget ((Widget
) m_buttonWidget
);
121 XtUnmanageChild (optionLabel
);
125 XtVaSetValues((Widget
) m_formWidget
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
127 AttachWidget (parent
, m_buttonWidget
, m_formWidget
, pos
.x
, pos
.y
, size
.x
, size
.y
);
129 SetFont(* parent
->GetFont());
130 ChangeColour(m_mainWidget
);
135 wxChoice::~wxChoice()
137 // For some reason destroying the menuWidget
138 // can cause crashes on some machines. It will
139 // be deleted implicitly by deleting the parent form
141 // XtDestroyWidget (menuWidget);
143 delete[] m_widgetList
;
145 DetachWidget(GetMainWidget()); // Removes event handlers
147 XtDestroyWidget((Widget
) m_formWidget
);
148 m_formWidget
= (WXWidget
) 0;
150 // Presumably the other widgets have been deleted now, via the form
151 m_mainWidget
= (WXWidget
) 0;
152 m_buttonWidget
= (WXWidget
) 0;
155 void wxChoice::Append(const wxString
& item
)
157 wxStripMenuCodes ((char *)(const char *)item
, wxBuffer
);
158 Widget w
= XtVaCreateManagedWidget (wxBuffer
,
160 xmPushButtonGadgetClass
, (Widget
) m_menuWidget
,
162 xmPushButtonWidgetClass
, (Widget
) m_menuWidget
,
166 if (m_windowFont
.Ok())
168 XmNfontList
, (XmFontList
) m_windowFont
.GetFontList(1.0, XtDisplay((Widget
) m_formWidget
)),
171 WXWidget
*new_widgetList
= new WXWidget
[m_noStrings
+ 1];
173 for (i
= 0; i
< m_noStrings
; i
++)
174 new_widgetList
[i
] = m_widgetList
[i
];
175 new_widgetList
[m_noStrings
] = (WXWidget
) w
;
177 delete[] m_widgetList
;
178 m_widgetList
= new_widgetList
;
180 char mnem
= wxFindMnemonic ((char*) (const char*) item
);
182 XtVaSetValues (w
, XmNmnemonic
, mnem
, NULL
);
184 XtAddCallback (w
, XmNactivateCallback
, (XtCallbackProc
) wxChoiceCallback
, (XtPointer
) this);
186 if (m_noStrings
== 0 && m_buttonWidget
)
188 XtVaSetValues ((Widget
) m_buttonWidget
, XmNmenuHistory
, w
, NULL
);
189 Widget label
= XmOptionButtonGadget ((Widget
) m_buttonWidget
);
190 XmString text
= XmStringCreateSimple ((char*) (const char*) item
);
191 XtVaSetValues (label
,
192 XmNlabelString
, text
,
196 wxNode
*node
= m_stringList
.Add (item
);
197 XtVaSetValues (w
, XmNuserData
, node
->Data (), NULL
);
202 void wxChoice::Delete(int n
)
204 wxFAIL_MSG( "Sorry, wxChoice::Delete isn't implemented yet. Maybe you'd like to volunteer? :-)" );
206 // What should we do -- remove the callback for this button widget,
207 // delete the m_stringList entry, delete the button widget, construct a new widget list
214 void wxChoice::Clear()
216 m_stringList
.Clear ();
218 for (i
= 0; i
< m_noStrings
; i
++)
220 XtUnmanageChild ((Widget
) m_widgetList
[i
]);
221 XtDestroyWidget ((Widget
) m_widgetList
[i
]);
224 delete[] m_widgetList
;
225 m_widgetList
= (WXWidget
*) NULL
;
227 XtVaSetValues ((Widget
) m_buttonWidget
, XmNmenuHistory
, (Widget
) NULL
, NULL
);
231 int wxChoice::GetSelection() const
235 Widget label
= XmOptionButtonGadget ((Widget
) m_buttonWidget
);
236 XtVaGetValues (label
,
237 XmNlabelString
, &text
,
240 if (XmStringGetLtoR (text
, XmSTRING_DEFAULT_CHARSET
, &s
))
243 for (wxNode
* node
= m_stringList
.First (); node
; node
= node
->Next ())
245 char *s1
= (char *) node
->Data ();
246 if (s1
== s
|| strcmp (s1
, s
) == 0)
264 void wxChoice::SetSelection(int n
)
268 wxNode
*node
= m_stringList
.Nth (n
);
271 Dimension selectionWidth
, selectionHeight
;
273 char *s
= (char *) node
->Data ();
274 XmString text
= XmStringCreateSimple (s
);
275 XtVaGetValues ((Widget
) m_widgetList
[n
], XmNwidth
, &selectionWidth
, XmNheight
, &selectionHeight
, NULL
);
276 Widget label
= XmOptionButtonGadget ((Widget
) m_buttonWidget
);
277 XtVaSetValues (label
,
278 XmNlabelString
, text
,
281 XtVaSetValues ((Widget
) m_buttonWidget
,
282 XmNwidth
, selectionWidth
, XmNheight
, selectionHeight
,
283 XmNmenuHistory
, (Widget
) m_widgetList
[n
], NULL
);
285 m_inSetValue
= FALSE
;
288 int wxChoice::FindString(const wxString
& s
) const
291 for (wxNode
* node
= m_stringList
.First (); node
; node
= node
->Next ())
293 char *s1
= (char *) node
->Data ();
304 wxString
wxChoice::GetString(int n
) const
306 wxNode
*node
= m_stringList
.Nth (n
);
308 return wxString((char *) node
->Data ());
310 return wxEmptyString
;
313 void wxChoice::SetColumns(int n
)
317 short numColumns
= n
;
320 XtSetArg(args
[0], XmNnumColumns
, numColumns
);
321 XtSetArg(args
[1], XmNpacking
, XmPACK_COLUMN
);
322 XtSetValues((Widget
) m_menuWidget
,args
,2) ;
325 int wxChoice::GetColumns(void) const
329 XtVaGetValues((Widget
) m_menuWidget
,XmNnumColumns
,&numColumns
,NULL
) ;
333 void wxChoice::SetFocus()
335 XmProcessTraversal(XtParent((Widget
)m_mainWidget
), XmTRAVERSE_CURRENT
);
338 void wxChoice::SetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
340 XtVaSetValues((Widget
) m_formWidget
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
341 bool managed
= XtIsManaged((Widget
) m_formWidget
);
344 XtUnmanageChild ((Widget
) m_formWidget
);
346 int actualWidth
= width
, actualHeight
= height
;
351 for (i
= 0; i
< m_noStrings
; i
++)
352 XtVaSetValues ((Widget
) m_widgetList
[i
], XmNwidth
, actualWidth
, NULL
);
353 XtVaSetValues ((Widget
) m_buttonWidget
, XmNwidth
, actualWidth
,
359 for (i
= 0; i
< m_noStrings
; i
++)
360 XtVaSetValues ((Widget
) m_widgetList
[i
], XmNheight
, actualHeight
, NULL
);
361 XtVaSetValues ((Widget
) m_buttonWidget
, XmNheight
, actualHeight
,
366 XtManageChild ((Widget
) m_formWidget
);
367 XtVaSetValues((Widget
) m_formWidget
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
369 wxControl::SetSize (x
, y
, width
, height
, sizeFlags
);
372 wxString
wxChoice::GetStringSelection () const
374 int sel
= GetSelection ();
376 return wxString(this->GetString (sel
));
378 return wxEmptyString
;
381 bool wxChoice::SetStringSelection (const wxString
& s
)
383 int sel
= FindString (s
);
393 void wxChoice::Command(wxCommandEvent
& event
)
395 SetSelection (event
.GetInt());
396 ProcessCommand (event
);
399 void wxChoiceCallback (Widget w
, XtPointer clientData
,
402 wxChoice
*item
= (wxChoice
*) clientData
;
405 if (item
->m_inSetValue
)
409 XtVaGetValues (w
, XmNuserData
, &s
, NULL
);
412 wxCommandEvent
event (wxEVT_COMMAND_CHOICE_SELECTED
);
413 event
.m_commandInt
= item
->FindString (s
);
414 // event.m_commandString = s;
415 item
->ProcessCommand (event
);