]> git.saurik.com Git - wxWidgets.git/blame - include/wx/ctrlsub.h
Allow OS X Cocoa (or any OS X port) to override GetBestSize and provide a native...
[wxWidgets.git] / include / wx / ctrlsub.h
CommitLineData
6c8a980f
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: wx/ctrlsub.h (read: "wxConTRoL with SUBitems")
3// Purpose: wxControlWithItems interface
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 22.10.99
7// RCS-ID: $Id$
77ffb593 8// Copyright: (c) wxWidgets team
65571936 9// Licence: wxWindows licence
6c8a980f
VZ
10/////////////////////////////////////////////////////////////////////////////
11
12#ifndef _WX_CTRLSUB_H_BASE_
13#define _WX_CTRLSUB_H_BASE_
14
2ecf902b
WS
15#include "wx/defs.h"
16
1e6feb95
VZ
17#if wxUSE_CONTROLS
18
a236aa20 19#include "wx/arrstr.h"
6c8a980f
VZ
20#include "wx/control.h" // base class
21
22// ----------------------------------------------------------------------------
1e6feb95 23// wxItemContainer defines an interface which is implemented by all controls
6c8a980f
VZ
24// which have string subitems each of which may be selected.
25//
8ba7c771
VZ
26// It is decomposed in wxItemContainerImmutable which omits all methods
27// adding/removing items and is used by wxRadioBox and wxItemContainer itself.
28//
1e6feb95
VZ
29// Examples: wxListBox, wxCheckListBox, wxChoice and wxComboBox (which
30// implements an extended interface deriving from this one)
6c8a980f
VZ
31// ----------------------------------------------------------------------------
32
53a2db12 33class WXDLLIMPEXP_CORE wxItemContainerImmutable
8ba7c771
VZ
34{
35public:
36 wxItemContainerImmutable() { }
37 virtual ~wxItemContainerImmutable();
38
39 // accessing strings
40 // -----------------
41
aa61d352 42 virtual unsigned int GetCount() const = 0;
8ba7c771
VZ
43 bool IsEmpty() const { return GetCount() == 0; }
44
aa61d352 45 virtual wxString GetString(unsigned int n) const = 0;
8ba7c771 46 wxArrayString GetStrings() const;
aa61d352 47 virtual void SetString(unsigned int n, const wxString& s) = 0;
853dcc57
WS
48
49 // finding string natively is either case sensitive or insensitive
50 // but never both so fall back to this base version for not
51 // supported search type
52 virtual int FindString(const wxString& s, bool bCase = false) const
53 {
aa61d352 54 unsigned int count = GetCount();
853dcc57 55
aa61d352 56 for ( unsigned int i = 0; i < count ; ++i )
853dcc57
WS
57 {
58 if (GetString(i).IsSameAs( s , bCase ))
aa61d352 59 return (int)i;
853dcc57
WS
60 }
61
62 return wxNOT_FOUND;
63 }
8ba7c771
VZ
64
65
66 // selection
67 // ---------
68
69 virtual void SetSelection(int n) = 0;
70 virtual int GetSelection() const = 0;
71
72 // set selection to the specified string, return false if not found
73 bool SetStringSelection(const wxString& s);
74
75 // return the selected string or empty string if none
0ec1179b 76 virtual wxString GetStringSelection() const;
8ba7c771
VZ
77
78 // this is the same as SetSelection( for single-selection controls but
79 // reads better for multi-selection ones
80 void Select(int n) { SetSelection(n); }
81
789f6795
WS
82
83protected:
789f6795 84 // check that the index is valid
a236aa20
VZ
85 bool IsValid(unsigned int n) const { return n < GetCount(); }
86 bool IsValidInsert(unsigned int n) const { return n <= GetCount(); }
8ba7c771
VZ
87};
88
a236aa20
VZ
89// ----------------------------------------------------------------------------
90// wxItemContainer extends wxItemContainerImmutable interface with methods
91// for adding/removing items.
92//
93// Classes deriving from this one must override DoInsertItems() to implement
94// adding items to the control. This can often be implemented more efficiently
95// than simply looping over the elements and inserting them but if this is not
96// the case, the generic DoInsertItemsInLoop can be used in implementation, but
97// in this case DoInsertItem() needs to be overridden.
98// ----------------------------------------------------------------------------
99
53a2db12 100class WXDLLIMPEXP_CORE wxItemContainer : public wxItemContainerImmutable
6c8a980f 101{
a236aa20
VZ
102private:
103 // AppendItems() and InsertItems() helpers just call DoAppend/InsertItems()
104 // after doing some checks
105 //
106 // NB: they're defined here so that they're inlined when used in public part
107 int AppendItems(const wxArrayStringsAdapter& items,
108 void **clientData,
109 wxClientDataType type)
110 {
111 if ( items.IsEmpty() )
112 return wxNOT_FOUND;
113
114 return DoAppendItems(items, clientData, type);
115 }
116
117 int AppendItems(const wxArrayStringsAdapter& items)
118 {
119 return AppendItems(items, NULL, wxClientData_None);
120 }
121
122 int AppendItems(const wxArrayStringsAdapter& items, void **clientData)
123 {
131b1fba 124 wxASSERT_MSG( GetClientDataType() != wxClientData_Object,
9a83f860 125 wxT("can't mix different types of client data") );
a236aa20
VZ
126
127 return AppendItems(items, clientData, wxClientData_Void);
128 }
129
130 int AppendItems(const wxArrayStringsAdapter& items,
131 wxClientData **clientData)
132 {
131b1fba 133 wxASSERT_MSG( GetClientDataType() != wxClientData_Void,
9a83f860 134 wxT("can't mix different types of client data") );
a236aa20 135
5c33522f 136 return AppendItems(items, reinterpret_cast<void **>(clientData),
a236aa20
VZ
137 wxClientData_Object);
138 }
139
140 int InsertItems(const wxArrayStringsAdapter& items,
141 unsigned int pos,
142 void **clientData,
143 wxClientDataType type)
144 {
9a83f860 145 wxASSERT_MSG( !IsSorted(), wxT("can't insert items in sorted control") );
a236aa20
VZ
146
147 wxCHECK_MSG( pos <= GetCount(), wxNOT_FOUND,
9a83f860 148 wxT("position out of range") );
a236aa20
VZ
149
150 // not all derived classes handle empty arrays correctly in
151 // DoInsertItems() and besides it really doesn't make much sense to do
152 // this (for append it could correspond to creating an initially empty
153 // control but why would anybody need to insert 0 items?)
154 wxCHECK_MSG( !items.IsEmpty(), wxNOT_FOUND,
9a83f860 155 wxT("need something to insert") );
a236aa20
VZ
156
157 return DoInsertItems(items, pos, clientData, type);
158 }
159
160 int InsertItems(const wxArrayStringsAdapter& items, unsigned int pos)
161 {
162 return InsertItems(items, pos, NULL, wxClientData_None);
163 }
164
165 int InsertItems(const wxArrayStringsAdapter& items,
166 unsigned int pos,
167 void **clientData)
168 {
131b1fba 169 wxASSERT_MSG( GetClientDataType() != wxClientData_Object,
9a83f860 170 wxT("can't mix different types of client data") );
a236aa20
VZ
171
172 return InsertItems(items, pos, clientData, wxClientData_Void);
173 }
174
175 int InsertItems(const wxArrayStringsAdapter& items,
176 unsigned int pos,
177 wxClientData **clientData)
178 {
131b1fba 179 wxASSERT_MSG( GetClientDataType() != wxClientData_Void,
9a83f860 180 wxT("can't mix different types of client data") );
a236aa20
VZ
181
182 return InsertItems(items, pos,
5c33522f 183 reinterpret_cast<void **>(clientData),
a236aa20
VZ
184 wxClientData_Object);
185 }
186
6c8a980f 187public:
6463b9f5 188 wxItemContainer() { m_clientDataItemsType = wxClientData_None; }
799ea011 189 virtual ~wxItemContainer();
6c8a980f
VZ
190
191 // adding items
192 // ------------
193
a236aa20
VZ
194 // append single item, return its position in the control (which can be
195 // different from the last one if the control is sorted)
1e6feb95 196 int Append(const wxString& item)
a236aa20 197 { return AppendItems(item); }
1e6feb95 198 int Append(const wxString& item, void *clientData)
a236aa20 199 { return AppendItems(item, &clientData); }
1e6feb95 200 int Append(const wxString& item, wxClientData *clientData)
a236aa20
VZ
201 { return AppendItems(item, &clientData); }
202
203 // append several items at once to the control, return the position of the
204 // last item appended
205 int Append(const wxArrayString& items)
206 { return AppendItems(items); }
207 int Append(const wxArrayString& items, void **clientData)
208 { return AppendItems(items, clientData); }
209 int Append(const wxArrayString& items, wxClientData **clientData)
210 { return AppendItems(items, clientData); }
211 int Append(unsigned int n, const wxString *items)
212 { return AppendItems(wxArrayStringsAdapter(n, items)); }
213 int Append(unsigned int n, const wxString *items, void **clientData)
214 { return AppendItems(wxArrayStringsAdapter(n, items), clientData); }
215 int Append(unsigned int n,
216 const wxString *items,
217 wxClientData **clientData)
218 { return AppendItems(wxArrayStringsAdapter(n, items), clientData); }
219
220 // only for RTTI needs (separate name)
221 void AppendString(const wxString& item)
222 { Append(item); }
223
224
225 // inserting items: not for sorted controls!
226 // -----------------------------------------
227
228 // insert single item at the given position, return its effective position
aa61d352 229 int Insert(const wxString& item, unsigned int pos)
a236aa20
VZ
230 { return InsertItems(item, pos); }
231 int Insert(const wxString& item, unsigned int pos, void *clientData)
232 { return InsertItems(item, pos, &clientData); }
233 int Insert(const wxString& item, unsigned int pos, wxClientData *clientData)
234 { return InsertItems(item, pos, &clientData); }
235
236 // insert several items at once into the control, return the index of the
237 // last item inserted
238 int Insert(const wxArrayString& items, unsigned int pos)
239 { return InsertItems(items, pos); }
240 int Insert(const wxArrayString& items, unsigned int pos, void **clientData)
241 { return InsertItems(items, pos, clientData); }
242 int Insert(const wxArrayString& items,
243 unsigned int pos,
244 wxClientData **clientData)
245 { return InsertItems(items, pos, clientData); }
246 int Insert(unsigned int n, const wxString *items, unsigned int pos)
247 { return InsertItems(wxArrayStringsAdapter(n, items), pos); }
248 int Insert(unsigned int n,
249 const wxString *items,
250 unsigned int pos,
251 void **clientData)
252 { return InsertItems(wxArrayStringsAdapter(n, items), pos, clientData); }
253 int Insert(unsigned int n,
254 const wxString *items,
255 unsigned int pos,
256 wxClientData **clientData)
257 { return InsertItems(wxArrayStringsAdapter(n, items), pos, clientData); }
258
259
260 // replacing items
261 // ---------------
262
263 void Set(const wxArrayString& items)
264 { Clear(); Append(items); }
265 void Set(const wxArrayString& items, void **clientData)
266 { Clear(); Append(items, clientData); }
267 void Set(const wxArrayString& items, wxClientData **clientData)
268 { Clear(); Append(items, clientData); }
269 void Set(unsigned int n, const wxString *items)
270 { Clear(); Append(n, items); }
271 void Set(unsigned int n, const wxString *items, void **clientData)
272 { Clear(); Append(n, items, clientData); }
273 void Set(unsigned int n, const wxString *items, wxClientData **clientData)
274 { Clear(); Append(n, items, clientData); }
243dbf1a 275
6c8a980f
VZ
276 // deleting items
277 // --------------
278
a236aa20
VZ
279 void Clear();
280 void Delete(unsigned int pos);
6c8a980f 281
6c8a980f 282
131b1fba
VZ
283 // various accessors
284 // -----------------
285
286 // The control may maintain its items in a sorted order in which case
287 // items are automatically inserted at the right position when they are
288 // inserted or appended. Derived classes have to override this method if
289 // they implement sorting, typically by returning HasFlag(wxXX_SORT)
290 virtual bool IsSorted() const { return false; }
291
292
6c8a980f 293 // client data stuff
a236aa20
VZ
294 // -----------------
295
aa61d352
VZ
296 void SetClientData(unsigned int n, void* clientData);
297 void* GetClientData(unsigned int n) const;
6c8a980f 298
aa61d352
VZ
299 void SetClientObject(unsigned int n, wxClientData* clientData);
300 wxClientData* GetClientObject(unsigned int n) const;
6c8a980f 301
131b1fba
VZ
302 // return the type of client data stored in this control: usually it just
303 // returns m_clientDataItemsType but must be overridden in the controls
304 // which delegate their client data storage to another one (e.g. wxChoice
305 // in wxUniv which stores data in wxListBox which it uses anyhow); don't
306 // forget to override SetClientDataType() if you override this one
307 //
308 // NB: for this to work no code should ever access m_clientDataItemsType
309 // directly but only via this function!
310 virtual wxClientDataType GetClientDataType() const
311 { return m_clientDataItemsType; }
312
a236aa20 313 bool HasClientData() const
131b1fba 314 { return GetClientDataType() != wxClientData_None; }
6c8a980f 315 bool HasClientObjectData() const
131b1fba 316 { return GetClientDataType() == wxClientData_Object; }
6c8a980f 317 bool HasClientUntypedData() const
131b1fba 318 { return GetClientDataType() == wxClientData_Void; }
a236aa20 319
6c8a980f 320protected:
a236aa20
VZ
321 // there is usually no need to override this method but you can do it if it
322 // is more convenient to only do "real" insertions in DoInsertItems() and
323 // to implement items appending here (in which case DoInsertItems() should
324 // call this method if pos == GetCount() as it can still be called in this
325 // case if public Insert() is called with such position)
326 virtual int DoAppendItems(const wxArrayStringsAdapter& items,
327 void **clientData,
328 wxClientDataType type)
329 {
330 return DoInsertItems(items, GetCount(), clientData, type);
331 }
6c8a980f 332
a236aa20
VZ
333 // this method must be implemented to insert the items into the control at
334 // position pos which can be GetCount() meaning that the items should be
335 // appended; for the sorted controls the position can be ignored
336 //
337 // the derived classes typically use AssignNewItemClientData() to
338 // associate the data with the items as they're being inserted
339 //
340 // the method should return the index of the position the last item was
341 // inserted into or wxNOT_FOUND if an error occurred
342 virtual int DoInsertItems(const wxArrayStringsAdapter & items,
343 unsigned int pos,
344 void **clientData,
345 wxClientDataType type) = 0;
346
347 // before the client data is set for the first time for the control which
348 // hadn't had it before, DoInitItemClientData() is called which gives the
349 // derived class the possibility to initialize its client data storage only
350 // when client data is really used
351 virtual void DoInitItemClientData() { }
352 virtual void DoSetItemClientData(unsigned int n, void *clientData) = 0;
353 virtual void *DoGetItemClientData(unsigned int n) const = 0;
354
355 virtual void DoClear() = 0;
356 virtual void DoDeleteOneItem(unsigned int pos) = 0;
357
358
359 // methods useful for the derived classes which don't have any better way
360 // of adding multiple items to the control than doing it one by one: such
361 // classes should call DoInsertItemsInLoop() from their DoInsert() and
362 // override DoInsertOneItem() to perform the real insertion
363 virtual int DoInsertOneItem(const wxString& item, unsigned int pos);
364 int DoInsertItemsInLoop(const wxArrayStringsAdapter& items,
365 unsigned int pos,
366 void **clientData,
367 wxClientDataType type);
368
369
370 // helper for DoInsertItems(): n is the index into clientData, pos is the
371 // position of the item in the control
372 void AssignNewItemClientData(unsigned int pos,
373 void **clientData,
374 unsigned int n,
375 wxClientDataType type);
376
377 // free the client object associated with the item at given position and
378 // set it to NULL (must only be called if HasClientObjectData())
379 void ResetItemClientObject(unsigned int n);
6c8a980f 380
131b1fba
VZ
381 // set the type of the client data stored in this control: override this if
382 // you override GetClientDataType()
383 virtual void SetClientDataType(wxClientDataType clientDataItemsType)
384 {
385 m_clientDataItemsType = clientDataItemsType;
386 }
593ac33e 387
131b1fba 388private:
6c8a980f
VZ
389 // the type of the client data for the items
390 wxClientDataType m_clientDataItemsType;
391};
392
0ae0bb79
VZ
393// this macro must (unfortunately) be used in any class deriving from both
394// wxItemContainer and wxControl because otherwise there is ambiguity when
395// calling GetClientXXX() functions -- the compiler can't choose between the
396// two versions
397#define wxCONTROL_ITEMCONTAINER_CLIENTDATAOBJECT_RECAST \
398 void SetClientData(void *data) \
9ebb7cad 399 { wxEvtHandler::SetClientData(data); } \
0ae0bb79 400 void *GetClientData() const \
9ebb7cad 401 { return wxEvtHandler::GetClientData(); } \
0ae0bb79 402 void SetClientObject(wxClientData *data) \
9ebb7cad 403 { wxEvtHandler::SetClientObject(data); } \
0ae0bb79 404 wxClientData *GetClientObject() const \
9ebb7cad 405 { return wxEvtHandler::GetClientObject(); } \
aa61d352 406 void SetClientData(unsigned int n, void* clientData) \
0ae0bb79 407 { wxItemContainer::SetClientData(n, clientData); } \
aa61d352 408 void* GetClientData(unsigned int n) const \
0ae0bb79 409 { return wxItemContainer::GetClientData(n); } \
aa61d352 410 void SetClientObject(unsigned int n, wxClientData* clientData) \
0ae0bb79 411 { wxItemContainer::SetClientObject(n, clientData); } \
aa61d352 412 wxClientData* GetClientObject(unsigned int n) const \
0ae0bb79
VZ
413 { return wxItemContainer::GetClientObject(n); }
414
53a2db12 415class WXDLLIMPEXP_CORE wxControlWithItemsBase : public wxControl,
a236aa20 416 public wxItemContainer
1e6feb95
VZ
417{
418public:
a236aa20 419 wxControlWithItemsBase() { }
0ae0bb79 420
1e6feb95
VZ
421 // we have to redefine these functions here to avoid ambiguities in classes
422 // deriving from us which would arise otherwise because both base classses
423 // have the methods with the same names - hopefully, a smart compiler can
424 // optimize away these simple inline wrappers so we don't suffer much from
425 // this
0ae0bb79 426 wxCONTROL_ITEMCONTAINER_CLIENTDATAOBJECT_RECAST
fc7a2a60 427
d4864e97
VZ
428 // usually the controls like list/combo boxes have their own background
429 // colour
430 virtual bool ShouldInheritColours() const { return false; }
431
929bd5fd 432protected:
593ac33e
VZ
433 // fill in the client object or data field of the event as appropriate
434 //
435 // calls InitCommandEvent() and, if n != wxNOT_FOUND, also sets the per
436 // item client data
437 void InitCommandEventWithItems(wxCommandEvent& event, int n);
438
fc7a2a60 439private:
c0c133e1 440 wxDECLARE_NO_COPY_CLASS(wxControlWithItemsBase);
1e6feb95
VZ
441};
442
a236aa20
VZ
443// define the platform-specific wxControlWithItems class
444#if defined(__WXMSW__)
445 #include "wx/msw/ctrlsub.h"
446#elif defined(__WXMOTIF__)
447 #include "wx/motif/ctrlsub.h"
448#else
53a2db12 449 class WXDLLIMPEXP_CORE wxControlWithItems : public wxControlWithItemsBase
a236aa20
VZ
450 {
451 public:
452 wxControlWithItems() { }
453
454 private:
455 DECLARE_ABSTRACT_CLASS(wxControlWithItems)
c0c133e1 456 wxDECLARE_NO_COPY_CLASS(wxControlWithItems);
a236aa20
VZ
457 };
458#endif
c6179a84 459
1e6feb95 460#endif // wxUSE_CONTROLS
6c8a980f 461
1e6feb95 462#endif // _WX_CTRLSUB_H_BASE_