From 20196e15ee74362130799968e1ac716b2c705836 Mon Sep 17 00:00:00 2001 From: Stefan Csomor Date: Mon, 21 Jun 2010 15:30:07 +0000 Subject: [PATCH] adding HitTest to osx_cocoa implementation of listbox, refactoring code, fixes #11972 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64670 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/osx/carbon/private.h | 1 + include/wx/osx/core/private.h | 2 + src/osx/carbon/listbox.cpp | 16 +++-- src/osx/cocoa/listbox.mm | 112 +++----------------------------- src/osx/listbox_osx.cpp | 5 ++ 5 files changed, 27 insertions(+), 109 deletions(-) diff --git a/include/wx/osx/carbon/private.h b/include/wx/osx/carbon/private.h index ab0cee5b83..647db702c7 100644 --- a/include/wx/osx/carbon/private.h +++ b/include/wx/osx/carbon/private.h @@ -896,6 +896,7 @@ public: // accessing content virtual unsigned int ListGetCount() const; + virtual int DoListHitTest( const wxPoint& inpoint ) const; virtual void UpdateLine( unsigned int n, wxListWidgetColumn* col = NULL ); virtual void UpdateLineToEnd( unsigned int n) ; diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index be5d4cee80..d826881b42 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -563,6 +563,8 @@ public: // accessing content virtual unsigned int ListGetCount() const = 0; + + virtual int DoListHitTest( const wxPoint& inpoint ) const = 0; }; // diff --git a/src/osx/carbon/listbox.cpp b/src/osx/carbon/listbox.cpp index 55cf9e6e07..2ee41be25e 100644 --- a/src/osx/carbon/listbox.cpp +++ b/src/osx/carbon/listbox.cpp @@ -43,7 +43,7 @@ wxWidgetImplType* wxWidgetImpl::CreateListBox( wxWindowMac* wxpeer, return control; } -int wxListBox::DoListHitTest(const wxPoint& inpoint) const +int wxMacDataBrowserListControl::DoListHitTest(const wxPoint& inpoint) const { OSStatus err; @@ -59,7 +59,7 @@ int wxListBox::DoListHitTest(const wxPoint& inpoint) const // get column property ID (req. for call to itempartbounds) DataBrowserTableViewColumnID colId = 0; - err = GetDataBrowserTableViewColumnProperty(m_peer->GetControlRef(), 0, &colId); + err = GetDataBrowserTableViewColumnProperty(GetControlRef(), 0, &colId); wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserTableViewColumnProperty")); // OK, first we need to find the first visible item we have - @@ -68,17 +68,19 @@ int wxListBox::DoListHitTest(const wxPoint& inpoint) const // until we find a visible item, but we can do a cheap calculation // via the row height to speed things up a bit UInt32 scrollx, scrolly; - err = GetDataBrowserScrollPosition(m_peer->GetControlRef(), &scrollx, &scrolly); + err = GetDataBrowserScrollPosition(GetControlRef(), &scrollx, &scrolly); wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserScrollPosition")); UInt16 height; - err = GetDataBrowserTableViewRowHeight(m_peer->GetControlRef(), &height); + err = GetDataBrowserTableViewRowHeight(GetControlRef(), &height); wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserTableViewRowHeight")); + wxListBox *list = wxDynamicCast( GetWXPeer() , wxListBox ); + // these indices are 0-based, as usual, so we need to add 1 to them when // passing them to data browser functions which use 1-based indices int low = scrolly / height, - high = GetCount() - 1; + high = list->GetCount() - 1; // search for the first visible item (note that the scroll guess above // is the low bounds of where the item might lie so we only use that as a @@ -87,7 +89,7 @@ int wxListBox::DoListHitTest(const wxPoint& inpoint) const { Rect bounds; err = GetDataBrowserItemPartBounds( - m_peer->GetControlRef(), low + 1, colId, + GetControlRef(), low + 1, colId, kDataBrowserPropertyEnclosingPart, &bounds); // note +1 to translate to Mac ID if ( err == noErr ) @@ -109,7 +111,7 @@ int wxListBox::DoListHitTest(const wxPoint& inpoint) const Rect bounds; err = GetDataBrowserItemPartBounds( - m_peer->GetControlRef(), mid + 1, colId, + GetControlRef(), mid + 1, colId, kDataBrowserPropertyEnclosingPart, &bounds); //note +1 to trans to mac id wxCHECK_MSG( err == noErr || err == errDataBrowserItemNotFound, diff --git a/src/osx/cocoa/listbox.mm b/src/osx/cocoa/listbox.mm index e4dc3d3aa6..02a4c62f00 100644 --- a/src/osx/cocoa/listbox.mm +++ b/src/osx/cocoa/listbox.mm @@ -135,6 +135,7 @@ public : // accessing content virtual unsigned int ListGetCount() const ; + virtual int DoListHitTest( const wxPoint& inpoint ) const; int ListGetColumnType( int col ) { @@ -145,6 +146,7 @@ public : virtual void controlDoubleAction(WXWidget slf, void* _cmd, void *sender); + protected : wxNSTableView* m_tableView ; @@ -559,108 +561,14 @@ wxWidgetImplType* wxWidgetImpl::CreateListBox( wxWindowMac* wxpeer, return c; } -int wxListBox::DoListHitTest(const wxPoint& WXUNUSED(inpoint)) const -{ -#if wxOSX_USE_CARBON - OSStatus err; - - // There are few reasons why this is complicated: - // 1) There is no native HitTest function for Mac - // 2) GetDataBrowserItemPartBounds only works on visible items - // 3) We can't do it through GetDataBrowserTableView[Item]RowHeight - // because what it returns is basically inaccurate in the context - // of the coordinates we want here, but we use this as a guess - // for where the first visible item lies - - wxPoint point = inpoint; - - // get column property ID (req. for call to itempartbounds) - DataBrowserTableViewColumnID colId = 0; - err = GetDataBrowserTableViewColumnProperty(m_peer->GetControlRef(), 0, &colId); - wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserTableViewColumnProperty")); - - // OK, first we need to find the first visible item we have - - // this will be the "low" for our binary search. There is no real - // easy way around this, as we will need to do a SLOW linear search - // until we find a visible item, but we can do a cheap calculation - // via the row height to speed things up a bit - UInt32 scrollx, scrolly; - err = GetDataBrowserScrollPosition(m_peer->GetControlRef(), &scrollx, &scrolly); - wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserScrollPosition")); - - UInt16 height; - err = GetDataBrowserTableViewRowHeight(m_peer->GetControlRef(), &height); - wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserTableViewRowHeight")); - - // these indices are 0-based, as usual, so we need to add 1 to them when - // passing them to data browser functions which use 1-based indices - int low = scrolly / height, - high = GetCount() - 1; - - // search for the first visible item (note that the scroll guess above - // is the low bounds of where the item might lie so we only use that as a - // starting point - we should reach it within 1 or 2 iterations of the loop) - while ( low <= high ) - { - Rect bounds; - err = GetDataBrowserItemPartBounds( - m_peer->GetControlRef(), low + 1, colId, - kDataBrowserPropertyEnclosingPart, - &bounds); // note +1 to translate to Mac ID - if ( err == noErr ) - break; - - // errDataBrowserItemNotFound is expected as it simply means that the - // item is not currently visible -- but other errors are not - wxCHECK_MSG( err == errDataBrowserItemNotFound, wxNOT_FOUND, - wxT("Unexpected error from GetDataBrowserItemPartBounds") ); - - low++; - } - - // NOW do a binary search for where the item lies, searching low again if - // we hit an item that isn't visible - while ( low <= high ) - { - int mid = (low + high) / 2; - - Rect bounds; - err = GetDataBrowserItemPartBounds( - m_peer->GetControlRef(), mid + 1, colId, - kDataBrowserPropertyEnclosingPart, - &bounds); //note +1 to trans to mac id - wxCHECK_MSG( err == noErr || err == errDataBrowserItemNotFound, - wxNOT_FOUND, - wxT("Unexpected error from GetDataBrowserItemPartBounds") ); - - if ( err == errDataBrowserItemNotFound ) - { - // item not visible, attempt to find a visible one - // search lower - high = mid - 1; - } - else // visible item, do actual hitttest - { - // if point is within the bounds, return this item (since we assume - // all x coords of items are equal we only test the x coord in - // equality) - if ((point.x >= bounds.left && point.x <= bounds.right) && - (point.y >= bounds.top && point.y <= bounds.bottom) ) - { - // found! - return mid; - } - - if ( point.y < bounds.top ) - // index(bounds) greater then key(point) - high = mid - 1; - else - // index(bounds) less then key(point) - low = mid + 1; - } - } -#endif - return wxNOT_FOUND; +int wxListWidgetCocoaImpl::DoListHitTest(const wxPoint& inpoint) const +{ + // translate inpoint to listpoint via scrollview + NSPoint p = wxToNSPoint( m_osxView, inpoint ); + p = [m_osxView convertPoint:p toView:m_tableView]; + // hittest using new point + NSInteger i = [m_tableView rowAtPoint:p]; + return i; } #endif // wxUSE_LISTBOX diff --git a/src/osx/listbox_osx.cpp b/src/osx/listbox_osx.cpp index 2e33ac3de6..f89fd924d0 100644 --- a/src/osx/listbox_osx.cpp +++ b/src/osx/listbox_osx.cpp @@ -207,6 +207,11 @@ int wxListBox::GetSelection() const return GetListPeer()->ListGetSelection(); } +int wxListBox::DoListHitTest(const wxPoint& inpoint) const +{ + return GetListPeer()->DoListHitTest( inpoint ); +} + // ---------------------------------------------------------------------------- // display // ---------------------------------------------------------------------------- -- 2.45.2