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 wxPostEvent( list
->GetEventHandler() , event
) ;
110 // direct notification is not always having the listbox GetSelection() having in synch with event
111 // list->GetEventHandler()->ProcessEvent(event) ;
120 static pascal OSStatus
ListBoxGetSetItemData(ControlRef browser
,
121 DataBrowserItemID itemID
, DataBrowserPropertyID property
,
122 DataBrowserItemDataRef itemData
, Boolean changeValue
)
124 OSStatus err
= errDataBrowserPropertyNotSupported
;
133 long ref
= GetControlReference( browser
) ;
136 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
137 for ( size_t i
= 0 ; i
< list
->m_idArray
.GetCount() ; ++i
)
138 if ( list
->m_idArray
[i
] == (long) itemID
)
140 wxMacCFStringHolder
cf( list
->GetString(i
) , list
->GetFont().GetEncoding() ) ;
141 verify_noerr( ::SetDataBrowserItemDataText( itemData
, cf
) ) ;
148 case kCheckboxColumnId
:
150 long ref
= GetControlReference( browser
) ;
153 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
154 for ( size_t i
= 0 ; i
< list
->m_idArray
.GetCount() ; ++i
)
155 if ( list
->m_idArray
[i
] == (long) itemID
)
157 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData
, list
->IsChecked( i
) ? kThemeButtonOn
: kThemeButtonOff
) ) ;
164 case kDataBrowserItemIsEditableProperty
:
166 err
= ::SetDataBrowserItemDataBooleanValue(itemData
, true);
178 case kCheckboxColumnId
:
180 long ref
= GetControlReference( browser
) ;
183 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
184 for ( size_t i
= 0 ; i
< list
->m_idArray
.GetCount() ; ++i
)
185 if ( list
->m_idArray
[i
] == (long) itemID
)
187 // we have to change this behind the back, since Check() would be triggering another update round
188 bool newVal
= !list
->IsChecked( i
) ;
189 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData
, newVal
? kThemeButtonOn
: kThemeButtonOff
) ) ;
191 list
->m_checks
[ i
] = newVal
;
193 wxCommandEvent
event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
, list
->GetId());
195 event
.SetEventObject(list
);
196 list
->GetEventHandler()->ProcessEvent(event
);
212 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
215 int n
, const wxString choices
[],
217 const wxValidator
& validator
,
218 const wxString
& name
)
220 m_macIsUserPane
= FALSE
;
222 wxASSERT_MSG( !(style
& wxLB_MULTIPLE
) || !(style
& wxLB_EXTENDED
),
223 _T("only one of listbox selection modes can be specified") );
225 if ( !wxListBoxBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
228 m_noItems
= 0 ; // this will be increased by our append command
233 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
236 verify_noerr( ::CreateDataBrowserControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, kDataBrowserListView
, (ControlRef
*)&m_macControl
) );
237 browser
= (ControlRef
) m_macControl
;
239 DataBrowserSelectionFlags options
= kDataBrowserDragSelect
;
240 if ( style
& wxLB_MULTIPLE
)
242 options
+= kDataBrowserAlwaysExtendSelection
+ kDataBrowserCmdTogglesSelection
;
244 else if ( style
& wxLB_EXTENDED
)
250 options
+= kDataBrowserSelectOnlyOne
;
252 verify_noerr(SetDataBrowserSelectionFlags (browser
, options
) );
254 DataBrowserListViewColumnDesc columnDesc
;
255 columnDesc
.headerBtnDesc
.titleOffset
= 0;
256 columnDesc
.headerBtnDesc
.version
= kDataBrowserListViewLatestHeaderDesc
;
258 columnDesc
.headerBtnDesc
.btnFontStyle
.flags
=
259 kControlUseFontMask
| kControlUseJustMask
;
261 columnDesc
.headerBtnDesc
.btnContentInfo
.contentType
= kControlNoContent
;
262 columnDesc
.headerBtnDesc
.btnFontStyle
.just
= teFlushDefault
;
263 columnDesc
.headerBtnDesc
.btnFontStyle
.font
= kControlFontViewSystemFont
;
264 columnDesc
.headerBtnDesc
.btnFontStyle
.style
= normal
;
265 columnDesc
.headerBtnDesc
.titleString
= NULL
; // CFSTR( "" );
269 columnDesc
.headerBtnDesc
.minimumWidth
= 30 ;
270 columnDesc
.headerBtnDesc
.maximumWidth
= 30;
272 columnDesc
.propertyDesc
.propertyID
= kCheckboxColumnId
;
273 columnDesc
.propertyDesc
.propertyType
= kDataBrowserCheckboxType
;
274 columnDesc
.propertyDesc
.propertyFlags
= kDataBrowserPropertyIsMutable
| kDataBrowserTableViewSelectionColumn
|
275 kDataBrowserDefaultPropertyFlags
;
276 verify_noerr(::AddDataBrowserListViewColumn(browser
, &columnDesc
, kDataBrowserListViewAppendColumn
) ) ;
280 columnDesc
.headerBtnDesc
.minimumWidth
= 0;
281 columnDesc
.headerBtnDesc
.maximumWidth
= 10000;
283 columnDesc
.propertyDesc
.propertyID
= kTextColumnId
;
284 columnDesc
.propertyDesc
.propertyType
= kDataBrowserTextType
;
285 columnDesc
.propertyDesc
.propertyFlags
= kDataBrowserTableViewSelectionColumn
286 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
287 | kDataBrowserListViewTypeSelectColumn
292 verify_noerr(::AddDataBrowserListViewColumn(browser
, &columnDesc
, kDataBrowserListViewAppendColumn
) ) ;
294 verify_noerr(::AutoSizeDataBrowserListViewColumns( browser
) ) ;
295 verify_noerr(::SetDataBrowserHasScrollBars( browser
, false , true ) ) ;
296 verify_noerr(::SetDataBrowserTableViewHiliteStyle( browser
, kDataBrowserTableViewFillHilite
) ) ;
297 verify_noerr(::SetDataBrowserListViewHeaderBtnHeight( browser
, 0 ) ) ;
299 DataBrowserCallbacks callbacks
;
300 callbacks
.version
= kDataBrowserLatestCallbacks
;
301 InitDataBrowserCallbacks(&callbacks
);
302 callbacks
.u
.v1
.itemDataCallback
= NewDataBrowserItemDataUPP(ListBoxGetSetItemData
);
303 callbacks
.u
.v1
.itemNotificationCallback
=
304 #if TARGET_API_MAC_OSX
305 (DataBrowserItemNotificationUPP
) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc
) ;
307 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc
) ;
309 SetDataBrowserCallbacks(browser
, &callbacks
);
311 MacPostControlCreate(pos
,size
) ;
313 for ( int i
= 0 ; i
< n
; i
++ )
315 Append( choices
[i
] ) ;
318 SetBestSize(size
); // Needed because it is a wxControlWithItems
323 // ----------------------------------------------------------------------------
324 // wxCheckListBox functions
325 // ----------------------------------------------------------------------------
327 bool wxCheckListBox::IsChecked(size_t item
) const
329 wxCHECK_MSG( item
< m_checks
.GetCount(), FALSE
,
330 _T("invalid index in wxCheckListBox::IsChecked") );
332 return m_checks
[item
] != 0;
335 void wxCheckListBox::Check(size_t item
, bool check
)
337 wxCHECK_RET( item
< m_checks
.GetCount(),
338 _T("invalid index in wxCheckListBox::Check") );
340 // intermediate var is needed to avoid compiler warning with VC++
341 bool isChecked
= m_checks
[item
] != 0;
342 if ( check
!= isChecked
)
344 m_checks
[item
] = check
;
345 UInt32 id
= m_idArray
[item
] ;
346 verify_noerr( ::UpdateDataBrowserItems( (ControlRef
) m_macControl
, kDataBrowserNoItem
, 1 , &id
, kDataBrowserItemNoProperty
, kDataBrowserItemNoProperty
) ) ;
350 // ----------------------------------------------------------------------------
351 // methods forwarded to wxCheckListBox
352 // ----------------------------------------------------------------------------
354 void wxCheckListBox::Delete(int n
)
356 wxCHECK_RET( n
< GetCount(), _T("invalid index in wxCheckListBox::Delete") );
358 wxListBox::Delete(n
);
360 m_checks
.RemoveAt(n
);
363 int wxCheckListBox::DoAppend(const wxString
& item
)
365 int pos
= wxListBox::DoAppend(item
);
367 // the item is initially unchecked
368 m_checks
.Insert(FALSE
, pos
);
373 void wxCheckListBox::DoInsertItems(const wxArrayString
& items
, int pos
)
375 wxListBox::DoInsertItems(items
, pos
);
377 size_t count
= items
.GetCount();
378 for ( size_t n
= 0; n
< count
; n
++ )
380 m_checks
.Insert(FALSE
, pos
+ n
);
384 void wxCheckListBox::DoSetItems(const wxArrayString
& items
, void **clientData
)
386 // call it first as it does DoClear()
387 wxListBox::DoSetItems(items
, clientData
);
389 size_t count
= items
.GetCount();
390 for ( size_t n
= 0; n
< count
; n
++ )
396 void wxCheckListBox::DoClear()
401 #endif // wxUSE_CHECKLISTBOX