]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/cocoa/listbox.mm
Calculate correct client size for windows that are using deferred sizing.
[wxWidgets.git] / src / cocoa / listbox.mm
... / ...
CommitLineData
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
31IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
32BEGIN_EVENT_TABLE(wxListBox, wxListBoxBase)
33END_EVENT_TABLE()
34WX_IMPLEMENT_COCOA_OWNER(wxListBox,NSTableView,NSControl,NSView)
35
36bool 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
50bool 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/*
59wxLB_SINGLE
60Single-selection list.
61
62wxLB_MULTIPLE
63Multiple-selection list: the user can toggle multiple items on and off.
64
65wxLB_EXTENDED
66Extended-selection list: the user can select multiple items using the SHIFT key and the mouse or special key combinations.
67
68wxLB_HSCROLL
69Create horizontal scrollbar if contents are too wide (Windows only).
70
71wxLB_ALWAYS_SB
72Always show a vertical scrollbar.
73
74wxLB_NEEDED_SB
75Only create a vertical scrollbar if needed.
76
77wxLB_SORT
78The 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
127wxListBox::~wxListBox()
128{
129 [GetNSTableView() setDataSource: nil];
130 [m_cocoaDataSource release];
131 [m_cocoaItems release];
132 DisassociateNSTableView(GetNSTableView());
133}
134
135int wxListBox::CocoaDataSource_numberOfRows()
136{
137 return [m_cocoaItems count];
138}
139
140struct 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
147bool wxListBox::IsSelected(int n) const
148{
149 return [GetNSTableView() isRowSelected: n];
150}
151
152void wxListBox::DoSetSelection(int n, bool select)
153{
154 if(select)
155 [GetNSTableView() selectRow: n byExtendingSelection:NO];
156 else
157 [GetNSTableView() deselectRow: n];
158}
159
160int 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
171void 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
184void 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
200void 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
212void wxListBox::Clear()
213{
214 [m_cocoaItems removeAllObjects];
215 m_itemClientData.Clear();
216 [GetNSTableView() reloadData];
217}
218
219void wxListBox::Delete(int n)
220{
221 [m_cocoaItems removeObjectAtIndex:n];
222 m_itemClientData.RemoveAt(n);
223 [GetNSTableView() reloadData];
224}
225
226 // accessing strings
227int wxListBox::GetCount() const
228{
229 return [m_cocoaItems count];
230}
231
232wxString wxListBox::GetString(int n) const
233{
234 return wxStringWithNSString([m_cocoaItems objectAtIndex:n]);
235}
236
237void 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
245int 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
253int wxListBox::GetSelection() const
254{
255 return [GetNSTableView() selectedRow];
256}
257
258int 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
267void wxListBox::DoSetItemClientData(int n, void* clientData)
268{
269 m_itemClientData[n] = clientData;
270}
271
272void* wxListBox::DoGetItemClientData(int n) const
273{
274 return m_itemClientData[n];
275}
276
277void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
278{
279 m_itemClientData[n] = (void*) clientData;
280}
281
282wxClientData* wxListBox::DoGetItemClientObject(int n) const
283{
284 return (wxClientData*) m_itemClientData[n];
285}
286
287#endif