]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/checklst.cpp
wxTextPos for all GetLastPosition with constants for special cases. Make it virtual...
[wxWidgets.git] / src / mac / carbon / checklst.cpp
CommitLineData
e9576ca5
SC
1///////////////////////////////////////////////////////////////////////////////
2// Name: checklst.cpp
3// Purpose: implementation of wxCheckListBox class
a31a5f85 4// Author: Stefan Csomor
e9576ca5 5// Modified by:
a31a5f85 6// Created: 1998-01-01
e9576ca5 7// RCS-ID: $Id$
a31a5f85 8// Copyright: (c) Stefan Csomor
65571936 9// Licence: wxWindows licence
e9576ca5
SC
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// headers & declarations
14// ============================================================================
15
16#ifdef __GNUG__
17#pragma implementation "checklst.h"
18#endif
19
b698c8e9 20#include "wx/defs.h"
e9576ca5 21
55d60746
GD
22#if wxUSE_CHECKLISTBOX
23
b698c8e9 24#include "wx/checklst.h"
584ad2a3 25#include "wx/arrstr.h"
b698c8e9 26
dbfc5b97 27#include "wx/mac/uma.h"
7f0c3a63 28#include <Appearance.h>
dbfc5b97 29
e9576ca5 30// ============================================================================
dbfc5b97 31// implementation of wxCheckListBox
e9576ca5
SC
32// ============================================================================
33
dbfc5b97
SC
34IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxListBox)
35
d058c153
SC
36BEGIN_EVENT_TABLE(wxCheckListBox, wxListBox)
37END_EVENT_TABLE()
dbfc5b97 38
d058c153
SC
39const short kTextColumnId = 1024 ;
40const short kCheckboxColumnId = 1025 ;
dbfc5b97 41
d058c153 42// new databrowser based version
dbfc5b97 43
d058c153 44// Listbox item
dbfc5b97
SC
45void wxCheckListBox::Init()
46{
47}
48
584ad2a3
MB
49bool wxCheckListBox::Create(wxWindow *parent,
50 wxWindowID id,
51 const wxPoint &pos,
52 const wxSize &size,
53 const wxArrayString& choices,
54 long style,
55 const wxValidator& validator,
56 const wxString &name)
57{
58 wxCArrayString chs(choices);
59
60 return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
61 style, validator, name);
62}
63
d058c153
SC
64#if TARGET_API_MAC_OSX
65static pascal void DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID,
66 DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
67#else
68static pascal void DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID,
69 DataBrowserItemNotification message)
70#endif
71{
72 long ref = GetControlReference( browser ) ;
73 if ( ref )
74 {
75 wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
45285a62
RN
76 int i = itemID - 1 ;
77 if (i >= 0 && i < list->GetCount() )
683e36bc
SC
78 {
79 bool trigger = false ;
80 wxCommandEvent event(
81 wxEVT_COMMAND_LISTBOX_SELECTED, list->GetId() );
82 switch( message )
d058c153 83 {
683e36bc
SC
84 case kDataBrowserItemDeselected :
85 if ( list->HasMultipleSelection() )
d058c153 86 trigger = true ;
683e36bc
SC
87 break ;
88 case kDataBrowserItemSelected :
89 trigger = true ;
90 break ;
91 case kDataBrowserItemDoubleClicked :
92 event.SetEventType(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED) ;
93 trigger = true ;
94 break ;
95 default :
96 break ;
d058c153 97 }
683e36bc
SC
98
99 if ( trigger )
100 {
101 event.SetEventObject( list );
102 if ( list->HasClientObjectData() )
103 event.SetClientObject( list->GetClientObject(i) );
104 else if ( list->HasClientUntypedData() )
105 event.SetClientData( list->GetClientData(i) );
106 event.SetString( list->GetString(i) );
107 event.SetInt(i) ;
108 event.SetExtraLong( list->HasMultipleSelection() ? message == kDataBrowserItemSelected : TRUE );
109 wxPostEvent( list->GetEventHandler() , event ) ;
110 // direct notification is not always having the listbox GetSelection() having in synch with event
111 // list->GetEventHandler()->ProcessEvent(event) ;
112 }
113 }
d058c153
SC
114 }
115}
116
117
118static pascal OSStatus ListBoxGetSetItemData(ControlRef browser,
119 DataBrowserItemID itemID, DataBrowserPropertyID property,
120 DataBrowserItemDataRef itemData, Boolean changeValue)
121{
122 OSStatus err = errDataBrowserPropertyNotSupported;
123
124 if ( ! changeValue )
125 {
126 switch (property)
127 {
128
129 case kTextColumnId:
130 {
131 long ref = GetControlReference( browser ) ;
132 if ( ref )
133 {
134 wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
45285a62
RN
135 int i = itemID - 1 ;
136 if (i >= 0 && i < list->GetCount() )
683e36bc
SC
137 {
138 wxMacCFStringHolder cf( list->GetString(i) , list->GetFont().GetEncoding() ) ;
139 verify_noerr( ::SetDataBrowserItemDataText( itemData , cf ) ) ;
140 err = noErr ;
141 }
d058c153
SC
142 }
143 }
144 break;
145 case kCheckboxColumnId :
146 {
147 long ref = GetControlReference( browser ) ;
148 if ( ref )
149 {
150 wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
45285a62
RN
151 int i = itemID - 1 ;
152 if (i >= 0 && i < list->GetCount() )
683e36bc
SC
153 {
154 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData , list->IsChecked( i ) ? kThemeButtonOn : kThemeButtonOff ) ) ;
155 err = noErr ;
156 }
d058c153
SC
157 }
158 }
159 break ;
160 case kDataBrowserItemIsEditableProperty:
161 {
162 err = ::SetDataBrowserItemDataBooleanValue(itemData, true);
163 }
164 break;
165
166 default:
167 break;
168 }
169 }
170 else
171 {
172 switch( property )
173 {
174 case kCheckboxColumnId :
175 {
176 long ref = GetControlReference( browser ) ;
177 if ( ref )
178 {
179 wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
45285a62
RN
180 int i = itemID - 1 ;
181 if (i >= 0 && i < list->GetCount() )
683e36bc
SC
182 {
183 // we have to change this behind the back, since Check() would be triggering another update round
184 bool newVal = !list->IsChecked( i ) ;
185 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData , newVal ? kThemeButtonOn : kThemeButtonOff ) ) ;
186 err = noErr ;
187 list->m_checks[ i ] = newVal ;
188
189 wxCommandEvent event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, list->GetId());
190 event.SetInt(i);
191 event.SetEventObject(list);
192 list->GetEventHandler()->ProcessEvent(event);
193 }
194 }
d058c153
SC
195
196 }
197 break ;
198
199 default :
200 break ;
201 }
202 }
203
204 return err;
205}
206bool wxCheckListBox::Create(wxWindow *parent, wxWindowID id,
207 const wxPoint& pos,
208 const wxSize& size,
209 int n, const wxString choices[],
210 long style,
211 const wxValidator& validator,
212 const wxString& name)
dbfc5b97 213{
facd6764 214 m_macIsUserPane = FALSE ;
d058c153
SC
215
216 wxASSERT_MSG( !(style & wxLB_MULTIPLE) || !(style & wxLB_EXTENDED),
217 _T("only one of listbox selection modes can be specified") );
facd6764 218
d058c153 219 if ( !wxListBoxBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) )
b45ed7a2
VZ
220 return false;
221
dbfc5b97
SC
222 m_noItems = 0 ; // this will be increased by our append command
223 m_selected = 0;
facd6764
SC
224
225 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
dbfc5b97 226
21fd5529 227 m_peer = new wxMacControl() ;
5ca0d812 228 verify_noerr( ::CreateDataBrowserControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()), &bounds, kDataBrowserListView , m_peer->GetControlRefAddr() ) );
21fd5529 229
dbfc5b97 230
d058c153 231 DataBrowserSelectionFlags options = kDataBrowserDragSelect ;
dbfc5b97
SC
232 if ( style & wxLB_MULTIPLE )
233 {
d058c153 234 options += kDataBrowserAlwaysExtendSelection + kDataBrowserCmdTogglesSelection ;
dbfc5b97
SC
235 }
236 else if ( style & wxLB_EXTENDED )
237 {
d058c153 238 // default behaviour
dbfc5b97
SC
239 }
240 else
241 {
d058c153 242 options += kDataBrowserSelectOnlyOne ;
dbfc5b97 243 }
5ca0d812 244 verify_noerr(m_peer->SetSelectionFlags( options ) );
d058c153
SC
245
246 DataBrowserListViewColumnDesc columnDesc ;
247 columnDesc.headerBtnDesc.titleOffset = 0;
248 columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
249
250 columnDesc.headerBtnDesc.btnFontStyle.flags =
251 kControlUseFontMask | kControlUseJustMask;
252
253 columnDesc.headerBtnDesc.btnContentInfo.contentType = kControlNoContent;
254 columnDesc.headerBtnDesc.btnFontStyle.just = teFlushDefault;
255 columnDesc.headerBtnDesc.btnFontStyle.font = kControlFontViewSystemFont;
256 columnDesc.headerBtnDesc.btnFontStyle.style = normal;
257 columnDesc.headerBtnDesc.titleString = NULL ; // CFSTR( "" );
258
259 // check column
260
261 columnDesc.headerBtnDesc.minimumWidth = 30 ;
262 columnDesc.headerBtnDesc.maximumWidth = 30;
263
264 columnDesc.propertyDesc.propertyID = kCheckboxColumnId;
265 columnDesc.propertyDesc.propertyType = kDataBrowserCheckboxType;
266 columnDesc.propertyDesc.propertyFlags = kDataBrowserPropertyIsMutable | kDataBrowserTableViewSelectionColumn |
267 kDataBrowserDefaultPropertyFlags;
5ca0d812 268 verify_noerr( m_peer->AddListViewColumn( &columnDesc, kDataBrowserListViewAppendColumn) ) ;
d058c153
SC
269
270 // text column
271
272 columnDesc.headerBtnDesc.minimumWidth = 0;
273 columnDesc.headerBtnDesc.maximumWidth = 10000;
274
275 columnDesc.propertyDesc.propertyID = kTextColumnId;
276 columnDesc.propertyDesc.propertyType = kDataBrowserTextType;
277 columnDesc.propertyDesc.propertyFlags = kDataBrowserTableViewSelectionColumn
278#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
279 | kDataBrowserListViewTypeSelectColumn
280#endif
281 ;
282
283
5ca0d812 284 verify_noerr( m_peer->AddListViewColumn( &columnDesc, kDataBrowserListViewAppendColumn) ) ;
d058c153 285
5ca0d812
SC
286 verify_noerr( m_peer->AutoSizeListViewColumns() ) ;
287 verify_noerr( m_peer->SetHasScrollBars( false , true ) ) ;
288 verify_noerr( m_peer->SetTableViewHiliteStyle( kDataBrowserTableViewFillHilite ) ) ;
289 verify_noerr( m_peer->SetListViewHeaderBtnHeight(0 ) ) ;
d058c153
SC
290
291 DataBrowserCallbacks callbacks ;
292 callbacks.version = kDataBrowserLatestCallbacks;
293 InitDataBrowserCallbacks(&callbacks);
294 callbacks.u.v1.itemDataCallback = NewDataBrowserItemDataUPP(ListBoxGetSetItemData);
295 callbacks.u.v1.itemNotificationCallback =
296#if TARGET_API_MAC_OSX
297 (DataBrowserItemNotificationUPP) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc) ;
298#else
299 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc) ;
300#endif
5ca0d812 301 m_peer->SetCallbacks( &callbacks);
d058c153 302
facd6764 303 MacPostControlCreate(pos,size) ;
d058c153 304
dbfc5b97
SC
305 for ( int i = 0 ; i < n ; i++ )
306 {
307 Append( choices[i] ) ;
308 }
dbfc5b97 309
d058c153
SC
310 SetBestSize(size); // Needed because it is a wxControlWithItems
311
dbfc5b97
SC
312 return TRUE;
313}
e9576ca5
SC
314
315// ----------------------------------------------------------------------------
dbfc5b97 316// wxCheckListBox functions
e9576ca5
SC
317// ----------------------------------------------------------------------------
318
dbfc5b97
SC
319bool wxCheckListBox::IsChecked(size_t item) const
320{
321 wxCHECK_MSG( item < m_checks.GetCount(), FALSE,
322 _T("invalid index in wxCheckListBox::IsChecked") );
323
324 return m_checks[item] != 0;
325}
326
327void wxCheckListBox::Check(size_t item, bool check)
328{
329 wxCHECK_RET( item < m_checks.GetCount(),
330 _T("invalid index in wxCheckListBox::Check") );
331
dbfc5b97
SC
332 bool isChecked = m_checks[item] != 0;
333 if ( check != isChecked )
334 {
335 m_checks[item] = check;
683e36bc 336 UInt32 id = item + 1 ;
5ca0d812 337 verify_noerr( m_peer->UpdateItems(kDataBrowserNoItem , 1 , &id , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ;
dbfc5b97
SC
338 }
339}
340
341// ----------------------------------------------------------------------------
d058c153 342// methods forwarded to wxCheckListBox
dbfc5b97
SC
343// ----------------------------------------------------------------------------
344
345void wxCheckListBox::Delete(int n)
346{
d058c153 347 wxCHECK_RET( n < GetCount(), _T("invalid index in wxCheckListBox::Delete") );
e9576ca5 348
dbfc5b97 349 wxListBox::Delete(n);
e9576ca5 350
dbfc5b97
SC
351 m_checks.RemoveAt(n);
352}
353
354int wxCheckListBox::DoAppend(const wxString& item)
e9576ca5 355{
dbfc5b97
SC
356 int pos = wxListBox::DoAppend(item);
357
358 // the item is initially unchecked
359 m_checks.Insert(FALSE, pos);
360
361 return pos;
e9576ca5
SC
362}
363
dbfc5b97 364void wxCheckListBox::DoInsertItems(const wxArrayString& items, int pos)
e9576ca5 365{
dbfc5b97
SC
366 wxListBox::DoInsertItems(items, pos);
367
368 size_t count = items.GetCount();
369 for ( size_t n = 0; n < count; n++ )
370 {
371 m_checks.Insert(FALSE, pos + n);
372 }
e9576ca5
SC
373}
374
dbfc5b97
SC
375void wxCheckListBox::DoSetItems(const wxArrayString& items, void **clientData)
376{
377 // call it first as it does DoClear()
378 wxListBox::DoSetItems(items, clientData);
379
380 size_t count = items.GetCount();
381 for ( size_t n = 0; n < count; n++ )
382 {
383 m_checks.Add(FALSE);
384 }
385}
e9576ca5 386
dbfc5b97 387void wxCheckListBox::DoClear()
e9576ca5 388{
dbfc5b97 389 m_checks.Empty();
e9576ca5
SC
390}
391
dbfc5b97 392#endif // wxUSE_CHECKLISTBOX