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