1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/listbox.cpp
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
17 #include "wx/listbox.h"
18 #include "wx/button.h"
19 #include "wx/settings.h"
20 #include "wx/toplevel.h"
21 #include "wx/dynarray.h"
26 IMPLEMENT_DYNAMIC_CLASS(wxListBox
, wxControl
)
28 BEGIN_EVENT_TABLE(wxListBox
, wxControl
)
31 #include "wx/mac/uma.h"
32 #include "wx/dynarray.h"
33 #include "wx/arrstr.h"
35 // ============================================================================
36 // list box control implementation
37 // ============================================================================
39 wxListBox::wxListBox()
43 bool wxListBox::Create(
48 const wxArrayString
& choices
,
50 const wxValidator
& validator
,
51 const wxString
& name
)
53 wxCArrayString
chs(choices
);
56 parent
, id
, pos
, size
, chs
.GetCount(), chs
.GetStrings(),
57 style
, validator
, name
);
60 wxMacListControl
* wxListBox::GetPeer() const
62 return dynamic_cast<wxMacListControl
*>(m_peer
);
65 bool wxListBox::Create(
71 const wxString choices
[],
73 const wxValidator
& validator
,
74 const wxString
& name
)
76 m_macIsUserPane
= false;
78 wxASSERT_MSG( !(style
& wxLB_MULTIPLE
) || !(style
& wxLB_EXTENDED
),
79 wxT("only a single listbox selection mode can be specified") );
81 if ( !wxListBoxBase::Create( parent
, id
, pos
, size
, style
& ~(wxHSCROLL
| wxVSCROLL
), validator
, name
) )
84 wxMacDataBrowserListControl
* control
= new wxMacDataBrowserListControl( this, pos
, size
, style
);
85 control
->SetClientDataType( m_clientDataItemsType
);
88 MacPostControlCreate( pos
, size
);
90 InsertItems( n
, choices
, 0 );
92 // Needed because it is a wxControlWithItems
98 wxListBox::~wxListBox()
101 m_peer
->SetReference( 0 );
104 void wxListBox::FreeData()
106 GetPeer()->MacClear();
109 void wxListBox::DoSetFirstItem(int n
)
111 GetPeer()->MacScrollTo( n
);
114 void wxListBox::EnsureVisible(int n
)
116 GetPeer()->MacScrollTo( n
);
119 void wxListBox::Delete(unsigned int n
)
121 wxCHECK_RET( IsValid(n
), wxT("invalid index in wxListBox::Delete") );
123 GetPeer()->MacDelete( n
);
126 int wxListBox::DoAppend(const wxString
& item
)
128 InvalidateBestSize();
130 return GetPeer()->MacAppend( item
);
133 void wxListBox::DoSetItems(const wxArrayString
& choices
, void** clientData
)
137 unsigned int n
= choices
.GetCount();
139 for ( size_t i
= 0; i
< n
; ++i
)
143 Append( choices
[i
], clientData
[i
] );
146 Append( choices
[i
] );
151 int wxListBox::FindString(const wxString
& s
, bool bCase
) const
153 for ( size_t i
= 0; i
< GetCount(); ++ i
)
155 if (s
.IsSameAs( GetString( i
), bCase
) )
162 void wxListBox::Clear()
167 void wxListBox::DoSetSelection(int n
, bool select
)
169 wxCHECK_RET( n
== wxNOT_FOUND
|| IsValid(n
),
170 wxT("invalid index in wxListBox::SetSelection") );
172 if ( n
== wxNOT_FOUND
)
173 GetPeer()->MacDeselectAll();
175 GetPeer()->MacSetSelection( n
, select
);
178 bool wxListBox::IsSelected(int n
) const
180 wxCHECK_MSG( IsValid(n
), false, wxT("invalid index in wxListBox::Selected") );
182 return GetPeer()->MacIsSelected( n
);
185 void *wxListBox::DoGetItemClientData(unsigned int n
) const
187 wxCHECK_MSG( IsValid(n
), NULL
, wxT("invalid index in wxListBox::GetClientData"));
188 return GetPeer()->MacGetClientData( n
);
191 wxClientData
*wxListBox::DoGetItemClientObject(unsigned int n
) const
193 return (wxClientData
*)DoGetItemClientData( n
);
196 void wxListBox::DoSetItemClientData(unsigned int n
, void *clientData
)
198 wxCHECK_RET( IsValid(n
), wxT("invalid index in wxListBox::SetClientData") );
199 GetPeer()->MacSetClientData( n
, clientData
);
202 void wxListBox::DoSetItemClientObject(unsigned int n
, wxClientData
* clientData
)
204 DoSetItemClientData(n
, clientData
);
207 // Return number of selections and an array of selected integers
208 int wxListBox::GetSelections(wxArrayInt
& aSelections
) const
210 return GetPeer()->MacGetSelections( aSelections
);
213 // Get single selection, for single choice list items
214 int wxListBox::GetSelection() const
216 return GetPeer()->MacGetSelection();
219 // Find string for position
220 wxString
wxListBox::GetString(unsigned int n
) const
222 wxCHECK_MSG( IsValid(n
), wxEmptyString
, wxT("invalid index in wxListBox::GetString") );
223 return GetPeer()->MacGetString(n
);
226 void wxListBox::DoInsertItems(const wxArrayString
& items
, unsigned int pos
)
228 wxCHECK_RET( IsValidInsert(pos
), wxT("invalid index in wxListBox::InsertItems") );
230 InvalidateBestSize();
232 GetPeer()->MacInsert( pos
, items
);
235 void wxListBox::SetString(unsigned int n
, const wxString
& s
)
237 GetPeer()->MacSetString( n
, s
);
240 wxSize
wxListBox::DoGetBestSize() const
242 int lbWidth
= 100; // some defaults
247 wxMacPortStateHelper
st( UMAGetWindowPort( (WindowRef
)MacGetTopLevelWindowRef() ) );
249 // TODO: clean this up
252 ::TextFont( m_font
.MacGetFontNum() );
253 ::TextSize( m_font
.MacGetFontSize() );
254 ::TextFace( m_font
.MacGetFontStyle() );
258 ::TextFont( kFontIDMonaco
);
263 // Find the widest line
264 for (unsigned int i
= 0; i
< GetCount(); i
++)
266 wxString
str( GetString( i
) );
269 Point bounds
= {0, 0};
272 // NB: what if m_font.Ok() == false ???
273 ::GetThemeTextDimensions(
274 wxMacCFStringHolder( str
, m_font
.GetEncoding() ),
275 kThemeCurrentPortFont
,
282 wLine
= ::TextWidth( str
.c_str(), 0, str
.length() );
285 lbWidth
= wxMax( lbWidth
, wLine
);
288 // Add room for the scrollbar
289 lbWidth
+= wxSystemSettings::GetMetric( wxSYS_VSCROLL_X
);
291 // And just a bit more
293 int cx
= ::TextWidth( "X", 0, 1 );
296 // don't make the listbox too tall (limit height to around 10 items)
297 // but don't make it too small neither
298 lbHeight
= wxMax( (cy
+ 4) * wxMin( wxMax( GetCount(), 3 ), 10 ), 70 );
301 return wxSize( lbWidth
, lbHeight
);
304 unsigned int wxListBox::GetCount() const
306 return GetPeer()->MacGetCount();
309 void wxListBox::Refresh(bool eraseBack
, const wxRect
*rect
)
311 wxControl::Refresh( eraseBack
, rect
);
314 // Some custom controls depend on this
315 /* static */ wxVisualAttributes
316 wxListBox::GetClassDefaultAttributes(wxWindowVariant
WXUNUSED(variant
))
318 wxVisualAttributes attr
;
320 attr
.colFg
= wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT
);
321 attr
.colBg
= wxSystemSettings::GetColour( wxSYS_COLOUR_LISTBOX
);
322 attr
.font
= wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT
);
327 int wxListBox::DoListHitTest(const wxPoint
& inpoint
) const
331 // There are few reasons why this is complicated:
332 // 1) There is no native HitTest function for Mac
333 // 2) GetDataBrowserItemPartBounds only works on visible items
334 // 3) We can't do it through GetDataBrowserTableView[Item]RowHeight
335 // because what it returns is basically inaccurate in the context
336 // of the coordinates we want here, but we use this as a guess
337 // for where the first visible item lies
339 wxPoint point
= inpoint
;
341 // interestingly enough 10.2 (and below?) have GetDataBrowserItemPartBounds
342 // giving root window coordinates but 10.3 and above give client coordinates
343 // so we only compare using root window coordinates on 10.3 and up
344 if ( UMAGetSystemVersion() < 0x1030 )
345 MacClientToRootWindow(&point
.x
, &point
.y
);
347 // get column property ID (req. for call to itempartbounds)
348 DataBrowserTableViewColumnID colId
= 0;
349 err
= GetDataBrowserTableViewColumnProperty(m_peer
->GetControlRef(), 0, &colId
);
350 wxCHECK_MSG(err
== noErr
, wxNOT_FOUND
, wxT("Unexpected error from GetDataBrowserTableViewColumnProperty"));
352 // OK, first we need to find the first visible item we have -
353 // this will be the "low" for our binary search. There is no real
354 // easy way around this, as we will need to do a SLOW linear search
355 // until we find a visible item, but we can do a cheap calculation
356 // via the row height to speed things up a bit
357 UInt32 scrollx
, scrolly
;
358 err
= GetDataBrowserScrollPosition(m_peer
->GetControlRef(), &scrollx
, &scrolly
);
359 wxCHECK_MSG(err
== noErr
, wxNOT_FOUND
, wxT("Unexpected error from GetDataBrowserScrollPosition"));
362 err
= GetDataBrowserTableViewRowHeight(m_peer
->GetControlRef(), &height
);
363 wxCHECK_MSG(err
== noErr
, wxNOT_FOUND
, wxT("Unexpected error from GetDataBrowserTableViewRowHeight"));
365 // these indices are 0-based, as usual, so we need to add 1 to them when
366 // passing them to data browser functions which use 1-based indices
367 int low
= scrolly
/ height
,
368 high
= GetCount() - 1;
370 // search for the first visible item (note that the scroll guess above
371 // is the low bounds of where the item might lie so we only use that as a
372 // starting point - we should reach it within 1 or 2 iterations of the loop)
373 while ( low
<= high
)
376 err
= GetDataBrowserItemPartBounds(
377 m_peer
->GetControlRef(), low
+ 1, colId
,
378 kDataBrowserPropertyEnclosingPart
,
379 &bounds
); // note +1 to translate to Mac ID
383 // errDataBrowserItemNotFound is expected as it simply means that the
384 // item is not currently visible -- but other errors are not
385 wxCHECK_MSG( err
== errDataBrowserItemNotFound
, wxNOT_FOUND
,
386 wxT("Unexpected error from GetDataBrowserItemPartBounds") );
391 // NOW do a binary search for where the item lies, searching low again if
392 // we hit an item that isn't visible
393 while ( low
<= high
)
395 int mid
= (low
+ high
) / 2;
398 err
= GetDataBrowserItemPartBounds(
399 m_peer
->GetControlRef(), mid
+ 1, colId
,
400 kDataBrowserPropertyEnclosingPart
,
401 &bounds
); //note +1 to trans to mac id
402 wxCHECK_MSG( err
== noErr
|| err
== errDataBrowserItemNotFound
,
404 wxT("Unexpected error from GetDataBrowserItemPartBounds") );
406 if ( err
== errDataBrowserItemNotFound
)
408 // item not visible, attempt to find a visible one
412 else // visible item, do actual hitttest
414 // if point is within the bounds, return this item (since we assume
415 // all x coords of items are equal we only test the x coord in
417 if ((point
.x
>= bounds
.left
&& point
.x
<= bounds
.right
) &&
418 (point
.y
>= bounds
.top
&& point
.y
<= bounds
.bottom
) )
424 if ( point
.y
< bounds
.top
)
425 // index(bounds) greater then key(point)
428 // index(bounds) less then key(point)
436 // ============================================================================
437 // data browser based implementation
438 // ============================================================================
440 const short kTextColumnId
= 1024;
441 const short kNumericOrderColumnId
= 1025;
443 wxMacListBoxItem::wxMacListBoxItem()
449 wxMacListBoxItem::~wxMacListBoxItem()
453 void wxMacListBoxItem::SetOrder( SInt32 order
)
458 SInt32
wxMacListBoxItem::GetOrder() const
463 void wxMacListBoxItem::SetData( void* data
)
468 void* wxMacListBoxItem::GetData() const
473 void wxMacListBoxItem::SetLabel( const wxString
& str
)
476 m_cfLabel
.Assign( str
, wxLocale::GetSystemEncoding());
479 const wxString
& wxMacListBoxItem::GetLabel() const
484 bool wxMacListBoxItem::IsLessThan(wxMacDataItemBrowserControl
*owner
,
485 const wxMacDataItem
* rhs
,
486 DataBrowserPropertyID sortProperty
) const
488 const wxMacListBoxItem
* otherItem
= dynamic_cast<const wxMacListBoxItem
*>(rhs
);
490 switch (sortProperty
)
493 retval
= m_label
.CmpNoCase( otherItem
->m_label
) < 0;
496 case kNumericOrderColumnId
:
497 retval
= m_order
< otherItem
->m_order
;
507 OSStatus
wxMacListBoxItem::GetSetData( wxMacDataItemBrowserControl
*owner
,
508 DataBrowserPropertyID property
,
509 DataBrowserItemDataRef itemData
,
512 OSStatus err
= errDataBrowserPropertyNotSupported
;
513 wxListBox
*list
= wxDynamicCast( owner
->GetPeer() , wxListBox
);
514 wxCHECK_MSG( list
!= NULL
, errDataBrowserPropertyNotSupported
, wxT("Listbox expected"));
515 wxCheckListBox
*checklist
= wxDynamicCast( list
, wxCheckListBox
);
522 err
= ::SetDataBrowserItemDataText( itemData
, m_cfLabel
);
526 case kNumericOrderColumnId
:
527 err
= ::SetDataBrowserItemDataValue( itemData
, m_order
);
539 // no editable props here
548 void wxMacListBoxItem::Notification(wxMacDataItemBrowserControl
*owner
,
549 DataBrowserItemNotification message
,
550 DataBrowserItemDataRef itemData
) const
552 wxMacDataBrowserListControl
*lb
= dynamic_cast<wxMacDataBrowserListControl
*>(owner
);
554 // we want to depend on as little as possible to make sure tear-down of controls is safe
556 if ( message
== kDataBrowserItemRemoved
)
558 if ( lb
!= NULL
&& lb
->GetClientDataType() == wxClientData_Object
)
560 delete (wxClientData
*) (m_data
);
567 wxListBox
*list
= wxDynamicCast( owner
->GetPeer() , wxListBox
);
568 wxCHECK_RET( list
!= NULL
, wxT("Listbox expected"));
570 bool trigger
= false;
571 wxCommandEvent
event( wxEVT_COMMAND_LISTBOX_SELECTED
, list
->GetId() );
574 case kDataBrowserItemDeselected
:
575 if ( list
->HasMultipleSelection() )
576 trigger
= !lb
->IsSelectionSuppressed();
579 case kDataBrowserItemSelected
:
580 trigger
= !lb
->IsSelectionSuppressed();
583 case kDataBrowserItemDoubleClicked
:
584 event
.SetEventType( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED
);
594 event
.SetEventObject( list
);
595 if ( list
->HasClientObjectData() )
596 event
.SetClientObject( (wxClientData
*) m_data
);
597 else if ( list
->HasClientUntypedData() )
598 event
.SetClientData( m_data
);
599 event
.SetString( m_label
);
600 event
.SetInt( owner
->GetLineFromItem( this ) );
601 event
.SetExtraLong( list
->HasMultipleSelection() ? message
== kDataBrowserItemSelected
: true );
602 wxPostEvent( list
->GetEventHandler(), event
);
604 // direct notification is not always having the listbox GetSelection() having in synch with event
605 // list->GetEventHandler()->ProcessEvent(event);
609 wxMacDataBrowserListControl::wxMacDataBrowserListControl( wxListBox
*peer
, const wxPoint
& pos
, const wxSize
& size
, long style
)
610 : wxMacDataItemBrowserControl( peer
, pos
, size
, style
)
612 OSStatus err
= noErr
;
613 m_clientDataItemsType
= wxClientData_None
;
614 m_stringSorted
= style
& wxLB_SORT
;
616 DataBrowserSelectionFlags options
= kDataBrowserDragSelect
;
617 if ( style
& wxLB_MULTIPLE
)
619 options
|= kDataBrowserAlwaysExtendSelection
| kDataBrowserCmdTogglesSelection
;
621 else if ( style
& wxLB_EXTENDED
)
627 options
|= kDataBrowserSelectOnlyOne
;
629 err
= SetSelectionFlags( options
);
632 DataBrowserListViewColumnDesc columnDesc
;
633 columnDesc
.headerBtnDesc
.titleOffset
= 0;
634 columnDesc
.headerBtnDesc
.version
= kDataBrowserListViewLatestHeaderDesc
;
636 columnDesc
.headerBtnDesc
.btnFontStyle
.flags
=
637 kControlUseFontMask
| kControlUseJustMask
;
639 columnDesc
.headerBtnDesc
.btnContentInfo
.contentType
= kControlNoContent
;
640 columnDesc
.headerBtnDesc
.btnFontStyle
.just
= teFlushDefault
;
641 columnDesc
.headerBtnDesc
.btnFontStyle
.font
= kControlFontViewSystemFont
;
642 columnDesc
.headerBtnDesc
.btnFontStyle
.style
= normal
;
643 columnDesc
.headerBtnDesc
.titleString
= NULL
;
645 columnDesc
.headerBtnDesc
.minimumWidth
= 0;
646 columnDesc
.headerBtnDesc
.maximumWidth
= 10000;
648 columnDesc
.propertyDesc
.propertyID
= kTextColumnId
;
649 columnDesc
.propertyDesc
.propertyType
= kDataBrowserTextType
;
650 columnDesc
.propertyDesc
.propertyFlags
= kDataBrowserTableViewSelectionColumn
;
651 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
652 columnDesc
.propertyDesc
.propertyFlags
|= kDataBrowserListViewTypeSelectColumn
;
655 verify_noerr( AddColumn( &columnDesc
, kDataBrowserListViewAppendColumn
) );
657 columnDesc
.headerBtnDesc
.minimumWidth
= 0;
658 columnDesc
.headerBtnDesc
.maximumWidth
= 0;
659 columnDesc
.propertyDesc
.propertyID
= kNumericOrderColumnId
;
660 columnDesc
.propertyDesc
.propertyType
= kDataBrowserPropertyRelevanceRankPart
;
661 columnDesc
.propertyDesc
.propertyFlags
= kDataBrowserTableViewSelectionColumn
;
662 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
663 columnDesc
.propertyDesc
.propertyFlags
|= kDataBrowserListViewTypeSelectColumn
;
666 verify_noerr( AddColumn( &columnDesc
, kDataBrowserListViewAppendColumn
) );
668 SetDataBrowserSortProperty( m_controlRef
, kTextColumnId
);
669 if ( m_stringSorted
)
671 SetDataBrowserSortProperty( m_controlRef
, kTextColumnId
);
672 SetDataBrowserSortOrder( m_controlRef
, kDataBrowserOrderIncreasing
);
676 SetDataBrowserSortProperty( m_controlRef
, kNumericOrderColumnId
);
677 SetDataBrowserSortOrder( m_controlRef
, kDataBrowserOrderIncreasing
);
680 verify_noerr( AutoSizeColumns() );
681 verify_noerr( SetHiliteStyle(kDataBrowserTableViewFillHilite
) );
682 verify_noerr( SetHeaderButtonHeight( 0 ) );
683 err
= SetHasScrollBars( (style
& wxHSCROLL
) != 0 , true );
685 // shouldn't be necessary anymore under 10.2
686 m_peer
->SetData( kControlNoPart
, kControlDataBrowserIncludesFrameAndFocusTag
, (Boolean
)false );
687 m_peer
->SetNeedsFocusRect( true );
691 wxMacDataBrowserListControl::~wxMacDataBrowserListControl()
696 wxMacListBoxItem
* wxMacDataBrowserListControl::CreateItem()
698 return new wxMacListBoxItem();
701 wxListBox
* wxMacDataBrowserListControl::GetPeer() const
703 return wxDynamicCast( wxMacControl::GetPeer() , wxListBox
);
706 wxClientDataType
wxMacDataBrowserListControl::GetClientDataType() const
708 return m_clientDataItemsType
;
710 void wxMacDataBrowserListControl::SetClientDataType(wxClientDataType clientDataItemsType
)
712 m_clientDataItemsType
= clientDataItemsType
;
715 unsigned int wxMacDataBrowserListControl::MacGetCount() const
717 return GetItemCount(wxMacDataBrowserRootContainer
,false,kDataBrowserItemNoState
);
720 void wxMacDataBrowserListControl::MacDelete( unsigned int n
)
722 wxMacListBoxItem
* item
= (wxMacListBoxItem
*)GetItemFromLine( n
);
723 RemoveItem( wxMacDataBrowserRootContainer
, item
);
726 void wxMacDataBrowserListControl::MacInsert( unsigned int n
, const wxString
& text
)
728 wxMacListBoxItem
* newItem
= CreateItem();
729 newItem
->SetLabel( text
);
731 if ( !m_stringSorted
)
733 // increase the order of the lines to be shifted
734 unsigned int lines
= MacGetCount();
735 for ( unsigned int i
= n
; i
< lines
; ++i
)
737 wxMacListBoxItem
* iter
= (wxMacListBoxItem
*) GetItemFromLine(i
);
738 iter
->SetOrder( iter
->GetOrder() + 1 );
741 SInt32 frontLineOrder
= 0;
744 wxMacListBoxItem
* iter
= (wxMacListBoxItem
*) GetItemFromLine(n
-1);
745 frontLineOrder
= iter
->GetOrder();
747 newItem
->SetOrder( frontLineOrder
+ 1 );
750 AddItem( wxMacDataBrowserRootContainer
, newItem
);
753 void wxMacDataBrowserListControl::MacInsert( unsigned int n
, const wxArrayString
& items
)
755 size_t itemsCount
= items
.GetCount();
756 if ( itemsCount
== 0 )
759 SInt32 frontLineOrder
= 0;
761 if ( !m_stringSorted
)
763 // increase the order of the lines to be shifted
764 unsigned int lines
= MacGetCount();
765 for ( unsigned int i
= n
; i
< lines
; ++i
)
767 wxMacListBoxItem
* iter
= (wxMacListBoxItem
*) GetItemFromLine(i
);
768 iter
->SetOrder( iter
->GetOrder() + itemsCount
);
772 wxMacListBoxItem
* iter
= (wxMacListBoxItem
*) GetItemFromLine(n
-1);
773 frontLineOrder
= iter
->GetOrder();
777 wxArrayMacDataItemPtr ids
;
778 ids
.SetCount( itemsCount
);
780 for ( unsigned int i
= 0; i
< itemsCount
; ++i
)
782 wxMacListBoxItem
* item
= CreateItem();
783 item
->SetLabel( items
[i
]);
784 if ( !m_stringSorted
)
785 item
->SetOrder( frontLineOrder
+ 1 + i
);
790 AddItems( wxMacDataBrowserRootContainer
, ids
);
793 int wxMacDataBrowserListControl::MacAppend( const wxString
& text
)
795 wxMacListBoxItem
* item
= CreateItem();
796 item
->SetLabel( text
);
797 if ( !m_stringSorted
)
799 unsigned int lines
= MacGetCount();
804 wxMacListBoxItem
* frontItem
= (wxMacListBoxItem
*) GetItemFromLine(lines
-1);
805 item
->SetOrder( frontItem
->GetOrder() + 1 );
808 AddItem( wxMacDataBrowserRootContainer
, item
);
810 return GetLineFromItem(item
);
813 void wxMacDataBrowserListControl::MacClear()
815 wxMacDataItemBrowserSelectionSuppressor
suppressor(this);
816 RemoveAllItems(wxMacDataBrowserRootContainer
);
819 void wxMacDataBrowserListControl::MacDeselectAll()
821 wxMacDataItemBrowserSelectionSuppressor
suppressor(this);
822 SetSelectedAllItems( kDataBrowserItemsRemove
);
825 void wxMacDataBrowserListControl::MacSetSelection( unsigned int n
, bool select
)
827 wxMacListBoxItem
* item
= (wxMacListBoxItem
*) GetItemFromLine(n
);
828 wxMacDataItemBrowserSelectionSuppressor
suppressor(this);
830 if ( IsItemSelected( item
) != select
)
833 SetSelectedItem( item
, GetPeer()->HasMultipleSelection() ? kDataBrowserItemsAdd
: kDataBrowserItemsAssign
);
835 SetSelectedItem( item
, kDataBrowserItemsRemove
);
841 bool wxMacDataBrowserListControl::MacIsSelected( unsigned int n
) const
843 wxMacListBoxItem
* item
= (wxMacListBoxItem
*) GetItemFromLine(n
);
844 return IsItemSelected( item
);
847 int wxMacDataBrowserListControl::MacGetSelection() const
849 wxMacDataItemPtr first
, last
;
850 GetSelectionAnchor( &first
, &last
);
854 return GetLineFromItem( first
);
860 int wxMacDataBrowserListControl::MacGetSelections( wxArrayInt
& aSelections
) const
863 wxArrayMacDataItemPtr selectedItems
;
864 GetItems( wxMacDataBrowserRootContainer
, false , kDataBrowserItemIsSelected
, selectedItems
);
866 int count
= selectedItems
.GetCount();
868 for ( int i
= 0; i
< count
; ++i
)
870 aSelections
.Add(GetLineFromItem(selectedItems
[i
]));
876 void wxMacDataBrowserListControl::MacSetString( unsigned int n
, const wxString
& text
)
878 // as we don't store the strings we only have to issue a redraw
879 wxMacListBoxItem
* item
= (wxMacListBoxItem
*) GetItemFromLine( n
);
880 item
->SetLabel( text
);
881 UpdateItem( wxMacDataBrowserRootContainer
, item
, kTextColumnId
);
884 wxString
wxMacDataBrowserListControl::MacGetString( unsigned int n
) const
886 wxMacListBoxItem
* item
= (wxMacListBoxItem
*) GetItemFromLine( n
);
887 return item
->GetLabel();
890 void wxMacDataBrowserListControl::MacSetClientData( unsigned int n
, void * data
)
892 wxMacListBoxItem
* item
= (wxMacListBoxItem
*) GetItemFromLine( n
);
893 item
->SetData( data
);
894 // not displayed, therefore no Update infos to DataBrowser
897 void * wxMacDataBrowserListControl::MacGetClientData( unsigned int n
) const
899 wxMacListBoxItem
* item
= (wxMacListBoxItem
*) GetItemFromLine( n
);
900 return item
->GetData();
903 void wxMacDataBrowserListControl::MacScrollTo( unsigned int n
)
905 RevealItem( GetItemFromLine( n
) , kDataBrowserRevealWithoutSelecting
);
910 // in case we need that one day
912 // ============================================================================
913 // HIView owner-draw-based implementation
914 // ============================================================================
916 static pascal void ListBoxDrawProc(
917 ControlRef browser
, DataBrowserItemID item
, DataBrowserPropertyID property
,
918 DataBrowserItemState itemState
, const Rect
*itemRect
, SInt16 depth
, Boolean isColorDevice
)
920 CFStringRef cfString
;
921 ThemeDrawingState themeState
;
924 GetThemeDrawingState( &themeState
);
925 cfString
= CFStringCreateWithFormat( NULL
, NULL
, CFSTR("Row %d"), item
);
927 // In this sample we handle the "selected" state; all others fall through to our "active" state
928 if ( itemState
== kDataBrowserItemIsSelected
)
930 ThemeBrush colorBrushID
;
932 // TODO: switch over to wxSystemSettingsNative::GetColour() when kThemeBrushSecondaryHighlightColor
933 // is incorporated Panther DB starts using kThemeBrushSecondaryHighlightColor
934 // for inactive browser highlighting
935 Gestalt( gestaltSystemVersion
, &systemVersion
);
936 if ( (systemVersion
>= 0x00001030) && !IsControlActive( browser
) )
937 colorBrushID
= kThemeBrushSecondaryHighlightColor
;
939 colorBrushID
= kThemeBrushPrimaryHighlightColor
;
941 // First paint the hilite rect, then the text on top
942 SetThemePen( colorBrushID
, 32, true );
943 PaintRect( itemRect
);
944 SetThemeDrawingState( themeState
, false );
947 DrawThemeTextBox( cfString
, kThemeApplicationFont
, kThemeStateActive
, true, itemRect
, teFlushDefault
, NULL
);
948 SetThemeDrawingState( themeState
, true );
950 if ( cfString
!= NULL
)
951 CFRelease( cfString
);