]> git.saurik.com Git - wxWidgets.git/commitdiff
added wxListBox::HitTest() from Ryan (patch 1446207)
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 9 Mar 2006 12:48:52 +0000 (12:48 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 9 Mar 2006 12:48:52 +0000 (12:48 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37923 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
docs/latex/wx/listbox.tex
include/wx/gtk/listbox.h
include/wx/listbox.h
include/wx/mac/carbon/listbox.h
include/wx/msw/listbox.h
samples/listbox/lboxtest.cpp
src/gtk/listbox.cpp
src/mac/carbon/listbox.cpp
src/msw/listbox.cpp

index d8f127eca35fc7b1a5c78ab97cae84984b0f1d92..053ee2f8b15d48e15fc598a935f55bee4f5b0896 100644 (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:
 
index 649ba91e5954ae6fa0ec1c7de535a07f45078c89..75e7b48b5bffeff86329fc7fc63e4dfa1159c1ec 100644 (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}}
index 0acc30272e1c09adab87e32116d8e50e32a29a98..7804a966254e7a39ae6fb3ea66e3e41e26635e24 100644 (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:
index 0556f805cfa4cfe0cf42aca5a48b212ce43cc000..d22b0f47d3ddb839616f67c5a6ca36097e748c7c 100644 (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)
 };
index 0d55320f544478c0d38e4e9816d89ec6d244007a..7aa58cc559e284139923ad65be000bc6af846078 100644 (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) ;
index 46acf9a572e638efdb797c7a1e40c031a9201999..1ed147948ba6009e8e7d394f2d9b3b468d10dad8 100644 (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();
index 8f92c1920a46b2b74f9863058c72aadbdd618967..d2bbec8e791cf0c1110ddaad22039b25bf9ae6b1 100644 (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;
index f6dd76bf7dcd5493eb54dcf56b9313344fed13c1..42a5fe109add23783e53d18ada8b51536e977749 100644 (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
index 8d55c0f0ba0137871485e5f8d05e62a0074b4283..1dc7a3c2e4a71f02529b196caee859a9f1cc8cad 100644 (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)
index 1f8a77955d1dc60cc3a1bd615e77391d53a4aafe..7abbf18e2b553e7c78cb29a50a577d046474fdd1 100644 (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,