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