1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: implementation of wxCheckListBox class
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
13 // headers & declarations
14 // ============================================================================
16 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
17 #pragma implementation "checklst.h"
20 #include "wx/wxprec.h"
22 #if wxUSE_CHECKLISTBOX
24 #include "wx/checklst.h"
25 #include "wx/arrstr.h"
27 #include "wx/mac/uma.h"
28 #include <Appearance.h>
30 // ============================================================================
31 // implementation of wxCheckListBox
32 // ============================================================================
34 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox
, wxListBox
)
36 BEGIN_EVENT_TABLE(wxCheckListBox
, wxListBox
)
39 const short kTextColumnId
= 1024 ;
40 const short kCheckboxColumnId
= 1025 ;
42 // new databrowser based version
45 void wxCheckListBox::Init()
49 bool wxCheckListBox::Create(wxWindow
*parent
,
53 const wxArrayString
& choices
,
55 const wxValidator
& validator
,
58 wxCArrayString
chs(choices
);
60 return Create(parent
, id
, pos
, size
, chs
.GetCount(), chs
.GetStrings(),
61 style
, validator
, name
);
64 #if TARGET_API_MAC_OSX
65 static pascal void DataBrowserItemNotificationProc(ControlRef browser
, DataBrowserItemID itemID
,
66 DataBrowserItemNotification message
, DataBrowserItemDataRef itemData
)
68 static pascal void DataBrowserItemNotificationProc(ControlRef browser
, DataBrowserItemID itemID
,
69 DataBrowserItemNotification message
)
72 long ref
= GetControlReference( browser
) ;
75 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
77 if (i
>= 0 && i
< list
->GetCount() )
79 bool trigger
= false ;
81 wxEVT_COMMAND_LISTBOX_SELECTED
, list
->GetId() );
84 case kDataBrowserItemDeselected
:
85 if ( list
->HasMultipleSelection() )
88 case kDataBrowserItemSelected
:
91 case kDataBrowserItemDoubleClicked
:
92 event
.SetEventType(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
) ;
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
) );
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) ;
118 static pascal OSStatus
ListBoxGetSetItemData(ControlRef browser
,
119 DataBrowserItemID itemID
, DataBrowserPropertyID property
,
120 DataBrowserItemDataRef itemData
, Boolean changeValue
)
122 OSStatus err
= errDataBrowserPropertyNotSupported
;
131 long ref
= GetControlReference( browser
) ;
134 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
136 if (i
>= 0 && i
< list
->GetCount() )
138 wxMacCFStringHolder
cf( list
->GetString(i
) , list
->GetFont().GetEncoding() ) ;
139 verify_noerr( ::SetDataBrowserItemDataText( itemData
, cf
) ) ;
145 case kCheckboxColumnId
:
147 long ref
= GetControlReference( browser
) ;
150 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
152 if (i
>= 0 && i
< list
->GetCount() )
154 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData
, list
->IsChecked( i
) ? kThemeButtonOn
: kThemeButtonOff
) ) ;
160 case kDataBrowserItemIsEditableProperty
:
162 err
= ::SetDataBrowserItemDataBooleanValue(itemData
, true);
174 case kCheckboxColumnId
:
176 long ref
= GetControlReference( browser
) ;
179 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
181 if (i
>= 0 && i
< list
->GetCount() )
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
) ) ;
187 list
->m_checks
[ i
] = newVal
;
189 wxCommandEvent
event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
, list
->GetId());
191 event
.SetEventObject(list
);
192 list
->GetEventHandler()->ProcessEvent(event
);
206 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
209 int n
, const wxString choices
[],
211 const wxValidator
& validator
,
212 const wxString
& name
)
214 m_macIsUserPane
= FALSE
;
216 wxASSERT_MSG( !(style
& wxLB_MULTIPLE
) || !(style
& wxLB_EXTENDED
),
217 _T("only one of listbox selection modes can be specified") );
219 if ( !wxListBoxBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
222 m_noItems
= 0 ; // this will be increased by our append command
225 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
227 m_peer
= new wxMacControl() ;
228 verify_noerr( ::CreateDataBrowserControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, kDataBrowserListView
, m_peer
->GetControlRefAddr() ) );
231 DataBrowserSelectionFlags options
= kDataBrowserDragSelect
;
232 if ( style
& wxLB_MULTIPLE
)
234 options
+= kDataBrowserAlwaysExtendSelection
+ kDataBrowserCmdTogglesSelection
;
236 else if ( style
& wxLB_EXTENDED
)
242 options
+= kDataBrowserSelectOnlyOne
;
244 verify_noerr(m_peer
->SetSelectionFlags( options
) );
246 DataBrowserListViewColumnDesc columnDesc
;
247 columnDesc
.headerBtnDesc
.titleOffset
= 0;
248 columnDesc
.headerBtnDesc
.version
= kDataBrowserListViewLatestHeaderDesc
;
250 columnDesc
.headerBtnDesc
.btnFontStyle
.flags
=
251 kControlUseFontMask
| kControlUseJustMask
;
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( "" );
261 columnDesc
.headerBtnDesc
.minimumWidth
= 30 ;
262 columnDesc
.headerBtnDesc
.maximumWidth
= 30;
264 columnDesc
.propertyDesc
.propertyID
= kCheckboxColumnId
;
265 columnDesc
.propertyDesc
.propertyType
= kDataBrowserCheckboxType
;
266 columnDesc
.propertyDesc
.propertyFlags
= kDataBrowserPropertyIsMutable
| kDataBrowserTableViewSelectionColumn
|
267 kDataBrowserDefaultPropertyFlags
;
268 verify_noerr( m_peer
->AddListViewColumn( &columnDesc
, kDataBrowserListViewAppendColumn
) ) ;
272 columnDesc
.headerBtnDesc
.minimumWidth
= 0;
273 columnDesc
.headerBtnDesc
.maximumWidth
= 10000;
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
284 verify_noerr( m_peer
->AddListViewColumn( &columnDesc
, kDataBrowserListViewAppendColumn
) ) ;
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 ) ) ;
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
) ;
299 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc
) ;
301 m_peer
->SetCallbacks( &callbacks
);
303 MacPostControlCreate(pos
,size
) ;
305 for ( int i
= 0 ; i
< n
; i
++ )
307 Append( choices
[i
] ) ;
310 SetBestSize(size
); // Needed because it is a wxControlWithItems
315 // ----------------------------------------------------------------------------
316 // wxCheckListBox functions
317 // ----------------------------------------------------------------------------
319 bool wxCheckListBox::IsChecked(size_t item
) const
321 wxCHECK_MSG( item
< m_checks
.GetCount(), FALSE
,
322 _T("invalid index in wxCheckListBox::IsChecked") );
324 return m_checks
[item
] != 0;
327 void wxCheckListBox::Check(size_t item
, bool check
)
329 wxCHECK_RET( item
< m_checks
.GetCount(),
330 _T("invalid index in wxCheckListBox::Check") );
332 bool isChecked
= m_checks
[item
] != 0;
333 if ( check
!= isChecked
)
335 m_checks
[item
] = check
;
336 UInt32 id
= item
+ 1 ;
337 verify_noerr( m_peer
->UpdateItems(kDataBrowserNoItem
, 1 , &id
, kDataBrowserItemNoProperty
, kDataBrowserItemNoProperty
) ) ;
341 // ----------------------------------------------------------------------------
342 // methods forwarded to wxCheckListBox
343 // ----------------------------------------------------------------------------
345 void wxCheckListBox::Delete(int n
)
347 wxCHECK_RET( n
< GetCount(), _T("invalid index in wxCheckListBox::Delete") );
349 wxListBox::Delete(n
);
351 m_checks
.RemoveAt(n
);
354 int wxCheckListBox::DoAppend(const wxString
& item
)
356 int pos
= wxListBox::DoAppend(item
);
358 // the item is initially unchecked
359 m_checks
.Insert(FALSE
, pos
);
364 void wxCheckListBox::DoInsertItems(const wxArrayString
& items
, int pos
)
366 wxListBox::DoInsertItems(items
, pos
);
368 size_t count
= items
.GetCount();
369 for ( size_t n
= 0; n
< count
; n
++ )
371 m_checks
.Insert(FALSE
, pos
+ n
);
375 void wxCheckListBox::DoSetItems(const wxArrayString
& items
, void **clientData
)
377 // call it first as it does DoClear()
378 wxListBox::DoSetItems(items
, clientData
);
380 size_t count
= items
.GetCount();
381 for ( size_t n
= 0; n
< count
; n
++ )
387 void wxCheckListBox::DoClear()
392 #endif // wxUSE_CHECKLISTBOX