X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6cce68eaab1559c5c21dd0ce544090cc18dc8398..3863c5ebd92650ba88f29db4f5f8d794ec11bf80:/src/mac/carbon/listbox.cpp?ds=sidebyside diff --git a/src/mac/carbon/listbox.cpp b/src/mac/carbon/listbox.cpp index 5b7ef94b22..ee803cb958 100644 --- a/src/mac/carbon/listbox.cpp +++ b/src/mac/carbon/listbox.cpp @@ -13,24 +13,23 @@ #if wxUSE_LISTBOX -#include "wx/app.h" #include "wx/listbox.h" -#include "wx/button.h" -#include "wx/settings.h" -#include "wx/toplevel.h" -#include "wx/dynarray.h" -#include "wx/log.h" -#include "wx/utils.h" +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/intl.h" + #include "wx/utils.h" + #include "wx/settings.h" + #include "wx/arrstr.h" + #include "wx/dcclient.h" +#endif -IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl) +IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControlWithItems) BEGIN_EVENT_TABLE(wxListBox, wxControl) END_EVENT_TABLE() #include "wx/mac/uma.h" -#include "wx/dynarray.h" -#include "wx/arrstr.h" // ============================================================================ // list box control implementation @@ -57,9 +56,10 @@ bool wxListBox::Create( style, validator, name ); } -wxMacListControl* wxListBox::GetPeer() const -{ - return dynamic_cast(m_peer); +wxMacListControl* wxListBox::GetPeer() const +{ + wxMacDataBrowserListControl *lb = wxDynamicCast(m_peer,wxMacDataBrowserListControl); + return lb ? wx_static_cast(wxMacListControl*,lb) : 0 ; } bool wxListBox::Create( @@ -80,17 +80,17 @@ bool wxListBox::Create( if ( !wxListBoxBase::Create( parent, id, pos, size, style & ~(wxHSCROLL | wxVSCROLL), validator, name ) ) return false; - + wxMacDataBrowserListControl* control = new wxMacDataBrowserListControl( this, pos, size, style ); - control->SetClientDataType( m_clientDataItemsType ); + // TODO CHECK control->SetClientDataType( m_clientDataItemsType ); m_peer = control; MacPostControlCreate( pos, size ); - InsertItems( n, choices, 0 ); + Append(n, choices); // Needed because it is a wxControlWithItems - SetBestSize( size ); + SetInitialSize( size ); return true; } @@ -116,36 +116,29 @@ void wxListBox::EnsureVisible(int n) GetPeer()->MacScrollTo( n ); } -void wxListBox::Delete(unsigned int n) +void wxListBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::Delete") ); GetPeer()->MacDelete( n ); } -int wxListBox::DoAppend(const wxString& item) +int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { InvalidateBestSize(); - return GetPeer()->MacAppend( item ); -} - -void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData) -{ - Clear(); - - unsigned int n = choices.GetCount(); - - for ( size_t i = 0; i < n; ++i ) + GetPeer()->MacInsert( pos, items ); + const unsigned int count = items.GetCount(); + if ( clientData ) { - if ( clientData ) - { - Append( choices[i], clientData[i] ); - } - else - Append( choices[i] ); + for (unsigned int i = 0; i < count; ++i) + AssignNewItemClientData( pos + i, clientData, i, type ); } + return pos + count - 1; } int wxListBox::FindString(const wxString& s, bool bCase) const @@ -159,7 +152,7 @@ int wxListBox::FindString(const wxString& s, bool bCase) const return wxNOT_FOUND; } -void wxListBox::Clear() +void wxListBox::DoClear() { FreeData(); } @@ -172,7 +165,7 @@ void wxListBox::DoSetSelection(int n, bool select) if ( n == wxNOT_FOUND ) GetPeer()->MacDeselectAll(); else - GetPeer()->MacSetSelection( n, select ); + GetPeer()->MacSetSelection( n, select, HasMultipleSelection() ); } bool wxListBox::IsSelected(int n) const @@ -188,22 +181,12 @@ void *wxListBox::DoGetItemClientData(unsigned int n) const return GetPeer()->MacGetClientData( n ); } -wxClientData *wxListBox::DoGetItemClientObject(unsigned int n) const -{ - return (wxClientData*)DoGetItemClientData( n ); -} - void wxListBox::DoSetItemClientData(unsigned int n, void *clientData) { wxCHECK_RET( IsValid(n), wxT("invalid index in wxListBox::SetClientData") ); GetPeer()->MacSetClientData( n , clientData); } -void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - DoSetItemClientData(n, clientData); -} - // Return number of selections and an array of selected integers int wxListBox::GetSelections(wxArrayInt& aSelections) const { @@ -223,15 +206,6 @@ wxString wxListBox::GetString(unsigned int n) const return GetPeer()->MacGetString(n); } -void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) -{ - wxCHECK_RET( IsValidInsert(pos), wxT("invalid index in wxListBox::InsertItems") ); - - InvalidateBestSize(); - - GetPeer()->MacInsert( pos, items ); -} - void wxListBox::SetString(unsigned int n, const wxString& s) { GetPeer()->MacSetString( n, s ); @@ -244,44 +218,17 @@ wxSize wxListBox::DoGetBestSize() const int wLine; { - wxMacPortStateHelper st( UMAGetWindowPort( (WindowRef)MacGetTopLevelWindowRef() ) ); - - // TODO: clean this up - if ( m_font.Ok() ) - { - ::TextFont( m_font.MacGetFontNum() ); - ::TextSize( m_font.MacGetFontSize() ); - ::TextFace( m_font.MacGetFontStyle() ); - } - else - { - ::TextFont( kFontIDMonaco ); - ::TextSize( 9 ); - ::TextFace( 0 ); - } + wxClientDC dc(const_cast(this)); + dc.SetFont(GetFont()); // Find the widest line for (unsigned int i = 0; i < GetCount(); i++) { wxString str( GetString( i ) ); -#if wxUSE_UNICODE - Point bounds = {0, 0}; - SInt16 baseline; - - // NB: what if m_font.Ok() == false ??? - ::GetThemeTextDimensions( - wxMacCFStringHolder( str, m_font.GetEncoding() ), - kThemeCurrentPortFont, - kThemeStateActive, - false, - &bounds, - &baseline ); - wLine = bounds.h; -#else - wLine = ::TextWidth( str.c_str(), 0, str.length() ); -#endif - + wxCoord width, height ; + dc.GetTextExtent( str , &width, &height); + wLine = width ; lbWidth = wxMax( lbWidth, wLine ); } @@ -290,7 +237,10 @@ wxSize wxListBox::DoGetBestSize() const // And just a bit more int cy = 12; - int cx = ::TextWidth( "X", 0, 1 ); + + wxCoord width, height ; + dc.GetTextExtent( wxT("XX") , &width, &height); + int cx = width ; lbWidth += cx; // don't make the listbox too tall (limit height to around 10 items) @@ -338,12 +288,6 @@ int wxListBox::DoListHitTest(const wxPoint& inpoint) const wxPoint point = inpoint; - // interestingly enough 10.2 (and below?) have GetDataBrowserItemPartBounds - // giving root window coordinates but 10.3 and above give client coordinates - // so we only compare using root window coordinates on 10.3 and up - if ( UMAGetSystemVersion() < 0x1030 ) - MacClientToRootWindow(&point.x, &point.y); - // get column property ID (req. for call to itempartbounds) DataBrowserTableViewColumnID colId = 0; err = GetDataBrowserTableViewColumnProperty(m_peer->GetControlRef(), 0, &colId); @@ -437,122 +381,23 @@ int wxListBox::DoListHitTest(const wxPoint& inpoint) const // data browser based implementation // ============================================================================ -const short kTextColumnId = 1024; -const short kNumericOrderColumnId = 1025; - wxMacListBoxItem::wxMacListBoxItem() + :wxMacDataItem() { - m_data = NULL; - m_order = 0; } wxMacListBoxItem::~wxMacListBoxItem() { } -void wxMacListBoxItem::SetOrder( SInt32 order ) -{ - m_order = order; -} - -SInt32 wxMacListBoxItem::GetOrder() const -{ - return m_order; -} - -void wxMacListBoxItem::SetData( void* data) -{ - m_data = data; -} - -void* wxMacListBoxItem::GetData() const -{ - return m_data; -} - -void wxMacListBoxItem::SetLabel( const wxString& str) -{ - m_label = str; - m_cfLabel.Assign( str , wxLocale::GetSystemEncoding()); -} - -const wxString& wxMacListBoxItem::GetLabel() const -{ - return m_label; -} - -bool wxMacListBoxItem::IsLessThan(wxMacDataItemBrowserControl *owner , - const wxMacDataItem* rhs, - DataBrowserPropertyID sortProperty) const -{ - const wxMacListBoxItem* otherItem = dynamic_cast(rhs); - bool retval = false; - switch (sortProperty) - { - case kTextColumnId: - retval = m_label.CmpNoCase( otherItem->m_label) < 0; - break; - - case kNumericOrderColumnId: - retval = m_order < otherItem->m_order; - break; - - default: - break; - }; - - return retval; -} - -OSStatus wxMacListBoxItem::GetSetData( wxMacDataItemBrowserControl *owner , - DataBrowserPropertyID property, - DataBrowserItemDataRef itemData, - bool changeValue ) -{ - OSStatus err = errDataBrowserPropertyNotSupported; - wxListBox *list = wxDynamicCast( owner->GetPeer() , wxListBox ); - wxCHECK_MSG( list != NULL , errDataBrowserPropertyNotSupported , wxT("Listbox expected")); - wxCheckListBox *checklist = wxDynamicCast( list , wxCheckListBox ); - - if ( !changeValue ) - { - switch (property) - { - case kTextColumnId: - err = ::SetDataBrowserItemDataText( itemData, m_cfLabel ); - err = noErr; - break; - - case kNumericOrderColumnId: - err = ::SetDataBrowserItemDataValue( itemData, m_order ); - err = noErr; - break; - - default: - break; - } - } - else - { - switch (property) - { - // no editable props here - default: - break; - } - } - - return err; -} - -void wxMacListBoxItem::Notification(wxMacDataItemBrowserControl *owner , +void wxMacListBoxItem::Notification(wxMacDataItemBrowserControl *owner , DataBrowserItemNotification message, - DataBrowserItemDataRef itemData ) const + DataBrowserItemDataRef WXUNUSED(itemData) ) const { - wxMacDataBrowserListControl *lb = dynamic_cast(owner); + wxMacDataBrowserListControl *lb = wxDynamicCast(owner,wxMacDataBrowserListControl); // we want to depend on as little as possible to make sure tear-down of controls is safe - + if ( message == kDataBrowserItemRemoved) { if ( lb != NULL && lb->GetClientDataType() == wxClientData_Object ) @@ -563,7 +408,7 @@ void wxMacListBoxItem::Notification(wxMacDataItemBrowserControl *owner , delete this; return; } - + wxListBox *list = wxDynamicCast( owner->GetPeer() , wxListBox ); wxCHECK_RET( list != NULL , wxT("Listbox expected")); @@ -599,20 +444,25 @@ void wxMacListBoxItem::Notification(wxMacDataItemBrowserControl *owner , event.SetString( m_label ); event.SetInt( owner->GetLineFromItem( this ) ); event.SetExtraLong( list->HasMultipleSelection() ? message == kDataBrowserItemSelected : true ); - wxPostEvent( list->GetEventHandler(), event ); - // direct notification is not always having the listbox GetSelection() having in synch with event - // list->GetEventHandler()->ProcessEvent(event); + // direct notification is not always having the listbox GetSelection() + // having in synch with event, so use wxPostEvent instead + // list->HandleWindowEvent(event); + + wxPostEvent( list->GetEventHandler(), event ); } } -wxMacDataBrowserListControl::wxMacDataBrowserListControl( wxListBox *peer, const wxPoint& pos, const wxSize& size, long style) +IMPLEMENT_DYNAMIC_CLASS( wxMacDataBrowserListControl , wxMacDataItemBrowserControl ) + +wxMacDataBrowserListControl::wxMacDataBrowserListControl( wxWindow *peer, const wxPoint& pos, const wxSize& size, long style) : wxMacDataItemBrowserControl( peer, pos, size, style ) { OSStatus err = noErr; m_clientDataItemsType = wxClientData_None; - m_stringSorted = style & wxLB_SORT; - + if ( style & wxLB_SORT ) + m_sortOrder = SortOrder_Text_Ascending; + DataBrowserSelectionFlags options = kDataBrowserDragSelect; if ( style & wxLB_MULTIPLE ) { @@ -620,7 +470,7 @@ wxMacDataBrowserListControl::wxMacDataBrowserListControl( wxListBox *peer, const } else if ( style & wxLB_EXTENDED ) { - // default behaviour + options |= kDataBrowserCmdTogglesSelection; } else { @@ -628,7 +478,7 @@ wxMacDataBrowserListControl::wxMacDataBrowserListControl( wxListBox *peer, const } err = SetSelectionFlags( options ); verify_noerr( err ); - + DataBrowserListViewColumnDesc columnDesc; columnDesc.headerBtnDesc.titleOffset = 0; columnDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc; @@ -648,9 +498,7 @@ wxMacDataBrowserListControl::wxMacDataBrowserListControl( wxListBox *peer, const columnDesc.propertyDesc.propertyID = kTextColumnId; columnDesc.propertyDesc.propertyType = kDataBrowserTextType; columnDesc.propertyDesc.propertyFlags = kDataBrowserTableViewSelectionColumn; -#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 columnDesc.propertyDesc.propertyFlags |= kDataBrowserListViewTypeSelectColumn; -#endif verify_noerr( AddColumn( &columnDesc, kDataBrowserListViewAppendColumn ) ); @@ -659,14 +507,12 @@ wxMacDataBrowserListControl::wxMacDataBrowserListControl( wxListBox *peer, const columnDesc.propertyDesc.propertyID = kNumericOrderColumnId; columnDesc.propertyDesc.propertyType = kDataBrowserPropertyRelevanceRankPart; columnDesc.propertyDesc.propertyFlags = kDataBrowserTableViewSelectionColumn; -#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 columnDesc.propertyDesc.propertyFlags |= kDataBrowserListViewTypeSelectColumn; -#endif verify_noerr( AddColumn( &columnDesc, kDataBrowserListViewAppendColumn ) ); SetDataBrowserSortProperty( m_controlRef , kTextColumnId); - if ( m_stringSorted ) + if ( m_sortOrder == SortOrder_Text_Ascending ) { SetDataBrowserSortProperty( m_controlRef , kTextColumnId); SetDataBrowserSortOrder( m_controlRef , kDataBrowserOrderIncreasing); @@ -692,217 +538,14 @@ wxMacDataBrowserListControl::~wxMacDataBrowserListControl() { } - -wxMacListBoxItem* wxMacDataBrowserListControl::CreateItem() +wxWindow * wxMacDataBrowserListControl::GetPeer() const { - return new wxMacListBoxItem(); -} - -wxListBox * wxMacDataBrowserListControl::GetPeer() const -{ - return wxDynamicCast( wxMacControl::GetPeer() , wxListBox ); + return wxDynamicCast( wxMacControl::GetPeer() , wxWindow ); } -wxClientDataType wxMacDataBrowserListControl::GetClientDataType() const +wxMacDataItem* wxMacDataBrowserListControl::CreateItem() { - return m_clientDataItemsType; -} -void wxMacDataBrowserListControl::SetClientDataType(wxClientDataType clientDataItemsType) -{ - m_clientDataItemsType = clientDataItemsType; -} - -unsigned int wxMacDataBrowserListControl::MacGetCount() const -{ - return GetItemCount(wxMacDataBrowserRootContainer,false,kDataBrowserItemNoState); -} - -void wxMacDataBrowserListControl::MacDelete( unsigned int n ) -{ - wxMacListBoxItem* item = (wxMacListBoxItem*)GetItemFromLine( n ); - RemoveItem( wxMacDataBrowserRootContainer, item ); -} - -void wxMacDataBrowserListControl::MacInsert( unsigned int n, const wxString& text) -{ - wxMacListBoxItem* newItem = CreateItem(); - newItem->SetLabel( text ); - - if ( !m_stringSorted ) - { - // increase the order of the lines to be shifted - unsigned int lines = MacGetCount(); - for ( unsigned int i = n; i < lines; ++i) - { - wxMacListBoxItem* iter = (wxMacListBoxItem*) GetItemFromLine(i); - iter->SetOrder( iter->GetOrder() + 1 ); - } - - SInt32 frontLineOrder = 0; - if ( n > 0 ) - { - wxMacListBoxItem* iter = (wxMacListBoxItem*) GetItemFromLine(n-1); - frontLineOrder = iter->GetOrder(); - } - newItem->SetOrder( frontLineOrder + 1 ); - } - - AddItem( wxMacDataBrowserRootContainer, newItem ); -} - -void wxMacDataBrowserListControl::MacInsert( unsigned int n, const wxArrayString& items) -{ - size_t itemsCount = items.GetCount(); - if ( itemsCount == 0 ) - return; - - SInt32 frontLineOrder = 0; - - if ( !m_stringSorted ) - { - // increase the order of the lines to be shifted - unsigned int lines = MacGetCount(); - for ( unsigned int i = n; i < lines; ++i) - { - wxMacListBoxItem* iter = (wxMacListBoxItem*) GetItemFromLine(i); - iter->SetOrder( iter->GetOrder() + itemsCount ); - } - if ( n > 0 ) - { - wxMacListBoxItem* iter = (wxMacListBoxItem*) GetItemFromLine(n-1); - frontLineOrder = iter->GetOrder(); - } - } - - wxArrayMacDataItemPtr ids; - ids.SetCount( itemsCount ); - - for ( unsigned int i = 0; i < itemsCount; ++i ) - { - wxMacListBoxItem* item = CreateItem(); - item->SetLabel( items[i]); - if ( !m_stringSorted ) - item->SetOrder( frontLineOrder + 1 + i ); - - ids[i] = item; - } - - AddItems( wxMacDataBrowserRootContainer, ids ); -} - -int wxMacDataBrowserListControl::MacAppend( const wxString& text) -{ - wxMacListBoxItem* item = CreateItem(); - item->SetLabel( text ); - if ( !m_stringSorted ) - { - unsigned int lines = MacGetCount(); - if ( lines == 0 ) - item->SetOrder( 1 ); - else - { - wxMacListBoxItem* frontItem = (wxMacListBoxItem*) GetItemFromLine(lines-1); - item->SetOrder( frontItem->GetOrder() + 1 ); - } - } - AddItem( wxMacDataBrowserRootContainer, item ); - - return GetLineFromItem(item); -} - -void wxMacDataBrowserListControl::MacClear() -{ - wxMacDataItemBrowserSelectionSuppressor suppressor(this); - RemoveAllItems(wxMacDataBrowserRootContainer); -} - -void wxMacDataBrowserListControl::MacDeselectAll() -{ - wxMacDataItemBrowserSelectionSuppressor suppressor(this); - SetSelectedAllItems( kDataBrowserItemsRemove ); -} - -void wxMacDataBrowserListControl::MacSetSelection( unsigned int n, bool select ) -{ - wxMacListBoxItem* item = (wxMacListBoxItem*) GetItemFromLine(n); - wxMacDataItemBrowserSelectionSuppressor suppressor(this); - - if ( IsItemSelected( item ) != select ) - { - if ( select ) - SetSelectedItem( item, GetPeer()->HasMultipleSelection() ? kDataBrowserItemsAdd : kDataBrowserItemsAssign ); - else - SetSelectedItem( item, kDataBrowserItemsRemove ); - } - - MacScrollTo( n ); -} - -bool wxMacDataBrowserListControl::MacIsSelected( unsigned int n ) const -{ - wxMacListBoxItem* item = (wxMacListBoxItem*) GetItemFromLine(n); - return IsItemSelected( item ); -} - -int wxMacDataBrowserListControl::MacGetSelection() const -{ - wxMacDataItemPtr first, last; - GetSelectionAnchor( &first, &last ); - - if ( first != NULL ) - { - return GetLineFromItem( first ); - } - - return -1; -} - -int wxMacDataBrowserListControl::MacGetSelections( wxArrayInt& aSelections ) const -{ - aSelections.Empty(); - wxArrayMacDataItemPtr selectedItems; - GetItems( wxMacDataBrowserRootContainer, false , kDataBrowserItemIsSelected, selectedItems); - - int count = selectedItems.GetCount(); - - for ( int i = 0; i < count; ++i) - { - aSelections.Add(GetLineFromItem(selectedItems[i])); - } - - return count; -} - -void wxMacDataBrowserListControl::MacSetString( unsigned int n, const wxString& text ) -{ - // as we don't store the strings we only have to issue a redraw - wxMacListBoxItem* item = (wxMacListBoxItem*) GetItemFromLine( n); - item->SetLabel( text ); - UpdateItem( wxMacDataBrowserRootContainer, item , kTextColumnId ); -} - -wxString wxMacDataBrowserListControl::MacGetString( unsigned int n ) const -{ - wxMacListBoxItem * item = (wxMacListBoxItem*) GetItemFromLine( n ); - return item->GetLabel(); -} - -void wxMacDataBrowserListControl::MacSetClientData( unsigned int n, void * data) -{ - wxMacListBoxItem* item = (wxMacListBoxItem*) GetItemFromLine( n); - item->SetData( data ); - // not displayed, therefore no Update infos to DataBrowser -} - -void * wxMacDataBrowserListControl::MacGetClientData( unsigned int n) const -{ - wxMacListBoxItem * item = (wxMacListBoxItem*) GetItemFromLine( n ); - return item->GetData(); -} - -void wxMacDataBrowserListControl::MacScrollTo( unsigned int n ) -{ - RevealItem( GetItemFromLine( n) , kDataBrowserRevealWithoutSelecting ); + return new wxMacListBoxItem(); } #if 0 @@ -932,8 +575,7 @@ static pascal void ListBoxDrawProc( // TODO: switch over to wxSystemSettingsNative::GetColour() when kThemeBrushSecondaryHighlightColor // is incorporated Panther DB starts using kThemeBrushSecondaryHighlightColor // for inactive browser highlighting - Gestalt( gestaltSystemVersion, &systemVersion ); - if ( (systemVersion >= 0x00001030) && !IsControlActive( browser ) ) + if ( !IsControlActive( browser ) ) colorBrushID = kThemeBrushSecondaryHighlightColor; else colorBrushID = kThemeBrushPrimaryHighlightColor; @@ -954,4 +596,4 @@ static pascal void ListBoxDrawProc( #endif -#endif +#endif // wxUSE_LISTBOX