]> git.saurik.com Git - wxWidgets.git/commitdiff
Implement best size calculation for report mode wxListCtrl.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sat, 7 Jan 2012 15:09:43 +0000 (15:09 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sat, 7 Jan 2012 15:09:43 +0000 (15:09 +0000)
Use the column labels to determine the minimal width required by the control
to show them all in full.

Also declare all image list and column-related wxListCtrl methods in
wxListCtrlBase now as we need some of them in DoGetBestClientSize()
implementation.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@70282 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
include/wx/generic/listctrl.h
include/wx/generic/private/listctrl.h
include/wx/listbase.h
include/wx/msw/listctrl.h
include/wx/osx/listctrl.h
src/common/listctrlcmn.cpp
src/generic/listctrl.cpp
src/msw/listctrl.cpp
src/osx/carbon/listctrl_mac.cpp

index d36572119a79146b3ea541498e57008b010f1218..7bf55bb1f9740c797b6f119fcf2fc8aad42d8c83 100644 (file)
@@ -465,6 +465,7 @@ All (GUI):
 - Allow using wxEVT_UPDATE_UI with wxRibbonButtonBar (Emilien Kia).
 - Add wxRibbonButtonBar::InsertXXXButton() methods (Emilien Kia).
 - Fix multiple item selection in generic wxTreeCtrl (Igor Korot).
+- Implement best size calculation for report mode wxListCtrl.
 
 GTK:
 
index 5b8de4c7c6a6240c8effe3a2691e5b35c67243f0..4117b7a9d1c25dcf4ecb8f7f876ffda0cfd969d0 100644 (file)
@@ -14,8 +14,6 @@
 #include "wx/scrolwin.h"
 #include "wx/textctrl.h"
 
-class WXDLLIMPEXP_FWD_CORE wxImageList;
-
 #if wxUSE_DRAG_AND_DROP
 class WXDLLIMPEXP_FWD_CORE wxDropTarget;
 #endif
@@ -66,7 +64,7 @@ public:
                  const wxString &name = wxListCtrlNameStr);
 
     bool GetColumn( int col, wxListItem& item ) const;
-    bool SetColumn( int col, wxListItem& item );
+    bool SetColumn( int col, const wxListItem& item );
     int GetColumnWidth( int col ) const;
     bool SetColumnWidth( int col, int width);
     int GetCountPerPage() const; // not the same in wxGLC as in Windows, I think
@@ -134,9 +132,6 @@ public:
     long InsertItem( long index, const wxString& label );
     long InsertItem( long index, int imageIndex );
     long InsertItem( long index, const wxString& label, int imageIndex );
-    long InsertColumn( long col, wxListItem& info );
-    long InsertColumn( long col, const wxString& heading,
-                       int format = wxLIST_FORMAT_LEFT, int width = -1 );
     bool ScrollList( int dx, int dy );
     bool SortItems( wxListCtrlCompare fn, wxIntPtr data );
 
@@ -208,6 +203,10 @@ public:
     wxListMainWindow    *m_mainWin;
 
 protected:
+    // Implement base class pure virtual methods.
+    long DoInsertColumn(long col, const wxListItem& info);
+
+
     virtual bool DoPopupMenu( wxMenu *menu, int x, int y );
 
     // take into account the coordinates difference between the container
index 30dc76f73647ad3c03418a2224703e789f9dee6b..66752660c6eb8a268ab2fc96f7469863380e3e83 100644 (file)
@@ -581,7 +581,7 @@ public:
     void SetItemSpacing( int spacing, bool isSmall = false );
     int GetItemSpacing( bool isSmall = false );
 
-    void SetColumn( int col, wxListItem &item );
+    void SetColumn( int col, const wxListItem &item );
     void SetColumnWidth( int col, int width );
     void GetColumn( int col, wxListItem &item ) const;
     int GetColumnWidth( int col ) const;
@@ -645,7 +645,7 @@ public:
     long FindItem( const wxPoint& pt );
     long HitTest( int x, int y, int &flags ) const;
     void InsertItem( wxListItem &item );
