X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8907154c1a8a6882c6797d1f16393ddfb23e7f3a..7807a2b4998ef075b5ac7c05ab48274c28b477ba:/src/univ/listbox.cpp diff --git a/src/univ/listbox.cpp b/src/univ/listbox.cpp index a938fbd880..a2697e5b41 100644 --- a/src/univ/listbox.cpp +++ b/src/univ/listbox.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: univ/listbox.cpp +// Name: src/univ/listbox.cpp // Purpose: wxListBox implementation // Author: Vadim Zeitlin // Modified by: @@ -37,6 +37,62 @@ #include "wx/univ/inphand.h" #include "wx/univ/theme.h" +// ---------------------------------------------------------------------------- +// wxStdListboxInputHandler: handles mouse and kbd in a single or multi +// selection listbox +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxStdListboxInputHandler : public wxStdInputHandler +{ +public: + // if pressing the mouse button in a multiselection listbox should toggle + // the item under mouse immediately, then specify true as the second + // parameter (this is the standard behaviour, under GTK the item is toggled + // only when the mouse is released in the multi selection listbox) + wxStdListboxInputHandler(wxInputHandler *inphand, + bool toggleOnPressAlways = true); + + // base class methods + virtual bool HandleKey(wxInputConsumer *consumer, + const wxKeyEvent& event, + bool pressed); + virtual bool HandleMouse(wxInputConsumer *consumer, + const wxMouseEvent& event); + virtual bool HandleMouseMove(wxInputConsumer *consumer, + const wxMouseEvent& event); + +protected: + // return the item under mouse, 0 if the mouse is above the listbox or + // GetCount() if it is below it + int HitTest(const wxListBox *listbox, const wxMouseEvent& event); + + // parts of HitTest(): first finds the pseudo (because not in range) index + // of the item and the second one adjusts it if necessary - that is if the + // third one returns false + int HitTestUnsafe(const wxListBox *listbox, const wxMouseEvent& event); + int FixItemIndex(const wxListBox *listbox, int item); + bool IsValidIndex(const wxListBox *listbox, int item); + + // init m_btnCapture and m_actionMouse + wxControlAction SetupCapture(wxListBox *lbox, + const wxMouseEvent& event, + int item); + + wxRenderer *m_renderer; + + // the button which initiated the mouse capture (currently 0 or 1) + int m_btnCapture; + + // the action to perform when the mouse moves while we capture it + wxControlAction m_actionMouse; + + // the ctor parameter toggleOnPressAlways (see comments near it) + bool m_toggleOnPressAlways; + + // do we track the mouse outside the window when it is captured? + bool m_trackMouseOutside; +}; + // ============================================================================ // implementation of wxListBox // ============================================================================ @@ -84,6 +140,7 @@ wxListBox::wxListBox(wxWindow *parent, long style, const wxValidator& validator, const wxString &name) + :wxScrollHelper(this) { Init(); @@ -135,8 +192,6 @@ bool wxListBox::Create(wxWindow *parent, validator, name) ) return false; - SetWindow(this); - m_strings = new wxArrayString; Set(n, choices); @@ -169,7 +224,7 @@ int wxCMPFUNC_CONV wxListBoxSortNoCase(wxString* s1, wxString* s2) int wxListBox::DoAppendOnly(const wxString& item) { - size_t index; + unsigned int index; if ( IsSorted() ) { @@ -212,14 +267,14 @@ int wxListBox::DoAppend(const wxString& item) return index; } -void wxListBox::DoInsertItems(const wxArrayString& items, int pos) +void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) { // the position of the item being added to a sorted listbox can't be // specified wxCHECK_RET( !IsSorted(), _T("can't insert items into sorted listbox") ); - size_t count = items.GetCount(); - for ( size_t n = 0; n < count; n++ ) + unsigned int count = items.GetCount(); + for ( unsigned int n = 0; n < count; n++ ) { m_strings->Insert(items[n], pos + n); m_itemsClientData.Insert(NULL, pos + n); @@ -242,16 +297,16 @@ void wxListBox::DoSetItems(const wxArrayString& items, void **clientData) { DoClear(); - size_t count = items.GetCount(); + unsigned int count = items.GetCount(); if ( !count ) return; m_strings->Alloc(count); m_itemsClientData.Alloc(count); - for ( size_t n = 0; n < count; n++ ) + for ( unsigned int n = 0; n < count; n++ ) { - size_t index = DoAppendOnly(items[n]); + unsigned int index = DoAppendOnly(items[n]); m_itemsClientData.Insert(clientData ? clientData[n] : NULL, index); } @@ -261,7 +316,7 @@ void wxListBox::DoSetItems(const wxArrayString& items, void **clientData) RefreshAll(); } -void wxListBox::SetString(int n, const wxString& s) +void wxListBox::SetString(unsigned int n, const wxString& s) { wxCHECK_RET( !IsSorted(), _T("can't set string in sorted listbox") ); @@ -283,7 +338,7 @@ void wxListBox::SetString(int n, const wxString& s) m_updateScrollbarX = true; } // or also decreased if the old string was the longest one - else if ( n == m_maxWidthItem ) + else if ( n == (unsigned int)m_maxWidthItem ) { RefreshHorzScrollbar(); } @@ -302,8 +357,8 @@ void wxListBox::DoClear() if ( HasClientObjectData() ) { - size_t count = m_itemsClientData.GetCount(); - for ( size_t n = 0; n < count; n++ ) + unsigned int count = m_itemsClientData.GetCount(); + for ( unsigned int n = 0; n < count; n++ ) { delete (wxClientData *) m_itemsClientData[n]; } @@ -326,9 +381,9 @@ void wxListBox::Clear() RefreshAll(); } -void wxListBox::Delete(int n) +void wxListBox::Delete(unsigned int n) { - wxCHECK_RET( n >= 0 && n < GetCount(), + wxCHECK_RET( IsValid(n), _T("invalid index in wxListBox::Delete") ); // do it before removing the index as otherwise the last item will not be @@ -345,11 +400,11 @@ void wxListBox::Delete(int n) m_itemsClientData.RemoveAt(n); // when the item disappears we must not keep using its index - if ( n == m_current ) + if ( (int)n == m_current ) { m_current = -1; } - else if ( n < m_current ) + else if ( (int)n < m_current ) { m_current--; } @@ -358,15 +413,15 @@ void wxListBox::Delete(int n) // update the selections array: the indices of all seletected items after // the one being deleted must change and the item itselfm ust be removed int index = wxNOT_FOUND; - size_t count = m_selections.GetCount(); - for ( size_t item = 0; item < count; item++ ) + unsigned int count = m_selections.GetCount(); + for ( unsigned int item = 0; item < count; item++ ) { - if ( m_selections[item] == n ) + if ( m_selections[item] == (int)n ) { // remember to delete it later index = item; } - else if ( m_selections[item] > n ) + else if ( m_selections[item] > (int)n ) { // to account for the index shift m_selections[item]--; @@ -383,7 +438,7 @@ void wxListBox::Delete(int n) m_updateScrollbarY = true; // finally, if the longest item was deleted the scrollbar may disappear - if ( n == m_maxWidthItem ) + if ( (int)n == m_maxWidthItem ) { RefreshHorzScrollbar(); } @@ -393,22 +448,22 @@ void wxListBox::Delete(int n) // client data handling // ---------------------------------------------------------------------------- -void wxListBox::DoSetItemClientData(int n, void* clientData) +void wxListBox::DoSetItemClientData(unsigned int n, void* clientData) { m_itemsClientData[n] = clientData; } -void *wxListBox::DoGetItemClientData(int n) const +void *wxListBox::DoGetItemClientData(unsigned int n) const { return m_itemsClientData[n]; } -void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData) +void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) { m_itemsClientData[n] = clientData; } -wxClientData* wxListBox::DoGetItemClientObject(int n) const +wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const { return (wxClientData *)m_itemsClientData[n]; } @@ -462,10 +517,10 @@ void wxListBox::DoSetSelection(int n, bool select) int wxListBox::GetSelection() const { - wxCHECK_MSG( !HasMultipleSelection(), -1, + wxCHECK_MSG( !HasMultipleSelection(), wxNOT_FOUND, _T("use wxListBox::GetSelections for ths listbox") ); - return m_selections.IsEmpty() ? -1 : m_selections[0]; + return m_selections.IsEmpty() ? wxNOT_FOUND : m_selections[0]; } int wxCMPFUNC_CONV wxCompareInts(int *n, int *m) @@ -477,7 +532,7 @@ int wxListBox::GetSelections(wxArrayInt& selections) const { // always return sorted array to the user selections = m_selections; - size_t count = m_selections.GetCount(); + unsigned int count = m_selections.GetCount(); // don't call sort on an empty array if ( count ) @@ -575,9 +630,9 @@ void wxListBox::UpdateScrollbars() wxSize size = GetClientSize(); // is our height enough to show all items? - int nLines = GetCount(); + unsigned int nLines = GetCount(); wxCoord lineHeight = GetLineHeight(); - bool showScrollbarY = nLines*lineHeight > size.y; + bool showScrollbarY = (int)nLines*lineHeight > size.y; // check the width too if required wxCoord charWidth, maxWidth; @@ -706,9 +761,9 @@ void wxListBox::DoDraw(wxControlRenderer *renderer) // get the items which must be redrawn wxCoord lineHeight = GetLineHeight(); - size_t itemFirst = yTop / lineHeight, - itemLast = (yBottom + lineHeight - 1) / lineHeight, - itemMax = m_strings->GetCount(); + unsigned int itemFirst = yTop / lineHeight, + itemLast = (yBottom + lineHeight - 1) / lineHeight, + itemMax = m_strings->GetCount(); if ( itemFirst >= itemMax ) return; @@ -777,8 +832,8 @@ wxCoord wxListBox::GetMaxWidth() const { wxListBox *self = wxConstCast(this, wxListBox); wxCoord width; - size_t count = m_strings->GetCount(); - for ( size_t n = 0; n < count; n++ ) + unsigned int count = m_strings->GetCount(); + for ( unsigned int n = 0; n < count; n++ ) { GetTextExtent(this->GetString(n), &width, NULL); if ( width > m_maxWidth ) @@ -834,8 +889,8 @@ wxSize wxListBox::DoGetBestClientSize() const wxCoord width = 0, height = 0; - size_t count = m_strings->GetCount(); - for ( size_t n = 0; n < count; n++ ) + unsigned int count = m_strings->GetCount(); + for ( unsigned int n = 0; n < count; n++ ) { wxCoord w,h; GetTextExtent(this->GetString(n), &w, &h); @@ -914,8 +969,8 @@ void wxListBox::SetCurrentItem(int n) bool wxListBox::FindItem(const wxString& prefix, bool strictlyAfter) { - int count = GetCount(); - if ( !count ) + unsigned int count = GetCount(); + if ( count==0 ) { // empty listbox, we can't find anything in it return false; @@ -928,7 +983,7 @@ bool wxListBox::FindItem(const wxString& prefix, bool strictlyAfter) { // the following line will set first correctly to 0 if there is no // selection (m_current == -1) - first = m_current == count - 1 ? 0 : m_current + 1; + first = m_current == (int)(count - 1) ? 0 : m_current + 1; } else // start with the current { @@ -938,13 +993,13 @@ bool wxListBox::FindItem(const wxString& prefix, bool strictlyAfter) int last = first == 0 ? count - 1 : first - 1; // if this is not true we'd never exit from the loop below! - wxASSERT_MSG( first < count && last < count, _T("logic error") ); + wxASSERT_MSG( first < (int)count && last < (int)count, _T("logic error") ); // precompute it outside the loop size_t len = prefix.length(); // loop over all items in the listbox - for ( int item = first; item != last; item < count - 1 ? item++ : item = 0 ) + for ( int item = first; item != (int)last; item < (int)(count - 1) ? item++ : item = 0 ) { if ( wxStrnicmp(this->GetString(item).c_str(), prefix, len) == 0 ) { @@ -1056,8 +1111,8 @@ void wxListBox::ExtendSelection(int itemTo) SetSelection(n); } - int count = GetCount(); - for ( ; n < count; n++ ) + unsigned int count = GetCount(); + for ( ; n < (int)count; n++ ) { Deselect(n); } @@ -1191,6 +1246,14 @@ bool wxListBox::PerformAction(const wxControlAction& action, return true; } +/* static */ +wxInputHandler *wxListBox::GetStdInputHandler(wxInputHandler *handlerDef) +{ + static wxStdListboxInputHandler s_handler(handlerDef); + + return &s_handler; +} + // ============================================================================ // implementation of wxStdListboxInputHandler // ============================================================================ @@ -1231,7 +1294,7 @@ int wxStdListboxInputHandler::FixItemIndex(const wxListBox *lbox, // mouse is above the first item item = 0; } - else if ( item >= lbox->GetCount() ) + else if ( (unsigned int)item >= lbox->GetCount() ) { // mouse is below the last item item = lbox->GetCount() - 1; @@ -1242,7 +1305,7 @@ int wxStdListboxInputHandler::FixItemIndex(const wxListBox *lbox, bool wxStdListboxInputHandler::IsValidIndex(const wxListBox *lbox, int item) { - return item >= 0 && item < lbox->GetCount(); + return item >= 0 && (unsigned int)item < lbox->GetCount(); } wxControlAction @@ -1341,14 +1404,10 @@ bool wxStdListboxInputHandler::HandleKey(wxInputConsumer *consumer, break; case WXK_PAGEUP: - - case WXK_PRIOR: action = wxACTION_LISTBOX_PAGEUP; break; case WXK_PAGEDOWN: - - case WXK_NEXT: action = wxACTION_LISTBOX_PAGEDOWN; break;