]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/listbox.cpp
concentrating content and structure region calculations
[wxWidgets.git] / src / univ / listbox.cpp
index 65c41bc9dfad0b3eec2e8d964b0b964efee5a13e..d05da69d53f92793babfe4d21e0fbadc8b506946 100644 (file)
@@ -17,7 +17,7 @@
 // headers
 // ----------------------------------------------------------------------------
 
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "univlistbox.h"
 #endif
 
     #pragma implementation "univlistbox.h"
 #endif
 
@@ -49,8 +49,6 @@ IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
 
 BEGIN_EVENT_TABLE(wxListBox, wxListBoxBase)
     EVT_SIZE(wxListBox::OnSize)
 
 BEGIN_EVENT_TABLE(wxListBox, wxListBoxBase)
     EVT_SIZE(wxListBox::OnSize)
-
-    EVT_IDLE(wxListBox::OnIdle)
 END_EVENT_TABLE()
 
 // ----------------------------------------------------------------------------
 END_EVENT_TABLE()
 
 // ----------------------------------------------------------------------------
@@ -65,6 +63,7 @@ void wxListBox::Init()
     m_maxWidth = 0;
     m_scrollRangeY = 0;
     m_maxWidthItem = -1;
     m_maxWidth = 0;
     m_scrollRangeY = 0;
     m_maxWidthItem = -1;
+    m_strings = NULL;
 
     // no items hence no current item
     m_current = -1;
 
     // no items hence no current item
     m_current = -1;
@@ -81,6 +80,35 @@ void wxListBox::Init()
     m_showScrollbarY = FALSE;
 }
 
     m_showScrollbarY = FALSE;
 }
 
