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"
29 #include <Appearance.h>
32 // ============================================================================
33 // implementation of wxCheckListBox
34 // ============================================================================
36 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox
, wxListBox
)
38 BEGIN_EVENT_TABLE(wxCheckListBox
, wxListBox
)
41 const short kTextColumnId
= 1024 ;
42 const short kCheckboxColumnId
= 1025 ;
44 // new databrowser based version
47 void wxCheckListBox::Init()
51 bool wxCheckListBox::Create(wxWindow
*parent
,
55 const wxArrayString
& choices
,
57 const wxValidator
& validator
,
60 wxCArrayString
chs(choices
);
62 return Create(parent
, id
, pos
, size
, chs
.GetCount(), chs
.GetStrings(),
63 style
, validator
, name
);
66 #if TARGET_API_MAC_OSX
67 static pascal void DataBrowserItemNotificationProc(ControlRef browser
, DataBrowserItemID itemID
,
68 DataBrowserItemNotification message
, DataBrowserItemDataRef itemData
)
70 static pascal void DataBrowserItemNotificationProc(ControlRef browser
, DataBrowserItemID itemID
,
71 DataBrowserItemNotification message
)
74 long ref
= GetControlReference( browser
) ;
77 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
79 if (i
>= 0 && i
< list
->GetCount() )
81 bool trigger
= false ;
83 wxEVT_COMMAND_LISTBOX_SELECTED
, list
->GetId() );
86 case kDataBrowserItemDeselected
:
87 if ( list
->HasMultipleSelection() )
90 case kDataBrowserItemSelected
:
93 case kDataBrowserItemDoubleClicked
:
94 event
.SetEventType(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
) ;
103 event
.SetEventObject( list
);
104 if ( list
->HasClientObjectData() )
105 event
.SetClientObject( list
->GetClientObject(i
) );
106 else if ( list
->HasClientUntypedData() )
107 event
.SetClientData( list
->GetClientData(i
) );
108 event
.SetString( list
->GetString(i
) );
110 event
.SetExtraLong( list
->HasMultipleSelection() ? message
== kDataBrowserItemSelected
: TRUE
);
111 wxPostEvent( list
->GetEventHandler() , event
) ;
112 // direct notification is not always having the listbox GetSelection() having in synch with event
113 // 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
) ;
138 if (i
>= 0 && i
< list
->GetCount() )
140 wxMacCFStringHolder
cf( list
->GetString(i
) , list
->GetFont().GetEncoding() ) ;
141 verify_noerr( ::SetDataBrowserItemDataText( itemData
, cf
) ) ;
147 case kCheckboxColumnId
:
149 long ref
= GetControlReference( browser
) ;
152 wxCheckListBox
* list
= wxDynamicCast( (wxObject
*) ref
, wxCheckListBox
) ;
154 if (i
>= 0 && i
< list
->GetCount() )
156 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
) ;
183 if (i
>= 0 && i
< list
->GetCount() )
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
);
208 bool wxCheckListBox::Create(wxWindow
*parent
, wxWindowID id
,
211 int n
, const wxString choices
[],
213 const wxValidator
& validator
,
214 const wxString
& name
)
216 m_macIsUserPane
= false ;
218 wxASSERT_MSG( !(style
& wxLB_MULTIPLE
) || !(style
& wxLB_EXTENDED
),
219 _T("only one of listbox selection modes can be specified") );
221 if ( !wxListBoxBase::Create(parent
, id
, pos
, size
, style
& ~(wxHSCROLL
|wxVSCROLL
), validator
, name
) )
224 m_noItems
= 0 ; // this will be increased by our append command
227 Rect bounds
= wxMacGetBoundsForControl( this , pos
, size
) ;
229 m_peer
= new wxMacControl(this) ;
230 verify_noerr( ::CreateDataBrowserControl( MAC_WXHWND(parent
->MacGetTopLevelWindowRef()), &bounds
, kDataBrowserListView
, m_peer
->GetControlRefAddr() ) );
233 DataBrowserSelectionFlags options
= kDataBrowserDragSelect
;
234 if ( style
& wxLB_MULTIPLE
)
236 options
+= kDataBrowserAlwaysExtendSelection
+ kDataBrowserCmdTogglesSelection
;
238 else if ( style
& wxLB_EXTENDED
)
244 options
+= kDataBrowserSelectOnlyOne
;
246 verify_noerr(m_peer
->SetSelectionFlags( options
) );
248 DataBrowserListViewColumnDesc columnDesc
;
249 columnDesc
.headerBtnDesc
.titleOffset
= 0;
250 columnDesc
.headerBtnDesc
.version
= kDataBrowserListViewLatestHeaderDesc
;
252 columnDesc
.headerBtnDesc
.btnFontStyle
.flags
=
253 kControlUseFontMask
| kControlUseJustMask
;
255 columnDesc
.headerBtnDesc
.btnContentInfo
.contentType
= kControlNoContent
;
256 columnDesc
.headerBtnDesc
.btnFontStyle
.just
= teFlushDefault
;
257 columnDesc
.headerBtnDesc
.btnFontStyle
.font
= kControlFontViewSystemFont
;
258 columnDesc
.headerBtnDesc
.btnFontStyle
.style
= normal
;
259 columnDesc
.headerBtnDesc
.titleString
= NULL
; // CFSTR( "" );
263 columnDesc
.headerBtnDesc
.minimumWidth
= 30 ;
264 columnDesc
.headerBtnDesc
.maximumWidth
= 30;
266 columnDesc
.propertyDesc
.propertyID
= kCheckboxColumnId
;
267 columnDesc
.propertyDesc
.propertyType
= kDataBrowserCheckboxType
;
268 columnDesc
.propertyDesc
.propertyFlags
= kDataBrowserPropertyIsMutable
| kDataBrowserTableViewSelectionColumn
|
269 kDataBrowserDefaultPropertyFlags
;
270 verify_noerr( m_peer
->AddListViewColumn( &columnDesc
, kDataBrowserListViewAppendColumn
) ) ;
274 columnDesc
.headerBtnDesc
.minimumWidth
= 0;
275 columnDesc
.headerBtnDesc
.maximumWidth
= 10000;
277 columnDesc
.propertyDesc
.propertyID
= kTextColumnId
;
278 columnDesc
.propertyDesc
.propertyType
= kDataBrowserTextType
;
279 columnDesc
.propertyDesc
.propertyFlags
= kDataBrowserTableViewSelectionColumn
280 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
281 | kDataBrowserListViewTypeSelectColumn
286 verify_noerr( m_peer
->AddListViewColumn( &columnDesc
, kDataBrowserListViewAppendColumn
) ) ;
288 verify_noerr( m_peer
->AutoSizeListViewColumns() ) ;
289 verify_noerr( m_peer
->SetHasScrollBars( false , true ) ) ;
290 verify_noerr( m_peer
->SetTableViewHiliteStyle( kDataBrowserTableViewFillHilite
) ) ;
291 verify_noerr( m_peer
->SetListViewHeaderBtnHeight(0 ) ) ;
293 DataBrowserCallbacks callbacks
;
294 callbacks
.version
= kDataBrowserLatestCallbacks
;
295 InitDataBrowserCallbacks(&callbacks
);
296 callbacks
.u
.v1
.itemDataCallback
= NewDataBrowserItemDataUPP(ListBoxGetSetItemData
);
297 callbacks
.u
.v1
.itemNotificationCallback
=
298 #if TARGET_API_MAC_OSX
299 (DataBrowserItemNotificationUPP
) NewDataBrowserItemNotificationWithItemUPP(DataBrowserItemNotificationProc
) ;
301 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc
) ;
303 m_peer
->SetCallbacks( &callbacks
);
306 // shouldn't be necessary anymore under 10.2
307 m_peer
->SetData( kControlNoPart
, kControlDataBrowserIncludesFrameAndFocusTag
, (Boolean
) false ) ;
308 m_peer
->SetNeedsFocusRect( true ) ;
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 bool isChecked
= m_checks
[item
] != 0;
341 if ( check
!= isChecked
)
343 m_checks
[item
] = check
;
344 UInt32 id
= item
+ 1 ;
345 verify_noerr( m_peer
->UpdateItems(kDataBrowserNoItem
, 1 , &id
, kDataBrowserItemNoProperty
, kDataBrowserItemNoProperty
) ) ;
349 // ----------------------------------------------------------------------------
350 // methods forwarded to wxCheckListBox
351 // ----------------------------------------------------------------------------
353 void wxCheckListBox::Delete(int n
)
355 wxCHECK_RET( n
< GetCount(), _T("invalid index in wxCheckListBox::Delete") );
357 wxListBox::Delete(n
);
359 m_checks
.RemoveAt(n
);
362 int wxCheckListBox::DoAppend(const wxString
& item
)
364 int pos
= wxListBox::DoAppend(item
);
366 // the item is initially unchecked
367 m_checks
.Insert(false, pos
);
372 void wxCheckListBox::DoInsertItems(const wxArrayString
& items
, int pos
)
374 wxListBox::DoInsertItems(items
, pos
);
376 size_t count
= items
.GetCount();
377 for ( size_t n
= 0; n
< count
; n
++ )
379 m_checks
.Insert(false, pos
+ n
);
383 void wxCheckListBox::DoSetItems(const wxArrayString
& items
, void **clientData
)
385 // call it first as it does DoClear()
386 wxListBox::DoSetItems(items
, clientData
);
388 size_t count
= items
.GetCount();
389 for ( size_t n
= 0; n
< count
; n
++ )
395 void wxCheckListBox::DoClear()
400 #endif // wxUSE_CHECKLISTBOX