]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/checklst.cpp
Use empty check consistent with other parts.
[wxWidgets.git] / src / mac / carbon / checklst.cpp
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: checklst.cpp
3// Purpose: implementation of wxCheckListBox class
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
7// RCS-ID: $Id$
8// Copyright: (c) Stefan Csomor
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// headers & declarations
14// ============================================================================
15
16#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
17#pragma implementation "checklst.h"
18#endif
19
20#include "wx/wxprec.h"
21
22#if wxUSE_CHECKLISTBOX
23
24#include "wx/checklst.h"
25#include "wx/arrstr.h"
26
27#include "wx/mac/uma.h"
28#include <Appearance.h>
29
30// ============================================================================
31// implementation of wxCheckListBox
32// ============================================================================
33
34IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxListBox)
35
36BEGIN_EVENT_TABLE(wxCheckListBox, wxListBox)
37END_EVENT_TABLE()
38
39const short kTextColumnId = 1024 ;
40const short kCheckboxColumnId = 1025 ;
41
42// new databrowser based version
43
44// Listbox item
45void wxCheckListBox::Init()
46{
47}
48
49bool wxCheckListBox::Create(wxWindow *parent,
50 wxWindowID id,
51 const wxPoint &pos,
52 const wxSize &size,
53 const wxArrayString& choices,
54 long style,
55 const wxValidator& validator,
56 const wxString &name)
57{
58 wxCArrayString chs(choices);
59
60 return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
61 style, validator, name);
62}
63
64#if TARGET_API_MAC_OSX
65static pascal void DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID,
66 DataBrowserItemNotification message, DataBrowserItemDataRef itemData)
67#else
68static pascal void DataBrowserItemNotificationProc(ControlRef browser, DataBrowserItemID itemID,
69 DataBrowserItemNotification message)
70#endif
71{
72 long ref = GetControlReference( browser ) ;
73 if ( ref )
74 {
75 wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
76 int i = itemID - 1 ;
77 if (i >= 0 && i < list->GetCount() )
78 {
79 bool trigger = false ;
80 wxCommandEvent event(
81 wxEVT_COMMAND_LISTBOX_SELECTED, list->GetId() );
82 switch( message )
83 {
84 case kDataBrowserItemDeselected :
85 if ( list->HasMultipleSelection() )
86 trigger = true ;
87 break ;
88 case kDataBrowserItemSelected :
89 trigger = true ;
90 break ;
91 case kDataBrowserItemDoubleClicked :
92 event.SetEventType(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED) ;
93 trigger = true ;
94 break ;
95 default :
96 break ;
97 }
98
99 if ( trigger )
100 {
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) );
107 event.SetInt(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) ;
112 }
113 }
114 }
115}
116
117
118static pascal OSStatus ListBoxGetSetItemData(ControlRef browser,
119 DataBrowserItemID itemID, DataBrowserPropertyID property,
120 DataBrowserItemDataRef itemData, Boolean changeValue)
121{
122 OSStatus err = errDataBrowserPropertyNotSupported;
123
124 if ( ! changeValue )
125 {
126 switch (property)
127 {
128
129 case kTextColumnId:
130 {
131 long ref = GetControlReference( browser ) ;
132 if ( ref )
133 {
134 wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
135 int i = itemID - 1 ;
136 if (i >= 0 && i < list->GetCount() )
137 {
138 wxMacCFStringHolder cf( list->GetString(i) , list->GetFont().GetEncoding() ) ;
139 verify_noerr( ::SetDataBrowserItemDataText( itemData , cf ) ) ;
140 err = noErr ;
141 }
142 }
143 }
144 break;
145 case kCheckboxColumnId :
146 {
147 long ref = GetControlReference( browser ) ;
148 if ( ref )
149 {
150 wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
151 int i = itemID - 1 ;
152 if (i >= 0 && i < list->GetCount() )
153 {
154 verify_noerr( ::SetDataBrowserItemDataButtonValue( itemData , list->IsChecked( i ) ? kThemeButtonOn : kThemeButtonOff ) ) ;
155 err = noErr ;
156 }
157 }
158 }
159 break ;
160 case kDataBrowserItemIsEditableProperty:
161 {
162 err = ::SetDataBrowserItemDataBooleanValue(itemData, true);
163 }
164 break;
165
166 default:
167 break;
168 }
169 }
170 else
171 {
172 switch( property )
173 {
174 case kCheckboxColumnId :
175 {
176 long ref = GetControlReference( browser ) ;
177 if ( ref )
178 {
179 wxCheckListBox* list = wxDynamicCast( (wxObject*) ref , wxCheckListBox ) ;
180 int i = itemID - 1 ;
181 if (i >= 0 && i < list->GetCount() )
182 {
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 ) ) ;
186 err = noErr ;
187 list->m_checks[ i ] = newVal ;
188
189 wxCommandEvent event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, list->GetId());
190 event.SetInt(i);
191 event.SetEventObject(list);
192 list->GetEventHandler()->ProcessEvent(event);
193 }
194 }
195
196 }
197 break ;
198
199 default :
200 break ;
201 }
202 }
203
204 return err;
205}
206bool wxCheckListBox::Create(wxWindow *parent, wxWindowID id,
207 const wxPoint& pos,
208 const wxSize& size,
209 int n, const wxString choices[],
210 long style,
211 const wxValidator& validator,
212 const wxString& name)
213{
214 m_macIsUserPane = FALSE ;
215
216 wxASSERT_MSG( !(style & wxLB_MULTIPLE) || !(style & wxLB_EXTENDED),
217 _T("only one of listbox selection modes can be specified") );
218
219 if ( !wxListBoxBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) )
220 return false;
221
222 m_noItems = 0 ; // this will be increased by our append command
223 m_selected = 0;
224
225 Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ;
226
227 m_peer = new wxMacControl(this) ;
228 verify_noerr( ::CreateDataBrowserControl( MAC_WXHWND(parent->MacGetTopLevelWindowRef()), &bounds, kDataBrowserListView , m_peer->GetControlRefAddr() ) );
229
230
231 DataBrowserSelectionFlags options = kDataBrowserDragSelect ;
232 if ( style & wxLB_MULTIPLE )
233 {
234 options += kDataBrowserAlwaysExtendSelection + kDataBrowserCmdTogglesSelection ;
235 }
236 else if ( style & wxLB_EXTENDED )
237 {
238 // default behaviour
239 }
240 else
241 {
242 options += kDataBrowserSelectOnlyOne ;
243 }
244 verify_noerr(m_peer->SetSelectionFlags( options ) );
245
246 DataBrowserListViewColumnDesc columnDesc ;
247 columnDesc.headerBtnDesc.titleOffset = 0;
248 columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
249
250 columnDesc.headerBtnDesc.btnFontStyle.flags =
251 kControlUseFontMask | kControlUseJustMask;
252
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( "" );
258
259 // check column
260
261 columnDesc.headerBtnDesc.minimumWidth = 30 ;
262 columnDesc.headerBtnDesc.maximumWidth = 30;
263
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) ) ;
269
270 // text column
271
272 columnDesc.headerBtnDesc.minimumWidth = 0;
273 columnDesc.headerBtnDesc.maximumWidth = 10000;
274
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
280#endif
281 ;
282
283
284 verify_noerr( m_peer->AddListViewColumn( &columnDesc, kDataBrowserListViewAppendColumn) ) ;
285
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 ) ) ;
290
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) ;
298#else
299 NewDataBrowserItemNotificationUPP(DataBrowserItemNotificationProc) ;
300#endif
301 m_peer->SetCallbacks( &callbacks);
302
303#if 0
304 // shouldn't be necessary anymore under 10.2
305 m_peer->SetData( kControlNoPart, kControlDataBrowserIncludesFrameAndFocusTag, (Boolean) false ) ;
306 m_peer->SetNeedsFocusRect( true ) ;
307#endif
308
309 MacPostControlCreate(pos,size) ;
310
311 for ( int i = 0 ; i < n ; i++ )
312 {
313 Append( choices[i] ) ;
314 }
315
316 SetBestSize(size); // Needed because it is a wxControlWithItems
317
318 return TRUE;
319}
320
321// ----------------------------------------------------------------------------
322// wxCheckListBox functions
323// ----------------------------------------------------------------------------
324
325bool wxCheckListBox::IsChecked(size_t item) const
326{
327 wxCHECK_MSG( item < m_checks.GetCount(), FALSE,
328 _T("invalid index in wxCheckListBox::IsChecked") );
329
330 return m_checks[item] != 0;
331}
332
333void wxCheckListBox::Check(size_t item, bool check)
334{
335 wxCHECK_RET( item < m_checks.GetCount(),
336 _T("invalid index in wxCheckListBox::Check") );
337
338 bool isChecked = m_checks[item] != 0;
339 if ( check != isChecked )
340 {
341 m_checks[item] = check;
342 UInt32 id = item + 1 ;
343 verify_noerr( m_peer->UpdateItems(kDataBrowserNoItem , 1 , &id , kDataBrowserItemNoProperty , kDataBrowserItemNoProperty ) ) ;
344 }
345}
346
347// ----------------------------------------------------------------------------
348// methods forwarded to wxCheckListBox
349// ----------------------------------------------------------------------------
350
351void wxCheckListBox::Delete(int n)
352{
353 wxCHECK_RET( n < GetCount(), _T("invalid index in wxCheckListBox::Delete") );
354
355 wxListBox::Delete(n);
356
357 m_checks.RemoveAt(n);
358}
359
360int wxCheckListBox::DoAppend(const wxString& item)
361{
362 int pos = wxListBox::DoAppend(item);
363
364 // the item is initially unchecked
365 m_checks.Insert(FALSE, pos);
366
367 return pos;
368}
369
370void wxCheckListBox::DoInsertItems(const wxArrayString& items, int pos)
371{
372 wxListBox::DoInsertItems(items, pos);
373
374 size_t count = items.GetCount();
375 for ( size_t n = 0; n < count; n++ )
376 {
377 m_checks.Insert(FALSE, pos + n);
378 }
379}
380
381void wxCheckListBox::DoSetItems(const wxArrayString& items, void **clientData)
382{
383 // call it first as it does DoClear()
384 wxListBox::DoSetItems(items, clientData);
385
386 size_t count = items.GetCount();
387 for ( size_t n = 0; n < count; n++ )
388 {
389 m_checks.Add(FALSE);
390 }
391}
392
393void wxCheckListBox::DoClear()
394{
395 m_checks.Empty();
396}
397
398#endif // wxUSE_CHECKLISTBOX