+wxListBox::wxListBox(wxWindow *parent,
+                     wxWindowID id,
+                     const wxPoint &pos,
+                     const wxSize &size,
+                     const wxArrayString& choices,
+                     long style,
+                     const wxValidator& validator,
+                     const wxString &name)
+{
+    Init();
+
+    Create(parent, id, pos, size, choices, style, validator, name);
+}
+
+bool wxListBox::Create(wxWindow *parent,
+                       wxWindowID id,
+                       const wxPoint &pos,
+                       const wxSize &size,
+                       const wxArrayString& choices,
+                       long style,
+                       const wxValidator& validator,
+                       const wxString &name)
+{
+    wxCArrayString chs(choices);
+
+    return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
+                  style, validator, name);
+}
+
 bool wxListBox::Create(wxWindow *parent,
                        wxWindowID id,
                        const wxPoint &pos,
 bool wxListBox::Create(wxWindow *parent,
                        wxWindowID id,
                        const wxPoint &pos,
@@ -101,13 +129,22 @@ bool wxListBox::Create(wxWindow *parent,
     if ( !(style & (wxLB_MULTIPLE | wxLB_EXTENDED)) )
         style |= wxLB_SINGLE;
 
     if ( !(style & (wxLB_MULTIPLE | wxLB_EXTENDED)) )
         style |= wxLB_SINGLE;
 
-    if ( !wxControl::Create(parent, id, pos, size, style | wxVSCROLL , wxDefaultValidator, name) )
+#if wxUSE_TWO_WINDOWS
+    style |=  wxVSCROLL|wxHSCROLL;
+    if ((style & wxBORDER_MASK) == 0)
+        style |= wxBORDER_SUNKEN;
+#endif
+
+    if ( !wxControl::Create(parent, id, pos, size, style, 
+                            validator, name) )
         return FALSE;
 
     SetWindow(this);
 
     if ( style & wxLB_SORT )
         return FALSE;
 
     SetWindow(this);
 
     if ( style & wxLB_SORT )
-        m_strings = wxArrayString(TRUE /* auto sort */);
+        m_stringsSorted = new wxSortedArrayString;
+    else
+        m_strings = new wxArrayString;
 
     Set(n, choices);
 
 
     Set(n, choices);
 
@@ -120,6 +157,15 @@ bool wxListBox::Create(wxWindow *parent,
 
 wxListBox::~wxListBox()
 {
 
 wxListBox::~wxListBox()
 {
+    // call this just to free the client data -- and avoid leaking memory
+    DoClear();
+
+    if ( IsSorted() )
+        delete m_stringsSorted;
+    else
+        delete m_strings;
+
+    m_strings = NULL;
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -128,7 +174,18 @@ wxListBox::~wxListBox()
 
 int wxListBox::DoAppend(const wxString& item)
 {
 
 int wxListBox::DoAppend(const wxString& item)
 {
-    size_t index = m_strings.Add(item);
+    size_t index;
+
+    if ( IsSorted() )
+    {
+        index = m_stringsSorted->Add(item);
+    }
+    else
+    {
+        index = m_strings->GetCount();
+        m_strings->Add(item);
+    }
+
     m_itemsClientData.Insert(NULL, index);
 
     m_updateScrollbarY = TRUE;
     m_itemsClientData.Insert(NULL, index);
 
     m_updateScrollbarY = TRUE;
@@ -160,7 +217,7 @@ void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
     size_t count = items.GetCount();
     for ( size_t n = 0; n < count; n++ )
     {
     size_t count = items.GetCount();
     for ( size_t n = 0; n < count; n++ )
     {
-        m_strings.Insert(items[n], pos + n);
+        m_strings->Insert(items[n], pos + n);
         m_itemsClientData.Insert(NULL, pos + n);
     }
 
         m_itemsClientData.Insert(NULL, pos + n);
     }
 
@@ -185,11 +242,22 @@ void wxListBox::DoSetItems(const wxArrayString& items, void **clientData)
     if ( !count )
         return;
 
     if ( !count )
         return;
 
-    m_strings.Alloc(count);
+    m_strings->Alloc(count);
     m_itemsClientData.Alloc(count);
     for ( size_t n = 0; n < count; n++ )
     {
     m_itemsClientData.Alloc(count);
     for ( size_t n = 0; n < count; n++ )
     {
-        size_t index = m_strings.Add(items[n]);
+        size_t index;
+
+        if ( IsSorted() )
+        {
+            index = m_stringsSorted->Add(items[n]);
+        }
+        else
+        {
+            index = m_strings->GetCount();
+            m_strings->Add(items[n]);
+        }
+
         m_itemsClientData.Insert(clientData ? clientData[n] : NULL, index);
     }
 
         m_itemsClientData.Insert(clientData ? clientData[n] : NULL, index);
     }
 
@@ -205,7 +273,7 @@ void wxListBox::SetString(int n, const wxString& s)
         // we need to update m_maxWidth as changing the string may cause the
         // horz scrollbar [dis]appear
         wxCoord width;
         // we need to update m_maxWidth as changing the string may cause the
         // horz scrollbar [dis]appear
         wxCoord width;
-        m_strings[n] = s;
+        (*m_strings)[n] = s;
         GetTextExtent(s, &width, NULL);
 
         // it might have increased if the new string is long
         GetTextExtent(s, &width, NULL);
 
         // it might have increased if the new string is long
@@ -223,7 +291,7 @@ void wxListBox::SetString(int n, const wxString& s)
     }
     else // no horz scrollbar
     {
     }
     else // no horz scrollbar
     {
-        m_strings[n] = s;
+        (*m_strings)[n] = s;
     }
 
     RefreshItem(n);
     }
 
     RefreshItem(n);
@@ -235,7 +303,7 @@ void wxListBox::SetString(int n, const wxString& s)
 
 void wxListBox::DoClear()
 {
 
 void wxListBox::DoClear()
 {
-    m_strings.Clear();
+    m_strings->Clear();
 
     if ( HasClientObjectData() )
     {
 
     if ( HasClientObjectData() )
     {
@@ -265,13 +333,14 @@ void wxListBox::Clear()
 
 void wxListBox::Delete(int n)
 {
 
 void wxListBox::Delete(int n)
 {
-    wxCHECK_RET( n < GetCount(), _T("invalid index in wxListBox::Delete") );
+    wxCHECK_RET( n >= 0 && n < GetCount(),
+                 _T("invalid index in wxListBox::Delete") );
 
     // do it before removing the index as otherwise the last item will not be
     // refreshed (as GetCount() will be decremented)
     RefreshFromItemToEnd(n);
 
 
     // do it before removing the index as otherwise the last item will not be
     // refreshed (as GetCount() will be decremented)
     RefreshFromItemToEnd(n);
 
-    m_strings.RemoveAt(n);
+    m_strings->RemoveAt(n);
 
     if ( HasClientObjectData() )
     {
 
     if ( HasClientObjectData() )
     {
@@ -591,7 +660,7 @@ void wxListBox::UpdateItems()
     }
 }
 
     }
 }
 
-void wxListBox::OnIdle(wxIdleEvent& event)
+void wxListBox::OnInternalIdle()
 {
     if ( m_updateScrollbarY || m_updateScrollbarX )
     {
 {
     if ( m_updateScrollbarY || m_updateScrollbarX )
     {
@@ -614,8 +683,7 @@ void wxListBox::OnIdle(wxIdleEvent& event)
 
         m_updateCount = 0;
     }
 
         m_updateCount = 0;
     }
-
-    event.Skip();
+    wxListBoxBase::OnInternalIdle();
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -645,7 +713,7 @@ void wxListBox::DoDraw(wxControlRenderer *renderer)
     wxCoord lineHeight = GetLineHeight();
     size_t itemFirst = yTop / lineHeight,
            itemLast = (yBottom + lineHeight - 1) / lineHeight,
     wxCoord lineHeight = GetLineHeight();
     size_t itemFirst = yTop / lineHeight,
            itemLast = (yBottom + lineHeight - 1) / lineHeight,
-           itemMax = m_strings.GetCount();
+           itemMax = m_strings->GetCount();
 
     if ( itemFirst >= itemMax )
         return;
 
     if ( itemFirst >= itemMax )
         return;
@@ -714,10 +782,10 @@ wxCoord wxListBox::GetMaxWidth() const
     {
         wxListBox *self = wxConstCast(this, wxListBox);
         wxCoord width;
     {
         wxListBox *self = wxConstCast(this, wxListBox);
         wxCoord width;
-        size_t count = m_strings.GetCount();
+        size_t count = m_strings->GetCount();
         for ( size_t n = 0; n < count; n++ )
         {
         for ( size_t n = 0; n < count; n++ )
         {
-            GetTextExtent(m_strings[n], &width, NULL);
+            GetTextExtent((*m_strings)[n], &width, NULL);
             if ( width > m_maxWidth )
             {
                 self->m_maxWidth = width;
             if ( width > m_maxWidth )
             {
                 self->m_maxWidth = width;
@@ -763,7 +831,7 @@ void wxListBox::DoSetSize(int x, int y,
         height = ((height - hBorders + hLine - 1) / hLine)*hLine + hBorders;
     }
 
         height = ((height - hBorders + hLine - 1) / hLine)*hLine + hBorders;
     }
 
-    wxListBoxBase::DoSetSize(x, y, width, height);
+    wxListBoxBase::DoSetSize(x, y, width, height, sizeFlags);
 }
 
 wxSize wxListBox::DoGetBestClientSize() const
 }
 
 wxSize wxListBox::DoGetBestClientSize() const
@@ -771,11 +839,11 @@ wxSize wxListBox::DoGetBestClientSize() const
     wxCoord width = 0,
             height = 0;
 
     wxCoord width = 0,
             height = 0;
 
-    size_t count = m_strings.GetCount();
+    size_t count = m_strings->GetCount();
     for ( size_t n = 0; n < count; n++ )
     {
         wxCoord w,h;
     for ( size_t n = 0; n < count; n++ )
     {
         wxCoord w,h;
-        GetTextExtent(m_strings[n], &w, &h);
+        GetTextExtent((*m_strings)[n], &w, &h);
 
         if ( w > width )
             width = w;
 
         if ( w > width )
             width = w;
@@ -883,7 +951,7 @@ bool wxListBox::FindItem(const wxString& prefix, bool strictlyAfter)
     // loop over all items in the listbox
     for ( int item = first; item != last; item < count - 1 ? item++ : item = 0 )
     {
     // loop over all items in the listbox
     for ( int item = first; item != last; item < count - 1 ? item++ : item = 0 )
     {
-        if ( wxStrnicmp(m_strings[item], prefix, len) == 0 )
+        if ( wxStrnicmp((*m_strings)[item], prefix, len) == 0 )
         {
             SetCurrentItem(item);
 
         {
             SetCurrentItem(item);
 
@@ -1000,7 +1068,7 @@ void wxListBox::ExtendSelection(int itemTo)
     }
 }
 
     }
 }
 
-void wxListBox::Select(bool sel, int item)
+void wxListBox::DoSelect(int item, bool sel)
 {
     if ( item != -1 )
     {
 {
     if ( item != -1 )
     {
@@ -1020,7 +1088,7 @@ void wxListBox::Select(bool sel, int item)
 
 void wxListBox::SelectAndNotify(int item)
 {
 
 void wxListBox::SelectAndNotify(int item)
 {
-    Select(TRUE, item);
+    DoSelect(item);
 
     SendEvent(wxEVT_COMMAND_LISTBOX_SELECTED);
 }
 
     SendEvent(wxEVT_COMMAND_LISTBOX_SELECTED);
 }
@@ -1039,7 +1107,7 @@ void wxListBox::Activate(int item)
 
     if ( item != -1 )
     {
 
     if ( item != -1 )
     {
-        Select(TRUE, item);
+        DoSelect(item);
 
         SendEvent(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED);
     }
 
         SendEvent(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED);
     }
@@ -1082,7 +1150,7 @@ bool wxListBox::PerformAction(const wxControlAction& action,
             item = m_current;
 
         if ( IsSelected(item) )
             item = m_current;
 
         if ( IsSelected(item) )
-            Unselect(item);
+            DoUnselect(item);
         else
             SelectAndNotify(item);
     }
         else
             SelectAndNotify(item);
     }
@@ -1093,12 +1161,12 @@ bool wxListBox::PerformAction(const wxControlAction& action,
         if ( strArg.empty() )
             SelectAndNotify(item);
         else
         if ( strArg.empty() )
             SelectAndNotify(item);
         else
-            Select(TRUE, item);
+            DoSelect(item);
     }
     else if ( action == wxACTION_LISTBOX_SELECTADD )
     }
     else if ( action == wxACTION_LISTBOX_SELECTADD )
-        Select(TRUE, item);
+        DoSelect(item);
     else if ( action == wxACTION_LISTBOX_UNSELECT )
     else if ( action == wxACTION_LISTBOX_UNSELECT )
-        Select(FALSE, item);
+        DoUnselect(item);
     else if ( action == wxACTION_LISTBOX_MOVEDOWN )
         ChangeCurrent(1);
     else if ( action == wxACTION_LISTBOX_MOVEUP )
     else if ( action == wxACTION_LISTBOX_MOVEDOWN )
         ChangeCurrent(1);
     else if ( action == wxACTION_LISTBOX_MOVEUP )