added wxListBox::HitTest() from Ryan (patch 1446207)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37923 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2006-03-09 12:48:52 +00:00
parent 22d29469a0
commit c00fed0ef4
10 changed files with 157 additions and 0 deletions

View File

@ -91,6 +91,7 @@ All (GUI):
- Implemented wxDisplay::GetFromWindow() for platforms other than MSW.
- UpdateUI handler can now show/hide the window too (Ronald Weiss)
- More than one filter allowed in in wxDocTemplate filter.
- Added wxListBox::HitTest()
wxMSW:

View File

@ -201,6 +201,25 @@ parameter for wxPython, which is a list of strings.}
\perlnote{In wxPerl there is just an array reference in place of {\tt nItems}
and {\tt items}.}
\membersection{wxListBox::HitTest}\label{wxlistboxhittest}
\constfunc{int}{HitTest}{\param{const wxPoint&}{ point}}
Returns the item located at \arg{point}, or \texttt{wxNOT\_FOUND} if there
is no item located at \arg{point}.
\newsince{2.7.0}. It is currently implemented for wxMSW, wxMac and wxGTK2
ports.
\wxheading{Parameters}
\docparam{point}{Point of item (in client coordinates) to obtain}
\wxheading{Return value}
Item located at \arg{point}, or \texttt{wxNOT\_FOUND} if unimplemented
or the item does not exist.
\membersection{wxListBox::IsSelected}\label{wxlistboxisselected}
\constfunc{bool}{IsSelected}{\param{int}{ n}}

View File

@ -114,6 +114,8 @@ protected:
virtual void* DoGetItemClientData(int n) const;
virtual void DoSetItemClientObject(int n, wxClientData* clientData);
virtual wxClientData* DoGetItemClientObject(int n) const;
virtual int DoListHitTest(const wxPoint& point) const;
void DoApplyWidgetStyle(GtkRcStyle *style);
private:

View File

@ -107,6 +107,9 @@ public:
// instead
bool Selected(int n) const { return IsSelected(n); }
// returns the item number at a point or wxNOT_FOUND
int HitTest(const wxPoint& point) const { return DoListHitTest(point); }
protected:
// NB: due to wxGTK implementation details, DoInsert() is implemented
// using DoInsertItems() and not the other way round
@ -121,6 +124,10 @@ protected:
virtual void DoSetSelection(int n, bool select) = 0;
// there is already wxWindow::DoHitTest() so call this one differently
virtual int DoListHitTest(const wxPoint& WXUNUSED(point)) const
{ return wxNOT_FOUND; }
DECLARE_NO_COPY_CLASS(wxListBoxBase)
};

View File

@ -113,6 +113,7 @@ protected:
virtual void DoSetItemClientObject(int n, wxClientData* clientData);
virtual wxClientData* DoGetItemClientObject(int n) const;
virtual void DoSetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO);
virtual int DoListHitTest(const wxPoint& point) const;
void MacDelete( int n ) ;
void MacInsert( int n , const wxString& item) ;

View File

@ -142,6 +142,7 @@ protected:
virtual void* DoGetItemClientData(int n) const;
virtual void DoSetItemClientObject(int n, wxClientData* clientData);
virtual wxClientData* DoGetItemClientObject(int n) const;
virtual int DoListHitTest(const wxPoint& point) const;
// free memory (common part of Clear() and dtor)
void Free();

View File

@ -124,6 +124,7 @@ protected:
void OnListbox(wxCommandEvent& event);
void OnListboxDClick(wxCommandEvent& event);
void OnListboxRDown(wxMouseEvent& event);
void OnCheckOrRadioBox(wxCommandEvent& event);
@ -487,6 +488,9 @@ LboxTestFrame::LboxTestFrame(const wxString& title)
m_logTarget = new LboxLogger(m_lboxLog, wxLog::GetActiveTarget());
wxLog::SetActiveTarget(m_logTarget);
#endif // wxUSE_LOG
m_lbox->Connect(wxEVT_RIGHT_DOWN,
wxMouseEventHandler(LboxTestFrame::OnListboxRDown), NULL, this);
}
LboxTestFrame::~LboxTestFrame()
@ -699,6 +703,18 @@ void LboxTestFrame::OnListboxDClick(wxCommandEvent& event)
wxLogMessage(_T("Listbox item %d double clicked"), sel);
}
void LboxTestFrame::OnListboxRDown(wxMouseEvent& event)
{
int item = m_lbox->HitTest(event.GetPosition());
if ( item != wxNOT_FOUND )
wxLogMessage(_T("Listbox item %d right clicked"), item);
else
wxLogMessage(_T("Listbox right clicked but no item clicked upon"));
event.Skip();
}
void LboxTestFrame::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
{
m_dirty = true;

View File

@ -1015,6 +1015,30 @@ void wxListBox::DoSetFirstItem( int n )
gtk_adjustment_set_value( adjustment, y );
}
// ----------------------------------------------------------------------------
// hittest
// ----------------------------------------------------------------------------
int wxListBox::DoListHitTest(const wxPoint& point)
{
//Need to translate from master window since it is in client coords
gint binx, biny;
gdk_window_get_geometry(gtk_tree_view_get_bin_window(m_treeview),
&binx, &biny, NULL, NULL, NULL);
GtkTreePath* path;
if(!gtk_tree_view_get_path_at_pos(m_treeview,
point.x - binx, point.y - biny,
&path, NULL, NULL, NULL)) //last two == x,y rel to cell
{
return wxNOT_FOUND;
}
int index = gtk_tree_path_get_indices(path)[0];
gtk_tree_path_free(path);
return index;
}
// ----------------------------------------------------------------------------
// helpers

