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 #include "wx/wxprec.h"
18 #if wxUSE_CHECKLISTBOX
20 #include "wx/checklst.h"
21 #include "wx/arrstr.h"
23 #include "wx/mac/uma.h"
25 #include <Appearance.h>
28 // ============================================================================
29 // implementation of wxCheckListBox
30 // ============================================================================
32 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox
, wxListBox
)
34 BEGIN_EVENT_TABLE(wxCheckListBox
, wxListBox
)
37 const short kTextColumnId
= 1024 ;
38 const short kCheckboxColumnId
= 1025 ;
40 // new databrowser based version
43 void wxCheckListBox::Init()
47 bool wxCheckListBox::Create(wxWindow
*parent
,
51 const wxArrayString
& choices
,
53 const wxValidator
& validator
,
56 wxCArrayString
chs(choices
);
58 return Create(parent
, id
, pos
, size
, chs
.GetCount(), chs
.GetStrings(),
59 style
, validator
, name
);
62 #if TARGET_API_MAC_OSX
63 static pascal void DataBrowserItemNotificationProc(ControlRef browser
, DataBrowserItemID itemID
,
64 DataBrowserItemNotification message
, DataBrowserItemDataRef itemData
)
66 static pascal void DataBrowserItemNotificationProc(ControlRef browser
, DataBrowserItemID itemID
,
67 DataBrowserItemNotification message
)
70 long ref
= GetControlReference( browser
) ;
73 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
75 if (i
>= 0 && i
< list
->GetCount() )
77 bool trigger
= false ;
79 wxEVT_COMMAND_LISTBOX_SELECTED
, list
->GetId() );
82 case kDataBrowserItemDeselected
:
83 if ( list
->HasMultipleSelection() )
86 case kDataBrowserItemSelected
:
89 case kDataBrowserItemDoubleClicked
:
90 event
.SetEventType(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
) ;
99 event
.SetEventObject( list
);
100 if ( list
->HasClientObjectData() )
101 event
.SetClientObject( list
->GetClientObject(i
) );
102 else if ( list
->HasClientUntypedData() )
103 event
.SetClientData( list
->GetClientData(i
) );
104 event
.SetString( list
->GetString(i
) );
106 event
.SetExtraLong( list
->HasMultipleSelection() ? message
== kDataBrowserItemSelected
: TRUE
);
107 wxPostEvent( list
->GetEventHandler() , event
) ;
108 // direct notification is not always having the listbox GetSelection() having in synch with event
109 // list->GetEventHandler()->ProcessEvent(event) ;
116 static pascal OSStatus
ListBoxGetSetItemData(ControlRef browser
,
117 DataBrowserItemID itemID
, DataBrowserPropertyID property
,
118 DataBrowserItemDataRef itemData
, Boolean changeValue
)
120 OSStatus err
= errDataBrowserPropertyNotSupported
;
129 long ref
= GetControlReference( browser
) ;
132 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
134 if (i
>= 0 && i
< list
->GetCount() )
136 wxMacCFStringHolder
cf( list
->GetString(i
) , list
->GetFont().GetEncoding() ) ;
137 verify_noerr( ::SetDataBrowserItemDataText( itemData
, cf
) ) ;
143 case kCheckboxColumnId
:
145 long ref
= GetControlReference( browser
) ;
148 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
150 if (i
>= 0 && i
< list
->GetCount() )
152 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData
, list
->IsChecked( i
) ? kThemeButtonOn
: kThemeButtonOff
) ) ;
158 case kDataBrowserItemIsEditableProperty
:
160 err
= ::SetDataBrowserItemDataBooleanValue(itemData
, true);
172 case kCheckboxColumnId
:
174 long ref
= GetControlReference( browser
) ;
177 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
179 if (i
>= 0 && i
< list
->GetCount() )
181 // we have to change this behind the back, since Check() would be triggering another update round
182 bool newVal
= !list
->IsChecked( i
) ;
183 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData
, newVal
? kThemeButtonOn
: kThemeButtonOff
) ) ;
185 list
->m_checks
[ i
] = newVal
;
187 wxCommandEvent
event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED
, list
->GetId());
189 event
.SetEventObject(list
);
190 list
->GetEventHandler()->ProcessEvent(event
);
204 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
207 int n
, const wxString choices
[],
209 const wxValidator
& validator
,
210 const wxString
& name
)
212 m_macIsUserPane
= false ;
214 wxASSERT_MSG( !(style
& wxLB_MULTIPLE
) || !(style
& wxLB_EXTENDED
),
215 _T("only one of listbox selection modes can be specified") );
217 if ( !wxListBoxBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
220 m_noItems
= 0 ; // this will be increased by our append command
223 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
225 m_peer
= new wxMacControl(this) ;
226 verify_noerr( ::CreateDataBrowserControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, kDataBrowserListView
, m_peer
->GetControlRefAddr() ) );
229 DataBrowserSelectionFlags options
= kDataBrowserDragSelect
;
230 if ( style
& wxLB_MULTIPLE
)
232 options
+= kDataBrowserAlwaysExtendSelection
+ kDataBrowserCmdTogglesSelection
;
234 else if ( style
& wxLB_EXTENDED
)
240 options
+= kDataBrowserSelectOnlyOne
;
242 verify_noerr(m_peer
->SetSelectionFlags( options
) );
244 DataBrowserListViewColumnDesc columnDesc
;
245 columnDesc
.headerBtnDesc
.titleOffset
= 0;
246 columnDesc
.headerBtnDesc
.version
= kDataBrowserListViewLatestHeaderDesc
;
248 columnDesc
.headerBtnDesc
.btnFontStyle
.flags
=
249 kControlUseFontMask
| kControlUseJustMask
;
251 columnDesc
.headerBtnDesc
.btnContentInfo
.contentType
= kControlNoContent
;
252 columnDesc
.headerBtnDesc
.btnFontStyle
.just
= teFlushDefault
;
253 columnDesc
.headerBtnDesc
.btnFontStyle
.font
= kControlFontViewSystemFont
;
254 columnDesc
.headerBtnDesc
.btnFontStyle
.style
= normal
;
255 columnDesc
.headerBtnDesc
.titleString
= NULL
; // CFSTR( "" );
259 columnDesc
.headerBtnDesc
.minimumWidth
= 30 ;
260 columnDesc
.headerBtnDesc
.maximumWidth
= 30;
262 columnDesc
.propertyDesc
.propertyID
= kCheckboxColumnId
;
263 columnDesc
.propertyDesc
.propertyType
= kDataBrowserCheckboxType
;
264 columnDesc
.propertyDesc
.propertyFlags
= kDataBrowserPropertyIsMutable
| kDataBrowserTableViewSelectionColumn
|
265 kDataBrowserDefaultPropertyFlags
;
266 verify_noerr( m_peer
->AddListViewColumn( &columnDesc
, kDataBrowserListViewAppendColumn
) ) ;
270 columnDesc
.headerBtnDesc
.minimumWidth
= 0;
271 columnDesc
.headerBtnDesc
.maximumWidth
= 10000;
273 columnDesc
.propertyDesc
.propertyID
= kTextColumnId
;
274 columnDesc
.propertyDesc
.propertyType
= kDataBrowserTextType
;
275 columnDesc
.propertyDesc
.propertyFlags
= kDataBrowserTableViewSelectionColumn
276 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
277 | kDataBrowserListViewTypeSelectColumn
282 verify_noerr( m_peer
->AddListViewColumn( &columnDesc
, kDataBrowserListViewAppendColumn
) ) ;
284 verify_noerr( m_peer
->AutoSizeListViewColumns() ) ;
285 verify_noerr( m_peer
->SetHasScrollBars( false , true ) ) ;
286 verify_noerr( m_peer
->SetTableViewHiliteStyle( kDataBrowserTableViewFillHilite
) ) ;
287 verify_noerr( m_peer
->SetListViewHeaderBtnHeight(0 ) ) ;
289 DataBrowserCallbacks callbacks
;
290 callbacks
.version
= kDataBrowserLatestCallbacks
;
291 InitDataBrowserCallbacks(&callbacks
);
292 callbacks
.u
.v1
.itemDataCallback
= NewDataBrowserItemDataUPP(ListBoxGetSetItemData
);
293 callbacks
.u
.v1
.itemNotificationCallback
=
294 #if TARGET_API_MAC_OSX
295 (DataBrowserItemNotificationUPP
) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc
) ;
297 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc
) ;
299 m_peer
->SetCallbacks( &callbacks
);
302 // shouldn't be necessary anymore under 10.2
303 m_peer
->SetData( kControlNoPart
, kControlDataBrowserIncludesFrameAndFocusTag
, (Boolean
) false ) ;
304 m_peer
->SetNeedsFocusRect( true ) ;
307 MacPostControlCreate(pos
,size
) ;
309 for ( int i
= 0 ; i
< n
; i
++ )
311 Append( choices
[i
] ) ;
314 SetBestSize(size
); // Needed because it is a wxControlWithItems
319 // ----------------------------------------------------------------------------
320 // wxCheckListBox functions
321 // ----------------------------------------------------------------------------
323 bool wxCheckListBox::IsChecked(size_t item
) const
325 wxCHECK_MSG( item
< m_checks
.GetCount(), false,
326 _T("invalid index in wxCheckListBox::IsChecked") );
328 return m_checks
[item
] != 0;
331 void wxCheckListBox::Check(size_t item
, bool check
)
333 wxCHECK_RET( item
< m_checks
.GetCount(),
334 _T("invalid index in wxCheckListBox::Check") );
336 bool isChecked
= m_checks
[item
] != 0;
337 if ( check
!= isChecked
)
339 m_checks
[item
] = check
;
340 UInt32 id
= item
+ 1 ;
341 verify_noerr( m_peer
->UpdateItems(kDataBrowserNoItem
, 1 , &id
, kDataBrowserItemNoProperty
, kDataBrowserItemNoProperty
) ) ;
345 // ----------------------------------------------------------------------------
346 // methods forwarded to wxCheckListBox
347 // ----------------------------------------------------------------------------
349 void wxCheckListBox::Delete(int n
)
351 wxCHECK_RET( n
< GetCount(), _T("invalid index in wxCheckListBox::Delete") );
353 wxListBox::Delete(n
);
355 m_checks
.RemoveAt(n
);
358 int wxCheckListBox::DoAppend(const wxString
& item
)
360 int pos
= wxListBox::DoAppend(item
);
362 // the item is initially unchecked
363 m_checks
.Insert(false, pos
);
368 void wxCheckListBox::DoInsertItems(const wxArrayString
& items
, int pos
)
370 wxListBox::DoInsertItems(items
, pos
);
372 size_t count
= items
.GetCount();
373 for ( size_t n
= 0; n
< count
; n
++ )
375 m_checks
.Insert(false, pos
+ n
);
379 void wxCheckListBox::DoSetItems(const wxArrayString
& items
, void **clientData
)
381 // call it first as it does DoClear()
382 wxListBox::DoSetItems(items
, clientData
);
384 size_t count
= items
.GetCount();
385 for ( size_t n
= 0; n
< count
; n
++ )
391 void wxCheckListBox::DoClear()
396 #endif // wxUSE_CHECKLISTBOX