X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/519cb848a8f4c91c73421bb75314754284e593a4..f21b2fd89d02837dfd0d195f8ff0f3f5640af017:/src/mac/carbon/listbox.cpp diff --git a/src/mac/carbon/listbox.cpp b/src/mac/carbon/listbox.cpp index e17f1b8213..05cc0e249a 100644 --- a/src/mac/carbon/listbox.cpp +++ b/src/mac/carbon/listbox.cpp @@ -13,13 +13,18 @@ #pragma implementation "listbox.h" #endif +#include "wx/app.h" #include "wx/listbox.h" #include "wx/settings.h" #include "wx/dynarray.h" #include "wx/log.h" #include "wx/utils.h" -#include "extldef.h" +#ifdef __UNIX__ + #include "ldef/extldef.h" +#else + #include "extldef.h" +#endif #if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl) @@ -43,6 +48,7 @@ wxListBox::wxListBox() { m_noItems = 0; m_selected = 0; + m_macList = NULL ; } bool wxListBox::Create(wxWindow *parent, wxWindowID id, @@ -58,20 +64,19 @@ bool wxListBox::Create(wxWindow *parent, wxWindowID id, Rect bounds ; Str255 title ; - m_macHorizontalBorder = 5 ; // additional pixels around the real control - m_macVerticalBorder = 5 ; MacPreControlCreate( parent , id , "" , pos , size ,style, validator , name , &bounds , title ) ; - m_macControl = UMANewControl( parent->GetMacRootWindow() , &bounds , title , true , kwxMacListWithVerticalScrollbar , 0 , 0, + m_macControl = UMANewControl( parent->GetMacRootWindow() , &bounds , title , false , kwxMacListWithVerticalScrollbar , 0 , 0, kControlListBoxProc , (long) this ) ; long result ; UMAGetControlData( m_macControl , kControlNoPart , kControlListBoxListHandleTag , sizeof( ListHandle ) , (char*) &m_macList , &result ) ; + HLock( (Handle) m_macList ) ; NewExtLDEFInfo( m_macList , MacDrawStringCell , (long) this ) ; - (**m_macList).selFlags = lOnlyOne ; - if ( style & wxLB_MULTIPLE ) + (**m_macList).selFlags = 0 ; + if ( style & wxLB_MULTIPLE ) { (**m_macList).selFlags += lNoExtend ; } @@ -79,6 +84,10 @@ bool wxListBox::Create(wxWindow *parent, wxWindowID id, { (**m_macList).selFlags += lExtendDrag ; } + else + { + (**m_macList).selFlags = lOnlyOne ; + } Point pt = (**m_macList).cellSize ; pt.v = 14 ; LCellSize( pt , m_macList ) ; @@ -106,57 +115,126 @@ bool wxListBox::Create(wxWindow *parent, wxWindowID id, wxListBox::~wxListBox() { -// DisposeExtLDEFInfo( m_macList ) ; + Free() ; + if ( m_macList ) + { + DisposeExtLDEFInfo( m_macList ) ; + m_macList = NULL ; + } } -void wxListBox::SetFirstItem(int N) +void wxListBox::Free() { - MacScrollTo( N ) ; +#if wxUSE_OWNER_DRAWN + if ( m_windowStyle & wxLB_OWNERDRAW ) + { + size_t uiCount = m_aItems.Count(); + while ( uiCount-- != 0 ) { + delete m_aItems[uiCount]; + } + + m_aItems.Clear(); + } + else +#endif // wxUSE_OWNER_DRAWN + if ( HasClientObjectData() ) + { + for ( size_t n = 0; n < (size_t)m_noItems; n++ ) + { + delete GetClientObject(n); + } + } } -void wxListBox::SetFirstItem(const wxString& s) +void wxListBox::DoSetFirstItem(int N) { - MacScrollTo( FindString( s ) ) ; + MacScrollTo( N ) ; } void wxListBox::Delete(int N) { - m_dataArray.Remove( N ) ; + wxCHECK_RET( N >= 0 && N < m_noItems, + wxT("invalid index in wxListBox::Delete") ); + +#if wxUSE_OWNER_DRAWN + delete m_aItems[N]; + m_aItems.Remove(N); +#else // !wxUSE_OWNER_DRAWN + if ( HasClientObjectData() ) + { + delete GetClientObject(N); + } +#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN m_stringArray.Remove( N ) ; - m_noItems --; + m_dataArray.Remove( N ) ; + m_noItems --; MacDelete( N ) ; } -void wxListBox::Append(const wxString& item) -{ - Append( item , NULL ) ; -} - -void wxListBox::Append(const wxString& item, char *Client_data) +int wxListBox::DoAppend(const wxString& item) { + int index = m_noItems ; if( wxApp::s_macDefaultEncodingIsPC ) { m_stringArray.Add( wxMacMakeMacStringFromPC( item ) ) ; + m_dataArray.Add( NULL ); } - else + else { m_stringArray.Add( item ) ; - m_dataArray.Add( Client_data ) ; - m_noItems ++; - + m_dataArray.Add( NULL ); + } + m_noItems ++; + DoSetItemClientData( index , NULL ) ; MacAppend( item ) ; + + return index ; } -void wxListBox::Set(int n, const wxString *choices, char** clientData) -{ +void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData) +{ + MacSetRedraw( false ) ; Clear() ; + int n = choices.GetCount(); + for( int i = 0 ; i < n ; ++i ) { if ( clientData ) - Append( choices[i] , clientData[0] ) ; + { +#if wxUSE_OWNER_DRAWN + wxASSERT_MSG(clientData[i] == NULL, + wxT("Can't use client data with owner-drawn listboxes")); +#else // !wxUSE_OWNER_DRAWN + Append( choices[i] , clientData[i] ) ; + #endif + } else Append( choices[i] ) ; } + +#if wxUSE_OWNER_DRAWN + if ( m_windowStyle & wxLB_OWNERDRAW ) { + // first delete old items + size_t ui = m_aItems.Count(); + while ( ui-- != 0 ) { + delete m_aItems[ui]; + } + m_aItems.Empty(); + + // then create new ones + for ( ui = 0; ui < (size_t)m_noItems; ui++ ) { + wxOwnerDrawn *pNewItem = CreateItem(ui); + pNewItem->SetName(choices[ui]); + m_aItems.Add(pNewItem); + } + } +#endif // wxUSE_OWNER_DRAWN + MacSetRedraw( true ) ; +} + +bool wxListBox::HasMultipleSelection() const +{ + return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED); } int wxListBox::FindString(const wxString& st) const @@ -173,25 +251,66 @@ int wxListBox::FindString(const wxString& st) const { wxString search = s.Left( s.Length() - 1 ) ; int len = search.Length() ; - for ( int i = 0 ; i < m_noItems ; ++ i ) - { - if ( equalstring( m_stringArray[i].Left( len ) , search , false , false ) ) - return i ; - } + Str255 s1 , s2 ; + +#if TARGET_CARBON + c2pstrcpy( (StringPtr) s2 , search.c_str() ) ; +#else + strcpy( (char *) s2 , search.c_str() ) ; + c2pstr( (char *) s2 ) ; +#endif + + for ( int i = 0 ; i < m_noItems ; ++ i ) + { +#if TARGET_CARBON + c2pstrcpy( (StringPtr) s1 , m_stringArray[i].Left( len ).c_str() ) ; +#else + strcpy( (char *) s1 , m_stringArray[i].Left( len ).c_str() ) ; + c2pstr( (char *) s1 ) ; +#endif + if ( EqualString( s1 , s2 , false , false ) ) + return i ; + } + if ( s.Left(1) = "*" && s.Length() > 1 ) + { + s.MakeLower() ; + for ( int i = 0 ; i < m_noItems ; ++i ) + { + if ( GetString(i).Lower().Matches(s) ) + return i ; + } + } + } else { - for ( int i = 0 ; i < m_noItems ; ++ i ) - { - if ( equalstring( m_stringArray[i] , s , false , false ) ) - return i ; - } + Str255 s1 , s2 ; + +#if TARGET_CARBON + c2pstrcpy( (StringPtr) s2 , s.c_str() ) ; +#else + strcpy( (char *) s2 , s.c_str() ) ; + c2pstr( (char *) s2 ) ; +#endif + + for ( int i = 0 ; i < m_noItems ; ++ i ) + { +#if TARGET_CARBON + c2pstrcpy( (StringPtr) s1 , m_stringArray[i].c_str() ) ; +#else + strcpy( (char *) s1 , m_stringArray[i].c_str() ) ; + c2pstr( (char *) s1 ) ; +#endif + if ( EqualString( s1 , s2 , false , false ) ) + return i ; + } } return -1; } void wxListBox::Clear() { + Free(); m_noItems = 0; m_stringArray.Empty() ; m_dataArray.Empty() ; @@ -205,7 +324,7 @@ void wxListBox::SetSelection(int N, bool select) MacSetSelection( N , select ) ; } -bool wxListBox::Selected(int N) const +bool wxListBox::IsSelected(int N) const { wxCHECK_MSG( N >= 0 && N < m_noItems, FALSE, "invalid index in wxListBox::Selected" ); @@ -213,28 +332,47 @@ bool wxListBox::Selected(int N) const return MacIsSelected( N ) ; } -void wxListBox::Deselect(int N) +void *wxListBox::DoGetItemClientData(int N) const { - wxCHECK_RET( N >= 0 && N < m_noItems, - "invalid index in wxListBox::Deselect" ); + wxCHECK_MSG( N >= 0 && N < m_noItems, NULL, + "invalid index in wxListBox::GetClientData" ); - SetSelection( N , false ) ; + return (void *)m_dataArray[N]; } -char *wxListBox::GetClientData(int N) const +wxClientData *wxListBox::DoGetItemClientObject(int N) const { - wxCHECK_MSG( N >= 0 && N < m_noItems, NULL, - "invalid index in wxListBox::GetClientData" ); - - return m_dataArray[N]; + return (wxClientData *) DoGetItemClientData( N ) ; } -void wxListBox::SetClientData(int N, char *Client_data) +void wxListBox::DoSetItemClientData(int N, void *Client_data) { wxCHECK_RET( N >= 0 && N < m_noItems, "invalid index in wxListBox::SetClientData" ); - m_dataArray[N] = Client_data ; +#if wxUSE_OWNER_DRAWN + if ( m_windowStyle & wxLB_OWNERDRAW ) + { + // client data must be pointer to wxOwnerDrawn, otherwise we would crash + // in OnMeasure/OnDraw. + wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes")); + } +#endif // wxUSE_OWNER_DRAWN + wxASSERT_MSG( m_dataArray.GetCount() >= N , "invalid client_data array" ) ; + + if ( m_dataArray.GetCount() > N ) + { + m_dataArray[N] = (char*) Client_data ; + } + else + { + m_dataArray.Add( (char*) Client_data ) ; + } +} + +void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData) +{ + DoSetItemClientData(n, clientData); } // Return number of selections and an array of selected integers @@ -277,8 +415,13 @@ wxString wxListBox::GetString(int N) const return m_stringArray[N] ; } -void wxListBox::InsertItems(int nItems, const wxString items[], int pos) +void wxListBox::DoInsertItems(const wxArrayString& items, int pos) { + wxCHECK_RET( pos >= 0 && pos <= m_noItems, + wxT("invalid index in wxListBox::InsertItems") ); + + int nItems = items.GetCount(); + for ( int i = 0 ; i < nItems ; i++ ) { m_stringArray.Insert( items[i] , pos + i ) ; @@ -291,51 +434,54 @@ void wxListBox::InsertItems(int nItems, const wxString items[], int pos) void wxListBox::SetString(int N, const wxString& s) { - m_stringArray[N] = s ; + wxString str ; + if( wxApp::s_macDefaultEncodingIsPC ) + { + str = wxMacMakeMacStringFromPC( s ) ; + } + else + str = s ; + m_stringArray[N] = str ; MacSet( N , s ) ; } -int wxListBox::Number () const +wxSize wxListBox::DoGetBestSize() const { - return m_noItems; + return wxSize(100, 100); } -// For single selection items only -wxString wxListBox::GetStringSelection () const +int wxListBox::GetCount() const { - int sel = GetSelection (); - if (sel > -1) - { - return GetString (sel); - } - else - return wxString(""); + return m_noItems; } -bool wxListBox::SetStringSelection (const wxString& s, bool flag) +void wxListBox::SetupColours() { - int sel = FindString (s); - if (sel > -1) - { - SetSelection (sel, flag); - return TRUE; - } - else - return FALSE; + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW)); + SetForegroundColour(GetParent()->GetForegroundColour()); } -void wxListBox::Command (wxCommandEvent & event) +#if wxUSE_OWNER_DRAWN + +class wxListBoxItem : public wxOwnerDrawn { - if (event.m_extraLong) - SetSelection (event.m_commandInt); - else - { - Deselect (event.m_commandInt); - return; - } - ProcessCommand (event); +public: + wxListBoxItem(const wxString& str = ""); +}; + +wxListBoxItem::wxListBoxItem(const wxString& str) : wxOwnerDrawn(str, FALSE) +{ + // no bitmaps/checkmarks + SetMarginWidth(0); +} + +wxOwnerDrawn *wxListBox::CreateItem(size_t n) +{ + return new wxListBoxItem(); } +#endif //USE_OWNER_DRAWN + // ============================================================================ // list box control implementation // ============================================================================ @@ -359,7 +505,6 @@ void wxListBox::MacDelete( int N ) { ListHandle list ; long result ; - Cell cell = { 0 , 0 } ; UMAGetControlData( m_macControl , kControlNoPart , kControlListBoxListHandleTag , sizeof( ListHandle ) , (char*) &list , &result ) ; LDelRow( 1 , N , list ) ; } @@ -455,7 +600,7 @@ void wxListBox::MacScrollTo( int n ) void wxListBox::OnSize( const wxSizeEvent &event) { Point pt = (**m_macList).cellSize ; - pt.h = m_width - 15 /* scrollbar */ - m_macHorizontalBorder * 2 ; + pt.h = m_width - 15 ; LCellSize( pt , m_macList ) ; } @@ -484,29 +629,27 @@ void wxListBox::MacSetRedraw( bool doDraw ) void wxListBox::MacDoClick() { wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId); + event.SetEventObject( this ); + wxArrayInt aSelections; - int count = GetSelections(aSelections); + int n, count = GetSelections(aSelections); if ( count > 0 ) { - event.m_commandInt = aSelections[0] ; - event.m_clientData = GetClientData(event.m_commandInt); - wxString str(GetString(event.m_commandInt)); - if (str != "") - event.m_commandString = copystring((char *)(const char *)str); + n = aSelections[0]; + if ( HasClientObjectData() ) + event.SetClientObject( GetClientObject(n) ); + else if ( HasClientUntypedData() ) + event.SetClientData( GetClientData(n) ); + event.SetString( GetString(n) ); } else { - return ; - /* - event.m_commandInt = -1 ; - event.m_commandString = copystring("") ; - */ + n = -1; } - event.SetEventObject( this ); - ProcessCommand(event); - if (event.m_commandString) - delete[] event.m_commandString ; + event.m_commandInt = n; + + GetEventHandler()->ProcessEvent(event); } void wxListBox::MacDoDoubleClick()