View File

@ -782,6 +782,82 @@ void wxListBox::MacScrollTo( int n )
verify_noerr( m_peer->RevealItem( id , kTextColumnId , kDataBrowserRevealWithoutSelecting ) ) ;
}
int wxListBox::DoListHitTest(const wxPoint& point) const
{
//Yuck - there is no easy way to get a databrowseritem from a point
//so we need to iterate through our items to see which one this falls under
int count = GetCount();
DataBrowserTableViewColumnID colId = 0;
//Get column property id (req. for call to itempartbounds)
GetDataBrowserTableViewColumnProperty(m_peer->GetControlRef(), 0, &colId);
for(int i = 1; i <= count; ++i)
{
Rect bounds;
GetDataBrowserItemPartBounds(m_peer->GetControlRef(), i, colId,
kDataBrowserPropertyEnclosingPart,
&bounds);
//translate to client coords
MacRootWindowToWindow(&bounds.left, &bounds.top);
MacRootWindowToWindow(&bounds.right, &bounds.bottom);
#if 0 //debugging :)
wxPrintf(wxT("L:%i R:%i T:%i B:%i HT:%i,%i\n"),
bounds.left, bounds.right,
bounds.top, bounds.bottom,
point.x, point.y);
fflush(stdout);
#endif
//if point is within the bounds, return this item
if( (point.x >= bounds.left && point.x <= bounds.right) &&
(point.y >= bounds.top && point.y <= bounds.bottom) )
{
return i - 1; //found
}
}
return wxNOT_FOUND;
}
int wxListBox::MacHitTest(const wxPoint& point)
{
//Yuck - there is no easy way to get a databrowseritem from a point
//so we need to iterate through our items to see which one this falls under
// TODO: binary search would be faster
int count = GetCount();
DataBrowserTableViewColumnID colId = 0;
//Get column property id (req. for call to itempartbounds)
GetDataBrowserTableViewColumnProperty(m_peer->GetControlRef(), 0, &colId);
for(int i = 1; i <= count; ++i)
{
Rect bounds;
GetDataBrowserItemPartBounds(m_peer->GetControlRef(), i, colId,
kDataBrowserPropertyEnclosingPart,
&bounds);
//translate to client coords
//
// TODO: it would probably be more efficient to translate point to
// screen coordinates once outside of the loop
MacRootWindowToWindow(&bounds.left, &bounds.top);
MacRootWindowToWindow(&bounds.right, &bounds.bottom);
//if point is within the bounds, return this item
if( (point.x >= bounds.left && point.x <= bounds.right) &&
(point.y >= bounds.top && point.y <= bounds.bottom) )
{
return i - 1; //found
}
}
return wxNOT_FOUND;
}
#if !TARGET_API_MAC_OSX
void wxListBox::OnChar(wxKeyEvent& event)

View File

@ -552,6 +552,16 @@ wxListBox::DoInsertItems(const wxArrayString& items, int pos)
InvalidateBestSize();
}
int wxListBox::DoListHitTest(const wxPoint& point) const
{
LRESULT lRes = ::SendMessage(GetHwnd(), LB_ITEMFROMPOINT,
0L, MAKELONG(point.x, point.y));
// non zero high-order word means that this item is outside of the client
// area, IOW the point is outside of the listbox
return HIWORD(lRes) ? wxNOT_FOUND : lRes;
}
void wxListBox::SetString(int N, const wxString& s)
{
wxCHECK_RET( N >= 0 && N < m_noItems,