]> git.saurik.com Git - wxWidgets.git/blob - src/os2/choice.cpp
better implementation from VZ
[wxWidgets.git] / src / os2 / choice.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/choice.cpp
3 // Purpose: wxChoice
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/13/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxUSE_CHOICE
16
17 #include "wx/choice.h"
18
19 #ifndef WX_PRECOMP
20 #include "wx/utils.h"
21 #include "wx/log.h"
22 #include "wx/settings.h"
23 #endif
24
25 #include "wx/os2/private.h"
26
27 IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControlWithItems)
28
29 bool wxChoice::Create(
30 wxWindow* pParent
31 , wxWindowID vId
32 , const wxPoint& rPos
33 , const wxSize& rSize
34 , const wxArrayString& asChoices
35 , long lStyle
36 , const wxValidator& rValidator
37 , const wxString& rsName
38 )
39 {
40 wxCArrayString chs(asChoices);
41
42 return Create(pParent, vId, rPos, rSize, chs.GetCount(), chs.GetStrings(),
43 lStyle, rValidator, rsName);
44 }
45
46 bool wxChoice::Create(
47 wxWindow* pParent
48 , wxWindowID vId
49 , const wxPoint& rPos
50 , const wxSize& rSize
51 , int n
52 , const wxString asChoices[]
53 , long lStyle
54 , const wxValidator& rValidator
55 , const wxString& rsName
56 )
57 {
58 long lSstyle;
59
60 if (!CreateControl( pParent
61 ,vId
62 ,rPos
63 ,rSize
64 ,lStyle
65 ,rValidator
66 ,rsName
67 ))
68 return false;
69 lSstyle = CBS_DROPDOWNLIST |
70 WS_TABSTOP |
71 WS_VISIBLE;
72
73 // clipping siblings does not yet work
74 // if (lStyle & wxCLIP_SIBLINGS )
75 // lSstyle |= WS_CLIPSIBLINGS;
76
77 wxASSERT_MSG( !(lStyle & wxCB_DROPDOWN) &&
78 !(lStyle & wxCB_READONLY) &&
79 !(lStyle & wxCB_SIMPLE),
80 wxT("this style flag is ignored by wxChoice, you "
81 "probably want to use a wxComboBox") );
82
83 if (!OS2CreateControl( wxT("COMBOBOX")
84 ,lSstyle
85 ))
86 return false;
87
88 //
89 // A choice/combobox normally has a white background (or other, depending
90 // on global settings) rather than inheriting the parent's background colour.
91 //
92 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
93
94 // initialize the controls contents
95 for (int i = 0; i < n; i++)
96 {
97 Append(asChoices[i]);
98 }
99 SetSize( rPos.x
100 ,rPos.y
101 ,rSize.x
102 ,rSize.y
103 );
104
105 // Set height to use with sizers i.e. without the dropdown listbox
106 wxFont vFont = GetFont();
107 int nEditHeight;
108 wxGetCharSize( GetHWND(), NULL, &nEditHeight, &vFont );
109 nEditHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nEditHeight);
110 SetInitialSize(wxSize(-1,nEditHeight+4)); // +2x2 for the border
111
112 return true;
113 } // end of wxChoice::Create
114
115 wxChoice::~wxChoice()
116 {
117 Clear();
118 }
119
120 // ----------------------------------------------------------------------------
121 // adding/deleting items to/from the list
122 // ----------------------------------------------------------------------------
123
124 int wxChoice::DoInsertItems(const wxArrayStringsAdapter& items
125 , unsigned int pos
126 , void **clientData
127 , wxClientDataType type
128 )
129 {
130 int nIndex = wxNOT_FOUND;
131 LONG nIndexType = 0;
132 bool incrementPos = false;
133 if ( IsSorted() )
134 nIndexType = LIT_SORTASCENDING;
135 else if (pos == GetCount())
136 nIndexType = LIT_END;
137 else
138 {
139 nIndexType = pos;
140 incrementPos = true;
141 }
142
143 const unsigned int count = items.GetCount();
144 for( unsigned int i = 0; i < count; ++i )
145 {
146 nIndex = (int)::WinSendMsg( GetHwnd()
147 ,LM_INSERTITEM
148 ,(MPARAM)nIndexType
149 ,(MPARAM)items[i].wx_str()
150 );
151 if (nIndex < 0)
152 {
153 nIndex = wxNOT_FOUND;
154 break;
155 }
156 AssignNewItemClientData(nIndex, clientData, i, type);
157
158 if (incrementPos)
159 ++nIndexType;
160 }
161 return nIndex;
162 } // end of wxChoice::DoInsertAppendItemsWithData
163
164 void wxChoice::DoDeleteOneItem(unsigned int n)
165 {
166 wxCHECK_RET( IsValid(n), wxT("invalid item index in wxChoice::Delete") );
167
168 ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0);
169 } // end of wxChoice::Delete
170
171 void wxChoice::DoClear()
172 {
173 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
174 } // end of wxChoice::Clear
175
176 // ----------------------------------------------------------------------------
177 // selection
178 // ----------------------------------------------------------------------------
179
180 int wxChoice::GetSelection() const
181 {
182 return((int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0)));
183 } // end of wxChoice::GetSelection
184
185 void wxChoice::SetSelection(
186 int n
187 )
188 {
189 ::WinSendMsg( GetHwnd()
190 ,LM_SELECTITEM
191 ,(MPARAM)n
192 ,(MPARAM)TRUE
193 );
194 } // end of wxChoice::SetSelection
195
196 // ----------------------------------------------------------------------------
197 // string list functions
198 // ----------------------------------------------------------------------------
199
200 unsigned int wxChoice::GetCount() const
201 {
202 return((unsigned int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMCOUNT, (MPARAM)0, (MPARAM)0)));
203 } // end of wxChoice::GetCount
204
205 void wxChoice::SetString(unsigned int n, const wxString& rsStr)
206 {
207 LONG nIndexType = 0;
208 void* pData;
209
210 if ( HasClientData() )
211 {
212 pData = DoGetItemClientData(n);
213 }
214 else // no client data
215 {
216 pData = NULL;
217 }
218
219 ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, 0);
220
221 if (m_windowStyle & wxCB_SORT)
222 nIndexType = LIT_SORTASCENDING;
223 else
224 nIndexType = LIT_END;
225 ::WinSendMsg( GetHwnd()
226 ,LM_INSERTITEM
227 ,(MPARAM)nIndexType
228 ,(MPARAM)rsStr.wx_str()
229 );
230
231 if (pData)
232 {
233 DoSetItemClientData(n, pData);
234 }
235 } // end of wxChoice::SetString
236
237 wxString wxChoice::GetString(unsigned int n) const
238 {
239 int nLen = 0;
240 wxString sStr = wxEmptyString;
241 wxChar* zBuf;
242
243 nLen = (size_t)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)n, (MPARAM)0));
244 if (nLen != LIT_ERROR && nLen > 0)
245 {
246 zBuf = new wxChar[++nLen];
247 ::WinSendMsg( GetHwnd()
248 ,LM_QUERYITEMTEXT
249 ,MPFROM2SHORT((SHORT)n, (SHORT)nLen)
250 ,(MPARAM)zBuf
251 );
252 sStr = zBuf;
253 delete [] zBuf;
254 }
255 return sStr;
256 } // end of wxChoice::GetString
257
258 // ----------------------------------------------------------------------------
259 // client data
260 // ----------------------------------------------------------------------------
261
262 void wxChoice::DoSetItemClientData(unsigned int n, void* pClientData)
263 {
264 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)n, MPFROMP(pClientData));
265 } // end of wxChoice::DoSetItemClientData
266
267 void* wxChoice::DoGetItemClientData(unsigned int n) const
268 {
269 MRESULT rc = ::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, (MPARAM)n, (MPARAM)0);
270 return((void*)rc);
271 } // end of wxChoice::DoGetItemClientData
272
273 // ----------------------------------------------------------------------------
274 // wxOS2 specific helpers
275 // ----------------------------------------------------------------------------
276
277 void wxChoice::DoSetSize(int nX,
278 int nY,
279 int nWidth,
280 int WXUNUSED(nHeight),
281 int nSizeFlags)
282 {
283 //
284 // Ignore height parameter because height doesn't mean 'initially
285 // displayed' height, it refers to the drop-down menu as well. The
286 // wxWidgets interpretation is different; also, getting the size returns
287 // the _displayed_ size (NOT the drop down menu size) so
288 // setting-getting-setting size would not work.
289 //
290 wxControl::DoSetSize( nX
291 ,nY
292 ,nWidth
293 ,wxDefaultCoord
294 ,nSizeFlags
295 );
296 } // end of wxChoice::DoSetSize
297
298 wxSize wxChoice::DoGetBestSize() const
299 {
300 //
301 // Find the widest string
302 //
303 int nLineWidth;
304 int nChoiceWidth = 0;
305 int nCx;
306 int nCy;
307 wxFont vFont = (wxFont)GetFont();
308
309 const unsigned int nItems = GetCount();
310
311 for (unsigned int i = 0; i < nItems; i++)
312 {
313 wxString sStr(GetString(i));
314 GetTextExtent( sStr, &nLineWidth, NULL );
315 if (nLineWidth > nChoiceWidth)
316 nChoiceWidth = nLineWidth;
317 }
318
319 //
320 // Give it some reasonable default value if there are no strings in the
321 // list
322 //
323 if (nChoiceWidth == 0L)
324 nChoiceWidth = 100L;
325
326 //
327 // The combobox should be larger than the widest string
328 //
329 wxGetCharSize( GetHWND(), &nCx, &nCy, &vFont );
330 nChoiceWidth += 5 * nCx;
331
332 //
333 // Choice drop-down list depends on number of items (limited to 10)
334 //
335 size_t nStrings = nItems == 0 ? 10 : wxMin(10, nItems) + 1;
336 int nChoiceHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * nStrings;
337
338 return wxSize(nChoiceWidth, nChoiceHeight);
339 } // end of wxChoice::DoGetBestSize
340
341 MRESULT wxChoice::OS2WindowProc(
342 WXUINT uMsg
343 , WXWPARAM wParam
344 , WXLPARAM lParam
345 )
346 {
347 return wxWindow::OS2WindowProc( uMsg
348 ,wParam
349 ,lParam
350 );
351 } // end of wxChoice::OS2WindowProc
352
353 bool wxChoice::OS2Command(
354 WXUINT uParam
355 , WXWORD WXUNUSED(wId)
356 )
357 {
358 if (uParam != LN_SELECT)
359 {
360 //
361 // "selection changed" is the only event we're after
362 //
363 return false;
364 }
365 int n = GetSelection();
366
367 if (n > -1)
368 {
369 wxCommandEvent vEvent( wxEVT_COMMAND_CHOICE_SELECTED
370 ,m_windowId
371 );
372
373 vEvent.SetInt(n);
374 vEvent.SetEventObject(this);
375 vEvent.SetString(GetStringSelection());
376 if (HasClientObjectData())
377 vEvent.SetClientObject(GetClientObject(n));
378 else if (HasClientUntypedData())
379 vEvent.SetClientData(GetClientData(n));
380 ProcessCommand(vEvent);
381 }
382 return true;
383 } // end of wxChoice::OS2Command
384
385 #endif // wxUSE_CHOICE