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:
@@ -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) ;
|
||||||
|
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@@ -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,
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user