]> git.saurik.com Git - wxWidgets.git/blame - src/motif/combobox.cpp
cleanup - reformatting; simplified OnPaint
[wxWidgets.git] / src / motif / combobox.cpp
CommitLineData
4bb6408c 1/////////////////////////////////////////////////////////////////////////////
11e62fe6 2// Name: src/motif/combobox.cpp
4bb6408c
JS
3// Purpose: wxComboBox class
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
89c7e962
JS
15#if wxUSE_COMBOBOX
16
9b1bd0c6 17#include "wx/combobox.h"
584ad2a3 18#include "wx/arrstr.h"
9b1bd0c6 19
338dd992
JJ
20#ifdef __VMS__
21#pragma message disable nosimpint
22#endif
89c7e962 23#include <Xm/Xm.h>
338dd992
JJ
24#ifdef __VMS__
25#pragma message enable nosimpint
26#endif
9b1bd0c6
MB
27
28// use the old, GPL'd combobox
29#if (XmVersion < 2000)
30
8704bf74 31#include "xmcombo/xmcombo.h"
89c7e962 32
ec75d791
MB
33#include "wx/motif/private.h"
34
89c7e962 35void wxComboBoxCallback (Widget w, XtPointer clientData,
2d120f83 36 XmComboBoxSelectionCallbackStruct * cbs);
89c7e962 37
4bb6408c 38IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)
4bb6408c
JS
39
40bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
2d120f83
JS
41 const wxString& value,
42 const wxPoint& pos,
43 const wxSize& size,
44 int n, const wxString choices[],
45 long style,
46 const wxValidator& validator,
47 const wxString& name)
4bb6408c 48{
ec75d791 49 if( !CreateControl( parent, id, pos, size, style, validator, name ) )
7d8268a1 50 return false;
31528cd3 51
ec75d791 52 m_noStrings = n;
31528cd3 53
89c7e962 54 Widget parentWidget = (Widget) parent->GetClientWidget();
31528cd3
VZ
55
56 Widget buttonWidget = XtVaCreateManagedWidget(name.c_str(),
2d120f83
JS
57 xmComboBoxWidgetClass, parentWidget,
58 XmNmarginHeight, 0,
59 XmNmarginWidth, 0,
60 XmNshowLabel, False,
61 XmNeditable, ((style & wxCB_READONLY) != wxCB_READONLY),
62 XmNsorted, ((style & wxCB_SORT) == wxCB_SORT),
63 XmNstaticList, ((style & wxCB_SIMPLE) == wxCB_SIMPLE),
64 NULL);
31528cd3 65
89c7e962
JS
66 int i;
67 for (i = 0; i < n; i++)
68 {
ec75d791
MB
69 wxXmString str( choices[i] );
70 XmComboBoxAddItem(buttonWidget, str(), 0);
89c7e962
JS
71 m_stringList.Add(choices[i]);
72 }
31528cd3 73
89c7e962 74 m_mainWidget = (Widget) buttonWidget;
31528cd3 75
89c7e962 76 XtManageChild (buttonWidget);
31528cd3 77
89c7e962 78 SetValue(value);
31528cd3 79
7d8268a1 80 ChangeFont(false);
31528cd3 81
f6bcfd97
BP
82 XtAddCallback (buttonWidget, XmNselectionCallback, (XtCallbackProc) wxComboBoxCallback,
83 (XtPointer) this);
84 XtAddCallback (buttonWidget, XmNvalueChangedCallback, (XtCallbackProc) wxComboBoxCallback,
85 (XtPointer) this);
86
89c7e962 87 AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, size.x, size.y);
31528cd3 88
0d57be45 89 ChangeBackgroundColour();
31528cd3 90
7d8268a1 91 return true;
4bb6408c
JS
92}
93
584ad2a3
MB
94bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
95 const wxString& value,
96 const wxPoint& pos,
97 const wxSize& size,
98 const wxArrayString& choices,
99 long style,
100 const wxValidator& validator,
101 const wxString& name)
102{
103 wxCArrayString chs(choices);
7d8268a1 104 return Create(parent, id, value, pos, size, chs.GetCount(),
584ad2a3
MB
105 chs.GetStrings(), style, validator, name);
106}
107
8aa04e8b
JS
108wxComboBox::~wxComboBox()
109{
110 DetachWidget((Widget) m_mainWidget); // Removes event handlers
111 XtDestroyWidget((Widget) m_mainWidget);
112 m_mainWidget = (WXWidget) 0;
ec75d791
MB
113 if ( HasClientObjectData() )
114 m_clientDataDict.DestroyData();
8aa04e8b
JS
115}
116
a7bdad33
VZ
117void wxComboBox::DoSetSize(int x, int y,
118 int width, int WXUNUSED(height),
119 int sizeFlags)
8aa04e8b
JS
120{
121 // Necessary so it doesn't call wxChoice::SetSize
ec75d791 122 wxWindow::DoSetSize(x, y, width, DoGetBestSize().y, sizeFlags);
8aa04e8b
JS
123}
124
4bb6408c
JS
125wxString wxComboBox::GetValue() const
126{
89c7e962
JS
127 char *s = XmComboBoxGetString ((Widget) m_mainWidget);
128 if (s)
129 {
130 wxString str(s);
131 XtFree (s);
132 return str;
133 }
134 else
135 return wxEmptyString;
4bb6408c
JS
136}
137
138void wxComboBox::SetValue(const wxString& value)
139{
7d8268a1 140 m_inSetValue = true;
ec75d791 141 if( !value.empty() )
d3a80c92
MB
142 XmComboBoxSetString( (Widget)m_mainWidget,
143 wxConstCast(value.c_str(), char) );
7d8268a1 144 m_inSetValue = false;
4bb6408c
JS
145}
146
a7bdad33 147void wxComboBox::SetString(int WXUNUSED(n), const wxString& WXUNUSED(s))
9b1bd0c6
MB
148{
149 wxFAIL_MSG( wxT("wxComboBox::SetString only implemented for Motif 2.0") );
150}
151
ec75d791 152int wxComboBox::DoAppend(const wxString& item)
8aa04e8b 153{
ec75d791
MB
154 wxXmString str( item.c_str() );
155 XmComboBoxAddItem((Widget) m_mainWidget, str(), 0);
8aa04e8b 156 m_stringList.Add(item);
8aa04e8b 157 m_noStrings ++;
ec75d791
MB
158
159 return GetCount() - 1;
8aa04e8b
JS
160}
161
243dbf1a
VZ
162int wxComboBox::DoInsert(const wxString& item, int pos)
163{
164 wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list"));
165 wxCHECK_MSG((pos>=0) && (pos<=GetCount()), -1, wxT("invalid index"));
166
167 if (pos == GetCount())
168 return DoAppend(item);
169
170 wxXmString str( item.c_str() );
171 XmComboBoxAddItem((Widget) m_mainWidget, str(), pos+1);
46ec70fb
MB
172 wxChar* copy = wxStrcpy(new wxChar[item.length() + 1], item.c_str());
173 m_stringList.Insert(pos, copy);
243dbf1a
VZ
174 m_noStrings ++;
175
176 return pos;
177}
178
8aa04e8b
JS
179void wxComboBox::Delete(int n)
180{
ec75d791 181 XmComboBoxDeletePos((Widget) m_mainWidget, n+1);
fd304d98 182 wxStringList::Node *node = m_stringList.Item(n);
8aa04e8b
JS
183 if (node)
184 {
fd304d98 185 delete[] node->GetData();
2d120f83 186 delete node;
8aa04e8b 187 }
ec75d791 188 m_clientDataDict.Delete(n, HasClientObjectData());
8aa04e8b
JS
189 m_noStrings--;
190}
191
192void wxComboBox::Clear()
193{
194 XmComboBoxDeleteAllItems((Widget) m_mainWidget);
195 m_stringList.Clear();
f6bcfd97
BP
196
197 if ( HasClientObjectData() )
ec75d791 198 m_clientDataDict.DestroyData();
f6bcfd97 199 m_noStrings = 0;
8aa04e8b
JS
200}
201
202void wxComboBox::SetSelection (int n)
203{
204 XmComboBoxSelectPos((Widget) m_mainWidget, n+1, False);
205}
206
207int wxComboBox::GetSelection (void) const
208{
2d120f83
JS
209 int sel = XmComboBoxGetSelectedPos((Widget) m_mainWidget);
210 if (sel == 0)
211 return -1;
212 else
213 return sel - 1;
8aa04e8b
JS
214}
215
216wxString wxComboBox::GetString(int n) const
217{
fd304d98 218 wxStringList::Node *node = m_stringList.Item(n);
8aa04e8b 219 if (node)
fd304d98 220 return wxString(node->GetData ());
8aa04e8b 221 else
2d120f83 222 return wxEmptyString;
8aa04e8b
JS
223}
224
a7bdad33 225int wxComboBox::FindString(const wxString& s, bool WXUNUSED(bCase)) const
8aa04e8b 226{
11e62fe6
WS
227 // FIXME: back to base class for not supported value of bCase
228
2d120f83
JS
229 int *pos_list = NULL;
230 int count = 0;
ec75d791 231 wxXmString text( s );
2d120f83 232 bool found = (XmComboBoxGetMatchPos((Widget) m_mainWidget,
ec75d791 233 text(), &pos_list, &count) != 0);
31528cd3 234
2d120f83
JS
235 if (found && count > 0)
236 {
237 int pos = pos_list[0] - 1;
238 free(pos_list);
239 return pos;
240 }
31528cd3 241
11e62fe6 242 return wxNOT_FOUND;
8aa04e8b
JS
243}
244
4bb6408c
JS
245// Clipboard operations
246void wxComboBox::Copy()
247{
89c7e962 248 XmComboBoxCopy((Widget) m_mainWidget, CurrentTime);
4bb6408c
JS
249}
250
251void wxComboBox::Cut()
252{
89c7e962 253 XmComboBoxCut((Widget) m_mainWidget, CurrentTime);
4bb6408c
JS
254}
255
256void wxComboBox::Paste()
257{
89c7e962 258 XmComboBoxPaste((Widget) m_mainWidget);
4bb6408c
JS
259}
260
f9e02ac7 261void wxComboBox::SetEditable(bool WXUNUSED(editable))
4bb6408c
JS
262{
263 // TODO
264}
265
266void wxComboBox::SetInsertionPoint(long pos)
267{
89c7e962 268 XmComboBoxSetInsertionPosition ((Widget) m_mainWidget, (XmTextPosition) pos);
4bb6408c
JS
269}
270
271void wxComboBox::SetInsertionPointEnd()
272{
89c7e962
JS
273 XmTextPosition pos = XmComboBoxGetLastPosition ((Widget) m_mainWidget);
274 XmComboBoxSetInsertionPosition ((Widget) m_mainWidget, (XmTextPosition) (pos + 1));
4bb6408c
JS
275}
276
277long wxComboBox::GetInsertionPoint() const
278{
89c7e962 279 return (long) XmComboBoxGetInsertionPosition ((Widget) m_mainWidget);
4bb6408c
JS
280}
281
7d8268a1 282wxTextPos wxComboBox::GetLastPosition() const
4bb6408c 283{
7d8268a1 284 return (wxTextPos) XmComboBoxGetLastPosition ((Widget) m_mainWidget);
4bb6408c
JS
285}
286
287void wxComboBox::Replace(long from, long to, const wxString& value)
288{
d3a80c92
MB
289 XmComboBoxReplace ((Widget) m_mainWidget, (XmTextPosition) from,
290 (XmTextPosition) to,
291 wxConstCast(value.c_str(), char));
4bb6408c
JS
292}
293
294void wxComboBox::Remove(long from, long to)
295{
89c7e962 296 XmComboBoxSetSelection ((Widget) m_mainWidget, (XmTextPosition) from, (XmTextPosition) to,
31528cd3 297 (Time) 0);
89c7e962 298 XmComboBoxRemove ((Widget) m_mainWidget);
4bb6408c
JS
299}
300
301void wxComboBox::SetSelection(long from, long to)
302{
89c7e962 303 XmComboBoxSetSelection ((Widget) m_mainWidget, (XmTextPosition) from, (XmTextPosition) to,
31528cd3 304 (Time) 0);
89c7e962
JS
305}
306
f9e02ac7 307void wxComboBoxCallback (Widget WXUNUSED(w), XtPointer clientData,
2d120f83 308 XmComboBoxSelectionCallbackStruct * cbs)
89c7e962
JS
309{
310 wxComboBox *item = (wxComboBox *) clientData;
31528cd3 311
89c7e962
JS
312 switch (cbs->reason)
313 {
2d120f83
JS
314 case XmCR_SINGLE_SELECT:
315 case XmCR_BROWSE_SELECT:
89c7e962 316 {
9b1bd0c6
MB
317 wxCommandEvent event (wxEVT_COMMAND_COMBOBOX_SELECTED,
318 item->GetId());
687706f5
KH
319 event.SetInt(cbs->index - 1);
320 event.SetString( item->GetString ( event.GetInt() ) );
ec75d791
MB
321 if ( item->HasClientObjectData() )
322 event.SetClientObject( item->GetClientObject(cbs->index - 1) );
323 else if ( item->HasClientUntypedData() )
324 event.SetClientData( item->GetClientData(cbs->index - 1) );
96be256b 325 event.SetExtraLong(true);
2d120f83
JS
326 event.SetEventObject(item);
327 item->ProcessCommand (event);
328 break;
89c7e962 329 }
2d120f83 330 case XmCR_VALUE_CHANGED:
89c7e962
JS
331 {
332 wxCommandEvent event (wxEVT_COMMAND_TEXT_UPDATED, item->GetId());
687706f5
KH
333 event.SetInt(-1);
334 event.SetString( item->GetValue() );
96be256b 335 event.SetExtraLong(true);
2d120f83
JS
336 event.SetEventObject(item);
337 item->ProcessCommand (event);
89c7e962
JS
338 break;
339 }
2d120f83
JS
340 default:
341 break;
89c7e962 342 }
4bb6408c
JS
343}
344
4b5f3fe6 345void wxComboBox::ChangeFont(bool keepOriginalSize)
0d57be45 346{
321db4b6 347 // Don't use the base class wxChoice's ChangeFont
4b5f3fe6 348 wxWindow::ChangeFont(keepOriginalSize);
0d57be45
JS
349}
350
351void wxComboBox::ChangeBackgroundColour()
352{
321db4b6 353 wxWindow::ChangeBackgroundColour();
0d57be45
JS
354}
355
356void wxComboBox::ChangeForegroundColour()
357{
ec75d791
MB
358 wxWindow::ChangeForegroundColour();
359}
360
361wxSize wxComboBox::DoGetBestSize() const
362{
363 if( (GetWindowStyle() & wxCB_DROPDOWN) == wxCB_DROPDOWN ||
364 (GetWindowStyle() & wxCB_READONLY) == wxCB_READONLY )
365 {
366 wxSize items = GetItemsSize();
367 // FIXME arbitrary constants
368 return wxSize( ( items.x ? items.x + 50 : 120 ),
369 items.y + 10 );
370 }
371 else
372 return wxWindow::DoGetBestSize();
0d57be45
JS
373}
374
9b1bd0c6 375#endif // XmVersion < 2000
89c7e962 376
9b1bd0c6 377#endif // wxUSE_COMBOBOX