-    void InsertColumn( long col, wxListItem &item );
+    void InsertColumn( long col, const wxListItem &item );
     int GetItemWidthWithImage(wxListItem * item);
     void SortItems( wxListCtrlCompare fn, wxIntPtr data );
 
index 55849b3c762f8c9621c171165021b9d21d7f1ec9..85450e236ced47cdafe709dc426f679aa2a69a6f 100644 (file)
@@ -17,6 +17,8 @@
 #include "wx/gdicmn.h"
 #include "wx/event.h"
 
+class WXDLLIMPEXP_FWD_CORE wxImageList;
+
 // ----------------------------------------------------------------------------
 // types
 // ----------------------------------------------------------------------------
@@ -384,9 +386,72 @@ class WXDLLIMPEXP_CORE wxListCtrlBase : public wxControl
 public:
     wxListCtrlBase() { }
 
+    // Image list methods.
+    // -------------------
+
+    // Associate the given (possibly NULL to indicate that no images will be
+    // used) image list with the control. The ownership of the image list
+    // passes to the control, i.e. it will be deleted when the control itself
+    // is destroyed.
+    //
+    // The value of "which" must be one of wxIMAGE_LIST_{NORMAL,SMALL,STATE}.
+    virtual void AssignImageList(wxImageList* imageList, int which) = 0;
+
+    // Same as AssignImageList() but the control does not delete the image list
+    // so it can be shared among several controls.
+    virtual void SetImageList(wxImageList* imageList, int which) = 0;
+
+    // Return the currently used image list, may be NULL.
+    virtual wxImageList* GetImageList(int which) const = 0;
+
+
+    // Column-related methods.
+    // -----------------------
+
+    // All these methods can only be used in report view mode.
+
+    // Add a new column to the control at the position "col".
+    //
+    // Returns the index of the newly inserted column or -1 on error.
+    long InsertColumn(long col, const wxListItem& info);
+    long InsertColumn(long col,
+                      const wxString& heading,
+                      int format = wxLIST_FORMAT_LEFT,
+                      int width = -1);
+
+    // Delete the given or all columns.
+    virtual bool DeleteColumn(int col) = 0;
+    virtual bool DeleteAllColumns() = 0;
+
+    // Return the current number of columns.
+    virtual int GetColumnCount() const = 0;
+
+    // Get or update information about the given column. Set item mask to
+    // indicate the fields to retrieve or change.
+    //
+    // Returns false on error, e.g. if the column index is invalid.
+    virtual bool GetColumn(int col, wxListItem& item) const = 0;
+    virtual bool SetColumn(int col, const wxListItem& item) = 0;
+
+    // Convenient wrappers for the above methods which get or update just the
+    // column width.
+    virtual int GetColumnWidth(int col) const = 0;
+    virtual bool SetColumnWidth(int col, int width) = 0;
+
+
+    // Other miscellaneous accessors.
+    // ------------------------------
+
     // Convenient functions for testing the list control mode:
     bool InReportView() const { return HasFlag(wxLC_REPORT); }
     bool IsVirtual() const { return HasFlag(wxLC_VIRTUAL); }
+
+protected:
+    // Real implementations methods to which our public forwards.
+    virtual long DoInsertColumn(long col, const wxListItem& info) = 0;
+
+    // Overridden methods of the base class.
+    virtual wxSize DoGetBestClientSize() const;
 };
 
 // ----------------------------------------------------------------------------
index c4cb6597ac9e5659427596c007fff43692c95a55..75c30270be549118c96cbe55c34e7c3d56d5526a 100644 (file)
@@ -16,7 +16,6 @@
 #include "wx/dynarray.h"
 #include "wx/vector.h"
 
-class WXDLLIMPEXP_FWD_CORE wxImageList;
 class wxMSWListItemData;
 
 // define this symbol to indicate the availability of SetColumnsOrder() and
