replaced all int/size_t indices in wxControlWithItems API with unsigned int (committi...
[wxWidgets.git] / src / cocoa / listbox.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/cocoa/listbox.mm
3 // Purpose:     wxListBox
4 // Author:      David Elliott
5 // Modified by:
6 // Created:     2003/03/18
7 // Id:          $Id$
8 // Copyright:   (c) 2003 David Elliott
9 // Licence:     wxWidgets licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #if wxUSE_LISTBOX
15
16 #ifndef WX_PRECOMP
17     #include "wx/log.h"
18     #include "wx/app.h"
19     #include "wx/listbox.h"
20 #endif //WX_PRECOMP
21
22 #include "wx/cocoa/string.h"
23 #include "wx/cocoa/autorelease.h"
24 #include "wx/cocoa/NSTableDataSource.h"
25
26 #import <Foundation/NSArray.h>
27 #import <Foundation/NSEnumerator.h>
28 #import <AppKit/NSTableView.h>
29 #import <AppKit/NSTableColumn.h>
30
31 IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
32 BEGIN_EVENT_TABLE(wxListBox, wxListBoxBase)
33 END_EVENT_TABLE()
34 WX_IMPLEMENT_COCOA_OWNER(wxListBox,NSTableView,NSControl,NSView)
35
36 bool wxListBox::Create(wxWindow *parent, wxWindowID winid,
37             const wxPoint& pos,
38             const wxSize& size,
39             const wxArrayString& choices,
40             long style,
41             const wxValidator& validator,
42             const wxString& name)
43 {
44     wxCArrayString chs(choices);
45
46     return Create(parent, winid, pos, size, chs.GetCount(), chs.GetStrings(),
47                   style, validator, name);
48 }
49
50 bool wxListBox::Create(wxWindow *parent, wxWindowID winid,
51             const wxPoint& pos,
52             const wxSize& size,
53             int n, const wxString choices[],
54             long style,
55             const wxValidator& validator,
56             const wxString& name)
57 {
58 /*
59 wxLB_SINGLE
60 Single-selection list.
61
62 wxLB_MULTIPLE
63 Multiple-selection list: the user can toggle multiple items on and off.
64
65 wxLB_EXTENDED
66 Extended-selection list: the user can select multiple items using the SHIFT key and the mouse or special key combinations.
67
68 wxLB_HSCROLL
69 Create horizontal scrollbar if contents are too wide (Windows only).
70
71 wxLB_ALWAYS_SB
72 Always show a vertical scrollbar.
73
74 wxLB_NEEDED_SB
75 Only create a vertical scrollbar if needed.
76
77 wxLB_SORT
78 The listbox contents are sorted in alphabetical order.
79 */
80     wxAutoNSAutoreleasePool pool;
81     if(!CreateControl(parent,winid,pos,size,style,validator,name))
82         return false;
83
84     // Provide the data
85     m_cocoaItems = [[NSMutableArray arrayWithCapacity:n] retain];
86     for(int i=0; i < n; i++)
87     {
88         [m_cocoaItems addObject: wxNSStringWithWxString(choices[i])];
89     }
90     // Remove everything
91     m_itemClientData.Clear();
92     // Initialize n elements to NULL
93     m_itemClientData.SetCount(n,NULL);
94
95     SetNSTableView([[NSTableView alloc] initWithFrame: MakeDefaultNSRect(size)]);
96     [m_cocoaNSView release];
97     [GetNSTableView() setHeaderView: nil];
98
99     // Set up the data source
100     m_cocoaDataSource = [[wxCocoaNSTableDataSource alloc] init];
101     [GetNSTableView() setDataSource:m_cocoaDataSource];
102
103     // Add the single column
104     NSTableColumn *tableColumn = [[NSTableColumn alloc] initWithIdentifier:nil];
105     [GetNSTableView() addTableColumn: tableColumn];
106     [tableColumn release];
107
108     [GetNSTableView() sizeToFit];
109     // Finish
110     if(m_parent)
111         m_parent->CocoaAddChild(this);
112     // NSTableView does WEIRD things with sizes.  Wrapping it in an
113     // NSScrollView seems to be the only reasonable solution.
114     CocoaCreateNSScrollView();
115     SetInitialFrameRect(pos,size);
116
117     // Set up extended/multiple selection flags
118     if ((style & wxLB_EXTENDED) || (style & wxLB_MULTIPLE))
119         //diff is that mult requires shift down for multi selection
120         [GetNSTableView() setAllowsMultipleSelection:true];
121
122     [GetNSTableView() setAllowsColumnSelection:false];
123
124     return true;
125 }
126
127 wxListBox::~wxListBox()
128 {
129     [GetNSTableView() setDataSource: nil];
130     [m_cocoaDataSource release];
131     [m_cocoaItems release];
132     DisassociateNSTableView(GetNSTableView());
133 }
134
135 int wxListBox::CocoaDataSource_numberOfRows()
136 {
137     return [m_cocoaItems count];
138 }
139
140 struct objc_object* wxListBox::CocoaDataSource_objectForTableColumn(
141         WX_NSTableColumn tableColumn, int rowIndex)
142 {
143     return [m_cocoaItems objectAtIndex:rowIndex];
144 }
145
146 // pure virtuals from wxListBoxBase
147 bool wxListBox::IsSelected(int n) const
148 {
149     return [GetNSTableView() isRowSelected: n];
150 }
151
152 void wxListBox::DoSetSelection(int n, bool select)
153 {
154     if(select)
155         [GetNSTableView() selectRow: n byExtendingSelection:NO];
156     else
157         [GetNSTableView() deselectRow: n];
158 }
159
160 int wxListBox::GetSelections(wxArrayInt& aSelections) const
161 {
162     aSelections.Clear();
163     NSEnumerator *enumerator = [GetNSTableView() selectedRowEnumerator];
164     while(NSNumber *num = [enumerator nextObject])
165     {
166         aSelections.Add([num intValue]);
167     }
168     return [GetNSTableView() numberOfSelectedRows];
169 }
170
171 void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos)
172 {
173     wxAutoNSAutoreleasePool pool;
174
175     for(int i=int(items.GetCount())-1; i >= 0; i--)
176     {
177         [m_cocoaItems insertObject: wxNSStringWithWxString(items[i])
178             atIndex: pos];
179         m_itemClientData.Insert(NULL,pos);
180     }
181     [GetNSTableView() reloadData];
182 }
183
184 void wxListBox::DoSetItems(const wxArrayString& items, void **clientData)
185 {
186     wxAutoNSAutoreleasePool pool;
187
188     // Remove everything
189     [m_cocoaItems removeAllObjects];
190     m_itemClientData.Clear();
191     // Provide the data
192     for(unsigned int i=0; i < items.GetCount(); i++)
193     {
194         [m_cocoaItems addObject: wxNSStringWithWxString(items[i])];
195         m_itemClientData.Add(clientData[i]);
196     }
197     [GetNSTableView() reloadData];
198 }
199
200 void wxListBox::DoSetFirstItem(int n)
201 {
202     [m_cocoaItems exchangeObjectAtIndex:0 withObjectAtIndex:n];
203     void* pOld = m_itemClientData[n];
204     m_itemClientData[n] = m_itemClientData[0];
205     m_itemClientData[0] = pOld;
206     [GetNSTableView() reloadData];
207 }
208
209
210 // pure virtuals from wxItemContainer
211     // deleting items
212 void wxListBox::Clear()
213 {
214     [m_cocoaItems removeAllObjects];
215     m_itemClientData.Clear();
216     [GetNSTableView() reloadData];
217 }
218
219 void wxListBox::Delete(unsigned int n)
220 {
221     [m_cocoaItems removeObjectAtIndex:n];
222     m_itemClientData.RemoveAt(n);
223     [GetNSTableView() reloadData];
224 }
225
226     // accessing strings
227 unsigned int wxListBox::GetCount() const
228 {
229     return (unsigned int)[m_cocoaItems count];
230 }
231
232 wxString wxListBox::GetString(unsigned int n) const
233 {
234     return wxStringWithNSString([m_cocoaItems objectAtIndex:n]);
235 }
236
237 void wxListBox::SetString(unsigned int n, const wxString& s)
238 {
239     wxAutoNSAutoreleasePool pool;
240     [m_cocoaItems removeObjectAtIndex:n];
241     [m_cocoaItems insertObject: wxNSStringWithWxString(s) atIndex: n];
242     [GetNSTableView() reloadData];
243 }
244
245 int wxListBox::FindString(const wxString& s, bool bCase) const
246 {
247     // FIXME: use wxItemContainerImmutable::FindString for bCase parameter
248     wxAutoNSAutoreleasePool pool;
249     return [m_cocoaItems indexOfObject:wxNSStringWithWxString(s)];
250 }
251
252     // selection
253 int wxListBox::GetSelection() const
254 {
255     return [GetNSTableView() selectedRow];
256 }
257
258 int wxListBox::DoAppend(const wxString& item)
259 {
260     wxAutoNSAutoreleasePool pool;
261     [m_cocoaItems addObject:wxNSStringWithWxString(item)];
262     [GetNSTableView() reloadData];
263     m_itemClientData.Add(NULL);
264     return [m_cocoaItems count];
265 }
266
267 void wxListBox::DoSetItemClientData(unsigned int n, void* clientData)
268 {
269     m_itemClientData[n] = clientData;
270 }
271
272 void* wxListBox::DoGetItemClientData(unsigned int n) const
273 {
274     return m_itemClientData[n];
275 }
276
277 void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData)
278 {
279     m_itemClientData[n] = (void*) clientData;
280 }
281
282 wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const
283 {
284     return (wxClientData*) m_itemClientData[n];
285 }
286
287 #endif