Fix wxDataViewCtrl::GetItemRect() in wxGTK and enable its test
A couple of fixes compared to the previous commit: - Use the correct gtk_tree_view_get_cell_area() rather than gtk_tree_view_get_background_area() which doesn't work correctly for the items which are not shown because their parent is collapsed. - Translate logical coordinates to physical ones using gtk_tree_view_convert_bin_window_to_widget_coords(). With these fixes, the unit tests for this function pass and can now be enabled under wxGTK as well. See https://github.com/wxWidgets/wxWidgets/pull/990
This commit is contained in:
@@ -5304,7 +5304,15 @@ wxDataViewCtrl::GetItemRect(const wxDataViewItem& item,
|
|||||||
wxGtkTreePath path(m_internal->get_path( &iter ));
|
wxGtkTreePath path(m_internal->get_path( &iter ));
|
||||||
|
|
||||||
GdkRectangle item_rect;
|
GdkRectangle item_rect;
|
||||||
gtk_tree_view_get_background_area(GTK_TREE_VIEW(m_treeview), path, gcolumn, &item_rect);
|
gtk_tree_view_get_cell_area(GTK_TREE_VIEW(m_treeview), path, gcolumn, &item_rect);
|
||||||
|
|
||||||
|
// GTK returns rectangles with the position and height, but not width, for
|
||||||
|
// some reason, set to 0 if the item is not currently shown, so an explicit
|
||||||
|
// check is needed as this rectangle is not quite the empty rectangle we're
|
||||||
|
// supposed to return in this case.
|
||||||
|
if ( item_rect.height == 0 )
|
||||||
|
return wxRect();
|
||||||
|
|
||||||
// If column is NULL we compute the combined width of all the columns
|
// If column is NULL we compute the combined width of all the columns
|
||||||
if ( !column )
|
if ( !column )
|
||||||
{
|
{
|
||||||
@@ -5318,6 +5326,33 @@ wxDataViewCtrl::GetItemRect(const wxDataViewItem& item,
|
|||||||
}
|
}
|
||||||
item_rect.width = width;
|
item_rect.width = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need to convert logical coordinates to physical ones, i.e. the
|
||||||
|
// rectangle of the topmost item should start at ~0, even if it's a 100th
|
||||||
|
// item shown on top only because the window is scrolled.
|
||||||
|
#if GTK_CHECK_VERSION(2, 12, 0)
|
||||||
|
if ( wx_is_at_least_gtk2(12) )
|
||||||
|
{
|
||||||
|
gtk_tree_view_convert_bin_window_to_widget_coords
|
||||||
|
(
|
||||||
|
GTK_TREE_VIEW(m_treeview),
|
||||||
|
item_rect.x, item_rect.y,
|
||||||
|
&item_rect.x, &item_rect.y
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( item_rect.y > GetClientSize().y ||
|
||||||
|
item_rect.y + item_rect.height < 0 )
|
||||||
|
{
|
||||||
|
// If it turns out that the item is not visible at all, indicate it
|
||||||
|
// by returning an empty rectangle for it.
|
||||||
|
return wxRect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else: There doesn't seem to be anything reasonable to do here, so we'll
|
||||||
|
// just return wrong values with the very old GTK+ versions if the
|
||||||
|
// window is scrolled.
|
||||||
|
#endif // GTK+ 2.12+
|
||||||
|
|
||||||
return wxRectFromGDKRect(&item_rect);
|
return wxRectFromGDKRect(&item_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#include "wx/dataview.h"
|
#include "wx/dataview.h"
|
||||||
|
|
||||||
#include "testableframe.h"
|
#include "testableframe.h"
|
||||||
|
#include "asserthelper.h"
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// test class
|
// test class
|
||||||
@@ -203,8 +204,10 @@ TEST_CASE_METHOD(SingleSelectDataViewCtrlTestCase,
|
|||||||
"[wxDataViewCtrl][item]")
|
"[wxDataViewCtrl][item]")
|
||||||
{
|
{
|
||||||
#ifdef __WXGTK__
|
#ifdef __WXGTK__
|
||||||
WARN("Disabled under GTK because GetItemRect() is not implemented");
|
// We need to let the native control have some events to lay itself out.
|
||||||
#else
|
wxYield();
|
||||||
|
#endif // __WXGTK__
|
||||||
|
|
||||||
const wxRect rect1 = m_dvc->GetItemRect(m_child1);
|
const wxRect rect1 = m_dvc->GetItemRect(m_child1);
|
||||||
const wxRect rect2 = m_dvc->GetItemRect(m_child2);
|
const wxRect rect2 = m_dvc->GetItemRect(m_child2);
|
||||||
|
|
||||||
@@ -214,7 +217,11 @@ TEST_CASE_METHOD(SingleSelectDataViewCtrlTestCase,
|
|||||||
CHECK( rect1.x == rect2.x );
|
CHECK( rect1.x == rect2.x );
|
||||||
CHECK( rect1.width == rect2.width );
|
CHECK( rect1.width == rect2.width );
|
||||||
CHECK( rect1.height == rect2.height );
|
CHECK( rect1.height == rect2.height );
|
||||||
CHECK( rect1.y < rect2.y );
|
|
||||||
|
{
|
||||||
|
INFO("First child: " << rect1 << ", second one: " << rect2);
|
||||||
|
CHECK( rect1.y < rect2.y );
|
||||||
|
}
|
||||||
|
|
||||||
const wxRect rectNotShown = m_dvc->GetItemRect(m_grandchild);
|
const wxRect rectNotShown = m_dvc->GetItemRect(m_grandchild);
|
||||||
CHECK( rectNotShown == wxRect() );
|
CHECK( rectNotShown == wxRect() );
|
||||||
@@ -228,6 +235,11 @@ TEST_CASE_METHOD(SingleSelectDataViewCtrlTestCase,
|
|||||||
// This should scroll the window to bring this item into view.
|
// This should scroll the window to bring this item into view.
|
||||||
m_dvc->EnsureVisible(last);
|
m_dvc->EnsureVisible(last);
|
||||||
|
|
||||||
|
#ifdef __WXGTK__
|
||||||
|
// And again to let it scroll the correct items into view.
|
||||||
|
wxYield();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Check that this was indeed the case.
|
// Check that this was indeed the case.
|
||||||
const wxDataViewItem top = m_dvc->GetTopItem();
|
const wxDataViewItem top = m_dvc->GetTopItem();
|
||||||
CHECK( top != m_root );
|
CHECK( top != m_root );
|
||||||
@@ -242,7 +254,6 @@ TEST_CASE_METHOD(SingleSelectDataViewCtrlTestCase,
|
|||||||
// scrolled off).
|
// scrolled off).
|
||||||
const wxRect rectRoot = m_dvc->GetItemRect(m_root);
|
const wxRect rectRoot = m_dvc->GetItemRect(m_root);
|
||||||
CHECK( rectRoot == wxRect() );
|
CHECK( rectRoot == wxRect() );
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //wxUSE_DATAVIEWCTRL
|
#endif //wxUSE_DATAVIEWCTRL
|
||||||
|
Reference in New Issue
Block a user