@@ -320,14 +319,6 @@ public:
     // Insert an image/string item
     long InsertItem(long index, const wxString& label, int imageIndex);
 
-    // For list view mode (only), inserts a column.
-    long InsertColumn(long col, const wxListItem& info);
-
-    long InsertColumn(long col,
-                      const wxString& heading,
-                      int format = wxLIST_FORMAT_LEFT,
-                      int width = -1);
-
     // set the number of items in a virtual list control
     void SetItemCount(long count);
 
@@ -393,6 +384,9 @@ protected:
     // common part of all ctors
     void Init();
 
+    // Implement base class pure virtual methods.
+    long DoInsertColumn(long col, const wxListItem& info);
+
     // free memory taken by all internal data
     void FreeAllInternalData();
 
index 0e9fcf122602b5d77e2f52e5ad73a80eb880ae9d..23b660dfdd8fff53851beaa30486d8b228f8f2c9 100644 (file)
@@ -252,12 +252,6 @@ class WXDLLIMPEXP_CORE wxListCtrl: public wxListCtrlBase
   // Insert an image/string item
   long InsertItem(long index, const wxString& label, int imageIndex);
 
-  // For list view mode (only), inserts a column.
-  long InsertColumn(long col, wxListItem& info);
-
-  long InsertColumn(long col, const wxString& heading, int format = wxLIST_FORMAT_LEFT,
-    int width = -1);
-
   // Scrolls the list control. If in icon, small icon or report view mode,
   // x specifies the number of pixels to scroll. If in list view mode, x
   // specifies the number of columns to scroll.
@@ -371,14 +365,14 @@ class WXDLLIMPEXP_CORE wxListCtrl: public wxListCtrlBase
   GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);
 
 protected:
+  // Implement base class pure virtual methods.
+  long DoInsertColumn(long col, const wxListItem& info);
 
   // protected overrides needed for pimpl approach
   virtual void DoSetSize(int x, int y,
                          int width, int height,
                          int sizeFlags = wxSIZE_AUTO);
 
-  virtual wxSize DoGetBestSize() const;
-
   long               m_current;
   wxListCtrlTextCtrlWrapper *m_textctrlWrapper;
   wxListCtrlRenameTimer *m_renameTimer;
index e2b18e9602ea2278937df9ab21c41b42e124e9ea..861beef99454112132f73f330a6cc641057ae219 100644 (file)
 
 #include "wx/listctrl.h"
 
+#ifndef WX_PRECOMP
+    #include "wx/dcclient.h"
+#endif
+
 const char wxListCtrlNameStr[] = "listCtrl";
 
 // ListCtrl events
@@ -128,4 +132,73 @@ IMPLEMENT_DYNAMIC_CLASS(wxListView, wxListCtrl)
 IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject)
 IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxNotifyEvent)
 
+// ----------------------------------------------------------------------------
+// wxListCtrlBase implementation
+// ----------------------------------------------------------------------------
+
+long
+wxListCtrlBase::InsertColumn(long col,
+                             const wxString& heading,
+                             int format,
+                             int width)
+{
+    wxListItem item;
+    item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
+    item.m_text = heading;
+    if ( width > -1 )
+    {
+        item.m_mask |= wxLIST_MASK_WIDTH;
+        item.m_width = width;
+    }
+    item.m_format = format;
+
+    return InsertColumn(col, item);
+}
+
+long wxListCtrlBase::InsertColumn(long col, const wxListItem& info)
+{
+    long rc = DoInsertColumn(col, info);
+    if ( rc != -1 )
+    {
+        // As our best size calculation depends on the column headers,
+        // invalidate the previously cached best size when a column is added.
+        InvalidateBestSize();
+    }
+
+    return rc;
+}
+
+wxSize wxListCtrlBase::DoGetBestClientSize() const
+{
+    // There is no obvious way to determine the best size in icon and list
+    // modes so just don't do it for now.
+    if ( !InReportView() )
+        return wxControl::DoGetBestClientSize();
+
+    // In report mode, we use only the column headers, not items, to determine
+    // the best width. The reason for this is that it's easier (we can't just
+    // iterate over all items, especially not in a virtual control, so we'd
+    // have to do something relatively complicated such as checking the size of
+    // some items in the beginning and the end only) and also because the
+    // columns are usually static while the list contents is dynamic so it
+    // usually doesn't make much sense to adjust the control size to it anyhow.
+    // And finally, scrollbars can always be used with the items while the
+    // headers are just truncated if there is not enough place for them.
+    const int columns = GetColumnCount();
+    if ( HasFlag(wxLC_NO_HEADER) || !columns )
+        return wxControl::DoGetBestClientSize();
+
+    wxClientDC dc(const_cast<wxListCtrlBase*>(this));
+
+    // Total width of all headers determines the best control width.
+    int totalWidth = 0;
+    for ( int col = 0; col < columns; col++ )
+    {
+        totalWidth += GetColumnWidth(col);
+    }
+
+    // Use some arbitrary height, there is no good way to determine it.
+    return wxSize(totalWidth, 10*dc.GetCharHeight());
+}
+
 #endif // wxUSE_LISTCTRL
