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