]> git.saurik.com Git - wxWidgets.git/blame - src/common/ctrlsub.cpp
Return NULL from wxWindow::GetCapture() when the capture is being lost.
[wxWidgets.git] / src / common / ctrlsub.cpp
CommitLineData
6c8a980f 1///////////////////////////////////////////////////////////////////////////////
aa61d352 2// Name: src/common/ctrlsub.cpp
1e6feb95 3// Purpose: wxItemContainer implementation
6c8a980f
VZ
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 22.10.99
77ffb593 7// Copyright: (c) wxWidgets team
65571936 8// Licence: wxWindows licence
6c8a980f
VZ
9///////////////////////////////////////////////////////////////////////////////
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
6c8a980f
VZ
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
1e6feb95
VZ
26#if wxUSE_CONTROLS
27
6c8a980f
VZ
28#ifndef WX_PRECOMP
29 #include "wx/ctrlsub.h"
a9711a4d 30 #include "wx/arrstr.h"
6c8a980f
VZ
31#endif
32
1440bc7a
VZ
33IMPLEMENT_ABSTRACT_CLASS(wxControlWithItems, wxControl)
34
6c8a980f 35// ============================================================================
8ba7c771 36// wxItemContainerImmutable implementation
6c8a980f
VZ
37// ============================================================================
38
8ba7c771 39wxItemContainerImmutable::~wxItemContainerImmutable()
799ea011
GD
40{
41 // this destructor is required for Darwin
42}
43
6c8a980f
VZ
44// ----------------------------------------------------------------------------
45// selection
46// ----------------------------------------------------------------------------
47
8ba7c771 48wxString wxItemContainerImmutable::GetStringSelection() const
6c8a980f
VZ
49{
50 wxString s;
aa61d352 51
6c8a980f 52 int sel = GetSelection();
aa61d352
VZ
53 if ( sel != wxNOT_FOUND )
54 s = GetString((unsigned int)sel);
6c8a980f
VZ
55
56 return s;
57}
58
8ba7c771 59bool wxItemContainerImmutable::SetStringSelection(const wxString& s)
64fa6f16
VZ
60{
61 const int sel = FindString(s);
62 if ( sel == wxNOT_FOUND )
63 return false;
64
c6179a84 65 SetSelection(sel);
64fa6f16
VZ
66
67 return true;
68}
69
8ba7c771 70wxArrayString wxItemContainerImmutable::GetStrings() const
b8d5be01 71{
8ba7c771
VZ
72 wxArrayString result;
73
aa61d352 74 const unsigned int count = GetCount();
8ba7c771 75 result.Alloc(count);
aa61d352 76 for ( unsigned int n = 0; n < count; n++ )
b8d5be01 77 result.Add(GetString(n));
8ba7c771
VZ
78
79 return result;
80}
81
82// ============================================================================
83// wxItemContainer implementation
84// ============================================================================
85
86wxItemContainer::~wxItemContainer()
87{
88 // this destructor is required for Darwin
b8d5be01
SC
89}
90
0e0bc921 91// ----------------------------------------------------------------------------
a236aa20 92// deleting items
0e0bc921
VZ
93// ----------------------------------------------------------------------------
94
a236aa20 95void wxItemContainer::Clear()
0e0bc921 96{
a236aa20 97 if ( HasClientObjectData() )
0e0bc921 98 {
a236aa20
VZ
99 const unsigned count = GetCount();
100 for ( unsigned i = 0; i < count; ++i )
101 ResetItemClientObject(i);
0e0bc921 102 }
a236aa20 103
131b1fba 104 SetClientDataType(wxClientData_None);
a236aa20
VZ
105
106 DoClear();
0e0bc921
VZ
107}
108
a236aa20 109void wxItemContainer::Delete(unsigned int pos)
243dbf1a 110{
9a83f860 111 wxCHECK_RET( pos < GetCount(), wxT("invalid index") );
243dbf1a 112
a236aa20
VZ
113 if ( HasClientObjectData() )
114 ResetItemClientObject(pos);
115
116 DoDeleteOneItem(pos);
117
118 if ( IsEmpty() )
119 {
131b1fba 120 SetClientDataType(wxClientData_None);
a236aa20 121 }
243dbf1a
VZ
122}
123
a236aa20 124// ----------------------------------------------------------------------------
03647350 125//
a236aa20
VZ
126// ----------------------------------------------------------------------------
127
128int wxItemContainer::DoInsertItemsInLoop(const wxArrayStringsAdapter& items,
129 unsigned int pos,
130 void **clientData,
131 wxClientDataType type)
243dbf1a 132{
a236aa20
VZ
133 int n = wxNOT_FOUND;
134
135 const unsigned int count = items.GetCount();
136 for ( unsigned int i = 0; i < count; ++i )
137 {
138 n = DoInsertOneItem(items[i], pos++);
139 if ( n == wxNOT_FOUND )
140 break;
141
142 AssignNewItemClientData(n, clientData, i, type);
143 }
243dbf1a
VZ
144
145 return n;
146}
147
a236aa20
VZ
148int
149wxItemContainer::DoInsertOneItem(const wxString& WXUNUSED(item),
150 unsigned int WXUNUSED(pos))
151{
9a83f860 152 wxFAIL_MSG( wxT("Must be overridden if DoInsertItemsInLoop() is used") );
a236aa20
VZ
153
154 return wxNOT_FOUND;
155}
156
157
6c8a980f
VZ
158// ----------------------------------------------------------------------------
159// client data
160// ----------------------------------------------------------------------------
161
aa61d352 162void wxItemContainer::SetClientObject(unsigned int n, wxClientData *data)
6c8a980f 163{
131b1fba 164 wxASSERT_MSG( !HasClientUntypedData(),
6c8a980f
VZ
165 wxT("can't have both object and void client data") );
166
8584b0e6
VZ
167 wxCHECK_RET( IsValid(n), "Invalid index passed to SetClientObject()" );
168
131b1fba 169 if ( HasClientObjectData() )
da6069e2 170 {
a236aa20 171 wxClientData * clientDataOld
5c33522f 172 = static_cast<wxClientData *>(DoGetItemClientData(n));
da6069e2
VZ
173 if ( clientDataOld )
174 delete clientDataOld;
175 }
131b1fba 176 else // didn't have any client data so far
da6069e2
VZ
177 {
178 // now we have object client data
a236aa20
VZ
179 DoInitItemClientData();
180
131b1fba 181 SetClientDataType(wxClientData_Object);
da6069e2 182 }
6c8a980f 183
a236aa20 184 DoSetItemClientData(n, data);
6c8a980f
VZ
185}
186
aa61d352 187wxClientData *wxItemContainer::GetClientObject(unsigned int n) const
6c8a980f 188{
131b1fba 189 wxCHECK_MSG( HasClientObjectData(), NULL,
6c8a980f
VZ
190 wxT("this window doesn't have object client data") );
191
8584b0e6
VZ
192 wxCHECK_MSG( IsValid(n), NULL,
193 "Invalid index passed to GetClientObject()" );
194
5c33522f 195 return static_cast<wxClientData *>(DoGetItemClientData(n));
6c8a980f
VZ
196}
197
ab989357
VZ
198wxClientData *wxItemContainer::DetachClientObject(unsigned int n)
199{
200 wxClientData * const data = GetClientObject(n);
201 if ( data )
202 {
203 // reset the pointer as we don't own it any more
204 DoSetItemClientData(n, NULL);
205 }
206
207 return data;
208}
209
aa61d352 210void wxItemContainer::SetClientData(unsigned int n, void *data)
6c8a980f 211{
131b1fba 212 if ( !HasClientData() )
a236aa20
VZ
213 {
214 DoInitItemClientData();
131b1fba 215 SetClientDataType(wxClientData_Void);
a236aa20
VZ
216 }
217
131b1fba 218 wxASSERT_MSG( HasClientUntypedData(),
6c8a980f
VZ
219 wxT("can't have both object and void client data") );
220
8584b0e6
VZ
221 wxCHECK_RET( IsValid(n), "Invalid index passed to SetClientData()" );
222
6c8a980f 223 DoSetItemClientData(n, data);
6c8a980f
VZ
224}
225
aa61d352 226void *wxItemContainer::GetClientData(unsigned int n) const
6c8a980f 227{
131b1fba 228 wxCHECK_MSG( HasClientUntypedData(), NULL,
6c8a980f
VZ
229 wxT("this window doesn't have void client data") );
230
8584b0e6
VZ
231 wxCHECK_MSG( IsValid(n), NULL,
232 "Invalid index passed to GetClientData()" );
233
6c8a980f
VZ
234 return DoGetItemClientData(n);
235}
236
a236aa20
VZ
237void wxItemContainer::AssignNewItemClientData(unsigned int pos,
238 void **clientData,
239 unsigned int n,
240 wxClientDataType type)
241{
242 switch ( type )
243 {
244 case wxClientData_Object:
245 SetClientObject
246 (
247 pos,
5c33522f 248 (reinterpret_cast<wxClientData **>(clientData))[n]
a236aa20
VZ
249 );
250 break;
251
252 case wxClientData_Void:
253 SetClientData(pos, clientData[n]);
254 break;
255
256 default:
9a83f860 257 wxFAIL_MSG( wxT("unknown client data type") );
a236aa20
VZ
258 // fall through
259
260 case wxClientData_None:
261 // nothing to do
262 break;
263 }
264}
265
266void wxItemContainer::ResetItemClientObject(unsigned int n)
267{
268 wxClientData * const data = GetClientObject(n);
269 if ( data )
270 {
271 delete data;
272 DoSetItemClientData(n, NULL);
273 }
274}
275
4c15a375
VZ
276// ============================================================================
277// wxControlWithItems implementation
278// ============================================================================
279
a236aa20
VZ
280void
281wxControlWithItemsBase::InitCommandEventWithItems(wxCommandEvent& event, int n)
4c15a375
VZ
282{
283 InitCommandEvent(event);
284
285 if ( n != wxNOT_FOUND )
286 {
287 if ( HasClientObjectData() )
288 event.SetClientObject(GetClientObject(n));
289 else if ( HasClientUntypedData() )
290 event.SetClientData(GetClientData(n));
291 }
292}
293
7bc74071
VZ
294void wxControlWithItemsBase::SendSelectionChangedEvent(wxEventType eventType)
295{
296 const int n = GetSelection();
297 if ( n == wxNOT_FOUND )
298 return;
299
300 wxCommandEvent event(eventType, m_windowId);
301 event.SetInt(n);
302 event.SetEventObject(this);
303 event.SetString(GetStringSelection());
304 InitCommandEventWithItems(event, n);
305
306 HandleWindowEvent(event);
307}
308
1e6feb95 309#endif // wxUSE_CONTROLS