index 49d023895badc4aebf1afa2cf7ac333d2c21db7f..d6c70b065f2627260daaedd5da2ea340df146a40 100644 (file)
@@ -3017,18 +3017,18 @@ int wxListMainWindow::GetItemSpacing( bool isSmall )
 // columns
 // ----------------------------------------------------------------------------
 
-void wxListMainWindow::SetColumn( int col, wxListItem &item )
+void wxListMainWindow::SetColumn( int col, const wxListItem &item )
 {
     wxListHeaderDataList::compatibility_iterator node = m_columns.Item( col );
 
     wxCHECK_RET( node, wxT("invalid column index in SetColumn") );
 
-    if ( item.m_width == wxLIST_AUTOSIZE_USEHEADER )
-        item.m_width = GetTextLength( item.m_text );
-
     wxListHeaderData *column = node->GetData();
     column->SetItem( item );
 
+    if ( item.m_width == wxLIST_AUTOSIZE_USEHEADER )
+        column->SetWidth(GetTextLength( item.m_text ));
+
     wxListHeaderWindow *headerWin = GetListCtrl()->m_headerWin;
     if ( headerWin )
         headerWin->m_dirty = true;
@@ -4122,15 +4122,15 @@ void wxListMainWindow::InsertItem( wxListItem &item )
     RefreshLines(id, GetItemCount() - 1);
 }
 
