From 164a797204e4738fceac9ad0d3ef2b0ffffae8cb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 28 May 2006 18:10:10 +0000 Subject: [PATCH] added wxListCtrl::GetSubItemRect() and subitem hit testing (patch 1476971) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@39385 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + docs/latex/wx/listctrl.tex | 28 ++++++++++++++++- include/wx/generic/listctrl.h | 2 +- include/wx/listbase.h | 3 ++ include/wx/msw/listctrl.h | 8 +++-- samples/listctrl/listtest.cpp | 32 +++++++++++++++++++ samples/listctrl/listtest.h | 2 ++ src/generic/listctrl.cpp | 3 +- src/msw/listctrl.cpp | 59 ++++++++++++++++++++++++++++++----- 9 files changed, 126 insertions(+), 12 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 040bdaf073..f92c2afc87 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -89,6 +89,7 @@ All (GUI): - Added wxHyperlinkCtrl (Francesco Montorsi) - Added clipboard events (wxEVT_COMMAND_TEXT_COPY/CUT/PASTE) - Added wxRadioBox::SetItemToolTip() +- Added wxListCtrl::GetSubItemRect() and subitem hit testing (Agron Selimaj) - Added wxKeyEvent::GetModifiers() - Added wxDialog::SetEscapeId(). - wxItemContainerImmutable::FindString unified (affects wxRadioBox, wxListBox, diff --git a/docs/latex/wx/listctrl.tex b/docs/latex/wx/listctrl.tex index 1d8039bb5d..fb2b75828c 100644 --- a/docs/latex/wx/listctrl.tex +++ b/docs/latex/wx/listctrl.tex @@ -425,6 +425,24 @@ returns a Wx::Rect ( or undef ).} +\membersection{wxListCtrl::GetSubItemRect}\label{wxlistctrlgetsubitemrect} + +\constfunc{bool}{GetSubItemRect}{\param{long }{item}, \param{long }{subItem}, \param{wxRect\& }{rect}, \param{int }{code = wxLIST\_RECT\_BOUNDS}} + +Returns the rectangle representing the size and position, in physical +coordinates, of the given subitem, i.e. the part of the row \arg{item} in the +column \arg{subItem}. + +This method is only meaningfull when the wxListCtrl is in the report mode. If +\arg{subItem} parameter is equal to the special value +\texttt{wxLIST\_GETSUBITEMRECT\_WHOLEITEM} the return value is the same as +for \helpref{GetItemRect}{wxlistctrlgetitemrect}. + +\arg{code} can be one of \texttt{wxLIST\_RECT\_BOUNDS}, +\texttt{wxLIST\_RECT\_ICON} or \texttt{wxLIST\_RECT\_LABEL}. + + + \membersection{wxListCtrl::GetItemSpacing}\label{wxlistctrlgetitemspacing} \constfunc{wxSize}{GetItemSpacing}{\void} @@ -554,7 +572,7 @@ list or report views (this is a limitation of the native Win32 control). \membersection{wxListCtrl::HitTest}\label{wxlistctrlhittest} -\func{long}{HitTest}{\param{const wxPoint\& }{point}, \param{int\& }{flags}} +\func{long}{HitTest}{\param{const wxPoint\& }{point}, \param{int\& }{flags}, \param{long\* }{ptrSubItem}} Determines which item (if any) is at the specified point, giving details in {\it flags}. Returns index of the item or {\tt wxNOT\_FOUND} @@ -576,6 +594,14 @@ if no item is at the specified point. wxLIST\_HITTEST\_ONITEMSTATEICON.} \end{twocollist} +If \arg{ptrSubItem} is not \NULL and the wxListCtrl is in the report +mode the subitem (or column) number will also be provided. +This feature is currently only implemented under wxMSW and requires at least +comctl32.dll of verion 4.70 on the host system or the value stored in +\arg{ptrSubItem} will be always -1. To compile this feature into wxWidgets +library you need to have access to commctrl.h of version 4.70 that is provided +by Microsoft. + \pythonnote{A tuple of values is returned in the wxPython version of this method. The first value is the item id and the second is the flags value mentioned above.} diff --git a/include/wx/generic/listctrl.h b/include/wx/generic/listctrl.h index a35bc0e7a5..6d04d813d0 100644 --- a/include/wx/generic/listctrl.h +++ b/include/wx/generic/listctrl.h @@ -149,7 +149,7 @@ public: long FindItem( long start, const wxString& str, bool partial = false ); long FindItem( long start, wxUIntPtr data ); long FindItem( long start, const wxPoint& pt, int direction ); // not supported in wxGLC - long HitTest( const wxPoint& point, int& flags); + long HitTest( const wxPoint& point, int& flags, long *pSubItem = NULL ); long InsertItem(wxListItem& info); long InsertItem( long index, const wxString& label ); long InsertItem( long index, int imageIndex ); diff --git a/include/wx/listbase.h b/include/wx/listbase.h index 71f8983831..84bb31b99f 100644 --- a/include/wx/listbase.h +++ b/include/wx/listbase.h @@ -104,6 +104,9 @@ typedef int (wxCALLBACK *wxListCtrlCompare)(long item1, long item2, long sortDat #define wxLIST_HITTEST_ONITEM (wxLIST_HITTEST_ONITEMICON | wxLIST_HITTEST_ONITEMLABEL | wxLIST_HITTEST_ONITEMSTATEICON) +// GetSubItemRect constants +#define wxLIST_GETSUBITEMRECT_WHOLEITEM -1l + // Flags for GetNextItem (MSW only except wxLIST_NEXT_ALL) enum { diff --git a/include/wx/msw/listctrl.h b/include/wx/msw/listctrl.h index 92adaffc37..2008397f8f 100644 --- a/include/wx/msw/listctrl.h +++ b/include/wx/msw/listctrl.h @@ -2,7 +2,7 @@ // Name: wx/msw/listctrl.h // Purpose: wxListCtrl class // Author: Julian Smart -// Modified by: +// Modified by: Agron Selimaj // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart @@ -174,6 +174,9 @@ public: // Gets the item rectangle bool GetItemRect(long item, wxRect& rect, int code = wxLIST_RECT_BOUNDS) const ; + // Gets the subitem rectangle in report mode + bool GetSubItemRect(long item, long subItem, wxRect& rect, int code = wxLIST_RECT_BOUNDS) const ; + // Gets the item position bool GetItemPosition(long item, wxPoint& pos) const ; @@ -293,7 +296,8 @@ public: // Determines which item (if any) is at the specified point, // giving details in 'flags' (see wxLIST_HITTEST_... flags above) - long HitTest(const wxPoint& point, int& flags); + // Request the subitem number as well at the given coordinate. + long HitTest(const wxPoint& point, int& flags, long* ptrSubItem = NULL); // Inserts an item, returning the index of the new item if successful, // -1 otherwise. diff --git a/samples/listctrl/listtest.cpp b/samples/listctrl/listtest.cpp index 116212c3bf..dd09aa34cc 100644 --- a/samples/listctrl/listtest.cpp +++ b/samples/listctrl/listtest.cpp @@ -125,6 +125,8 @@ BEGIN_EVENT_TABLE(MyListCtrl, wxListCtrl) EVT_CONTEXT_MENU(MyListCtrl::OnContextMenu) #endif EVT_CHAR(MyListCtrl::OnChar) + + EVT_RIGHT_DOWN(MyListCtrl::OnRightClick) END_EVENT_TABLE() IMPLEMENT_APP(MyApp) @@ -1009,6 +1011,36 @@ void MyListCtrl::OnChar(wxKeyEvent& event) } } +void MyListCtrl::OnRightClick(wxMouseEvent& event) +{ + if ( !event.ControlDown() ) + { + event.Skip(); + return; + } + + int flags; + long subitem; + long item = HitTest(event.GetPosition(), flags, &subitem); + + wxString where; + switch ( flags ) + { + case wxLIST_HITTEST_ABOVE: where = _T("above"); break; + case wxLIST_HITTEST_BELOW: where = _T("below"); break; + case wxLIST_HITTEST_NOWHERE: where = _T("nowhere near"); break; + case wxLIST_HITTEST_ONITEMICON: where = _T("on icon of"); break; + case wxLIST_HITTEST_ONITEMLABEL: where = _T("on label of"); break; + case wxLIST_HITTEST_ONITEMRIGHT: where = _T("right on"); break; + case wxLIST_HITTEST_TOLEFT: where = _T("to the left of"); break; + case wxLIST_HITTEST_TORIGHT: where = _T("to the right of"); break; + default: where = _T("not clear exactly where on"); break; + } + + wxLogMessage(_T("Right double click %s item %ld, subitem %ld"), + where.c_str(), item, subitem); +} + void MyListCtrl::LogEvent(const wxListEvent& event, const wxChar *eventName) { wxLogMessage(_T("Item %ld: %s (item text = %s, data = %ld)"), diff --git a/samples/listctrl/listtest.h b/samples/listctrl/listtest.h index 2673ce0e98..600eaf4b1a 100644 --- a/samples/listctrl/listtest.h +++ b/samples/listctrl/listtest.h @@ -76,6 +76,8 @@ public: void OnContextMenu(wxContextMenuEvent& event); #endif + void OnRightClick(wxMouseEvent& event); + private: void ShowContextMenu(const wxPoint& pos); wxLog *m_logOld; diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 99b530c7d7..d82d81b332 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -5255,7 +5255,8 @@ long wxGenericListCtrl::FindItem( long WXUNUSED(start), const wxPoint& pt, return m_mainWin->FindItem( pt ); } -long wxGenericListCtrl::HitTest( const wxPoint &point, int &flags ) +// TODO: sub item hit testing +long wxGenericListCtrl::HitTest(const wxPoint& point, int& flags, long *) { return m_mainWin->HitTest( (int)point.x, (int)point.y, flags ); } diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index 33c6741c59..e6c810ac1b 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -2,7 +2,7 @@ // Name: src/msw/listctrl.cpp // Purpose: wxListCtrl // Author: Julian Smart -// Modified by: +// Modified by: Agron Selimaj // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart @@ -1010,6 +1010,24 @@ wxRect wxListCtrl::GetViewRect() const // Gets the item rectangle bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const +{ + return GetSubItemRect( item, wxLIST_GETSUBITEMRECT_WHOLEITEM, rect, code) ; +} + +/*! + * Retrieve coordinates and size of a specified subitem of a listview control. + * This function only works if the listview control is in the report mode. + * + * @param item : Item number + * @param subItem : Subitem or column number, use -1 for the whole row including + * all columns or subitems + * @param rect : A pointer to an allocated wxRect object + * @param code : Specify the part of the subitem coordinates you need. Choices are + * wxLIST_RECT_BOUNDS, wxLIST_RECT_ICON, wxLIST_RECT_LABEL + * + * @return bool : True if successful. + */ +bool wxListCtrl::GetSubItemRect(long item, long subItem, wxRect& rect, int code) const { RECT rectWin; @@ -1022,12 +1040,24 @@ bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const codeWin = LVIR_LABEL; else { - wxFAIL_MSG( _T("incorrect code in GetItemRect()") ); - + wxFAIL_MSG( _T("incorrect code in GetItemRect() / GetSubItemRect()") ); codeWin = LVIR_BOUNDS; } - bool success = ListView_GetItemRect(GetHwnd(), (int) item, &rectWin, codeWin) != 0; + 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 + { + wxFAIL_MSG( _T("incorrect subItem number in GetSubItemRect()") ); + return false; + } rect.x = rectWin.left; rect.y = rectWin.top; @@ -1037,6 +1067,9 @@ bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const return success; } + + + // Gets the item position bool wxListCtrl::GetItemPosition(long item, wxPoint& pos) const { @@ -1478,13 +1511,24 @@ long wxListCtrl::FindItem(long start, const wxPoint& pt, int direction) // Determines which item (if any) is at the specified point, // giving details in 'flags' (see wxLIST_HITTEST_... flags above) -long wxListCtrl::HitTest(const wxPoint& point, int& flags) +long wxListCtrl::HitTest(const wxPoint& point, int& flags, long *ptrSubItem) { LV_HITTESTINFO hitTestInfo; hitTestInfo.pt.x = (int) point.x; hitTestInfo.pt.y = (int) point.y; - ListView_HitTest(GetHwnd(), & hitTestInfo); + long item; +#ifdef LVM_SUBITEMHITTEST + if ( ptrSubItem && wxApp::GetComCtl32Version() >= 470 ) + { + item = ListView_SubItemHitTest(GetHwnd(), &hitTestInfo); + *ptrSubItem = hitTestInfo.iSubItem; + } + else +#endif // LVM_SUBITEMHITTEST + { + item = ListView_HitTest(GetHwnd(), &hitTestInfo); + } flags = 0; @@ -1519,9 +1563,10 @@ long wxListCtrl::HitTest(const wxPoint& point, int& flags) flags |= wxLIST_HITTEST_ONITEMSTATEICON; } - return (long) hitTestInfo.iItem; + return item; } + // Inserts an item, returning the index of the new item if successful, // -1 otherwise. long wxListCtrl::InsertItem(const wxListItem& info) -- 2.45.2