Implement wxTextCtrl::HitTest() for single line controls in wxGTK

Use Pango API to find the character at the given position.

Closes #18144.
This commit is contained in:
Vadim Zeitlin 2018-06-03 17:04:06 +02:00
parent 085e4c354a
commit 690b95646b
3 changed files with 50 additions and 4 deletions

View File

@ -84,6 +84,7 @@ All (GUI):
wxGTK:
- Implement wxTextCtrl::HitTest() for single line controls.
- Fix the build with glib < 2.32 (e.g. CentOS 6).
wxMSW:

View File

@ -1337,7 +1337,7 @@ public:
parameter is not modified.
Please note that this function is currently only implemented in wxUniv,
wxMSW and wxGTK2 ports and always returns @c wxTE_HT_UNKNOWN in the
wxMSW and wxGTK ports and always returns @c wxTE_HT_UNKNOWN in the
other ports.
@beginWxPerlOnly
@ -1363,7 +1363,7 @@ public:
parameters are not modified.
Please note that this function is currently only implemented in wxUniv,
wxMSW and wxGTK2 ports and always returns @c wxTE_HT_UNKNOWN in the
wxMSW and wxGTK ports and always returns @c wxTE_HT_UNKNOWN in the
other ports.
@beginWxPerlOnly

View File

@ -1465,8 +1465,53 @@ wxTextCtrl::HitTest(const wxPoint& pt, long *pos) const
{
if ( !IsMultiLine() )
{
// not supported
return wxTE_HT_UNKNOWN;
// These variables will contain the position inside PangoLayout.
int x = pt.x,
y = pt.y;
// Get the offsets of PangoLayout inside the control.
//
// Note that contrary to what GTK+ documentation implies, the
// horizontal offset already accounts for scrolling, i.e. it will be
// negative if text is scrolled.
gint ofsX = 0,
ofsY = 0;
gtk_entry_get_layout_offsets(GTK_ENTRY(m_text), &ofsX, &ofsY);
x -= ofsX;
y -= ofsY;
// And scale the coordinates for Pango.
x *= PANGO_SCALE;
y *= PANGO_SCALE;
PangoLayout* const layout = gtk_entry_get_layout(GTK_ENTRY(m_text));
int idx = -1,
ofs = 0;
if ( !pango_layout_xy_to_index(layout, x, y, &idx, &ofs) )
{
// Try to guess why did it fail.
if ( x < 0 || y < 0 )
{
if ( pos )
*pos = 0;
return wxTE_HT_BEFORE;
}
else
{
if ( pos )
*pos = wxTextEntry::GetLastPosition();
return wxTE_HT_BEYOND;
}
}
if ( pos )
*pos = idx;
return wxTE_HT_ON_TEXT;
}
int x, y;