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