]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/generic/ctrlsub.h
many wxItemContainer-related changes:
[wxWidgets.git] / include / wx / generic / ctrlsub.h
diff --git a/include/wx/generic/ctrlsub.h b/include/wx/generic/ctrlsub.h
new file mode 100644 (file)
index 0000000..425380d
--- /dev/null
@@ -0,0 +1,123 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        wx/generic/ctrlsub.h
+// Purpose:     common functionality of wxItemContainer-derived controls
+// Author:      Vadim Zeitlin
+// Created:     2007-07-25
+// RCS-ID:      $Id$
+// Copyright:   (c) 2007 Vadim Zeitlin <vadim@wxwindows.org>
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_GENERIC_CTRLSUB_H_
+#define _WX_GENERIC_CTRLSUB_H_
+
+#include "wx/dynarray.h"
+
+// ----------------------------------------------------------------------------
+// wxControlWithItemsGeneric: generic implementation of item client data
+// ----------------------------------------------------------------------------
+
+class wxControlWithItemsGeneric : public wxControlWithItemsBase
+{
+public:
+    wxControlWithItemsGeneric() { }
+
+    virtual void DoInitItemClientData()
+    {
+        m_itemsClientData.resize(GetCount(), NULL);
+    }
+
+    virtual void DoSetItemClientData(unsigned int n, void *clientData)
+    {
+        m_itemsClientData[n] = clientData;
+    }
+
+    virtual void *DoGetItemClientData(unsigned int n) const
+    {
+        return m_itemsClientData[n];
+    }
+
+    virtual void DoClear() { m_itemsClientData.clear(); }
+    virtual void DoDeleteOneItem(unsigned int pos)
+    {
+        if ( HasClientData() )
+            m_itemsClientData.RemoveAt(pos);
+    }
+
+protected:
+    // preallocate memory for numItems new items: this should be called from
+    // the derived classes DoInsertItems() to speed up appending big numbers of
+    // items with client data; it is safe to call even if we don't use client
+    // data at all and does nothing in this case
+    void AllocClientData(unsigned int numItems)
+    {
+        if ( HasClientData() )
+            m_itemsClientData.reserve(m_itemsClientData.size() + numItems);
+    }
+
+    // this must be called by derived classes when a new item is added to the
+    // control to add storage for the corresponding client data pointer (before
+    // inserting many items, call AllocClientData())
+    void InsertNewItemClientData(unsigned int pos,
+                                 void **clientData,
+                                 unsigned int n,
+                                 wxClientDataType type)
+    {
+        if ( InitClientDataIfNeeded(type) )
+            m_itemsClientData.Insert(clientData[n], pos);
+    }
+
+    // the same as InsertNewItemClientData() but for numItems consecutive items
+    // (this can only be used if the control doesn't support sorting as
+    // otherwise the items positions wouldn't be consecutive any more)
+    void InsertNewItemsClientData(unsigned int pos,
+                                  unsigned int numItems,
+                                  void **clientData,
+                                  wxClientDataType type)
+    {
+        if ( InitClientDataIfNeeded(type) )
+        {
+            // it's more efficient to insert everything at once and then update
+            // for big number of items to avoid moving the array contents
+            // around (which would result in O(N^2) algorithm)
+            m_itemsClientData.Insert(NULL, pos, numItems);
+
+            for ( unsigned int n = 0; n < numItems; ++n, ++pos )
+                m_itemsClientData[pos] = clientData[n];
+        }
+    }
+
+
+    // vector containing the client data pointers: it is either empty (if
+    // client data is not used) or has the same number of elements as the
+    // control
+    wxArrayPtrVoid m_itemsClientData;
+
+private:
+    // initialize client data if needed, return false if we don't have any
+    // client data and true otherwise
+    bool InitClientDataIfNeeded(wxClientDataType type)
+    {
+        if ( !HasClientData() )
+        {
+            if ( type == wxClientData_None )
+            {
+                // we didn't have the client data before and are not asked to
+                // store it now neither
+                return false;
+            }
+
+            // this is the first time client data is used with this control
+            DoInitItemClientData();
+            m_clientDataItemsType = type;
+        }
+        //else: we already have client data
+
+        return true;
+    }
+
+    DECLARE_NO_COPY_CLASS(wxControlWithItemsGeneric)
+};
+
+#endif // _WX_GENERIC_CTRLSUB_H_
+