]> git.saurik.com Git - wxWidgets.git/blob - src/cocoa/listbox.mm
Allow translated 'Space' in menu accelerators (perhaps more entries should allow...
[wxWidgets.git] / src / cocoa / listbox.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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, 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(size_t 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(int n)
220 {
221 [m_cocoaItems removeObjectAtIndex:n];
222 m_itemClientData.RemoveAt(n);
223 [GetNSTableView() reloadData];
224 }
225
226 // accessing strings
227 int wxListBox::GetCount() const
228 {
229 return [m_cocoaItems count];
230 }
231
232 wxString wxListBox::GetString(int n) const
233 {
234 return wxStringWithNSString([m_cocoaItems objectAtIndex:n]);
235 }
236
237 void wxListBox::SetString(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(int n, void* clientData)
268 {
269 m_itemClientData[n] = clientData;
270 }
271
272 void* wxListBox::DoGetItemClientData(int n) const
273 {
274 return m_itemClientData[n];
275 }
276
277 void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
278 {
279 m_itemClientData[n] = (void*) clientData;
280 }
281
282 wxClientData* wxListBox::DoGetItemClientObject(int n) const
283 {
284 return (wxClientData*) m_itemClientData[n];
285 }
286
287 #endif