From: Vadim Zeitlin Date: Mon, 30 Jun 2008 18:21:33 +0000 (+0000) Subject: implement wxListCtrl::GetSubItemRect() for generic version and fix bug in it in wxMSW... X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/e974c5d258bbb398b0eed38397749d1d071dbbf8 implement wxListCtrl::GetSubItemRect() for generic version and fix bug in it in wxMSW one; also added a test for it in the sample git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54437 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index 6ddbf988f2..042470ed71 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -369,6 +369,7 @@ All (GUI): - Added wxImage::GetType() (troelsk). - Added wxGenericStaticBitmap suitable for display of large bitmaps. - Support wxListCtrl::GetViewRect() in report view too. +- Implement wxListCtrl::GetSubItemRect() in generic version (David Barnard). wxGTK: diff --git a/include/wx/generic/listctrl.h b/include/wx/generic/listctrl.h index 7d4b995b15..65ee0336e6 100644 --- a/include/wx/generic/listctrl.h +++ b/include/wx/generic/listctrl.h @@ -80,6 +80,7 @@ public: bool SetItemPtrData(long item, wxUIntPtr data); bool SetItemData(long item, long data) { return SetItemPtrData(item, data); } bool GetItemRect( long item, wxRect& rect, int code = wxLIST_RECT_BOUNDS ) const; + bool GetSubItemRect( long item, long subItem, wxRect& rect, int code = wxLIST_RECT_BOUNDS ) const; bool GetItemPosition( long item, wxPoint& pos ) const; bool SetItemPosition( long item, const wxPoint& pos ); // not supported in wxGLC int GetItemCount() const; diff --git a/samples/listctrl/listtest.cpp b/samples/listctrl/listtest.cpp index 629fa4a6a7..508ccfde34 100644 --- a/samples/listctrl/listtest.cpp +++ b/samples/listctrl/listtest.cpp @@ -970,6 +970,27 @@ void MyListCtrl::OnListKeyDown(wxListEvent& event) } break; + case '1': // show sub item bounding rectangle + case '2': + case '3': + case '4': // this column is invalid but we want to test it too + if ( InReportView() ) + { + int subItem = event.GetKeyCode() - '1'; + item = event.GetIndex(); + wxRect r; + if ( !GetSubItemRect(item, subItem, r) ) + { + wxLogError(_T("Failed to retrieve rect of item %ld column %d"), item, subItem + 1); + break; + } + + wxLogMessage(_T("Bounding rect of item %ld column %d is (%d, %d)-(%d, %d)"), + item, subItem + 1, + r.x, r.y, r.x + r.width, r.y + r.height); + } + break; + case 'U': // update if ( !IsVirtual() ) break; diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 8c886803cc..613d65a38e 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -639,7 +639,11 @@ public: void SetItemState( long item, long state, long stateMask ); void SetItemStateAll( long state, long stateMask ); int GetItemState( long item, long stateMask ) const; - void GetItemRect( long index, wxRect &rect ) const; + bool GetItemRect( long item, wxRect &rect ) const + { + return GetSubItemRect(item, wxLIST_GETSUBITEMRECT_WHOLEITEM, rect); + } + bool GetSubItemRect( long item, long subItem, wxRect& rect ) const; wxRect GetViewRect() const; bool GetItemPosition( long item, wxPoint& pos ) const; int GetSelectedItemCount() const; @@ -4146,10 +4150,13 @@ wxRect wxListMainWindow::GetViewRect() const return wxRect(0, 0, xMax, yMax); } -void wxListMainWindow::GetItemRect( long index, wxRect &rect ) const +bool +wxListMainWindow::GetSubItemRect(long item, long subItem, wxRect& rect) const { - wxCHECK_RET( index >= 0 && (size_t)index < GetItemCount(), - _T("invalid index in GetItemRect") ); + wxCHECK_MSG( InReportView(), false, + _T("GetSubItemRect only meaningful in report view") ); + wxCHECK_MSG( item >= 0 && (size_t)item < GetItemCount(), false, + _T("invalid item in GetSubItemRect") ); // ensure that we're laid out, otherwise we could return nonsense if ( m_dirty ) @@ -4158,9 +4165,24 @@ void wxListMainWindow::GetItemRect( long index, wxRect &rect ) const RecalculatePositions(true /* no refresh */); } - rect = GetLineRect((size_t)index); + rect = GetLineRect((size_t)item); + + // Adjust rect to specified column + if ( subItem != wxLIST_GETSUBITEMRECT_WHOLEITEM ) + { + wxCHECK_MSG( subItem >= 0 && subItem < GetColumnCount(), false, + _T("invalid subItem in GetSubItemRect") ); + + for (int i = 0; i < subItem; i++) + { + rect.x += GetColumnWidth(i); + } + rect.width = GetColumnWidth(subItem); + } CalcScrolledPosition(rect.x, rect.y, &rect.x, &rect.y); + + return true; } bool wxListMainWindow::GetItemPosition(long item, wxPoint& pos) const @@ -5261,11 +5283,22 @@ wxRect wxGenericListCtrl::GetViewRect() const return m_mainWin->GetViewRect(); } -bool wxGenericListCtrl::GetItemRect( long item, wxRect &rect, int WXUNUSED(code) ) const +bool wxGenericListCtrl::GetItemRect(long item, wxRect& rect, int code) const +{ + return GetSubItemRect(item, wxLIST_GETSUBITEMRECT_WHOLEITEM, rect, code); +} + +bool wxGenericListCtrl::GetSubItemRect(long item, + long subItem, + wxRect& rect, + int WXUNUSED(code)) const { - m_mainWin->GetItemRect( item, rect ); + if ( !m_mainWin->GetSubItemRect( item, subItem, rect ) ) + return false; + if ( m_mainWin->HasHeader() ) rect.y += m_headerHeight + 1; + return true; } @@ -5277,7 +5310,7 @@ bool wxGenericListCtrl::GetItemPosition( long item, wxPoint& pos ) const bool wxGenericListCtrl::SetItemPosition( long WXUNUSED(item), const wxPoint& WXUNUSED(pos) ) { - return 0; + return false; } int wxGenericListCtrl::GetItemCount() const diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index ef81fecd0c..d8a3184294 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -1141,7 +1141,12 @@ bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const */ bool wxListCtrl::GetSubItemRect(long item, long subItem, wxRect& rect, int code) const { - RECT rectWin; + // ListView_GetSubItemRect() doesn't do subItem error checking and returns + // true even for the out of range values of it (even if the results are + // completely bogus in this case), so we check item validity ourselves + wxCHECK_MSG( subItem == wxLIST_GETSUBITEMRECT_WHOLEITEM || + (subItem >= 0 && subItem < GetColumnCount()), + false, _T("invalid sub item index") ); int codeWin; if ( code == wxLIST_RECT_BOUNDS ) @@ -1156,27 +1161,26 @@ bool wxListCtrl::GetSubItemRect(long item, long subItem, wxRect& rect, int code) codeWin = LVIR_BOUNDS; } - bool success; - if( subItem == wxLIST_GETSUBITEMRECT_WHOLEITEM) - { - success = ListView_GetItemRect(GetHwnd(), (int) item, &rectWin, codeWin) != 0; - } - else if( subItem >= 0) - { - success = ListView_GetSubItemRect( GetHwnd(), (int) item, (int) subItem, codeWin, &rectWin) != 0; - } - else + RECT rectWin; + if ( !ListView_GetSubItemRect + ( + GetHwnd(), + item, + subItem == wxLIST_GETSUBITEMRECT_WHOLEITEM ? 0 : subItem, + codeWin, + &rectWin + ) ) { - wxFAIL_MSG( _T("incorrect subItem number in GetSubItemRect()") ); - return false; + return false; } - rect.x = rectWin.left; - rect.y = rectWin.top; - rect.width = rectWin.right - rectWin.left; - rect.height = rectWin.bottom - rectWin.top; + wxCopyRECTToRect(rectWin, rect); - return success; + // for the first sub item, i.e. the main item itself, the returned rect is + // the whole line one, we need to truncate it at first column ourselves + rect.width = GetColumnWidth(0); + + return true; }