-void wxListMainWindow::InsertColumn( long col, wxListItem &item )
+void wxListMainWindow::InsertColumn( long col, const wxListItem &item )
 {
     m_dirty = true;
     if ( InReportView() )
     {
+        wxListHeaderData *column = new wxListHeaderData( item );
         if (item.m_width == wxLIST_AUTOSIZE_USEHEADER)
-            item.m_width = GetTextLength( item.m_text );
+            column->SetWidth(GetTextLength( item.m_text ));
 
-        wxListHeaderData *column = new wxListHeaderData( item );
         wxColWidthInfo *colWidthInfo = new wxColWidthInfo();
 
         bool insert = (col >= 0) && ((size_t)col < m_columns.GetCount());
@@ -4528,7 +4528,7 @@ bool wxGenericListCtrl::GetColumn(int col, wxListItem &item) const
     return true;
 }
 
-bool wxGenericListCtrl::SetColumn( int col, wxListItem& item )
+bool wxGenericListCtrl::SetColumn( int col, const wxListItem& item )
 {
     m_mainWin->SetColumn( col, item );
     return true;
@@ -4945,7 +4945,7 @@ long wxGenericListCtrl::InsertItem( long index, const wxString &label, int image
     return InsertItem( info );
 }
 
-long wxGenericListCtrl::InsertColumn( long col, wxListItem &item )
+long wxGenericListCtrl::DoInsertColumn( long col, const wxListItem &item )
 {
     wxCHECK_MSG( InReportView(), -1, wxT("can't add column in non report mode") );
 
@@ -4959,23 +4959,6 @@ long wxGenericListCtrl::InsertColumn( long col, wxListItem &item )
     return 0;
 }
 
-long wxGenericListCtrl::InsertColumn( long col, const wxString &heading,
-                               int format, int width )
-{
-    wxListItem item;
-    item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
-    item.m_text = heading;
-    if (width >= -2)
-    {
-        item.m_mask |= wxLIST_MASK_WIDTH;
-        item.m_width = width;
-    }
-
-    item.m_format = format;
-
-    return InsertColumn( col, item );
-}
-
 bool wxGenericListCtrl::ScrollList( int dx, int dy )
 {
     return m_mainWin->ScrollList(dx, dy);
index 45e1d0c50360fa2fdc352201d10d472d6770d5f4..0d8ee0e785ce007fdb6ceacd1bf2c011343bcfbb 100644 (file)
@@ -1730,7 +1730,7 @@ long wxListCtrl::InsertItem(long index, const wxString& label, int imageIndex)
 }
 
 // For list view mode (only), inserts a column.
-long wxListCtrl::InsertColumn(long col, const wxListItem& item)
+long wxListCtrl::DoInsertColumn(long col, const wxListItem& item)
 {
     LV_COLUMN lvCol;
     wxConvertToMSWListCol(GetHwnd(), col, item, lvCol);
@@ -1757,24 +1757,6 @@ long wxListCtrl::InsertColumn(long col, const wxListItem& item)
     return n;
 }
 
-long wxListCtrl::InsertColumn(long col,
-                              const wxString& heading,
-                              int format,
-                              int width)
-{
-    wxListItem item;
-    item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
-    item.m_text = heading;
-    if ( width > -1 )
-    {
-        item.m_mask |= wxLIST_MASK_WIDTH;
-        item.m_width = width;
-    }
-    item.m_format = format;
-
-    return InsertColumn(col, item);
-}
-
 // scroll the control by the given number of pixels (exception: in list view,
 // dx is interpreted as number of columns)
 bool wxListCtrl::ScrollList(int dx, int dy)
index 96d9a10738ca8634467f61e59195393f2ad15dbb..40b16b2ba88ac17a88306ac8b583932a6d553a69 100644 (file)
@@ -801,11 +801,6 @@ void wxListCtrl::DoSetSize( int x, int y, int width, int height, int sizeFlags )
     }
 }
 
-wxSize wxListCtrl::DoGetBestSize() const
-{
-    return wxWindow::DoGetBestSize();
-}
-
 bool wxListCtrl::SetFont(const wxFont& font)
 {
     bool rv = true;
@@ -2161,7 +2156,7 @@ long wxListCtrl::InsertItem(long index, const wxString& label, int imageIndex)
 }
 
 // For list view mode (only), inserts a column.
-long wxListCtrl::InsertColumn(long col, wxListItem& item)
+long wxListCtrl::DoInsertColumn(long col, wxListItem& item)
 {
     if (m_genericImpl)
         return m_genericImpl->InsertColumn(col, item);
@@ -2214,27 +2209,6 @@ long wxListCtrl::InsertColumn(long col, wxListItem& item)
     return col;
 }
 
-long wxListCtrl::InsertColumn(long col,
-                              const wxString& heading,
-                              int format,
-                              int width)
-{
-    if (m_genericImpl)
-        return m_genericImpl->InsertColumn(col, heading, format, width);
-
-    wxListItem item;
-    item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
-    item.m_text = heading;
-    if ( width > -1 )
-    {
-        item.m_mask |= wxLIST_MASK_WIDTH;
-        item.m_width = width;
-    }
-    item.m_format = format;
-
-    return InsertColumn(col, item);
-}
-
 // scroll the control by the given number of pixels (exception: in list view,
 // dx is interpreted as number of columns)
 bool wxListCtrl::ScrollList(int dx, int dy)