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 // ============================================================================
17 #pragma implementation "checklst.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
) ;
76 for ( size_t i
= 0 ; i
< list
->m_idArray
.GetCount() ; ++i
)
77 if ( list
->m_idArray
[i
] == (long) itemID
)
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 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
) ;
135 for ( size_t i
= 0 ; i
< list
->m_idArray
.GetCount() ; ++i
)
136 if ( list
->m_idArray
[i
] == (long) itemID
)
138 wxMacCFStringHolder
cf( list
->GetString(i
) , list
->GetFont().GetEncoding() ) ;
139 verify_noerr( ::SetDataBrowserItemDataText( itemData
, cf
) ) ;
146 case kCheckboxColumnId
:
148 long ref
= GetControlReference( browser
) ;
151 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
152 for ( size_t i
= 0 ; i
< list
->m_idArray
.GetCount() ; ++i
)
153 if ( list
->m_idArray
[i
] == (long) itemID
)
155 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData
, list
->IsChecked( i
) ? kThemeButtonOn
: kThemeButtonOff
) ) ;
162 case kDataBrowserItemIsEditableProperty
:
164 err
= ::SetDataBrowserItemDataBooleanValue(itemData
, true);
176 case kCheckboxColumnId
:
178 long ref
= GetControlReference( browser
) ;
181 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
182 for ( size_t i
= 0 ; i
< list
->m_idArray
.GetCount() ; ++i
)
183 if ( list
->m_idArray
[i
] == (long) itemID
)
185 // we have to change this behind the back, since Check() would be triggering another update round
186 bool newVal
= !list
->IsChecked( i
) ;
187 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData
, newVal
? kThemeButtonOn
: kThemeButtonOff
) ) ;
189 list
->m_checks
[ i
] = newVal
;
191 wxCommandEvent
event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
, list
->GetId());
193 event
.SetEventObject(list
);
194 list
->GetEventHandler()->ProcessEvent(event
);
210 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
213 int n
, const wxString choices
[],
215 const wxValidator
& validator
,
216 const wxString
& name
)
218 m_macIsUserPane
= FALSE
;
220 wxASSERT_MSG( !(style
& wxLB_MULTIPLE
) || !(style
& wxLB_EXTENDED
),
221 _T("only one of listbox selection modes can be specified") );
223 if ( !wxListBoxBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
226 m_noItems
= 0 ; // this will be increased by our append command
231 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
234 verify_noerr( ::CreateDataBrowserControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, kDataBrowserListView
, (ControlRef
*)&m_macControl
) );
235 browser
= (ControlRef
) m_macControl
;
237 DataBrowserSelectionFlags options
= kDataBrowserDragSelect
;
238 if ( style
& wxLB_MULTIPLE
)
240 options
+= kDataBrowserAlwaysExtendSelection
+ kDataBrowserCmdTogglesSelection
;
242 else if ( style
& wxLB_EXTENDED
)
248 options
+= kDataBrowserSelectOnlyOne
;
250 verify_noerr(SetDataBrowserSelectionFlags (browser
, options
) );
252 DataBrowserListViewColumnDesc columnDesc
;
253 columnDesc
.headerBtnDesc
.titleOffset
= 0;
254 columnDesc
.headerBtnDesc
.version
= kDataBrowserListViewLatestHeaderDesc
;
256 columnDesc
.headerBtnDesc
.btnFontStyle
.flags
=
257 kControlUseFontMask
| kControlUseJustMask
;
259 columnDesc
.headerBtnDesc
.btnContentInfo
.contentType
= kControlNoContent
;
260 columnDesc
.headerBtnDesc
.btnFontStyle
.just
= teFlushDefault
;
261 columnDesc
.headerBtnDesc
.btnFontStyle
.font
= kControlFontViewSystemFont
;
262 columnDesc
.headerBtnDesc
.btnFontStyle
.style
= normal
;
263 columnDesc
.headerBtnDesc
.titleString
= NULL
; // CFSTR( "" );
267 columnDesc
.headerBtnDesc
.minimumWidth
= 30 ;
268 columnDesc
.headerBtnDesc
.maximumWidth
= 30;
270 columnDesc
.propertyDesc
.propertyID
= kCheckboxColumnId
;
271 columnDesc
.propertyDesc
.propertyType
= kDataBrowserCheckboxType
;
272 columnDesc
.propertyDesc
.propertyFlags
= kDataBrowserPropertyIsMutable
| kDataBrowserTableViewSelectionColumn
|
273 kDataBrowserDefaultPropertyFlags
;
274 verify_noerr(::AddDataBrowserListViewColumn(browser
, &columnDesc
, kDataBrowserListViewAppendColumn
) ) ;
278 columnDesc
.headerBtnDesc
.minimumWidth
= 0;
279 columnDesc
.headerBtnDesc
.maximumWidth
= 10000;
281 columnDesc
.propertyDesc
.propertyID
= kTextColumnId
;
282 columnDesc
.propertyDesc
.propertyType
= kDataBrowserTextType
;
283 columnDesc
.propertyDesc
.propertyFlags
= kDataBrowserTableViewSelectionColumn
284 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
285 | kDataBrowserListViewTypeSelectColumn
290 verify_noerr(::AddDataBrowserListViewColumn(browser
, &columnDesc
, kDataBrowserListViewAppendColumn
) ) ;
292 verify_noerr(::AutoSizeDataBrowserListViewColumns( browser
) ) ;
293 verify_noerr(::SetDataBrowserHasScrollBars( browser
, false , true ) ) ;
294 verify_noerr(::SetDataBrowserTableViewHiliteStyle( browser
, kDataBrowserTableViewFillHilite
) ) ;
295 verify_noerr(::SetDataBrowserListViewHeaderBtnHeight( browser
, 0 ) ) ;
297 DataBrowserCallbacks callbacks
;
298 callbacks
.version
= kDataBrowserLatestCallbacks
;
299 InitDataBrowserCallbacks(&callbacks
);
300 callbacks
.u
.v1
.itemDataCallback
= NewDataBrowserItemDataUPP(ListBoxGetSetItemData
);
301 callbacks
.u
.v1
.itemNotificationCallback
=
302 #if TARGET_API_MAC_OSX
303 (DataBrowserItemNotificationUPP
) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc
) ;
305 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc
) ;
307 SetDataBrowserCallbacks(browser
, &callbacks
);
309 MacPostControlCreate(pos
,size
) ;
311 for ( int i
= 0 ; i
< n
; i
++ )
313 Append( choices
[i
] ) ;
316 SetBestSize(size
); // Needed because it is a wxControlWithItems
321 // ----------------------------------------------------------------------------
322 // wxCheckListBox functions
323 // ----------------------------------------------------------------------------
325 bool wxCheckListBox::IsChecked(size_t item
) const
327 wxCHECK_MSG( item
< m_checks
.GetCount(), FALSE
,
328 _T("invalid index in wxCheckListBox::IsChecked") );
330 return m_checks
[item
] != 0;
333 void wxCheckListBox::Check(size_t item
, bool check
)
335 wxCHECK_RET( item
< m_checks
.GetCount(),
336 _T("invalid index in wxCheckListBox::Check") );
338 // intermediate var is needed to avoid compiler warning with VC++
339 bool isChecked
= m_checks
[item
] != 0;
340 if ( check
!= isChecked
)
342 m_checks
[item
] = check
;
343 UInt32 id
= m_idArray
[item
] ;
344 verify_noerr( ::UpdateDataBrowserItems( (ControlRef
) m_macControl
, kDataBrowserNoItem
, 1 , &id
, kDataBrowserItemNoProperty
, kDataBrowserItemNoProperty
) ) ;
348 // ----------------------------------------------------------------------------
349 // methods forwarded to wxCheckListBox
350 // ----------------------------------------------------------------------------
352 void wxCheckListBox::Delete(int n
)
354 wxCHECK_RET( n
< GetCount(), _T("invalid index in wxCheckListBox::Delete") );
356 wxListBox::Delete(n
);
358 m_checks
.RemoveAt(n
);
361 int wxCheckListBox::DoAppend(const wxString
& item
)
363 int pos
= wxListBox::DoAppend(item
);
365 // the item is initially unchecked
366 m_checks
.Insert(FALSE
, pos
);
371 void wxCheckListBox::DoInsertItems(const wxArrayString
& items
, int pos
)
373 wxListBox::DoInsertItems(items
, pos
);
375 size_t count
= items
.GetCount();
376 for ( size_t n
= 0; n
< count
; n
++ )
378 m_checks
.Insert(FALSE
, pos
+ n
);
382 void wxCheckListBox::DoSetItems(const wxArrayString
& items
, void **clientData
)
384 // call it first as it does DoClear()
385 wxListBox::DoSetItems(items
, clientData
);
387 size_t count
= items
.GetCount();
388 for ( size_t n
= 0; n
< count
; n
++ )
394 void wxCheckListBox::DoClear()
399 #endif // wxUSE_CHECKLISTBOX