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
This commit is contained in:
Stefan Csomor
2010-06-21 15:30:07 +00:00
parent 6bc5b23535
commit 20196e15ee
5 changed files with 26 additions and 108 deletions

View File

@@ -896,6 +896,7 @@ public:
// accessing content // accessing content
virtual unsigned int ListGetCount() const; virtual unsigned int ListGetCount() const;
virtual int DoListHitTest( const wxPoint& inpoint ) const;
virtual void UpdateLine( unsigned int n, wxListWidgetColumn* col = NULL ); virtual void UpdateLine( unsigned int n, wxListWidgetColumn* col = NULL );
virtual void UpdateLineToEnd( unsigned int n) ; virtual void UpdateLineToEnd( unsigned int n) ;

View File

@@ -563,6 +563,8 @@ public:
// accessing content // accessing content
virtual unsigned int ListGetCount() const = 0; virtual unsigned int ListGetCount() const = 0;
virtual int DoListHitTest( const wxPoint& inpoint ) const = 0;
}; };
// //

View File

@@ -43,7 +43,7 @@ wxWidgetImplType* wxWidgetImpl::CreateListBox( wxWindowMac* wxpeer,
return control; return control;
} }
int wxListBox::DoListHitTest(const wxPoint& inpoint) const int wxMacDataBrowserListControl::DoListHitTest(const wxPoint& inpoint) const
{ {
OSStatus err; OSStatus err;
@@ -59,7 +59,7 @@ int wxListBox::DoListHitTest(const wxPoint& inpoint) const
// get column property ID (req. for call to itempartbounds) // get column property ID (req. for call to itempartbounds)
DataBrowserTableViewColumnID colId = 0; 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")); wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserTableViewColumnProperty"));
// OK, first we need to find the first visible item we have - // 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 // until we find a visible item, but we can do a cheap calculation
// via the row height to speed things up a bit // via the row height to speed things up a bit
UInt32 scrollx, scrolly; 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")); wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserScrollPosition"));
UInt16 height; UInt16 height;
err = GetDataBrowserTableViewRowHeight(m_peer->GetControlRef(), &height); err = GetDataBrowserTableViewRowHeight(GetControlRef(), &height);
wxCHECK_MSG(err == noErr, wxNOT_FOUND, wxT("Unexpected error from GetDataBrowserTableViewRowHeight")); 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 // 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 // passing them to data browser functions which use 1-based indices
int low = scrolly / height, int low = scrolly / height,
high = GetCount() - 1; high = list->GetCount() - 1;
// search for the first visible item (note that the scroll guess above // 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 // 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; Rect bounds;
err = GetDataBrowserItemPartBounds( err = GetDataBrowserItemPartBounds(
m_peer->GetControlRef(), low + 1, colId, GetControlRef(), low + 1, colId,
kDataBrowserPropertyEnclosingPart, kDataBrowserPropertyEnclosingPart,
&bounds); // note +1 to translate to Mac ID &bounds); // note +1 to translate to Mac ID
if ( err == noErr ) if ( err == noErr )
@@ -109,7 +111,7 @@ int wxListBox::DoListHitTest(const wxPoint& inpoint) const
Rect bounds; Rect bounds;
err = GetDataBrowserItemPartBounds( err = GetDataBrowserItemPartBounds(
m_peer->GetControlRef(), mid + 1, colId, GetControlRef(), mid + 1, colId,
kDataBrowserPropertyEnclosingPart, kDataBrowserPropertyEnclosingPart,
&bounds); //note +1 to trans to mac id &bounds); //note +1 to trans to mac id
wxCHECK_MSG( err == noErr || err == errDataBrowserItemNotFound, wxCHECK_MSG( err == noErr || err == errDataBrowserItemNotFound,

View File

@@ -135,6 +135,7 @@ public :
// accessing content // accessing content
virtual unsigned int ListGetCount() const ; virtual unsigned int ListGetCount() const ;
virtual int DoListHitTest( const wxPoint& inpoint ) const;
int ListGetColumnType( int col ) int ListGetColumnType( int col )
{ {
@@ -145,6 +146,7 @@ public :
virtual void controlDoubleAction(WXWidget slf, void* _cmd, void *sender); virtual void controlDoubleAction(WXWidget slf, void* _cmd, void *sender);
protected : protected :
wxNSTableView* m_tableView ; wxNSTableView* m_tableView ;
@@ -559,108 +561,14 @@ wxWidgetImplType* wxWidgetImpl::CreateListBox( wxWindowMac* wxpeer,
return c; return c;
} }
int wxListBox::DoListHitTest(const wxPoint& WXUNUSED(inpoint)) const int wxListWidgetCocoaImpl::DoListHitTest(const wxPoint& inpoint) const
{ {
#if wxOSX_USE_CARBON // translate inpoint to listpoint via scrollview
OSStatus err; NSPoint p = wxToNSPoint( m_osxView, inpoint );
p = [m_osxView convertPoint:p toView:m_tableView];
// There are few reasons why this is complicated: // hittest using new point
// 1) There is no native HitTest function for Mac NSInteger i = [m_tableView rowAtPoint:p];
// 2) GetDataBrowserItemPartBounds only works on visible items return i;
// 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;
} }
#endif // wxUSE_LISTBOX #endif // wxUSE_LISTBOX

View File

@@ -207,6 +207,11 @@ int wxListBox::GetSelection() const
return GetListPeer()->ListGetSelection(); return GetListPeer()->ListGetSelection();
} }
int wxListBox::DoListHitTest(const wxPoint& inpoint) const
{
return GetListPeer()->DoListHitTest( inpoint );
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// display // display
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------